时序数据特点:
1、写多读少:持续高并发的写入,由于定期采样的特点,写入量平稳,几乎不会有更新操作。
2、冷热明显:查询一般查近期产生的数据,很少查过期数据。
3、数据关联性小:数据之间几乎不存在关系,不需要Join。
4、查询场景不同,索引特殊:数据都包含设备信息(服务器、传感器)和时间戳,大部分都是聚合查询。
应用场景:IOT传感器数据、服务器监控数据、证券交易数据
绝大多数关系型数据库的特点:
1、读多写少:大部分RDBMS都是基于B+树实现的,B+树主要通过增加节点大小降低树的层级从而减小IO,索引更多数据,从而优化读取性能。
2、随机读写:B+树读写会直达叶子节点,读写性能稳定,少部分热数据直接通过LRU进行缓存。
3、表间关系紧密:关系型数据库的特点就是关联关系,通过范式来避免数据冗余,查询数据库时通过Nested Loop Join,Hash Join,Sort Merge Join等算法进行关联。
4、按查询场景建立二级索引:为了提升查询性能,会对查询字段额外创建另一个B+树索引,也就是所谓的“二级索引”,这也导致写操作需要同时更新这些索引。
应用场景:一致性较强的应用数据
B+树的优缺点
优点:
1、随机读写:根据B+树索引查询,能对磁盘中的数据实现快速读写。按照InnoDB的16KB块大小计算,对8字节bigint类型的ID值进行索引,包括下级物理指针在内,一个16KB节点就可以存储1000左右的key。这样算第二层16MB的节点可以存1百万左右的key,内两层可以通过mmap的形式缓存在内存中,第三层可以索引16GB左右的数据,所以三层B+树基本只要一次I/O操作。
2、范围查询:B+树叶子节点通过双向链表连起来了,可以直接顺着叶子节点的链表进行范围扫描,避免了B树回溯节点的I/O问题。
3、查询稳定:数据都存在叶子节点,内部节点只存key,一方面可以让内部节点索引更多的数据,降低树的层级,另一方面能让查询都沉到叶子节点,性能相对稳定,不会像B树那样,有的查询读到第二层,有的查询读到第三层。
4、WAL保证写操作的持久性:将修改先写入预写日志(Write-Ahead Log),如果修改的脏页因为宕机等原因没有落盘,可以通过WAL进行恢复。
缺点:
1、页分裂,写性能不稳定:写操作可能导致页面数据已满,触发页分裂,页分裂会产生多次磁盘I/O,导致写放大。所以对于大并发量的写操作,B+树性能急剧下降。特别是当一张表存在多个二级索引时,这个现象越明显。
2、大数据量I/O性能下降:数据量过大,会导致B+树层级过深,I/O次数上升,性能下降。一般的策略是分库分表,通常单表超过三层B+树的百万级别数据量后就需要考虑分库分表。但是分库分表需要根据系统业务选择列进行路由,通用性不强。虽然现在MySQL和PostgreSQL等数据库都有提供分区表的功能,但是对于跨分区的查询性能仍有局限。
LSM存储结构
Log-Structure MergeTree将写操作写入内存树,当达到一定阈值再Flush进磁盘,磁盘中的小树会逐级合并大树。
优点:
1、写性能吞吐量极高:随机写合并成大批量的顺序写。支持高吞吐的写操作,写入性能能得到大幅度提升。
2、没有B+树的页分裂。删除操作,会以墓碑标记的方式追加到
缺点:
1、读放大:读取操作需要,从
2、写放大:对数据的修改和删除,需要延迟到Compact阶段进行后台合并。总体上,写操作的次数实际上增多了。
3、空间放大:LSM-Tree的深层树中可能存在未合并的垃圾数据。相比于B+树的原地修改,LSM-Tree会占用更多空间。
优化:
1、读优化:可以在内存中使用BloomFilter对树中的数据进行预判,如果不存在就不需要进行读操作了。
2、写优化和空间优化:优化Compact算法,尽量减少写放大和空间放大。Compact其实质是多路归并排序,目前有两种基本的Compact策略:level vs. size/tier。不同的Compact策略是对写优化和空间优化之间的权衡。
使用LSM-Tree实现时序数据库
LSM-Tree非常适合存储时序数据。
1、首先LSM-Tree的写性能满足了时序数据持续性高并发的写入和读多写少的场景。
2、时序数据基本不会修改和删除,所以避免了不必要的Compact操作,也就没有空间放大的问题,写放大也能避免。
3、老数据会随着层级的层架,进入更深层,契合了是冷热数据查询的场景。
参考资料:
- 深入浅出分析LSM树:https://zhuanlan.zhihu.com/p/415799237
- 卡内基梅隆大学数据库课程示例项目:https://github.com/skyzh/mini-lsm
- OceanBase Compaction策略介绍:https://www.oceanbase.com/docs/community-developer-advance-0000000000634014