4.1 性能调优地图

    下图展示 TiDB 各个模块地图,通过这张地图可以清晰展现 TiDB 如何处理一条 SQL。

    • TiDB 的【Server】模块会为 MySQL 客户端的每一个连接创建一个 session 并且分配一个 token。可以通过 Connection Count 这项监控来查看 TiDB 的连接数,通常建议单个 TiDB 的连接数不超过 500 个

    • 经由这个 session 发送到 TiDB 的 SQL 会在【Parse】中被转化为能够被 TiDB 所理解的语法树。转化时间可通过监控【Executor/Parse Duration】查看,通常应该在 10ms 以内

    • TiDB 根据语法树生成物理执行计划,决定选择哪些索引或者算子进行计算,这个过程被称作【Compile】。执行时间可通过监控【Executor/Compile Duration】查看

    • 生成的物理执行计划会在【Executor】中进行执行

      • 如果是 DML 语句,TiDB 会将用户更新的内容先缓存在【Transaction】模块中,等到用户执行事务的 Commit 时再进行两阶段提交,将结果写入到 TiKV

      • 对于复杂查询请求,TiDB 会通过 【DistSQL】模块并行地向 TiKV 的多个 region 发送查询请求,然后再按照执行计划中的流程计算出查询结果来

      • TiDB 发送给 TiKV 的各种请求耗时可以通过监控【KV Request/KV Request Duration 99 by type】查看

      • 事务在 channel 中等待的时间为监控【PD Client/PD TSO Wait Duration】

    • 参考 一章

    • TiKV 的主要由 6 个模块构成。分别是 gRPC、Scheduler、raftstore、apply、storage-readpool 以及 coprocessor-readpool

      • gRPC 是 TiKV 所有请求的入口,他会将外界的请求转发给各个模块

        • 对于写事务的请求,会转发给 scheduler 线程
        • 对于简单的读取请求 kv get 或者 kv batch get 会转发给 storage-readpool
        • 对于 TiDB 的 DistSQL 发送过来的 Coprocessor 请求会转发给 coprocessor-readpool(在 4.0 中 storage-readpool 与 coprocessor-readpool 已经被合并为了同一个线程池)
        • 如果是 PD 操作 region 的命令,则直接发送给 raftstore 线程
      • scheduler 负责检测事务冲突,将复杂的事务操作转换为简单的 key-value 插入、删除,发送给 raftstore 线程

        • scheduler 线程执行各个命令的时间可以通过监控【Scheduler-{{cmd}}/Scheduler command duration】查看。例如,Prewrite 请求的执行时间在【Scheduler-prewrite】面板
        • 写请求完成 raft 日志复制,到写入 RocksDB 的全部时间可以通过监控【Storage/async write duration】查看
      • raftstore 负责执行 raft 日志复制,将数据复制给多个副本。当日志在多个副本上达成一致后,会发送给 apply 线程

        • 写请求消耗在 raftstore 线程的时间为【Raft IO/Commit log duration】(raft 日志在多数副本上达成一致所需的时间)与【Raft Propose/Propose wait duration】(在队列中等待被处理的时间)之和
      • storage-readpool 处理 kv get 以及 kv batch get 等简单的查询请求

    • TiKV 共持有两个 RocksDB 实例,一个用于 raftstore 线程记录 raft 日志与 raft 元信息。另一个用于记录用户写入的数据,以及 TiKV 事务中的锁信息

    • 线程池调优请见 8.2.1 TiKV 线程池优化 章节

    RocskDB 是一款优秀的开源单机存储引擎,负责将 TiDB 的数据存储在磁盘上。

    • RocksDB 的三种基本文件格式

      • Memtable 是一种内存文件数据系统,新数据会被写进 Memtable

        • 读取数据如果 Memtable 没有,会访问 Block-Cache

        • Block-Cache 默认设置为系统总内存的 45%,单机多实例的情况下,按照实例个数分配

      • WAL Write Ahead Log 写操作先写入 logfile,再写入 Memtable

      • SST 在 Memtable 写满以后,将数据写入磁盘中的 SST 文件,对应 logfile 里的 log 会被安全删除。

        • SST 文件中的内容是有序的