微信的tablekv底层就是一个leveldb

应用场景

  • 读少写多的情况
  1. 日志系统
  2. 消息队列
  3. 分布式储存
  4. 缓存

特点

  • 底层使用LSM技术构建储存
  • 利用了磁盘的顺序写必随机写快的多的特点
  • 只提供Get,Put,Delete接口

优点

  • 强大的写性能
  • 强大的可靠性

缺点

  • 牺牲了sql的结构化,完全退化为KV
  • 牺牲一定的读性能
  • 不支持多线程写入
  • 生成很多文件,管理麻烦

WAL

  • Write Ahead Log,写入前先写日志,至于日志的刷盘时机可以通过
    • 每次写入都做一次sync,可靠性最高,不会丢数据,但是性能最低;
    • 每次写入,但是不sync,数据库崩溃不会丢数据,但是机器崩溃会丢数据,性能高,底层实现是共享内存,即使数据库崩了,内存也不会马上被回收;
    • 每次写入,不sync,但是每1s做一次sync,数据库崩溃不会丢数据,但是机器崩溃丢最多1s的数据,性能较高。

LSM

  • Log-Structured-Merge-Tree
  • 分级储存,分为在内存中的MemTable,在磁盘中的SSTable
  • 有一个lru缓存用于缓存sstable的热点数据,避免多次io读取,而且是以Data Block为最小单位进行缓存

PUT流程

  1. 先写日志(顺序写)
  2. 按照key的字典序排序key,维护一个有序的map,leveldb使用跳表实现,将这个key,val插入跳表(如果已经存在直接更新)
  3. 判断跳表的容量是否太大,太大将memtable刷成sstable0,新建新的sstable0
  4. 如果sstable0的数量太多(大概十倍),会将所有的sstable归并合并成一个大的sstable1,相同的key会直接合并(取最新的),sstable1也类似

DELETE流程

  1. 和PUT的流程类似,只是key的状态打上delete的状态

GET流程

  1. 计算key的int值,在memtable中查询这个key是否存在,如果存在直接返回,
  2. 如果不存在,在sstable0层寻找,找不到去sstable1找,找到之后将数据加入LRU缓存,为了避免尽量避免找太多次,每个table都维护布隆过滤器,先经过布隆过滤器,再进行二分查找

索引实现

  • 感觉上和B+索引的思想类似,计算索引字段对应的key值,然后构建跳表,key为计算值,val为原来的主键key,查找到主键key之后进行回表查询真实的数据

QA

为什么索引使用有序二分而不是哈希

  1. 存储的方面,hash磁盘的落地很麻烦,更何况还要用过链表存储解决hash冲突
  2. 这样设计使得范围查询和排序成为可能,hash无法范围查询
  3. 因为redis是内存数据库,快是主要的需求,因此用字典,和leveldb有差别

tablekv(Quorum_KV)

  • 底层是leveldb,但是套了一层paxos分布式协议,保证高可用性,但是通过LSM树的形式使得具有很快的写入速度,是一个非常厉害的平衡了可用性和速度的数据库(通常这两者是冲突的),但是读的速度比较慢,但是因为微信读写比例接近1:1,因此影响不大

总结

  • 很多公司最终都转型到这个数据库上面,大部分数据存储其实使用kv类型就足够了,对ACID业务型需求不是刚需
  • mysql这种写入速度完全不满足需求
  • redis这种满足需求了但是不可避免存在极端情况下数据丢失,因此不可能作为磁盘的持久化存储方案
  • 两者一起使用时之前的解决方案,但是缺点是一致性本质上是CAP的无解问题,解决一致性麻烦太大,如果对强一致性没有太大需求,用这个也可以,但是代码负责心和出错率会增加
  • leveldb属于均衡选手,牺牲本来就很快的读性能为写性能让路(在磁盘上),本身携带了缓存的系统,使得相当于将缓存和数据进行了结合,,具有极强的写性能和较强的读性能,因此很多公司最后的数据库选型都是这种

组件对比

公司字节腾讯
组件abasetablekv
底层RocketDB(底层也是LevelDB改编而来)LevelDB
上层组件上层通过类似 slots 分配的形式, 每个负责处理的集群再通过主从复制的方式实现一致性的, 只能保证最终一致性, 本质上和 redis的多集群方式类似 redis实现套了一层 paxos 协议, 能够保证强一致性

参考

  • https://juejin.cn/post/7123922716419178526
  • https://zhuanlan.zhihu.com/p/206608102
  • https://zhuanlan.zhihu.com/p/361699941