- 场景:设计一个海量读写的的kv数据库,优先保证写入速度,但是读取速度也不能很慢
- 因为海量数据存储,不能使用内存,得存到文件里。
- Q:对已经落盘的文件,怎么根据key修改value
- A:读取文件找到指定的key,修改指定的值
- Q:需要随机磁盘io,磁头、磁道、扇区三者合一,然后进行io操作,慢
- A:追加写:不找之前的了,直接写新的key-value(顺序io),新的key代替老的key
- Q:查询的时候一个key对应多个value,还需要排序过滤,慢
- A:异步compaction:新建一个文件(SSTable)接受新的写入数据,写到一定数量后关闭,然后创建一个新的SSTable,对关闭的SSTable进行异步的合并,根据key+版本删除旧版本数据
- Q:文件中检索指定的key 有什么方案
- A:同一个SSTable中,key按顺序排列
- A:创建若干索引文件
- A:每个SSTable,记录其 kmax,kmin
- A:对SSTable切分,分出若干segement并记录kmax,kmin
- A:每个segement添加一个bloomfilter,用于快速过滤
- Q:为了key在SSTable中按序排列,那写SSTable的过程也是随机io
- A:创建一个内存中的memtable,写入过程统一写入memtable,在内存中使key有序,而且同一个memtable写入相同的key,直接就可以在memtable中进行合并,一定大小后,溢写到磁盘形成SSTable,这样SSTable就是 key有序且唯一的数据结构,溢出过程也是顺序io
- Q:写入过程和溢写磁盘过程有冲突
- A:当一个memtable满足溢出条件后就停止写入,创建一个新的memtable,并将前一个memtable 改成 immutable memtable(不可变更的内存表)同时将 immutable memtable溢写磁盘
- Q:内存有序的memtable,用什么数据结构实现?
- A:跳表、红黑树,跳表合适并发比较好、实现更简单(不一定,lsm只是一个架构,怎么实现无所谓)
- Q:内存写磁盘的操作不够健壮,万一写的过程失败了怎么办
- A:采用预写日志机制WAL,将数据先写入日志中,然后写入memtable(该过程是原子性的),如果immutable memtable溢写形成(该过程是原子性的)SSTable的过程失败,可以将WAL数据重放,形成memtable,然后重试
- Q:每个sstable内部主键唯一且有序,但是多个之间还是会有冲突啊
- A:没错由immutable memtable形成的SSTable确实会有这个问题,我们得想办法把他们合并起来
- A:由immutable memtable形成的SSTable我们给他起个名字叫Level0层,假设0层的数据最多存10MB,如果一旦超出10MB我们就把它放到Level1层,而且在放的时候我们要根据Key进行合并,每个SSTable都有key区间(比如从a-e),在放到Level1层的时候,我们先根据key区间找到会受到合并影响的Level1的SSTable(比如SSTable1[a,c],SSTable2[d,e]),然后让他们三个SSTable 做一个排队按高矮个排序的动作,咋排呢?
- 先都站到一起,根据Key排序小的在前,大的在后,相同的key后来的替代先来的,这样之后三个SSTable的key就合并成了一个不重复且有序的大SSTable,但是也不能太大,按照大小限制,再切分成多个SSTable(上述假设可能最后会形成 [a,c],[d,e]两个SSTable)
- 这样从Level1层开始,一个key多个值的问题我们解决了,SSTable之间的key也是全局有序。
有序且唯一
- Q:Level0层的SSTable合并到Level1时,万一某个SSTable包含了Level2的最小Key和最大Key,这样就覆盖到了Level1整层,那Level1中所有的SSTable都要进行一次排序啊
- A:确实会有这个问题,因为level0中的SSTable key的范围没法控制,那得继续往下分层(这就是分层原因),Level0层存10M,那Level1层就存100M(10倍),Level1层满了就往Level2进行合并,level1中的SSTable key的范围肯定不会出现[Minkey,MaxKey],因为是有序的,而且每个SSTable的数据量均等。
- A:为了防止数据量过大依然导致这种问题,我们多分几层(默认7层),假设L0 10M 那7层 10*10^7,能存很多了。
- Q:那分这么多层,找的范围也多啊
- A:不是的,数据是从上往下流转的,新来了一个a=1,那我先找memtable,再找L0 SSTable、L1 SSTable。。,找到之后就不往下找了,自动就完成了冷热数据分离,热数据在上边,冷数据在下边
- Q:那万一我查一个最冷的Key呢?
- A:那就是最长寻址过程了:
- 1、memtable 内存快速查询,如果没找到
- 2、immutable memtable 内存快速查询,如果没找到
- 3、Level0,根据索引文件,获取到可能包含这个Key的所有SSTable,每一个SSTable都得读一遍,看看是否存在,但是可以倒序读,先读新的SSTable,再读老的SSTable,读取到就不用继续往下读了,如果没找到
- 4、Level1-Levelk,每一层都要根据索引文件,直接定位到包含这个key的SSTable segement,如果有,只会有一个SSTable,因为每一层内部都是有序的
- 5、对这个SSTable的所有的segement,循环进行bloom过滤,判断是否存在
- 6、bloom如果存在,判断是否为bloom假命中,
- 7、如果真命中,最后给出value的值,否则判断下一个segement
- 6、bloom如果存在,判断是否为bloom假命中,
- 5、对这个SSTable的所有的segement,循环进行bloom过滤,判断是否存在
- 4、Level1-Levelk,每一层都要根据索引文件,直接定位到包含这个key的SSTable segement,如果有,只会有一个SSTable,因为每一层内部都是有序的
- 3、Level0,根据索引文件,获取到可能包含这个Key的所有SSTable,每一个SSTable都得读一遍,看看是否存在,但是可以倒序读,先读新的SSTable,再读老的SSTable,读取到就不用继续往下读了,如果没找到
- 2、immutable memtable 内存快速查询,如果没找到
- 1、memtable 内存快速查询,如果没找到
- A:那就是最长寻址过程了:
LSM Tree 底层设计理念
2025/2/24 23:37:44
来源:https://blog.csdn.net/java_creatMylief/article/details/144141457
浏览:
次
关键词:LSM Tree 底层设计理念
版权声明:
本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。
我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com
热文排行
- 《警世贤文》摘抄:处人篇、受恩篇、宽人篇、听劝篇、劝善篇(多读书、多看报、少吃零食多睡觉)
- Vmess协议是什么意思? VLESS与VMess有什么区别?
- Android显示系统(08)- OpenGL ES - 图片拉伸
- `git restore` 和 `git checkout` 用于丢弃工作区的改动, `git switch` 和 `git checkout` 用来切换分支
- nccl 03 记 回顾:从下载,编译到调试 nccl-test
- 【CVE-2024-38077】核弹级Windows RCE漏洞如何自检并修复该漏洞(附批量漏洞检测工具及分析伪代码)
- windows11 ,ubuntu20.04双系统,ubuntu没有wifi的解决方式
- 【HW必备】用友NC-Cloud存在17处漏洞合集
- AD24设计步骤
- ctfshow-web入门-php特性(web132-web136)