levy5307 / blog

https://levy5307.github.io/blog/
MIT License
0 stars 0 forks source link

Pegasus ReadOnly集群调研 #67

Open levy5307 opened 2 years ago

levy5307 commented 2 years ago

https://levy5307.github.io/blog/Pegasus-ReadOnly/

RocksDB参数

   
  参数
  说明
  默认值
  建议
  原因

  DBOptions
  create_if_missing
  如果dababase丢失了,将会自动创建
  false
  保持默认值
   

   
  create_missing_column_families
  如果column families丢失,将会自动创建
  false
  保持默认值
   

   
  error_if_exists
  如果数据库已存在,抛出错误
  false
  保持默认值
   

   
  paranoid_checks
  每次取key的前N位,根据key的前N位来构造bloom filter,用于提高范围查询效率
  true
  保持默认值
   

   
  rate_limiter
  控制flush和compaction速度
  nullptr
  保持默认值
   

   
  sst_file_manager
  跟踪sst files并控制文件删除速率
  nullptr
  保持默认值
   

   
  info_log
  db error信息写入该log文件
   
  保持默认值
   

   
  info_log_level
  log level
  INFO_LEVEL/ DEBUG_LEVEL
  保持默认值
   

   
  max_open_files
  该DB可打开的最大文件数
  -1
  保持默认值
   

   
  max_file_opening_threads
  用于打开文件的最大线程数量
  16
  保持默认值
   

   
  max_total_wal_size
  wal超过该大小时,强制flush
  0
  保持默认值
   

   
  statistics
  统计metrics
  nullptr
  保持默认值
   

   
  use_fsync
  写入时是否使用fsync,默认使用fdatasync(fdatasync更快)
  false
  保持默认值
   

   
  db_paths
  sst文件可以存放的路径
  空
  保持默认值
   

   
  db_log_dir
  log路径
  ””
  保持默认值
   

   
  wal_dir
  wal绝对路径地址
  ””
  保持默认值
   

   
  delete_obsolete_files_period_micros
  删除废弃文件的时间
  6h
  保持默认值
   

   
  max_background_jobs
  compaction和flush的最大线程数
  2
  -1
  通过配置  max_background_compactions和  max_background_flushes来决定线程数

   
  max_background_compactions
  最大compaction线程数
  -1
  4
   

   
  max_background_flushes
  最大flush线程数
  -1
  0
   

   
  max_subcompactions
  将一个compaction任务切分成多个sub任务,每个线程执行一个sub任务
  1
  保持默认值
   

   
  max_log_file_size
  log文件的最大size
  0
  保持默认值
   

   
  log_file_time_to_roll
  Time for the info log file to roll
  0
  保持默认值
   

   
  keep_log_file_num
  最大保存的log文件数量
  1000
  保持默认值
   

   
  recycle_log_file_num
  如果配置不为0,reuse老的log文件,覆盖老数据
  0
  保持默认值
   

   
  max_manifest_file_size
  当达到指定值时,roll over manifest文件
  0
  保持默认值
   

   
  table_cache_numshardbits
  Number of shards used for table cache,RocksDB中的cache可以分成多个shard,以减少竞争
  6
  保持默认值
   

   
  WAL_ttl_seconds
  用于删除已归档的WAL文件
  0
  保持默认值
   

   
  WAL_size_limit_MB
   
  0
  保持默认值
   

   
  manifest_preallocation_size
  为manifest文件预分配的字节数
  4MB
  保持默认值
   

   
  allow_mmap_reads
  使用mmap读取sst文件:  什么是mmap?
  false
  保持默认值
   

   
  use_direct_reads
  对read/write操作使用direct IO模式
  false
  true
  Pegasus目前配置  使用RocksDB的缓存,不用操作系统内核的page cache。RocksDB比操作系统更懂自己的数据应该如何缓存

   
  use_direct_io_for_flush_and_compaction
  对flush和compaction的写入使用direct IO
  false
  true
  维持Pegasus中的值

   
  allow_fallocate
  是否允许fallocate
  true
  保持默认值  什么是fallocate
   

   
  is_fd_close_on_exec
  Disable child process inherit open files
  true
  保持默认值
   

   
  stats_dump_period_sec
  将rocksdb.stats dump到log文件的周期时间
  600
  保持默认值
   

   
  stats_persist_period_sec
  将rocksdb.stats dump到rocksdb的周期时间
  600
  保持默认值
   

   
  persist_stats_to_disk
  true- 将rocksdb.stats dump到隐藏的cf中  false- 将rocksdb.stats写入到内存结构中
  false
  false
   

   
  stats_history_buffer_size
  用于存储rocksdb.stats的内存大小
  1MB
  保持默认值
   

   
  advise_random_on_open
  sst文件打开时,告诉文件系统其访问模式是random
  true
  保持默认值
   

   
  db_write_buffer_size
  整个db所有cf的memtable总大小
  0
  保持默认值
  只读集群没有写入,无需write buffer

   
  write_buffer_manager
  通过write_buffer_manager,所有实例可共享write buffer
  nullptr
  保持默认值
  只读集群没有写入,无需write buffer

   
  access_hint_on_compaction_start
  compaction开始时的文件访问模式,作用于imput文件
  NORMAL
  保持默认值
   

   
  new_table_reader_for_compaction_inputs
  对compaction imput文件,时钟会创建新的fd和table reader。  后续不再维护
  false
  保持默认值
   

   
  compaction_readahead_size
  compaction时预读,改善随机读
  0
  2MB
  维护Pegasus中设置值

   
  random_access_max_buffer_size
  WinMmapReadableFile使用的buffer size最大值  仅在windows平台有效
  1MB
  保持默认值
   

   
  writable_file_max_buffer_size
  可写文件的最大写缓存
  1MB
  0
  readonly集群没有写入

   
  use_adaptive_mutex
  是否使用adaptive mutex。当锁竞争不激烈时,可以减少context切换;反之会浪费一些spin时间  关于adaptive mutex
  false
  保持默认值
   

   
  bytes_per_sync
  OS递增地sync file,每次sync的字节数
  0
  保持默认值
   

   
  wal_bytes_per_sync
  类似于bytes_per_sync,作用于WAL文件
  0
  保持默认值
   

   
  strict_bytes_per_sync
  搭配bytes_per_sync和wal_bytes_per_sync使用,决定是否控制写入的速度,防止写入过多导致flush堆积
  false
  保持默认值
   

   
  listeners
  当rocksdb的一些时间触发时,调用这些callback
   
   
   

   
  enable_thread_tracking
  跟踪DB内的线程状态
  false
  保持默认值
   

   
  delayed_write_rate
  对DB的写入限速,当下列三个条件之一发生时:  soft_pending_compaction_bytes_limit被触发  level0_slowdown_writes_trigger被触发  当允许超过3个以上的memtable时,正在写入允许的最后一个memtable
  0
  保持默认值
   

   
  enable_pipelined_write
  如果enable_pipelined_write为true,则为WAL写和memtable写保持单独的写线程队列。写线程首先进入WAL写入队列,然后进入memtable写入队列。因此,WAL写入队列上的pending线程只需要等待之前的写入者完成WAL写入,而不需要等待memtable写入。  启用该特性可以提高写吞吐量,减少两阶段提交准备阶段的延迟。
  false
  保持默认值
   

   
  unordered_write
  将unordered_write设置为true可以通过放松snapshot的不变性保证,换取更高的写吞吐量。  这违背了Get从snapshot中所期望的可重复性
  false
  保持默认值
   

   
  allow_concurrent_memtable_write
  允许multi-writers同时更新memtables  如果设置为true,强烈建议打开enable_write_thread_adaptive_yield
  true
  保持默认值
   

   
  enable_write_thread_adaptive_yield
  如果设置为true,写入线程将会和当前write batch group leader同步,等待write_thread_max_yield_usec时间后进入mutex阻塞
  true
  保持默认值
   

   
  max_write_batch_group_size_bytes
  一个WAL或memtable写的单个批处理中写入的最大字节数限制
  1MB
  保持默认值
   

   
  write_thread_max_yield_usec
  在mutex阻塞之前,一个写操作将使用spin loop与其他写线程协调的最大微秒数。
  100
  保持默认值
   

   
  write_thread_slow_yield_usec
  std::this_thread::yield调用(微秒)代表其他进程或线程想要使用当前内核。  增加这一点会使写线程更有可能通过spinning占用CPU,这将表现为上下文切换数量的增加
  3
  保持默认值
   

   
  skip_stats_update_on_db_open
  如果为true,那么DB::Open()将不会更新用于优化compaction的statistics  设置成false有利于减少DBopen时间
  false
  保持默认值
   

   
  wal_recovery_mode
  WAL的recovery mode,用以控制replaying WAL时的一致性
  WALRecoveryMode::kPointInTimeRecovery
  保持默认值
   

   
  allow_2pc
   
  false
  保持默认值
   

   
  row_cache
  global cache for table-level rows
  nullptr
  使用LRUCache
   

   
  wal_filter
  在recovery处理WAL时的filter。  该filter提供了一种检查日志记录、忽略特定记录或跳过replay的方法。
  nullptr
  保持默认值
   

   
  fail_if_options_file_error
  如果找不到options文件,  DB::Open/CreateColumnFamily/DropColumnFamily/SetOptions将会失败
  false
  保持默认值
   

   
  dump_malloc_stats
  如果设置成true,将会随着rocksdb.stats一起打印malloc相关的stats
  false
  保持默认值
   

   
  avoid_flush_during_recovery
  默认情况下,DB在open时会replay WAL,并进行flush,这样会导致产生很多小的sst文件。设置成true可以避免这种情况,并不会带来数据丢失的风险
  false
  保持默认值
   

   
  avoid_flush_during_shutdown
  默认情况下,DB在close时会刷新memtable中所有未持久化的数据。  设置成false可以提高close速度,但是数据会丢失
  false
  保持默认值
   

   
  allow_ingest_behind
  设置成true的话,会有以下影响:  会disable一些内部关于SST文件compression的优化  保留最底层作为ingest的文件使用  num_levels必须>=3
  false
  保持默认值
  只读集群没有写,使用ingest_behind是用于在ingest文件时,保存写请求写入的数据

   
  preserve_deletes
  如果设置成true,只有LSN小于  SetPreserveDeletesSequenceNumber(uint64_t ts)的delete数据才会被删掉,此时客户端需要周期性的调用该函数,否则这些delete数据永远无法删除
  false
  保持默认值
   

   
  two_write_queues
  双写入队列
  false
  保持默认值
   

   
  manual_wal_flush
  如果设置成true,那么每次写入时,WAL将不会自动刷新
  false
  保持默认值
   

   
  atomic_flush
  atomic flush所有的cf
  false
  true
  维持Pegasus中设置的值

   
  avoid_unnecessary_blocking_io
  如果设置成true,working thread将会避免做unnecessary和耗时的工作(例如:删除无用文件、删除memtable),并调度一个background线程来做
  false
  true
  对延迟敏感的话可以打开

   
  write_dbid_to_manifest
  DB ID存入DB folder中的特定文件,设置成true的话,DB ID将存入manifest文件
  false
  保持默认值
   

   
  log_readahead_size
  读取log文件时,预读取的大小,通常用于log文件在远端存储时,用于减少IO往返
  0
  保持默认值
   

  ColumnFamilyOptions
  comparator
  用于定义表中key的顺序
  BytewiseComparator
  字典序
   

   
  merge_operator
  当客户端需要使用Merge操作时,必须提供一个merge_operator
  nullptr
  保持默认值  Pegasus没有使用Merge接口
   

   
  compaction_filter
  当compaction进行时会调用,用于删除或者修改数据。  通过compaction_filter_factory进行配置,可以使每次compaction运行时都创建一个新的compaction filter
  nullptr
  保持默认值
   

   
  compaction_filter_factory
  每次compaction运行时都创建一个compaction filter
  nullptr
  KeyWithTTLCompactionFilterFactory
  维持Pegasus中的设置

   
  write_buffer_size
  write buffer大小
  64M
  参见上表
   

   
  compression
  使用指定的压缩算法对block压缩
  kSnappyCompression
   
   

   
  bottommost_compression
  用于最底层的压缩算法
  kDisableCompressionOption
   
   

   
  bottommost_compression_opts
  可用于bottommost_compression的压缩算法配置
   
   
   

   
  compression_opts
  压缩算法的配置
   
   
   

   
  compression_per_level
  每层所采用的压缩算法
   
  level 0和level 1不压缩
   

   
  level0_file_num_compaction_trigger
  L0层文件达到该数量,触发compaction
  4
  data: 4  meta: 10
  维持Pegasus设置值

   
  prefix_extractor
  每次取key的前N位,根据key的前N位来构造bloom filter,用于提高范围查询效率
  nullptr
  HashkeyTransform
  维持Pegasus设置值

   
  max_bytes_for_level_base
  L1层总大小
  256M
  640M
  维持Pegasus设置值

   
  disable_auto_compactions
  即使关闭,manual compaction仍然可以执行
  false
  保持默认值
   

   
  table_factory
  table factory
  block-based table factory
  NewBlockBasedTableFactory
  维持Pegasus设置值

   
  cf_paths
  该column family的SST文件的存放路径列表
  空
  保持默认值
   

   
  compaction_thread_limiter
  同时执行compaction的thread limiter,泳衣控制最大执行compaction任务的线程数量
  nullptr
  保持默认值
   

  BlockBasedTableOptions
  flush_block_policy_factory
  用于创建flush block policy,而flush block policy用于决定什么时候flush block
  FlushBlockBySizePolicy
  保持默认值
   

   
  cache_index_and_filter_blocks
  是否将index和filter放入block cache,如果不放入block cache,则每次在open表的时候预加载index和filter
  false
  保持默认值
   

   
  cache_index_and_filter_blocks_with_high_priority
  在block cache中,将index和filter设置为高优先级  搭配cache_index_and_filter_blocks使用
  true
  保持默认值
   

   
  pin_l0_filter_and_index_blocks_in_cache
  将L0层的index和filter一直放置在block cache中
  false
  保持默认值
   

   
  pin_top_level_index_and_filter
  搭配cache_index_and_filter_blocks使用,当两者都是true时,将top level的index和filter一直放在block cache中,不止包括L0层
  true
  保持默认值
   

   
  index_type
  索引类型,用于索引Data Block/Meta Block,支持:  kBinarySearch  kHashSearch  kTwoLevelIndexSearch  kBinarySearchWithFirstKey
  kBinarySearch
  保持默认值
   

   
  data_block_index_type
  索引类型,用于索引Data Block
  kDataBlockBinarySearch
  保持默认值
   

   
  data_block_hash_table_util_ratio
  entries/buckets比率。当data_block_hash_index_type=  kDataBlockBinaryAndHash时才有效
  0.75
  保持默认值
   

   
  checksum
  新创建的表会使用该checksum,老表仍旧用以前的checksum
  kCRC32c
  保持默认值
   

   
  no_block_cache
  是否关闭block cache
  false
  保持默认值
   

   
  block_cache
  block cache,可选:lru cache、clock cache
   
  LRU Cache  capacity: 10G  shards: -1 (auto)
  保持Pegasus中的设置

   
  persistent_cache
  读取硬盘page所用的cache
  nullptr
  保持默认值
   

   
  block_cache_compressed
  存放压缩block的cache
  nullptr
  保持默认值
   

   
  block_size
  data block size(非精确值),这里定义的是非压缩数据的大小,如果开启了压缩,实际大小会小于block_size
  4K
  保持默认值
   

   
  block_size_deviation
  创建新block的两个条件:  当前block的free space比率小于block_size_deviation  添加一条新的数据,导致当前block大小大于block_size
  10
  保持默认值
   

   
  block_restart_interval
  BlockBuilder对key的存储是前缀压缩的,对于有序的字符串来讲,这能极大的减少存储空间。但是却增加了查找的时间复杂度,为了兼顾查找效率,每隔K个key,leveldb就不使用前缀压缩,而是存储整个key,这就是重启点(restartpoint)。  在构建Block时,block_restart_interval指定每隔几个key就直接存储一个重启点key。
  16
  保持默认值
   

   
  index_block_restart_interval
  同block_restart_interval
  1
  保持默认值
   

   
  row_cachemetadata_block_size
  metadata block size,主要作用于:  使用kTwoLevelIndexSearch时的index  使用partition_filters时的filters
  4K
  保持默认值
   

   
  partition_filters
  需要搭配kTwoLevelIndexSearch使用
  false
  保持默认值
   

   
  use_delta_encoding
  在压缩block中的key时,使用delta encoding
  true
  保持默认值
   

   
  filter_policy
  bloom filter policy
   
  bits_per_key: 10
  保持Pegasus中的设置

   
  whole_key_filtering
  使用整个key作为filter
  true
  保持默认值
   

   
  verify_compression
  对压缩块进行解压缩以进行验证。这是一种验证模式,我们用它来检测压缩算法中的漏洞。
  false
  保持默认值
   

   
  read_amp_bytes_per_bit
  对于load到内存中的data block,创建一个bitmap,用于统计该block实际读取的比例  bitmap size:  block_size/read_amp_bytes_per_bit/8
  0
  保持默认值
   

   
  format_version
  table data format version
  2
  2或者5,根据rocksdb版本决定
   

   
  enable_index_compression
  使用压缩的方式来存储index block
  true
  保持默认值
   

   
  block_align
  当data block大小小于page size和block size时,对齐
  false
  保持默认值
   

   
  index_shortening
  提高index size以交换获取更高的seek性能。  详见:https://www.bookstack.cn/read/rocksdb-6.14-en/d4af078604e06f12.md
  kShortenSeparators
  保持默认值
   

ReadOnly集群调优

RocksDB参数调优

   
  参数
  说明
  原有值
  建议值
  原因

  DBOptions
  compaction_readahead_size
  compaction时预读,改善随机读
  2MB
  0
  readonly集群不需要compaction

   
  max_background_flushes
  执行flush的最大线程数
  4
  0
  readonly集群不需要flush

   
  max_background_compactions
  执行compaction的最大线程数
  12
  4
  readonly集群不需要compaction

   
  num_levels
  lsm-tree层数
  6
  1
  减少读放大  readonly集群不需要compaction,无需划分多层来优化compaction  Q: 只有一层,那这一层是不是L0,查找性能是否有问题?

   
  write_buffer_size
  write buffer大小
  64M
  0
  readonly集群没有写入,不需要write buffer

   
  max_write_buffer_number
  write buffer最大数量
  3
  0
  readonly集群没有写入,不需要write buffer

   
  writable_file_max_buffer_size
  可写文件的最大写缓存
  1MB
  0
  readonly集群没有写入

   
  row_cache
  A global cache for table-level rows
  nullptr  (disabled)
  LRUCache
  Row Cache来应付单行查询,Block Cache负责Row Cache miss的漏网之鱼,也用来应付scan  由于LSM的compaction操作会一次大批量更新大量的Data Block,导致Block Cache中大量数据短时间内失效,Row Cache可以适当弥补这种情况  经与百度kvRocks团队沟通,优化效果不理想

  data ColumnFamilyOptions
  memtable_prefix_bloom_size_ratio
  为memtable创建prefix bloom,其大小为:  write_buffer_size * memtable_prefix_bloom_size_ratio  最大不超过0.25
  0.1
  0.1
  readonly集群没有写入,不需要write buffer,更不需要为其创建prefix bloom

  BlockBasedTableOptions
  data_block_index_type
  索引类型,用于索引Data Block
  kDataBlockBinarySearch
  kDataBlockBinaryAndHash
  在 Data Block 上使用 Hash 索引来提升点查询的效率。  目前Pegasus 在查找 Data Block 时使用二分查找,二分查找会导致 CPU Cache Miss,增加 CPU 使用率。如果在 Data Block 上使用 Hash 索引,可以避免二分查找,在点查询场景下降低 CPU 利用率。官方的测试数据显示:该特性可降低 21.8% CPU 利用率,提升 10% 吞吐,但会增加 4.6% 的磁盘空间占用。

Pegasus调整

empty write需要关闭

其他存储引擎

可以考虑使用B+-tree及其变种的存储引擎,对读性能更加友好。

boltDB: 使用Golang开发的B+-tree KV存储引擎,被应用于influxDB项目作为底层存储

ForestDB:CouchBase使用的KV存储引擎,基于HB+-tree。HB+-tree对于长key的性能相对B+-tree更好,但是range查询性能稍差

Reference

kvrocks在RocksDB上的优化实践

ForestDB paper解读