存储引擎常见batchwrite写优化-阿里云开发者社区

开发者社区> 陈江@阿里> 正文

存储引擎常见batchwrite写优化

简介: # 引言 做有竞争力的存储系统迟早会遇到需要性能瓶颈,本文简单记录一些batchwrite常见朴素优化思想,以防哪天我们需要完成这方面的工作,可以翻出来看看,借鉴一下人家的思想 本文不做代码层面探讨,可自行阅读链接中给出的代码。
+关注继续查看

leveldb groupcommit思想

leveldb是一个KV引擎,支持上层多客户端线程并发写该引擎。所有客户端的写入会链接成一个链表,只需要head节点作为主writer负责写入,如图示例:
image.png

写由主writer负责,这个batch其他writer同步等待,等待被唤醒即可。主writer行为如下:

  • 合并所有writer的writeRequest,生成一个大batch
  • 写WAL
  • 写memtable
  • 都操作完,唤醒大batch中的其他writer回客户端ack,唤醒新进入的writer,作为主writer继续执行。

优点

  • 小的IO都会合并成大的IO落盘(合并batch),提升磁盘吞吐,写WAL,写memtable单线程执行,不需要锁。

缺点

  • 多线程变单线程工作,无法发挥多核优势。
    所以Rocksdb在这个方面做了很多优化工作,其中有一个特性就是pipelined write。

rocksdb pipelined write

image.png

思想很朴素,拆分写WAL,写Memtable等子任务项。客户端线程接力完成这些子任务项。每个子任务有个状态位,客户端线程通过状态位CAS操作抢任务项执行权力

拆分的task一般也就小几个,也就能多用几个线程,大量的客户端线程仍旧同步等待。现代cpu的多核架构仍不能有效发挥出来。

并行写+barrier思想,cassandra示例

客户端并行的写入,每个线程都写透,大家角色对等,这样也不存在rocksdb那样诡异的拆子任务逻辑,同时也能自适应硬件,充分发挥多核优势。但也存在如下问题:

  • 每个线程仅对自己的kv追加写WAL,单条kv都是小IO,浪费iops,这一点可以通过MMAP优化。
  • 多线程锁竞争激烈,其实仅在写wal及写memtable存在临界区,仅对这两块逻辑加锁即可。或者优化成lock-free编程。

客户端线程要源源不断写wal,然后写memtable。当memtable写满,flush线程要刷sst。要通知客户端切换写新memtable怎么实现,用互斥锁肯定可以实现。更朴素的思想是用barrier,核心思想是设置栅栏,栅栏前面的,栅栏后面的分别处理。参考下图
image.png

  • 有一个全局的writeorder,客户端线程写storage之前,调用writeorder.start方法,该方法增加当前group计数引用,将当前写attach到当前group上,上图就是group1. 然后继续写WAL,写memtable。可以看得出来整个链路耗时很长。该写线程完成后或异常时,当前group的引用计数-1。
  • 后台线程周期性尝试flush memtable,先创建新memtable,加入到链表头,标记为最新memtable。
  • 把old-memtable的barrier设置上,该barrier前一个group是group1.通过第一点我们知道客户端线程写完还是比较慢的,flush线程会等group1引用计数为0,也就是所有线程写完才会刷sst。
  • flush线程封箱barrier,意思是新的写会挂载在group2上,group1会减引用,如果为0然后unlink掉。
  • 新的写入attach到group2, 旧的写入写完慢慢减group1的引用,变为0之后,写线程都写完了,flush线程可以安全的刷sst,并且回收memtable。

总结

简单的记录了常见开源引擎里面一些令人印象深刻的优化,后续再慢慢追加wiretiger&innodb一些特别点。

源码参考

https://github.com/apache/cassandra/blob/6f213727b678be4ee6ec350bd3ed1869db394ae9/src/java/org/apache/cassandra/utils/concurrent/OpOrder.java

https://github.com/google/leveldb/blob/master/db/db_impl.cc

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
《OpenACC并行程序设计:性能优化实践指南》一 3.11 小结
本节书摘来自华章出版社《OpenACC并行程序设计:性能优化实践指南》一 书中的第3章,第3.11节,作者:[美] 罗布·法伯(Rob Farber),更多章节内容可以访问云栖社区“华章计算机”公众号查看。
898 0
解密OpenTSDB的表存储优化
本篇文章会详细讲解OpenTSDB的表结构设计,在理解它的表结构设计的同时,分析其采取该设计的深层次原因以及优缺点。它的表结构设计完全贴合HBase的存储模型,而表格存储(TableStore、原OTS)与HBase有类似的存储模型,理解透OpenTSDB的表结构设计后,我们也能够对这类数据库的存储
26426 0
《OpenACC并行程序设计:性能优化实践指南》一 3.12 参考文献
本节书摘来自华章出版社《OpenACC并行程序设计:性能优化实践指南》一 书中的第3章,第3.12节,作者:[美] 罗布·法伯(Rob Farber),更多章节内容可以访问云栖社区“华章计算机”公众号查看。
585 0
Linux系统中使用GCC CPU参数优化代码编译
Linux系统中使用GCC CPU参数优化代码编译 使用特定的GCC参数可以使编译出的程序执行效率有较大提升。具体如下: 1、优化原理: 在编译程序时,借助参数传递的方法,使用与系统CPU相匹配的gcc参数,编译出的程序就是为系统CPU而进行特定优化过的,因而执行速度和效率都会是最好。
733 0
常见的QGraphicsItem
简述 QGraphicsItem 类是 QGraphicsScene 中所有 item 的基类。 它提供了一个轻量级的基础,用于编写自定义 item。其中包括:定义 item 的几何形状、碰撞检测、绘制实现、以及通过其事件处理程序进行 item 的交互,QGraphicsItem 是 Qt之图形视图框架 的一部分。 简述 常见的 QGraphicsItem QG
1573 0
文件存储:购买存储包的方法及常见问题
通用型NAS支持绑定存储包,您可以先创建文件系统再绑定存储包,也可以在购买存储包时创建文件系统。
373 0
Ionic 1 & 2 开发常见问题 Q&A
原文发表于我的技术博客 本文分享了在 Ionic 1 & 2 版本开发过程中常见问题的一些 Q&A,供慕课网同学或其他朋友参考。原文发表于我的技术博客 1. 版本的问题 Ionic 2 目前属于快速迭代更新的版本,版本的更新会带来如文件结构和少许代码的变更,不过底层还是构建于 Angular 2 ...
1263 0
MySQL MHA配置常见问题
    MHA在MySQL数据库中被广泛使用,它小巧易用,功能强大,实现了基于MySQL replication架构的自手动主从故障转移,从库重定向到主库并自动同步。
1252 0
+关注
陈江@阿里
从业于BAT等公有云部门,分布式存储领域专家
21
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载