leveldb数据完全性及性能问题

发布于 2021-11-22 09:57:30 字数 96 浏览 841 评论 9

看到leveldb的一个文档,向memtable写数据之前会先写log,那意味着每写一次内存都写LOG到磁盘,那么性能如何保证?如果LOG不到磁盘,如何保证极端情况下,如掉电后的数据不丢失呢?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

惜醉颜 2021-11-27 21:56:19

可以设置为每次更新都写入LOG,但是性能会很低

带上头具痛哭 2021-11-27 21:54:33

找到源码解析了:

  1.       // 将更新写入log文件,如果设置了每次写入进行sync,则将其同步到磁盘,这个操作可能比较长,  
  2.       // 防止了mutex_对象长期被占用,因为其还负责其他一些资源的同步  
  3.       status = log_->AddRecord(WriteBatchInternal::Contents(updates));  
  4.       if (status.ok() && options.sync) {  
  5.         status = logfile_->Sync();  
  6.       }  
  7.       if (status.ok()) {  
  8.         // 成功写入了log后,才写入memtable  
  9.         status = WriteBatchInternal::InsertInto(updates, mem_);  
  10.       } 
三月梨花 2021-11-27 21:54:28

就是考虑极端情况,假如把用户钱袋存在leveldb,极端掉电,数据会不会丢失呢?

千笙结 2021-11-27 21:53:53

LevelDB采用LSM算法加速insert这个过程的,简单的LSM由两个Tree构成,一个Tree在内存中,可以是AVL或2、3Tree,称为C0,另外一个Tree是B+Tree,位于磁盘中,称为C1, 当C0中的节点达到一定数量时,把一些叶子节点批量移到C1中,这个过程叫Merge, 因为LOG的产生都是顺序的,所以Merge的永远只会在C1点某一些叶子节点上发生,Merge过程如下,首先把C1,C0上需要的merge的节点读出来,按照B+Tree的规则,重新生两个叶子节点,这两个叶子节点追加到C1点过程中,新节点写到磁盘也是顺序的,但会更新C1中被merge节点的父节点的子节点的块引用,以及这两个新节点的父节点的块引用。复杂的LSM可以有C0, C1, C2, ..., Ck个Tree,用来减少树操作的磁盘IO开销。C1, C2, ..., Ck这些B+Tree的块信息一般存储在内存中,用于快速检索“块”。

LSM在记录插入的时候,是非常高效对,在查找纪录时,必须要分多步查找C0, C1, C2, ..., Ck,效率比传统的AVL, B+Tree低一些,综合来看,LSM在数据库系统中比前两者表现的更好。

除来LevelDB外,Casandra、HBase也采用LSM算法。

爱的那么颓废 2021-11-27 21:53:03

如果追求极端 没有完美

千笙结 2021-11-27 19:03:18

块大小是64K,也就是说会在缓存中缓存64K后再刷到磁盘 “即便丢失也是很少量的”,那就是说不能用leveldb做关键的存储了?如用户钱袋、余额等

做个少女永远怀春 2021-11-27 14:29:49

那么高的读写效率,写数据的过程,依赖SSTable文件,(.sst)块文件块大小记得是64k,即便丢失也是很少量的

牵你的手,一向走下去 2021-11-27 10:31:04

刚测了一下磁盘的顺序写和随机写的速度, 随机写是0.67M/s , 而顺序写是 83.24M/s。 leveldb的巧妙之处就是把原本磁盘的随机写,转换成了速度非常高效顺序写。 

狠疯拽 2021-11-26 19:41:42

这个问题很关键。写log 是一个顺序写的过程,速度非常快 。 

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文