“一个扫描枪一张表”,韵达选择 TDengine 应对每日亿级数据量

news/2025/2/26 12:06:07

小 T 导读:此前,韵达使用 MySQL 分区+索引处理订单数据的方式遭受到了挑战,面对每日亿级的数据量,MySQL 显然已经无法满足当下的数据处理需求。为更好地发展业务,在此基础上韵达新增了 TDengine 的数据源,用专业的数据库来进行时序数据的处理。

 

作为一家头部物流公司,韵达每日的订单扫描量能达到上亿级,这也是目前公司数据量最大的一块业务。要保证业务的正常运作,系统就需要汇总统计全国网点的扫描数据(韵达的所有订单数据),并实时反馈给用户。此外,这些数据也会给到网点、分拨中心的内部员工使用,用于个人工作量、站点扫描量等统计工作。

在业务尚未扩张之前,我们采用的是 MySQL 分区+索引方式进行此类数据的处理,但随着企业的发展、业务量的增加,面对每日亿级的数据量,MySQL 显然已经无法满足当下的数据处理需求。

在这种背景下,我们决定进行数据库选型。考虑到目前业务主要是统计各个网点设备实时上传的数据,无需再进行修改等操作,是典型的时序数据。经过一番调研,我们发现时序数据库 TDengine 就很符合当下的业务要求,其数据模型与我们的场景十分契合,基于百亿千亿级大数据量的查询性能也很强悍。在对 TDengine Database 进行实际测试与使用后,实际的效果也让我们很满意。

一、落地实践与效果展示

当前我们的架构是 Spring Boot + MyBatis + MySQL + TDengine,TDengine 负责处理时序数据,MySQL 则负责非时序数据的存储及应用,整体架构如下:

由于我们的架构未做迁移,只是新增了 TDengine 的数据源,因此没有增加很多工作量就完成了数据架构的升级。

我们目前使用 TDengine2.2.2.0 版本,在三台 16C 64G 的服务器上部署了集群,数据写入速度大概为每秒 2000 行。根据“一个扫描枪一张表”的模型建表,把设备的地点和站点类型设置为标签

为了防止设备更换地点导致标签值发生变化,我们选择在建表的时候把地点也放进表名中,这样一来,当地点发生变化后,也能通过新建一张表达到同样的使用效果。比如:scan_6100000000265_790117,代表的就是设备编号为 6100000000265 所在地址为 790117 的扫描枪,当这把扫描枪更换位置的时候,我们可以新建一张 scan_6100000000265_800000 的子表,和旧表区分开,并且同时保留两份数据。

当前,这个超级表下面已经有了近百万子表,经过 1 个多月的正式使用,保存了大约 200 亿行的数据量。

值得一提的是,基于 TDengine 常用的查询基本可以在 1 秒之内完成,一些特定查询甚至可以达到毫秒级:

  1. select location,sum(weight_info) as weightSum,count (waybill_barcode) as ticketNum from base.scan_data where ts>='2022-04-07 00:00:00' and ts<='2022-04-07 23:59:59' group by location;

展示效果如下:

  1. select waybill_barcode,location,scanning_person,scan_category,remark,weight_info weight,scan_time,volume from base.scan_data where ts>='2022-04-07 00:00:00' and ts<='2022-04-07 23:59:59' and site_type=3 limit 0,10;

展示效果如下:

在存储上可以看到,我们的超级表是 20 个字段,大部分是 int 类型,有 5 个左右是 varchar 类型,最大的字段是一个用来存储中文的 500 长度的 nchar ,大约占用300GB 不到的磁盘而此前使用 MySQL 时,光硬盘使用就需要几个TB,这还没有算上内存和 CPU 等资源,由此可见 TDengine 带来的降本增效是多么显著。

写在最后

当然,TDengine 的测试使用过程中也并非一帆风顺,我们也遇到了一些问题,放在这里供大家参考:

  • 由于对数据并发量预估不足,我们使用的默认毫秒时间精度经常会出现时间戳重复的现象,导致数据没能成功入库,后续依靠增加精度解决。
  • 超级表如果新增标签,已有数据的标签为 null,需要手动为每个子表更改标签,不够友好。
  • 由于 TDengine 建表是单线程所以是有瓶颈的,大概每秒是万张以下,所以在初步搭建环境的时候不建议使用自动建表,如果表数据量不多就无所谓了。

在与 TDengine Database 的社区工作人员反馈之后,以上问题最终都通过参数的配置优化或者合理的使用方式得到了解决,之后我们会考虑把TDengine扩展到更多业务中去。相信随着 3.0 的优化,TDengine 可以更好地融入到韵达的使用场景中,未来我们会有更加紧密的合作。


想了解更多 TDengine 的具体细节,欢迎大家在GitHub​​​​​​​上查看相关源代码。


http://www.niftyadmin.cn/n/983069.html

相关文章

MFC单文档应用程序显示图像

1 利用VS2010向导创建一个MFC单文档应用程序MFCTest 2 在MFCTestView.h中引用<atlimage.h>&#xff0c;并创建一个CImage对象 #include <atlimage.h>private:CImage image;3 打开资源文件&#xff0c;选中Menu下面的IDR_MAINFRAME&#xff0c;添加一个新的菜单项“…

替代 Elasticsearch,TDengine 助力四维图新将存储空间利用率提升 8 倍

小 T 导读&#xff1a;面对海量的车载轨迹数据&#xff0c;四维图新数据存储面对非常大的压力——每分钟的轨迹数据大概有 2000 万条记录&#xff0c;他们此前使用的 Elasticsearch 存储方式不仅造成了严重的物理资源浪费&#xff0c;还存在查询瓶颈&#xff0c;所以急需转换数…

从Github用Python安装软件包

翻译自: https://www.pybloggers.com/2015/06/install-package-in-python-from-github/

如何解决springboot整合spark日志打印级别问题?

一、由于项目中使用到了springboot框架&#xff0c;会导致springboot中的slf4j和spark中的log4j日志组件冲突&#xff0c;springboot推荐使用slf4jlogback的模式来记录日志&#xff0c;logback比log4j更快的实现、更完善的配置&#xff0c;因此&#xff1a;1、pom文件中去除依赖…

七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 【转】

http://www.cnblogs.com/powertoolsteam/p/MVC_one.html 系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 七天学会ASP.NET MVC (三)——ASP.Net MVC 数据处理 七天学会ASP.NET MVC (四)——用户授权认证问题 七天…

BOM与DOM

BOM是浏览器对象模型&#xff0c;用来获取或设置浏览器的属性、行为&#xff0c;例如&#xff1a;新建窗口、获取屏幕分辨率、浏览器版本号等。DOM是文档对象模型&#xff0c;用来获取或设置文档中标签的属性&#xff0c;例如获取或者设置input表单的value值。转载于:https://w…

rust python_用于Python程序员的Rust

rust pythonNow that Rust 1.0 is out and quite stable, I thought it might be interesting to write an introduction to Rust for Python programmers. This guide goes over the basics of the language and compares different constructs and how they behave. 现在Rust…

slf4j-api、slf4j-log4j12、log4j之间关系

Content 1. slf4j-api2. slf4j-api、slf4j-log4j12、log4j3. log4j 3.1 log4j的使用3.2 log4j配置使用 3.2.1 定义配置文件3.2.2 在代码中使用log4jx. 参考资料1. slf4j-api slf4j:Simple Logging Facade for Java&#xff0c;为java提供的简单日志Facade。Facade门面&#x…