【HBZ分享】ClickHouse数据结构 之 LSM-TREE

ClickHouse高性能写入剖析-LSM-Tree数据结构

简介

先了解一组测试数据来对比磁盘的【随机读写】与【顺序读写】的性能差距

顺序读写: 磁盘的顺序读写,磁头基本不需要换道,即使换道,时间也是极短的,性能极高,比如0.03 * 2000 MB /s
随机读写: 随机读写会导致磁头不断地换道,从而导致性能大幅下降 0.03MB/s

了解LSM-TREE树

1. 充分利用了磁盘顺序写的特性,数据写入后,定期在后台Compaction(合并)
2. 在数据导入时,全部是顺序append写(追加的顺序写), 在后台合并时,也是多个段合并排序后,再顺序写入磁盘
3. 官方公开benchmark测试显示能够达到50MB-200MB/s的写入吞吐能力,按照每行100Byte估算,大约相当于
   50W-200W条/s的写入速度

什么是LSM-TREE树

1. 全称 Log-Structured Merge-Tree 日志结构合并树,但不是树,它是利用了磁盘顺序读写能力,实现了一个
   多层的存储结构
2. 是一种分层,有序,面向磁盘的数据结构。主要利用批量磁盘顺序写的性能要远高于随机写的性能
3. 大大提升写入能力,但会损失部分读性能来作为代价。
4. HBase、LevelDB、ClickHouse这些NOSQL存储都是采用了类LSM-TREE树结构
5. 在NOSQL这种类LSM树结构非常常见,基本已经成为必选,为了解决快速读写问题去设计的
6. LSM-TREE分为两部分来解读
    (1). Log-Structured日志结构的,打印日志是一行行往下写,不需要改,只需要在后面追加即可
    (2).Merge-Tree 和并树,就是把多个合并成1个,自上而下

LSM-TREE树的结构解析

【HBZ分享】ClickHouse数据结构 之 LSM-TREE_第1张图片

1. LSM-TREE是个多层结构,更像一个 喷泉树,上小下大
2. 专门为key-value存储系统设计的,就两个功能
    (1). 写入put(k, v);
    (2). 读取get(k); 得到v
3. put后首先存储到C0内存层,C0层存储着最近写入的(k, v) ,这个内存结构是有序的,且随时可以原地更新,同时
  支持随时查询
4. 接下去C1-Cn是存储在磁盘上,并且每一层都是有序的存储结构
5. 降低一点点读性能,来提高写性能

LSM-TREE树写入流程

1. put操作后,首先会追加到【写前日志(Write Ahead Log)】,然后加到C0 层
2. 当C0层达到一定大小,就会把C0和C1层合并,这个过程就是Compaction(合并)
3. 合并出来的新的C1,会顺序写入磁盘,替换掉原来的C1。可以看出,合并的时候实际是C0和C1合成了一个新的C1,
   并不是在原C1基础上追加,然后这个新C1会替换掉旧的 C1
4. C1达到一定大小后,依然以同样的方式和C2层合并,合并后会删除旧的,留下新的,后面的合并都是以此类推

LSM-TREE树查询流程

1. 最新的数据在C0层,最老的数据在Cn层
2. 查询时先查C0, 没有插到再查C1,逐层查,知道查到为止,如果都没有就返回null

LSM-TREE树缺点

1. 读放大:读取数据时,实际读取的数据量大于真正的数据量,在LSM树中,需要先从C0层查询,不存在,则要继续
   从Cn层查找
2. 写放大:实际写的数据量要大于真实的数据量,因为在Compaction合并时,会把之前写入的数据合并后,再次
   写入,也就比如A这个数据之前在C1层,但由于C0满了,要和C1合并,此时合并后,A这个数据要重新再写入一次
   C1层,因为LSM-TREE合并机制是重新写入合并后的数据,所以就导致A数据写了多次,这就叫写放大

你可能感兴趣的:(clickhouse,zookeeper,分布式,数据库)