传统库分表麻烦查询慢?TDengine 如何解决“搜狐基金”的应用难题

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 搜狐基金团队使用的 MySQL 数据库在面对海量数据时存在能力瓶颈,在此背景下,其决定基于 TDengine 尝试一下全新的方案。

该项目需要实时展示国内基金的净值和收益(货币基金),在保证满足折线图展示的功能基础上,还需要加入统计排行、分页展示等功能,为用户提供最全面实时的查询服务。此前搜狐基金团队使用的 MySQL 数据库在面对海量数据时存在能力瓶颈,在此背景下,其决定基于 TDengine 尝试一下全新的方案。

选型背景

在使用 TDengine 之前,我们使用的是 MySQL 数据库。

由于所购买的数据源的基金数据都是混在一起的,包含来自国内的2万只基金,跨越几十年(从九几年至今)的数千万行较宽的数据,如果通过 MySQL 来存储这些数据,我们首先要把每个基金的数据分表,有一定程度的工作量,所以我们决定先全量保存这些数据在一张表中。

但这种大表会导致查询的性能非常低下,为了应对这一问题,我们通过离线查询生成每天的基金数据图片返回给用户,暂未对外提供自定义查询服务。

与此同时,经历了以上种种,我们也在怀疑传统关系型数据库面对海量数据的能力瓶颈。这时候,我们了解到了 TDengine ,它的核心是一款时序数据库Time Series Database),它“一个设备一张表”的特殊设计,与我们正在做的“一个基金一张表”的分表工作不谋而合。因此我们决定基于 TDengine 尝试一下全新的方案。

使用经历

通过充分调研和测试后,我们发现:

由于“超级表”的存在,数据建模变得非常清晰,几乎所有查询都可以以“超级表”为核心用简单的 SQL 完成。

此外,由于“自动建表”这个特色功能,我们可以无需校验就能够直接建表,这让我们得以非常轻松地完成各只基金数据的拆分建表以及写入工作。

可以说,接入 TDengine 的前期准备工作十分顺利。

我们使用三台 4C 16GB 的服务器组建了 TDengine 的集群。

数据库创建语句如下:

值得一提的是,基金数据是一日一条,属于低频次数据。对于这种数据,默认的配置是不够的。一开始我们的查询性能并不快,基本都是在秒级别甚至还有更高。

通过文档和博客以及官方团队的支持,我们放大了 duration 和 stt_trigger 参数,这样确保了不会产生过多的文件碎片影响读写性能,后续的查询全部被优化至毫秒级别。

因此我们总结出来一点经验就是:不同的写入频率属于不同的业务场景,最好不要使用同一个库,而是要分库处理比较好。

超级表建模如下:

当前在日常使用时,业务查询在 100 qps 的情况下,均可以实现毫秒级实时返回数据。

从超级表的设计特点出发,我们在超级表维度上做统计分析就方便多了,比如:筛选类型和日期的全量基金查询——

select time, code, name, manager_id, manager_name, unit_net_value, pre_unit_net_value, accumulate_net_value, pre_day_rate, pre_week_rate, pre_month_rate, pre_three_month_rate, pre_half_year_rate, pre_year_rate, pre_cur_year_rate, pre_start_rate, last_time, last_unit_net_value, last_accumulate_net_value, asset_size from fund_net_value where time =#{date} and (type = '003009' or type = '003010')

又比如,查询目前基金净值排行和收益排行,通过简单的 SQL 即可实现——

select time, code, name, manager_id, manager_name, unit_net_value, pre_unit_net_value, accumulate_net_value, pre_day_rate, pre_week_rate, pre_month_rate, pre_three_month_rate, pre_half_year_rate, pre_year_rate, pre_cur_year_rate, pre_start_rate, last_time, last_unit_net_value, last_accumulate_net_value, asset_size from fund_net_value where time =#{date} and order by ${column} ${sort} limit #{offset}, #{size}

与此同时我们搭建了 Grafana 可视化监控体系,利用各种监控工具和软件来收集、存储和分析监控数据,并通过可视化界面提供实时的监控图表和警报,帮助项目相关负责人即时识别修改问题,进一步提高了服务的可靠性和稳定性。

写在最后

总而言之,在保证稳定高效运行的前提下,我们已经通过 TDengine 逐步平滑替代原有功能。考虑到国内基金项目只是一个开始,围绕着股票等其他项目,我们仍需要对这款国产时序库做更多的研究与学习。

企业简介

搜狐公司是中国著名的的综合性互联网企业,主要业务领域包括新媒体、通信以及移动增值服务,集成了娱乐中心、体育中心、时尚文化中心等多重角色。

作者介绍

武朋,搜狐智能平台高级开发工程师。

目录
相关文章
|
2月前
|
存储 数据库 流计算
TDengine 资深研发分享解决思路,长查询不再成为系统性能瓶颈!
本文探讨了如何应对和解决长查询问题,以提升 TDengine 在复杂查询场景下的表现。
52 0
|
7月前
|
存储 SQL 运维
单表 1000 万条数据,TDengine 助力麦当劳中国实现 PERCENTILE 秒级查询优化
今天我们为大家分享一个关于 TDengine 在 PERCENTILE 函数性能优化上的真实案例。
82 0
|
canal 中间件 Java
阿里终面:业务主表读写缓慢如何优化?
阿里终面:业务主表读写缓慢如何优化?
|
SQL 人工智能 NoSQL
持续九年,国际排名第一的宽表数据库概述|学习笔记
快速学习持续九年,国际排名第一的宽表数据库概述
151 0
持续九年,国际排名第一的宽表数据库概述|学习笔记
|
消息中间件 缓存 Dubbo
修正版 | 面对千万级、亿级流量怎么处理?
这是之前发过的一篇文章,写完之后小问题挺多的,于是还是重新改一版。
修正版 | 面对千万级、亿级流量怎么处理?
|
消息中间件 运维 监控
200张表,单表记录过亿,10多年核心老系统的重构之旅
200张表,单表记录过亿,10多年核心老系统的重构之旅
394 0
200张表,单表记录过亿,10多年核心老系统的重构之旅
|
存储 SQL 缓存
我是如何一步步让公司的MySQL支撑亿级流量的(上)
我是如何一步步让公司的MySQL支撑亿级流量的
186 0
我是如何一步步让公司的MySQL支撑亿级流量的(上)
|
SQL 存储 运维
我是如何一步步让公司的MySQL支撑亿级流量的(下)
我是如何一步步让公司的MySQL支撑亿级流量的
112 0
|
Cloud Native 关系型数据库 分布式数据库
独家 | 4982亿!揭秘新记录背后的数据库技术革新
揭秘2020双11新记录背后的数据库技术革新。
34449 0
独家 | 4982亿!揭秘新记录背后的数据库技术革新
|
SQL 运维 分布式计算
阿里云数据库助力完美日记深度优化数据库架构应对半年内50倍的流量增长
业务/技术亮点:高峰业务流量比半年前提高了50倍;比半年前的系统吞吐提升了50倍
3105 0
阿里云数据库助力完美日记深度优化数据库架构应对半年内50倍的流量增长