原子性,所以RocksDB对file的更改也会记录log,就记录在manifest里。实际上,可以将manifest看做,记录的是RocksDB的状态。manifest记录的内容就成了RocksDB按时间排序的一系列状态,如果,将每个状态看做RocksDB某个时间点的快照,manifest就是RocksDB的动图GIF。
Cache
没有cache的存储引擎是不完整的,RocksDB有两种cache,block cache和table cache。先来聊聊block cache。block cache缓存的单位就是sstfile的data block,这种cache有两种算法,经典的LRU和clock,任由你选择。除了data block,用于索引和提高读性能的index block和filter block更是重点缓存对象,但RocksDB并不会把这俩放在block cache中,RocksDB会单独照顾好这俩,基本不用外部操心。而table cache缓存的是sstfile的file descriptor,实际上,操作系统通过file descriptor用引用计数的方式来管理file结构体和其背后的资源。也就是说,table cache缓存的是操作系统用来操作sstfile的file结构体和其背后资源,更多关于file descriptor结构,推荐这篇文章。
Tips
以下是使用RocksDB的一些建议:
- RocksDB线程模型是单句柄对多线程。
- Get、Put、Delete等操作不需要操心数据同步问题,而Iterator和WriteBatch需要同步控制。
- WriteBatch类似于事务,提供将一个或多个数据库操作抽象为单位的能力,此单位是原子性的,但并不会互相隔离从而并发控制,也不会检测出异常并恢复。
本篇聊了很多RocksDB的设计思想。然而毕竟大多数工程师都是面向应用,不会去搞个存储引擎。这里就总结几条从LSM、RocksDB等存储引擎中学到的有关读写IO的技巧,理解了大有裨益。
- 相对于计算、内存读取,磁盘IO慢不知多少数量级。
- 相对于执行一次磁盘IO,磁盘IO的数据量多少不重要,也就说开始、结束一次磁盘IO更费时。尽量集中对磁盘进行IO。
- 相对于磁盘随机读写,磁盘顺序读写快上3个数量级。
- 读写分离,减少并发锁的性能开销。
引用