存储引擎常见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

相关文章
|
存储 安全 关系型数据库
什么是存储引擎
什么是存储引擎
812 0
|
7月前
|
存储 关系型数据库 MySQL
PolarDB-X 存储引擎核心技术 | 索引回表优化
数据库系统为了高效地存储、检索和维护数据,采用了多种不同的数据组织结构。不同的组织结构有其特定的用途和优化点,比如提高查询速度、优化写入性能、减少存储空间等,目前 PolarDB-X 采用了 B-Tree 的索引组织结构。
|
1月前
|
存储 安全 关系型数据库
InnoDB引擎特性
InnoDB事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键。MySQL5.5.5之后,InnoDB作为默认存储引擎,InnoDB主要特性有: InnoDB给MySQL提供了具有提交,回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎。InnoDB锁定在行级并且也在SELECT语句中提供了一个类似Oracle的非锁定读。 InnoDB是为处理巨大数据量的最大性能设计。它的CPU效率可能是任何其他基于磁盘关系的数据库引擎所不能匹敌的。 InnoDB存储引擎完全与MySQL服务器整合,InnoDB存储引擎为在主内存中缓存数据和索引而维持它自己的缓冲池
|
2月前
|
存储 消息中间件 大数据
解密存储引擎 bitcask 的设计原理
解密存储引擎 bitcask 的设计原理
73 2
|
7月前
|
存储 关系型数据库 分布式数据库
数据库索引回表困难,揭秘PolarDB存储引擎优化技术
PolarDB分布式版存储引擎采用CSM方案均衡资源开销与可用性。
数据库索引回表困难,揭秘PolarDB存储引擎优化技术
|
6月前
|
存储 算法 数据处理
惊人!PolarDB-X 存储引擎核心技术的索引回表优化如此神奇!
【6月更文挑战第11天】PolarDB-X存储引擎以其索引回表优化技术引领数据库发展,提升数据检索速度,优化磁盘I/O,确保系统在高并发场景下的稳定与快速响应。通过示例代码展示了在查询操作中如何利用该技术高效获取结果。索引回表优化具备出色性能、高度可扩展性和适应性,为应对大数据量和复杂业务提供保障,助力企业与开发者实现更高效的数据处理。
74 3
|
7月前
|
存储 NoSQL 关系型数据库
LSM设计一个数据库引擎
LSM设计一个数据库引擎
96 0
|
存储 缓存 关系型数据库
InnoDB 与 MyISAM 的区别?如何选择存储引擎?
InnoDB 与 MyISAM 的区别?如何选择存储引擎?
343 0
|
存储 缓存 Oracle
第05章_存储引擎
第05章_存储引擎
104 0
|
存储 SQL 监控
Innodb 相较于MyISAM 的优势在哪
Innodb 相较于MyISAM 的优势在哪
Innodb 相较于MyISAM 的优势在哪

相关实验场景

更多