浅谈分布式数据库与时序数据库
背景
大数据部门面向全公司提供了分布式数据库StarRocks,时序数据库VictoriaMetrics和时序数据库InfluxDB。但是业务方在有新的数据接入时,由于并不了解分布式数据库与时序数据库的区别,不知道如何选择,本文将以StarRocks和VictoriaMetrics为例,从多个角度角度对比分布式与时序数据库。
数据结构对比
Field | Type | Comment |
timestamp | time | 时间 |
endpoint | tag | ip地址 |
province | tag | 省份 |
version | tag | 组件版本 |
request | field | 请求数量 |
traffic | field | 请求字节 |
以上边的测试表t为例,假设一个新的业务,部署到了10000台机器,每分钟上报1条,接下来将介绍两种数据库是怎样处理数据的。
时序数据库(VictoriaMetrics)
时序数据库的数据分为三个部分:时间戳(timestamp)、指标维度(tag)、具体的数据指标(field)。
业务接入时序数据库时,会创建共 20000 个时间序列,其中包括:
10000 个针对请求(t__request)的时间序列
10000 个针对流量(t__traffic)的时间序列
在时序数据库中,每个 field 被视为一个独立的 metric,分别创建对应的时间序列。
当这 10000 台机器首次上报数据时,时序数据库会在内存中创建相应的时间序列,这可能会带来一定的压力冲击。但从第二分钟开始,组件再次上报数据时,由于tag没有变化,内存中已能找到对应的时间序列,系统只需将时间戳和 field 值追加到时间序列的末尾,相同时间戳的数据会自动覆盖。
分布式数据库(StarRocks)
StarRocks的数据没有tag和field之分,而是key和value
Field | Type | Comment |
timestamp | key | 时间 |
endpoint | key | ip地址 |
province | key | 省份 |
version | key | 组件版本 |
request | value | 请求数量 |
traffic | value | 请求字节 |
分布式架构
StarRocks 由 BE 和 FE 两种类型的节点组成,FE 负责解析 SQL 制定查询计划,BE 负责计算和存储。数据默认存储 3 份,相同的数据默认在 3 个 BE 中存在。如果任意节点故障,集群会自动将数据复制到新的可用 BE 节点,保证数据 3 份可用,无需人工操作。
四种数据模型
明细模型(所有数据原样保留)
更新模型(key列一样时,field会被覆盖)
聚合模型(key列一样时,field会被预设聚合函数聚合)
主键模型(更新模型的上位替代)
分区与分桶
表 t 会根据 timestamp 进行分区,一般分区字段为时间字段,并且可配置为动态分区,数据库自动创建未来若干个空分区,并删除过期的旧分区。
相同分区的数据,会根据指定的分桶列进行分桶,分桶列为上面的 key 的其中一个或几个字段。
两种压缩机制
数据在每次写入StarRocks的桶时,会落盘为1个singleton file。
如果singleton file文件数量过多,查询性能会受到极大干扰。
因此当singleton file文件数量到达一定阈值时,会自动执行cumulative compact,进行累积压缩,将若干single file压缩为1个cumulative file
当cumulative file文件数量到达一定阈值时,会自动执行base compaction,将所有cumulative file和之前压缩好的base file压缩为1个base file。
通常情况下每个桶下都有1个base file + 若干cumulative file + 若干 singleton file。
关于StarRocks更深一步的原理探索详见我的另一篇文章《StarRocks源码阅读系列(3)compaction 压缩机制》
测试数据写入
以上面的测试数据为例,10000行数据每分钟写入1次,数据经过分区和分桶后落入BE节点,默认3副本存储,多次写入后,定期执行cumulative copact和base compact两种压缩。
优劣势对比
时序数据库(VictoriaMetrics)
优势
- 数据占用空间小,时间序列创建完成后,新数据仅存储field和时间字段
- 时延低,新数据可直接落入对应时间序列
- 支持promQL协议,与Grafana契合度高,运维人员上手绘图难度低。
- 表结构修改便捷,如果要加一个新的tag,不用通知数据库,直接上报即可,时序数据库会因此创建新的时间序列,接收并处理数据。
劣势
- 运维成本高,稳定性差 集群为伪分布式集群,默认单副本存储,即使开启了多副本,单节点故障后,数据不会自动均衡修复。
- 扩容缩容难度高
- 内存为瓶颈,如果活跃的时间序列数量过高,超过了内存可承载的量级,那么集群会出现大量的读盘,读写性能急剧下降。
- 对写入数据的内容有要求,由于创建时间序列时集群资源消耗大,如果有指标将时间戳或者其他随机字段作为tag存储到时序数据库,那么该指标将永远无法命中时间序列,一直在创建新的时间序列,对集群影响较大。
分布式数据库(StarRocks)
优势
- 运维难度低,支持动态扩缩容,单节点故障后无需人工操作,集群会自动踢出异常节点,并将数据均衡到其他节点,保证数据3副本存储不受影响。
- 容量大,没有内存瓶颈,真正的分布式集群,目前经验来说,PB级的集群存储和百TB级的单表存储不成问题,这个是时序数据库做不到的。
- 使用MySQL协议,支持复杂SQL和跨表SQL,一些复杂的计算逻辑时序数据库不能满足,但是分布式数据库都没有问题。
- 支持物化视图,固定姿势的聚合查询语句,可以建立物化视图,数据在落盘时直接物化,将聚合结果物化存储,用空间换取时间,查询性能获得极大提升。
- 对写入的数据要求较低,时序数据库在无法命中时间序列时集群会有波动,StarRocks对数据内容要求较低,仅期望分桶列的离散程度符合要求,不要造成严重数据倾斜即可。
劣势
- 占用空间大,和时序数据库相比,没有时间序列的概念,所有字段均落盘存储,占用磁盘空间较大
- 时延较大,数据在写入StarRocks的时候,为避免频繁落盘生成过多Singleton File,创建过多压缩任务占据磁盘IO和CPU,写入数据要在上游进行攒批处理,控制写入频率,因此造成写入时延相比时序数据库较大,对于要求秒级时延要求的服务不能满足。
- 表结构修改困难,StarRocks不支持修改分区分桶列,不支持修改not null,对于数据量较大的表,修改表结构的操作需要动辄几个小时才能完成,并且操作过程中占据大量的磁盘IO和CPU资源,引发集群波动。
总结
综合来看,时序数据库适用于对时延要求较高、数据量较小、结构相对简单的场景,而分布式数据库适用于对运维成本和数据容量有较高要求的场景。选择时需根据业务需求、数据量和性能要求来进行权衡。