“双十一、二” 业务高峰如何扛住?韵达快递选择 TDengine
小 T 导读:
为了有效处理每日亿级的数据量,早在 2021 年,韵达就选择用 TDengine 替代了 MySQL,并在三台服务器上成功部署和上线了 TDengine 2.0 集群。如今,随着 TDengine 3.0 版本的逐渐成熟,韵达决定将现有的 2.0 版本升级到 3.0 版本,并基于本文为大家分享其在升级过程中所进行的优化措施以及升级后的性能表现。
作为一家头部物流公司,韵达每日的订单扫描量破亿级别,该类数据为典型的时序数据,这也是我们公司数据量最大的一块业务。系统需要汇总统计全国网点的扫描数据(韵达的所有订单数据),并实时反馈给用户。此外,这些数据也会给到网点、分拨中心的内部员工使用,用于个人工作量、站点扫描量等统计工作。在“双十一、二”期间,面对快递业务量的暴涨,TDengine 帮助我们很好地完成了既定规划,保障了“双十一、二”任务的顺利完成。
本文用于分享我司在 TDengine 上使用的历程和心得。
从 2.0 到 3.0
在早些年业务尚未扩张时,我们采用的是 MySQL 分区+索引方式进行扫描枪数据的处理,但随着企业的发展、业务量的增加,面对每日亿级的数据量,MySQL 显然已经无法满足当下的数据处理需求。
在这种背景下,我们决定进行时序数据库(Time Series Database)选型。经过严格的选项测试,我们最终选择了 TDengine 作为核心数据库处理该部分数据。在 2021 年,我们在三台 16C 64G 的服务器上部署上线了 TDengine 2.0 版本集群。(“一个扫描枪一张表”,韵达选择 TDengine 应对每日亿级数据量 - TDengine | 涛思数据)
该集群每天要承载日常 6 亿行数据的写入和一定量的查询,“双十一、二”等特殊业务期间,写入/查询量还要上涨 50% 左右,数据需要保留 2 个月。
我们的架构是 Spring Boot + MyBatis + MySQL + TDengine,TDengine 负责处理时序数据,MySQL 则负责非时序数据的存储及应用,如下:
使用 2.0 的这两年数据库是很稳定的,但考虑到后期业务需求会用到 3.0 的新特性,所以我们自打 TDengine 3.0 发布之后,就一直在着手准备数据库的迁移工作。
数据迁移经验分享
数据库迁移是一项很重大的工作,在此期间,我们仔细梳理了 2.0 版本使用期间的一些使用情况,尝试做出针对性的优化。
在 2.0 时期,我们是根据“一个扫描枪一张表”的模型建表,把设备的地点和站点类型设置为标签。来到 3.0 时期后,我们和官方团队反复调试,选择了“一个站点一张表”的建模方式。这样一来,表数量从百万级直接缩减到了万级。
做这个改动的核心原因有两个:
- 我们有很多临时的虚拟扫描枪,由于只是临时使用,所以没有几条数据,但却单独占据了一个表。
- 虽然扫描枪写入频率较低,但是整个站点有很多扫描枪,这样的建模方式使得低频写入转化为了高频写入,降低了存储中碎片数据的比例。
2.x 超级表结构:
优化过后,3.x 超级表的结构:
除此之外,3.0 由于底层有很多的重构,因此和 2.0 相比出现了很多的参数改动,可以参考:配置参数 | TDengine 文档 | 涛思数据,数据库 | TDengine 文档 | 涛思数据。优化思路可以参考这篇文章中的内容:万字解读|怎样激活 TDengine 最高性价比? - TDengine | 涛思数据。
尤其是 3.0 关于数据入库频率、数据乱序、更新、建表等处理逻辑的变化,均需要投入一定量的学习测试时间。尤其是在数据量极大的情况下,每一次测试环境的搭建都需要较大的时间人力成本。我们在 TDengine 官方团队的协助下,断断续续大概用了 2 个月的时间才完成这个阶段。
优化效果显著
最终优化过后,我们的查询速度得到了进一步提升。尤其是下面这类查询优化效果十分明显,该查询的逻辑是:从 6 亿行的当天数据中,通过标签、普通列做出多次筛选,最终返回分页后的十条结果。其中,最为耗时的便是从标签过滤之后的 1.5 亿条数据的普通列筛选。
在 2.6 版本中,这个过程需要大约 10 秒的时间,升级到 3.x 之后,只需要 2-3 秒左右便会返回结果:
select waybill_barcode,location,scanning_person,equipment_code,scan_category,remark,weight_info weight,scan_time,volume,lower_location,lrfs from base.scan_data WHERE ts >= #{beginTime} and ts <= #{endTime} and site_type=#{siteType} and equipment_code = #{equipmentCode} limit 0,10;
至此,我们从 TDengine 2.0 迁移到 3.0 版本的工作就圆满完成了。
写在最后
对于我们这种集快递、物流、电子商务配送和仓储服务为一体的快递企业,扫描枪设备产生的数据是相当庞大的,而 TDengine 可以轻松高效地处理和存储这些时序数据,它所具备的快速写入和查询的能力,使得我们的系统可以轻松应对高负载和大规模数据的需求。
落实到业务使用方面,通过实时了解包裹状态、配送进度等信息,我们能够更加方便地做出实时决策,物流运营的效率和效果也获得了大幅提高。
文章最后,祝 TDengine 越来越好,早日成为时序数据库领域的 NO.1。
了解更多 TDengine Database的具体细节,可在GitHub上查看相关源代码。
相关文章:

“双十一、二” 业务高峰如何扛住?韵达快递选择 TDengine
小 T 导读: 为了有效处理每日亿级的数据量,早在 2021 年,韵达就选择用 TDengine 替代了 MySQL,并在三台服务器上成功部署和上线了 TDengine 2.0 集群。如今,随着 TDengine 3.0 版本的逐渐成熟,韵达决定将现…...

STM32L432+LIS3DH【加速度传感器】:端侧AI
一、搜集芯片资料 1.LIS3DHTR:加速度传感器 查找链接: https://www.st.com/zh/mems-and-sensors/lis3dh.html 2. NUCLEO-L432KC:芯片 查找连接: https://www.st.com/zh/evaluation-tools/nucleo-l432kc.html#cad-resources 1.原理图 引…...
VCG Mesh刚性旋转(变换矩阵)
文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 旋转矩阵如果从线性空间的角度来看,它类似于一个投影过程。假设坐标 P ( x 1 , y 1 , z 1 ) P(x_1,y_1,z_1)...
R语言【base】——system.file() 在软件包等中查找文件的完整文件名。
Package base version 4.3.2 Parameters system.file(..., package "base", lib.loc NULL,mustWork FALSE) 参数【...】:字符向量,指定某个软件包中的子目录和文件。默认情况下,没有值则返回软件包的根目录。不支持通配符。 …...

HTML制作暴雨特效
🎀效果展示 🎀代码展示 <body> <!-- partial:index.partial.html --> <canvas id="canvas-club">...

cesium实现区域贴图及加载多个gif动图
1、cesium加载多个gif动图 Cesium的Billboard支持单帧纹理贴图,如果能够将gif动图进行解析,获得时间序列对应的每帧图片,然后按照时间序列动态更新Billboard的纹理,即可实现动图纹理效果。为此也找到了相对于好一点的第三方库libg…...

blackbox黑盒监控部署(k8s内)tensuns专用
一、前言 部署在k8s中需要用到deployment、configmap、service服务 二、部署 创建存放yaml的目录 mkdir /opt/blackbox-exporter && cd /opt/blackbox-exporter 编辑blackbox配置文件,使用configmap挂在这 vi configmap.yaml apiVersion: v1 kind: Confi…...

“C语言“——scanf()、getchar() 、putchar()、之间的关系
scanf函数说明 scanf函数是对来自于标准输入流的输入数据作格式转换,并将转换结果保存至format后面的实参所指向的对象。 而const char*format 指向的字符串为格式控制字符串,它指定了可输入的字符串以及赋值时转换方法。 简单来说给一个打印格式(输入…...

Spring Boot3 Web开发技术
前期回顾 springboot项目常见的配置文件类型有哪些?哪种类型的优先级最高 yml properties yaml 读取配置文件里的数据用什么注解? value restful风格 RESTful 风格与传统的 HTTP 请求方式相比,更加简洁,安全,能隐…...

学习笔记:数据挖掘与机器学习
文章目录 一、数据挖掘、机器学习、深度学习的区别(一)数据挖掘(二)机器学习(三)深度学习(四)总结 二、数据挖掘体系三、数据挖掘的流程四、典型的数据挖掘系统 一、数据挖掘、机器学…...

highcharts的甘特图设置滚动时表头固定,让其他内容跟随滚动
效果图:最左侧的分类列是跟随甘特图滚动的,因为这一列如果需要自定义,比如表格的话可能会存在行合并的情况,这个时候甘特图是没有办法做的,然后甘特图的表头又需要做滚动时固定,所以设置了甘特图滚动时&…...

ElasticSearch 架构设计
介绍 ElasticSearchMySQLIndexTableDocumentRowFieldColumnMappingSchemaQuery DSLSQLaggregationsgroup by,avg,sumcardinality去重 distinctreindex数据迁移 ElasticSearch 中的一个索引由一个或多个分片组成 每个分片包含多个 segment(分…...

HTML---定位
目录 文章目录 一.定位属性概述 二.position 基础数值 三.z-index属性 网页元素透明度 练习 一.定位属性概述 HTML中的定位属性指的是用来控制HTML元素在页面中的位置和布局的属性,包括position、top、bottom、left和right等。 position属性指定了元素的定位方式&a…...

JVM高频面试题(2023最新版)
JVM面试题 1、JVM内存区域 Jvm包含两个子系统和两个组件。 1.1子系统 Class loader(类加载器):根据给定的全限定名类名(java.lang.object)来装载class文件到Runtime data area(运行时数据区)…...

webpack学习-7.创建库
webpack学习-7.创建库 1.暴露库1.1概念1.2验证1.2.1 不导出方法1.2.2 导出方法 2.外部化 lodash3.外部化的限制4.最终步骤5.使用自己的库5.1坑 6.总结 1.暴露库 这个模块学习有点坑。看名字就是把自己写的个包传到npm,而且还要在项目中使用到它,支持各种…...
MQTT - 笔记
1 Mosquitto 官网 https://mosquitto.org/ 2 Windows环境下安装配置Mosquitto服务及入门操作介绍 Windows环境下安装配置Mosquitto服务及入门操作介绍-CSDN博客 3 开源:MQTT安装与配置使用 【C++】开源:MQTT安装与配置使用_c++ mqtt-CSDN博客 4 一文搞懂Qt-MQTT开发...
Django 安装
各位小伙伴想要博客相关资料的话,关注公众号:chuanyeTry即可领取相关资料! Django 安装 在安装 Django 前,系统需要已经安装了 Python 的开发环境。 如果你还没有安装 Python,请先从 Python 官网 https://www.python…...

推荐一个vscode看着比较舒服的主题:Dark High Contrast
主题名称:Dark High Contrast (意思就是,黑色的,高反差的) 步骤:设置→Themes→Color Theme→Dark High Contrast 效果如下: 感觉这个颜色的看起来比较舒服。...
YCSB 测试表预分区
最近使用 YCSB 测试时,一直使用如下方法创建预分区: TABLE_NAME"usertable" REGIN_SPLITS$((510-1)) cat << EOF | sudo -u hbase hbase shell create ${TABLE_NAME}, cf, {SPLITS > (1..${REGIN_SPLITS}).map {|i| "user#{100…...
K8s 教程
一文让你全面了解K8s(Kubernetes) - 知乎 Install and Set Up kubectl on Linux | Kubernetes阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 留存一份地址...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...