TiDB试用 来源:TiDB  浏览 87 扫码 分享 2023-05-09 09:02:19

TiKV 内存参数性能调优

本文档用于描述如何根据机器配置情况来调整 TiKV 的参数,使 TiKV 的性能达到最优。你可以在 etc/config-template.toml 找到配置文件模版,参考使用 TiUP 修改配置参数进行操作,部分配置项可以通过在线修改 TiKV 配置方式在线更新。具体配置项的含义可参考 TiKV 配置文件描述

TiKV 最底层使用的是 RocksDB 做为持久化存储,所以 TiKV 的很多性能相关的参数都是与 RocksDB 相关的。TiKV 使用了两个 RocksDB 实例,默认 RocksDB 实例存储 KV 数据,Raft RocksDB 实例(简称 RaftDB)存储 Raft 数据。

TiKV 使用了 RocksDB 的 Column Families (CF) 特性。

  • 默认 RocksDB 实例将 KV 数据存储在内部的 defaultwrite 和 lock 3 个 CF 内。

    • default CF 存储的是真正的数据,与其对应的参数位于 [rocksdb.defaultcf] 项中;
    • write CF 存储的是数据的版本信息 (MVCC) 以及索引相关的数据,相关的参数位于 [rocksdb.writecf] 项中;
    • lock CF 存储的是锁信息,系统使用默认参数。
  • Raft RocksDB 实例存储 Raft log。

    • default CF 主要存储的是 Raft log,与其对应的参数位于 [raftdb.defaultcf] 项中。

所有的 CF 默认共同使用一个 block cache 实例。通过在 [storage.block-cache] 下设置 capacity 参数,你可以配置该 block cache 的大小。block cache 越大,能够缓存的热点数据越多,读取数据越容易,同时占用的系统内存也越多。如果要为每个 CF 使用单独的 block cache 实例,需要在 [storage.block-cache] 下设置 shared=false,并为每个 CF 配置单独的 block cache 大小。例如,可以在 [rocksdb.writecf] 下设置 block-cache-size 参数来配置 write CF 的大小。

注意

在 TiKV 3.0 之前的版本中,不支持使用 shared block cache,需要为每个 CF 单独配置 block cache。

每个 CF 有各自的 write-buffer,大小通过 write-buffer-size 控制。

参数说明

  1. # 日志级别,可选值为:trace,debug,warn,error,info,off
  2. log-level = "info"
  3. [server]
  4. # 监听地址
  5. # addr = "127.0.0.1:20160"
  6. # gRPC 线程池大小
  7. # grpc-concurrency = 4
  8. # TiKV 每个实例之间的 gRPC 连接数
  9. # grpc-raft-conn-num = 10
  10. # TiDB 过来的大部分读请求都会发送到 TiKV 的 Coprocessor 进行处理,该参数用于设置
  11. # coprocessor 线程的个数,如果业务是读请求比较多,增加 coprocessor 的线程数,但应比系统的
  12. # CPU 核数小。例如:TiKV 所在的机器有 32 core,在重读的场景下甚至可以将该参数设置为 30。在没有
  13. # 设置该参数的情况下,TiKV 会自动将该值设置为 CPU 总核数乘以 0.8。
  14. # end-point-concurrency = 8
  15. # 可以给 TiKV 实例打标签,用于副本的调度
  16. # labels = {zone = "cn-east-1", host = "118", disk = "ssd"}
  17. [storage]
  18. # 数据目录
  19. # data-dir = "/tmp/tikv/store"
  20. # 通常情况下使用默认值就可以了。在导数据的情况下建议将该参数设置为 1024000。
  21. # scheduler-concurrency = 102400
  22. # 该参数控制写入线程的个数,当写入操作比较频繁的时候,需要把该参数调大。使用 top -H -p tikv-pid
  23. # 发现名称为 sched-worker-pool 的线程都特别忙,这个时候就需要将 scheduler-worker-pool-size
  24. # 参数调大,增加写线程的个数。
  25. # scheduler-worker-pool-size = 4
  26. [storage.block-cache]
  27. ## 是否为 RocksDB 的所有 CF 都创建一个 `shared block cache`。
  28. ##
  29. ## RocksDB 使用 block cache 来缓存未压缩的数据块。较大的 block cache 可以加快读取速度。
  30. ## 推荐开启 `shared block cache` 参数。这样只需要设置全部缓存大小,使配置过程更加方便。
  31. ## 在大多数情况下,可以通过 LRU 算法在各 CF 间自动平衡缓存用量。
  32. ##
  33. ## `storage.block-cache` 会话中的其余配置仅在开启 `shared block cache` 时起作用。
  34. # shared = true
  35. ## `shared block cache` 的大小。正常情况下应设置为系统全部内存的 30%-50%。
  36. ## 如果未设置该参数,则由以下字段或其默认值的总和决定。
  37. ##
  38. ## * rocksdb.defaultcf.block-cache-size 或系统全部内存的 25%
  39. ## * rocksdb.writecf.block-cache-size 或系统全部内存的 15%
  40. ## * rocksdb.lockcf.block-cache-size 或系统全部内存的 2%
  41. ## * raftdb.defaultcf.block-cache-size 或系统全部内存的 2%
  42. ##
  43. ## 要在单个物理机上部署多个 TiKV 节点,需要显式配置该参数。
  44. ## 否则,TiKV 中可能会出现 OOM 错误。
  45. # capacity = "1GB"
  46. [pd]
  47. # pd 的地址
  48. # endpoints = ["127.0.0.1:2379","127.0.0.2:2379","127.0.0.3:2379"]
  49. [metric]
  50. # 将 metrics 推送给 Prometheus pushgateway 的时间间隔
  51. interval = "15s"
  52. # Prometheus pushgateway 的地址
  53. address = ""
  54. job = "tikv"
  55. [raftstore]
  56. # Raft RocksDB 目录。默认值是 [storage.data-dir] 的 raft 子目录。
  57. # 如果机器上有多块磁盘,可以将 Raft RocksDB 的数据放在不同的盘上,提高 TiKV 的性能。
  58. # raftdb-path = "/tmp/tikv/store/raft"
  59. # 当 Region 写入的数据量超过该阈值的时候,TiKV 会检查该 Region 是否需要分裂。为了减少检查过程
  60. # 中扫描数据的成本,导入数据过程中可以将该值设置为 32 MB,正常运行状态下使用默认值即可。
  61. region-split-check-diff = "32MB"
  62. [coprocessor]
  63. ## 当区间为 [a,e) 的 Region 的大小超过 `region_max_size`,TiKV 会尝试分裂该 Region,例如分裂成 [a,b)、[b,c)、[c,d)、[d,e) 等区间的 Region 后
  64. ## 这些 Region [a,b), [b,c), [c,d) 的大小为 `region_split_size` (或者稍大于 `region_split_size`)
  65. # region-max-size = "144MB"
  66. # region-split-size = "96MB"
  67. [rocksdb]
  68. # RocksDB 进行后台任务的最大线程数,后台任务包括 compaction 和 flush。具体 RocksDB 为什么需要进行 compaction,
  69. # 请参考 RocksDB 的相关资料。在写流量比较大的时候(例如导数据),建议开启更多的线程,
  70. # 但应小于 CPU 的核数。例如在导数据的时候,32 核 CPU 的机器,可以设置成 28。
  71. # max-background-jobs = 8
  72. # RocksDB 能够打开的最大文件句柄数。
  73. # max-open-files = 40960
  74. # RocksDB MANIFEST 文件的大小限制.# 更详细的信息请参考:https://github.com/facebook/rocksdb/wiki/MANIFEST
  75. max-manifest-file-size = "20MB"
  76. # RocksDB write-ahead logs 目录。如果机器上有两块盘,可以将 RocksDB 的数据和 WAL 日志放在
  77. # 不同的盘上,提高 TiKV 的性能。
  78. # wal-dir = "/tmp/tikv/store"
  79. # 下面两个参数用于怎样处理 RocksDB 归档 WAL。
  80. # 更多详细信息请参考:https://github.com/facebook/rocksdb/wiki/How-to-persist-in-memory-RocksDB-database%3F
  81. # wal-ttl-seconds = 0
  82. # wal-size-limit = 0
  83. # RocksDB WAL 日志的最大总大小,通常情况下使用默认值就可以了。
  84. # max-total-wal-size = "4GB"
  85. # 可以通过该参数打开或者关闭 RocksDB 的统计信息。
  86. # enable-statistics = true
  87. # 开启 RocksDB compaction 过程中的预读功能,如果使用的是机械磁盘,建议该值至少为2MB。
  88. # compaction-readahead-size = "2MB"
  89. [rocksdb.defaultcf]
  90. # 数据块大小。RocksDB 是按照 block 为单元对数据进行压缩的,同时 block 也是缓存在 block-cache
  91. # 中的最小单元(类似其他数据库的 page 概念)。
  92. block-size = "64KB"
  93. # RocksDB 每一层数据的压缩方式,可选的值为:no,snappy,zlib,bzip2,lz4,lz4hc,zstd。
  94. # no:no:lz4:lz4:lz4:zstd:zstd 表示 level0 和 level1 不压缩,level2 到 level4 采用 lz4 压缩算法,
  95. # level5 和 level6 采用 zstd 压缩算法,。
  96. # no 表示没有压缩,lz4 是速度和压缩比较为中庸的压缩算法,zlib 的压缩比很高,对存储空间比较友
  97. # 好,但是压缩速度比较慢,压缩的时候需要占用较多的 CPU 资源。不同的机器需要根据 CPU 以及 I/O 资
  98. # 源情况来配置怎样的压缩方式。例如:如果采用的压缩方式为"no:no:lz4:lz4:lz4:zstd:zstd",在大量
  99. # 写入数据的情况下(导数据),发现系统的 I/O 压力很大(使用 iostat 发现 %util 持续 100% 或者使
  100. # 用 top 命令发现 iowait 特别多),而 CPU 的资源还比较充裕,这个时候可以考虑将 level0 和
  101. # level1 开启压缩,用 CPU 资源换取 I/O 资源。如果采用的压缩方式
  102. # 为"no:no:lz4:lz4:lz4:zstd:zstd",在大量写入数据的情况下,发现系统的 I/O 压力不大,但是 CPU
  103. # 资源已经吃光了,top -H 发现有大量的 bg 开头的线程(RocksDB 的 compaction 线程)在运行,这
  104. # 个时候可以考虑用 I/O 资源换取 CPU 资源,将压缩方式改成"no:no:no:lz4:lz4:zstd:zstd"。总之,目
  105. # 的是为了最大限度地利用系统的现有资源,使 TiKV 的性能在现有的资源情况下充分发挥。
  106. compression-per-level = ["no", "no", "lz4", "lz4", "lz4", "zstd", "zstd"]
  107. # RocksDB memtable 的大小。
  108. write-buffer-size = "128MB"
  109. # 最多允许几个 memtable 存在。写入到 RocksDB 的数据首先会记录到 WAL 日志里面,然后会插入到
  110. # memtable 里面,当 memtable 的大小到达了 write-buffer-size 限定的大小的时候,当前的
  111. # memtable 会变成只读的,然后生成一个新的 memtable 接收新的写入。只读的 memtable 会被
  112. # RocksDB 的 flush 线程(max-background-flushes 参数能够控制 flush 线程的最大个数)
  113. # flush 到磁盘,成为 level0 的一个 sst 文件。当 flush 线程忙不过来,导致等待 flush 到磁盘的
  114. # memtable 的数量到达 max-write-buffer-number 限定的个数的时候,RocksDB 会将新的写入
  115. # stall 住,stall 是 RocksDB 的一种流控机制。在导数据的时候可以将 max-write-buffer-number
  116. # 的值设置的更大一点,例如 10。
  117. max-write-buffer-number = 5
  118. # 当 level0 的 sst 文件个数到达 level0-slowdown-writes-trigger 指定的限度的时候,
  119. # RocksDB 会尝试减慢写入的速度。因为 level0 的 sst 太多会导致 RocksDB 的读放大上升。
  120. # level0-slowdown-writes-trigger 和 level0-stop-writes-trigger 是 RocksDB 进行流控的
  121. # 另一个表现。当 level0 的 sst 的文件个数到达 4(默认值),level0 的 sst 文件会和 level1 中
  122. # 有 overlap 的 sst 文件进行 compaction,缓解读放大的问题。
  123. level0-slowdown-writes-trigger = 20
  124. # 当 level0 的 sst 文件个数到达 level0-stop-writes-trigger 指定的限度的时候,RocksDB 会
  125. # stall 住新的写入。
  126. level0-stop-writes-trigger = 36
  127. # 当 level1 的数据量大小达到 max-bytes-for-level-base 限定的值的时候,会触发 level1 的
  128. # sst 和 level2 种有 overlap 的 sst 进行 compaction。
  129. # 黄金定律:max-bytes-for-level-base 的设置的第一参考原则就是保证和 level0 的数据量大致相
  130. # 等,这样能够减少不必要的 compaction。例如压缩方式为"no:no:lz4:lz4:lz4:lz4:lz4",那么
  131. # max-bytes-for-level-base 的值应该是 write-buffer-size 的大小乘以 4,因为 level0 和
  132. # level1 都没有压缩,而且 level0 触发 compaction 的条件是 sst 的个数到达 4(默认值)。在
  133. # level0 和 level1 都采取了压缩的情况下,就需要分析下 RocksDB 的日志,看一个 memtable 的压
  134. # 缩成一个 sst 文件的大小大概是多少,例如 32MB,那么 max-bytes-for-level-base 的建议值就应
  135. # 该是 32MB * 4 = 128MB。
  136. max-bytes-for-level-base = "512MB"
  137. # sst 文件的大小。level0 的 sst 文件的大小受 write-buffer-size 和 level0 采用的压缩算法的
  138. # 影响,target-file-size-base 参数用于控制 level1-level6 单个 sst 文件的大小。
  139. target-file-size-base = "32MB"
  140. [rocksdb.writecf]
  141. # 保持和 rocksdb.defaultcf.compression-per-level 一致。
  142. compression-per-level = ["no", "no", "lz4", "lz4", "lz4", "zstd", "zstd"]
  143. # 保持和 rocksdb.defaultcf.write-buffer-size 一致。
  144. write-buffer-size = "128MB"
  145. max-write-buffer-number = 5
  146. min-write-buffer-number-to-merge = 1
  147. # 保持和 rocksdb.defaultcf.max-bytes-for-level-base 一致。
  148. max-bytes-for-level-base = "512MB"
  149. target-file-size-base = "32MB"
  150. [raftdb]
  151. # RaftDB 能够打开的最大文件句柄数。
  152. # max-open-files = 40960
  153. # 可以通过该参数打开或者关闭 RaftDB 的统计信息。
  154. # enable-statistics = true
  155. # 开启 RaftDB compaction 过程中的预读功能,如果使用的是机械磁盘,建议该值至少为2MB。
  156. # compaction-readahead-size = "2MB"
  157. [raftdb.defaultcf]
  158. # 保持和 rocksdb.defaultcf.compression-per-level 一致。
  159. compression-per-level = ["no", "no", "lz4", "lz4", "lz4", "zstd", "zstd"]
  160. # 保持和 rocksdb.defaultcf.write-buffer-size 一致。
  161. write-buffer-size = "128MB"
  162. max-write-buffer-number = 5
  163. min-write-buffer-number-to-merge = 1
  164. # 保持和 rocksdb.defaultcf.max-bytes-for-level-base 一致。
  165. max-bytes-for-level-base = "512MB"
  166. target-file-size-base = "32MB"

TiKV 内存使用情况

除了以上列出的 block-cache 以及 write-buffer 会占用系统内存外:

  1. 需预留一些内存作为系统的 page cache
  2. TiKV 在处理大的查询的时候(例如 select * from ...)会读取数据然后在内存中生成对应的数据结构返回给 TiDB,这个过程中 TiKV 会占用一部分内存

TiKV 机器配置推荐

  1. 生产环境中,不建议将 TiKV 部署在 CPU 核数小于 8 或内存低于 32GB 的机器上
  2. 如果对写入吞吐要求比较高,建议使用吞吐能力比较好的磁盘
  3. 如果对读写的延迟要求非常高,建议使用 IOPS 比较高的 SSD 盘

[转帖]TiKV 内存调优的更多相关文章

  1. JVM实用参数(四)内存调优

    理想的情况下,一个Java程序使用JVM的默认设置也可以运行得很好,所以一般来说,没有必要设置任何JVM参数.然而,由于一些性能问题(很不幸的是,这些问题经常出现),一些相关的JVM参数知识会是我们工 ...

  2. JVM学习笔记(四)------内存调优【转】

    转自:http://blog.csdn.net/cutesource/article/details/5907418 版权声明:本文为博主原创文章,未经博主允许不得转载. 首先需要注意的是在对JVM内 ...

  3. [hadoop] 集群启动和内存调优

    1.启动Hadoop集群 #首先查看下zoo.cfg里面配置的server.id和集群主机的id是否一致 #如果不一致会造成yarn控制不了从节点的启动 cat /home/hadoop/zookee ...

  4. JVM学习笔记(四)------内存调优

    首先需要注意的是在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况,因为GC过后这个值是不会变化的,因此内存调优的时候要更多地使用JDK提 ...

  5. 【Spark篇】---Spark调优之代码调优,数据本地化调优,内存调优,SparkShuffle调优,Executor的堆外内存调优

    一.前述 Spark中调优大致分为以下几种 ,代码调优,数据本地化,内存调优,SparkShuffle调优,调节Executor的堆外内存. 二.具体    1.代码调优 1.避免创建重复的RDD,尽 ...

  6. 我进行jvm内存调优的一些记录

    jvm内存调优的一些记录 java内存调优的方法和过程 可以使用 jmap -heap pid号 查看,例如pid是9300,执行的结果可能是这样的. root@ubuntu:~# jmap -hea ...

  7. JVM、垃圾回收、内存调优、常见參数

    一.什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写.JVM是一种用于计算设备的规范.它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现 ...

  8. MapReduce内存调优

    内存调优 Hadoop处理数据时,出现内存溢出的处理方法?(内存调优) 1.Mapper/Reducer阶段JVM内存溢出(一般都是堆) 1)JVM堆(Heap)内存溢出:堆内存不足时,一般会抛出如下 ...

  9. JVM内存调优原则及几种JVM内存调优方法

      转载,如需帮助,请联系wlgchun@163.com https://blog.csdn.net/LeegooWang/article/details/88696195 如何对JVM进行内存调优? ...

  10. JVM参数配置及内存调优

    一.JVM常见参数配置 堆内存相关参数 参数名称 含义 默认值   -Xms 初始堆大小 物理内存的1/64(<1GB) 默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40% ...

随机推荐

  1. JavaFx之场景交互(二十一)

    JavaFx之场景交互(二十一) 有parent.son两个父子窗口,父窗口可以操作子窗口,父子可以相互调用对方的对象,下面我给出两种方案,我推荐使用第二种 一.构造传参 参数比较多的话代码不优雅.而 ...

  2. Spring 事务的实现原理

    在执行访问数据库相关的操作中,特别是针对数据的修改操作,由于对于数据的修改可能会出现异常,因此对于整个一组的数据修改实际上都不能算是生效的,在这种情况下,需要使用事务的 "回滚" ...

  3. 文心一言 VS 讯飞星火 VS chatgpt (37)-- 算法导论5.4 1题

    一.一个屋子里必须要有多少人,才能让某人和你生日相同的概率至少为1/2? 必须要有多少人,才能让至少两个人生日为 7月 4 日的概率大于 1/2? 文心一言: 一个屋子里必须要有多少人,才能让某人和你 ...

  4. 8种ETL算法汇总大全!看完你就全明白了

    摘要:ETL是将业务系统的数据经过抽取.清洗转换之后加载到数据仓库的过程,是构建数据仓库的重要一环,用户从数据源抽取出所需的数据,经过数据清洗,最终按照预先定义好的数据仓库模型,将数据加载到数据仓库中 ...

  5. 昇腾实战丨DVPP媒体数据处理图片解码问题案例

    摘要:本期就分享几个关于DVPP图片解码问题的典型案例,并给出原因分析及解决方法. 本文分享自华为云社区<DVPP媒体数据处理图片解码问题案例>,作者:昇腾CANN . DVPP(Digi ...

  6. 如何通过jstat命令进行查看堆内存使用情况?

    摘要:jstat命令可以查看堆内存各部分的使用量,以及加载类的数量. 本文分享自华为云社区<JVM之通过jstat命令进行查看堆内存使用情况>,作者:共饮一杯无 . 基本概念 jstat是 ...

  7. KAFKA EAGLE 监控MRS kafka之操作实践

    本文分享自华为云社区<KAFKA EAGLE 监控MRS kafka之操作实践>,作者: 啊喔YeYe . 1.Kafka Eagle简介 Kafka eagle 是一款分布式.高可用的k ...

  8. 解读clickhouse存算分离在华为云实践

    摘要:本文是我们对clickhouse做了最简单的支持obs的适配改造. 本文分享自华为云社区<clickhouse存算分离在华为云实践>,作者: he lifu. clickhouse是 ...

  9. vue2升级vue3:webpack vue-loader 打包配置

    如果没有啥特别的需求还是推荐vue-cli! vite  vue3 TSX项目 虽然vite 很香,但是vite  rollup 动态加载,多页面 等问题比较难搞 vite的缺点 wepback  _ ...

  10. 火山引擎DataLeap一站式数据治理解决方案及平台架构

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 在字节跳动内部,DataLeap数据平台数据治理团队致力于建立一站式.全链路的数据治理解决方案平台. 数据治理的概 ...