Pebble 性能参数调优

Pebble vs Rocksdb参数调优表

序号 Pebble参数 Pebble配置建议 Rocksdb参数 Rocksdb配置建议 其他
LevelOptions
1 BlockRestartInterval // BlockRestartInterval is the number of keys between restart points for delta encoding of keys.
// BlockRestartInterval是键的delta编码的重启点之间的键数量
// 所以什么是delta encoding, 什么又是restart points
// The default value is 16.
不太懂
2 BlockSize int BlockSize是每个表块的未压缩的目标大小,以字节为单位。
// The default value is 4096.
block-size = "64KB" 数据块大小。RocksDB 是按照 block 为单元对数据进行压缩的,同时 block 也是缓存在 block-cache中的最小单元(类似其他数据库的 page 概念)。 数据块越大
写放大和空间放大越小
读放大越大
3 BlockSizeThreshold int 如果区块大小大于目标区块大小的指定百分比,并且添加下一个条目会导致区块大于目标区块大小,则BlockSizeThreshold将结束一个区块。 // The default value is 90
4 Compression Compression 压缩定义了要使用的每个块的压缩算法。
The default value (DefaultCompression) uses snappy compression.
compression-per-level = ["no", "no", "lz4", "lz4", "lz4", "zstd", "zstd"] # RocksDB 每一层数据的压缩方式,可选的值为:no,snappy,zlib,bzip2,lz4,lz4hc,zstd。它表示 level0 和 level1 不压缩,level2 到 level4 采用 lz4 压缩算法, level5 和 level6 采用 zstd 压缩算法,。 no 表示没有压缩,lz4 是速度和压缩比较为中庸的压缩算法,zlib 的压缩比很高,对存储空间比较友好,但是压缩速度比较慢,压缩的时候需要占用较多的 CPU 资源。不同的机器需要根据 CPU 以及 I/O 资源情况来配置怎样的压缩方式。例如:如果采用的压缩方式为"no:no:lz4:lz4:lz4:zstd:zstd",在大量写入数据的情况下(导数据),发现系统的 I/O 压力很大(使用 iostat 发现 %util 持续 100% 或者使用 top 命令发现 iowait 特别多),而 CPU 的资源还比较充裕,这个时候可以考虑将 level0 和level1 开启压缩,用 CPU 资源换取 I/O 资源。如果采用的压缩方式 为"no:no:lz4:lz4:lz4:zstd:zstd",在大量写入数据的情况下,发现系统的 I/O 压力不大,但是 CPU资源已经吃光了,top -H 发现有大量的 bg 开头的线程(RocksDB 的 compaction 线程)在运行,这个时候可以考虑用 I/O 资源换取 CPU 资源,将压缩方式改成"no:no:no:lz4:lz4:zstd:zstd"。总之,目的是为了最大限度地利用系统的现有资源,使 TiKV 的性能在现有的资源情况下充分发挥。 重点关注
5 FilterPolicy FilterPolicy定义了一种过滤算法(比如Bloom过滤器),可以减少Get调用的磁盘读取。其中一个实现是来自pebble/bloom包的bloom.FilterPolicy(10)。
// The default value means to use no filter.
重点关注
最起码都有70%的空间压缩率, 而且查询的时间接近O(1),用一定的空间去换取更高效的(CPU节约, 时间节约)查询显然是合算的买卖.
6 FilterType FilterType FilterType定义了现有的过滤策略是应用在块级还是表级。块级过滤器在创建时使用的内存较少,但是访问速度较慢,因为必须首先对索引中的键进行检查以找到过滤器块。表级过滤器需要的内存与sstable中键的数量成正比,但在确定键是否存在时避免了索引的查找。除了在内存有限的情况下,表级过滤器应该是首选。
// Table-level filters should be preferred except under constrained memory situations. 但是怎样的情况算是内存受限的情况呢
7 IndexBlockSize int IndexBlockSize是每个索引块的未压缩的目标大小,单位是字节。当索引块的大小大于这个目标时,两级索引将被自动启用。把这个选项设置成一个大值(比如math.MaxInt32),就会禁止自动创建两级索引。
// The default value is the value of BlockSize.
8 TargetFileSize int64 当前level的目标文件大小
Options
1 L0 compaction相关配置 L0CompactionFileThreshold int 触发L0压实所需的L0文件的数量
1-2 L0CompactionThreshold int 触发L0compaction所需的L0 read-amplification。 level0-slowdown-writes-trigger = 20 当 level0 的 sst 文件个数到达 level0-slowdown-writes-trigger 指定的限度的时候 RocksDB 会尝试减慢写入的速度。因为 level0 的 sst 太多会导致 RocksDB 的读放大上升。level0-slowdown-writes-trigger 和 level0-stop-writes-trigger 是 RocksDB 进行流控的另一个表现。当 level0 的 sst 的文件个数到达 4(默认值),level0 的 sst 文件会和 level1 中有 overlap 的 sst 文件进行 compaction,缓解读放大的问题。
1-3 L0StopWritesThreshold int 对L0 read-amplification的硬限制,计算为L0子级的数量。当达到这个阈值时,写会被停止。 level0-stop-writes-trigger = 36 当 level0 的 sst 文件个数到达 level0-stop-writes-trigger 指定的限度的时候,RocksDB 会 stall 住新的写入。
2 LBaseMaxBytes LBase的最大字节数。基准层LBase是L0被压缩到的层次。基准层LBase是根据LSM中的现有数据动态确定的。其他级别的最大字节数是根据基础级别的最大尺寸动态计算的。当一个级别的最大字节数被超过时,会请求压缩。
3 MaxManifestFileSize int64 MaxManifestFileSize是允许MANIFEST文件的最大尺寸。当MANIFEST文件超过这个大小时,它就会被翻转并创建一个新的MANIFEST。 max-manifest-file-size = "20MB" # RocksDB MANIFEST 文件的大小限制更详细的信息请参考:https://github.com/facebook/rocksdb/wiki/MANIFEST
4 MaxOpenFiles MaxOpenFiles是对DB可以使用的Open File数量的一个软限制。 默认值是1000。 max-open-files = 40960 RocksDB 能够打开的最大文件句柄数。 将文件句柄都保持打开, 避免昂贵的table cache调用, 那么代价呢?
5 MemTableSize int 稳定状态下的MemTable的大小。实际的MemTable大小从min(256KB, MemTableSize)开始,之后的每一个MemTable都会加倍,直到MemTableSize。这减少了MemTable对短暂的(测试)DB实例造成的内存压力。注意,可以有多个MemTable存在,因为刷新一个MemTable需要在后台创建一个新的MemTable并写入旧的MemTable的内容。MemTableStopWritesThreshold对排队的MemTable的大小做了硬性限制。 write-buffer-size = "128MB"
官方512M
# RocksDB memtable 的大小。 原来是从256KB进行增加, 一直增加到MemTableSize
6 MemTableStopWritesThreshold int 队列中的MemTable大小的硬限制。当队列中的MemTable大小之和超过MemTableStopWritesThreshold*MemTableSize时,就会停止写入。这个值应该至少是2,否则每当MemTable被刷新时,写操作就会停止。 max-write-buffer-number = 5 # 最多允许几个 memtable 存在。写入到 RocksDB 的数据首先会记录到 WAL 日志里面,然后会插入到 memtable 里面,当 memtable 的大小到达了 write-buffer-size 限定的大小的时候,当前的memtable 会变成只读的,然后生成一个新的 memtable 接收新的写入。只读的 memtable 会被RocksDB 的 flush 线程(max-background-flushes 参数能够控制 flush 线程的最大个数) flush 到磁盘,成为 level0 的一个 sst 文件。当 flush 线程忙不过来,导致等待 flush 到磁盘的memtable 的数量到达 max-write-buffer-number 限定的个数的时候,RocksDB 会将新的写入stall 住,stall 是 RocksDB 的一种流控机制。在导数据的时候可以将 max-write-buffer-number的值设置的更大一点,例如 10。 不太理解,猜想是2*256k不太理解
7 WALDir string WALDir 指定 write-ahead logs (WALs) 的存储路径. 如果为空(默认),WALs将被存储在与sstables相同的目录下(即传递给pebble.Open的目录) wal-dir = "/tmp/tikv/store" RocksDB write-ahead logs 目录。如果机器上有两块盘,可以将 RocksDB 的数据和 WAL 日志放在不同的盘上,提高 TiKV 的性能。

参考资料

非常重要的阅读材料

RocksDB-Tuning-Guide.md

Auto-tuning RocksDB

pebble参数选项

leveldb的技术手册

rocksdb的技术博客

posted @ 2022-09-16 16:42  Aibot  阅读(484)  评论(0编辑  收藏  举报