Skip to content

TiKV Server 组件

角色定位

TiKV Server 是 TiDB 分布式数据库的分布式存储引擎,负责数据的持久化存储、复制和高可用。它是 TiDB 架构中的存储层核心组件,为上层 TiDB Server 提供可靠的数据存储服务。

核心功能

  • 分布式键值存储:提供基于范围的分布式键值存储服务
  • 数据复制:基于 Raft 协议实现数据多副本复制
  • 强一致性保证:通过 Raft 协议保证数据的线性一致性
  • 自动分片:数据自动划分为 Region,支持水平扩展
  • 分布式事务:支持乐观锁和悲观锁,实现 ACID 分布式事务
  • 热点数据处理:自动检测和处理热点数据
  • 数据压缩:支持多种压缩算法,降低存储成本

架构特点

  • 基于 RocksDB:使用 RocksDB 作为本地存储引擎
  • Raft 一致性:基于 Raft 协议实现数据复制和一致性
  • 水平扩展:支持通过增加节点线性扩展存储容量和性能
  • 高可用性:数据多副本存储,自动故障转移
  • 跨 AZ/Region 部署:支持跨可用区或跨地域部署,提高容灾能力
  • 云原生设计:支持容器化部署和 Kubernetes 管理

架构设计

内部模块

TiKV Server 内部包含多个核心模块,协同工作提供分布式存储服务:

1. 网络层

  • 功能:处理节点间通信和客户端请求
  • 协议支持:gRPC 协议,高效的跨语言通信
  • 连接管理:管理与其他 TiKV 节点、PD 节点和 TiDB 节点的连接
  • 负载均衡:客户端请求的负载均衡

2. Raft 层

  • 功能:实现 Raft 共识算法,保证数据一致性
  • Raft 组管理:管理多个 Region 的 Raft 组
  • 日志复制:负责 Raft 日志的复制和提交
  • Leader 选举:处理 Raft 组的 Leader 选举
  • 成员变更:支持 Raft 组成员的动态变更

3. 存储引擎层

  • 功能:负责数据的本地存储和管理
  • RocksDB 封装:对 RocksDB 进行封装,提供高效的键值存储
  • 多列族支持:支持多个列族,优化不同类型数据的存储
  • 数据压缩:支持多种压缩算法(如 Snappy、LZ4、Zlib 等)
  • 事务支持:支持乐观锁和悲观锁事务

4. Coprocessor 层

  • 功能:在存储层执行部分计算,减少网络传输
  • 下推计算:支持谓词下推、聚合下推等计算下推
  • 分布式执行:支持并行执行多个 Coprocessor 任务
  • 减少网络开销:将计算靠近数据,减少数据传输量

5. 事务层

  • 功能:实现分布式事务
  • 乐观事务:基于 Percolator 模型的乐观锁事务
  • 悲观事务:支持悲观锁,适合高冲突场景
  • 两阶段提交:实现分布式事务提交
  • MVCC 支持:多版本并发控制,支持快照读

6. Region 管理

  • 功能:管理数据分片(Region)
  • Region 拆分:当 Region 大小超过阈值时自动拆分
  • Region 合并:合并相邻的小 Region,减少元数据开销
  • Region 迁移:根据 PD 的调度指令迁移 Region
  • 热点处理:自动检测和处理热点 Region

数据组织方式

1. Key-Value 模型

TiKV 采用键值对存储模型,所有数据都以键值对的形式存储:

  • Key:全局唯一的字节串,按照字典序排序
  • Value:对应的数据字节串
  • Version:每个 Key 可以有多个版本,支持 MVCC

2. Region 机制

  • 定义:TiKV 将数据按照 Key 范围划分为多个 Region
  • 默认大小:96MB(可配置)
  • Raft 组:每个 Region 的副本组成一个 Raft 组
  • 副本数量:默认 3 个副本,可配置
  • Leader 节点:每个 Raft 组有一个 Leader 节点,处理所有读写请求
  • Follower 节点:其他节点为 Follower,负责复制日志和参与投票

3. 数据分布

  • Range 分片:数据按照 Key 范围自动分配到不同 Region
  • 副本分布:副本分布在不同节点,优先跨 AZ/Region 分布
  • 数据均衡:PD 自动调度 Region,平衡节点负载
  • 热点调度:PD 自动识别热点 Region,将其分散到不同节点

Raft 协议实现

1. Raft 基本概念

  • Leader:每个 Raft 组有一个 Leader,处理所有客户端请求
  • Follower:接收 Leader 的日志复制,参与 Leader 选举
  • Candidate:在 Leader 选举过程中,竞选 Leader 的节点
  • Term:选举周期,每个 Term 最多有一个 Leader
  • Log:Raft 日志,记录所有修改操作
  • Commit:日志被多数节点复制后,标记为已提交

2. Raft 核心流程

  • Leader 选举:当 Follower 超过选举超时时间未收到 Leader 的心跳,会转变为 Candidate 发起选举
  • 日志复制:Leader 接收客户端请求,将操作记录为日志条目,复制到所有 Follower
  • 日志提交:当日志被多数节点复制后,Leader 提交日志并应用到状态机
  • 成员变更:支持动态添加或移除节点,保证系统可用性

3. TiKV 对 Raft 的优化

  • 并行 Raft 组:每个 Region 对应一个 Raft 组,多个 Raft 组并行运行
  • Pipeline 复制:支持日志的流水线复制,提高复制效率
  • 批量提交:将多个小日志条目批量提交,减少网络往返
  • Pre-vote:在发起选举前进行预投票,减少不必要的选举
  • Learner 角色:支持 Learner 角色,用于节点加入或跨数据中心复制

部署与配置

部署方式

1. 使用 TiUP 部署

部署命令

bash
# 编辑拓扑文件
vi topology.yaml

# 部署集群
tiup cluster deploy <cluster-name> <tidb-version> topology.yaml --user root -p

# 启动集群
tiup cluster start <cluster-name>

拓扑文件示例

yaml
global:
  user: "tidb"
  ssh_port: 22
  deploy_dir: "/tidb-deploy"
  data_dir: "/tidb-data"

server_configs:
  tikv:
    log.level: "info"
    storage.scheduler: "rocksdb"

tikv_servers:
  - host: 10.0.0.3
    port: 20160
    status_port: 20180
  - host: 10.0.0.4
    port: 20160
    status_port: 20180
  - host: 10.0.0.5
    port: 20160
    status_port: 20180

2. 使用 TiDB Operator 部署

YAML 配置示例

yaml
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
  name: basic
spec:
  version: v7.5.0
  tikv:
    replicas: 3
    template:
      spec:
        containers:
        - name: tikv
          resources:
            requests:
              cpu: 4
              memory: 8Gi
            limits:
              cpu: 8
              memory: 16Gi
          storageClassName: local-storage
          volumeMounts:
          - name: tikv-data
            mountPath: /var/lib/tikv
    storage:
      volumeClaimTemplates:
      - metadata:
          name: tikv-data
        spec:
          accessModes:
          - ReadWriteOnce
          resources:
            requests:
              storage: 1Ti
          storageClassName: local-storage

核心配置参数

1. 基本配置

参数默认值说明
server.port20160TiKV Server 监听端口
server.status-port20180状态端口,用于监控和管理
server.advertise-address对外暴露的地址
server.labels{}节点标签,用于调度

2. 存储配置

参数默认值说明
storage.data-dir"./data"数据存储目录
storage.scheduler"rocksdb"存储引擎调度器
storage.engine"rocksdb"存储引擎类型
storage.rocksdb.db-optionsRocksDB 数据库级配置
storage.rocksdb.defaultcf-options默认列族配置
storage.rocksdb.writecf-options写列族配置
storage.rocksdb.lockcf-options锁列族配置
storage.rocksdb.raftcf-optionsRaft 日志列族配置

3. Raft 配置

参数默认值说明
raft.raft-entry-max-size8388608Raft 日志条目的最大大小(字节)
raft.max-inflight-msgs256每个 Raft 组的最大未处理消息数
raft.store-pool-size2Raft 存储线程池大小
raft.apply-pool-size2Raft 应用线程池大小
raft.raft-base-tick-interval"2s"Raft 基本 tick 间隔
raft.raft-election-timeout"10s"Raft 选举超时时间

4. 事务配置

参数默认值说明
storage.txn.local-latches20480本地锁数量
storage.txn.pessimistic-txntrue是否启用悲观事务
storage.txn.enable-async-committrue是否启用异步提交
storage.txn.enable-1pctrue是否启用一阶段提交优化

配置文件管理

  • 配置文件路径:默认位于 $DEPLOY_DIR/conf/tikv.toml
  • 动态配置:部分配置支持运行时修改,无需重启服务
  • 配置重载:使用 tiup cluster reload [cluster-name] -R tikv 命令重载配置
  • 在线修改:通过 PD 或 TiDB Operator 在线修改配置

监控与运维

监控指标

TiKV Server 提供了丰富的监控指标,可通过 Prometheus 收集和 Grafana 可视化:

1. Raft 指标

  • tikv_raft_logs_total:Raft 日志总数
  • tikv_raft_logs_committed_total:已提交的 Raft 日志数
  • tikv_raft_leader_count:当前 Leader 数量
  • tikv_raft_leader_transfer_total:Leader 转移次数
  • tikv_raft_propose_failed_total:Raft 提议失败次数

2. 存储指标

  • tikv_storage_size_bytes:存储总大小
  • tikv_storage_available_bytes:可用存储大小
  • tikv_rocksdb_bytes_written_total:RocksDB 写入字节数
  • tikv_rocksdb_bytes_read_total:RocksDB 读取字节数
  • tikv_rocksdb_sst_read_bytes_total:SST 文件读取字节数

3. 事务指标

  • tikv_txn_commit_total:提交的事务总数
  • tikv_txn_rollback_total:回滚的事务总数
  • tikv_txn_lock_keys_total:锁定的键总数
  • tikv_txn_conflict_total:事务冲突总数
  • tikv_txn_pessimistic_lock_total:悲观锁总数

4. 网络指标

  • tikv_network_bytes_sent_total:发送的字节数
  • tikv_network_bytes_received_total:接收的字节数
  • tikv_network_connections_total:当前连接数
  • tikv_network_incoming_connections_total:传入连接总数

日志分析

1. 日志格式

文本格式

[2024/01/20 10:00:00.123 +08:00] [INFO] [server.rs:1234] ["server is running"] [addr="0.0.0.0:20160"] [status_addr="0.0.0.0:20180"] [version="v7.5.0"]

JSON 格式

json
{
  "level": "info",
  "ts": "2024-01-20T10:00:00.123+08:00",
  "caller": "server.rs:1234",
  "msg": "server is running",
  "addr": "0.0.0.0:20160",
  "status_addr": "0.0.0.0:20180",
  "version": "v7.5.0"
}

2. 关键日志分析

  • Raft 日志:记录 Raft 组的状态变化、Leader 选举、日志复制等
  • Region 日志:记录 Region 的拆分、合并、迁移等操作
  • 事务日志:记录事务的提交、回滚、冲突等
  • 错误日志:记录系统错误和异常情况

常见运维操作

1. 查看 TiKV Server 状态

bash
# 使用 tiup 查看状态
tiup cluster display <cluster-name> | grep tikv

# 查看进程状态
ps -ef | grep tikv-server

# 查看端口监听
netstat -tlnp | grep 20160

2. 重启 TiKV Server

bash
# 重启单个 TiKV Server 节点
tiup cluster restart <cluster-name> -R tikv[0]

# 重启所有 TiKV Server 节点
tiup cluster restart <cluster-name> -R tikv

3. 升级 TiKV Server

bash
# 升级集群所有组件
tiup cluster upgrade <cluster-name> <new-version>

# 仅升级 TiKV Server 组件
tiup cluster upgrade <cluster-name> <new-version> -R tikv

4. 扩容 TiKV Server

bash
# 编辑拓扑文件,添加新节点
vi topology.yaml

# 扩容集群
tiup cluster scale-out <cluster-name> topology.yaml

5. 缩容 TiKV Server

bash
# 编辑缩容配置文件
vi scale-in.yaml

# 缩容集群
tiup cluster scale-in <cluster-name> -N <tikv-node-ip>:20160

性能优化

存储优化

1. RocksDB 优化

  • 调整内存配置

    toml
    storage.rocksdb.defaultcf-options = [
      "write_buffer_size = 134217728",
      "max_write_buffer_number = 4",
      "max_background_jobs = 8"
    ]
  • 选择合适的压缩算法

    toml
    storage.rocksdb.defaultcf-options = [
      "compression_per_level = [no, no, lz4, lz4, zstd, zstd, zstd]"
    ]
  • 优化写入性能

    toml
    storage.rocksdb.defaultcf-options = [
      "level0_file_num_compaction_trigger = 10",
      "level0_slowdown_writes_trigger = 20",
      "level0_stop_writes_trigger = 30"
    ]

2. Region 优化

  • 调整 Region 大小

    toml
    raftstore.region-max-size = "96MB"
    raftstore.region-split-check-diff = "16MB"
  • 优化 Region 分裂策略

    toml
    raftstore.split-region-check-enabled = true
    raftstore.split-scan-limit = 10000

Raft 优化

  • 调整 Raft 线程池大小

    toml
    raft.store-pool-size = 4
    raft.apply-pool-size = 4
  • 优化 Raft 日志复制

    toml
    raft.max-inflight-msgs = 1024
    raft.raft-entry-max-size = 67108864

事务优化

  • 选择合适的事务模式

    toml
    # 高冲突场景使用悲观事务
    storage.txn.pessimistic-txn = true
    
    # 低冲突场景使用乐观事务
    storage.txn.pessimistic-txn = false
  • 启用异步提交

    toml
    storage.txn.enable-async-commit = true
    storage.txn.enable-1pc = true

高可用性与容灾

高可用性设计

  • 多副本存储:默认 3 副本,可配置为 5 副本
  • Raft 共识算法:保证数据的强一致性和高可用性
  • 自动故障转移:节点故障时自动选举新 Leader,RTO < 30 秒
  • 跨 AZ 部署:将副本分布在不同可用区,提高容灾能力

容灾部署

  • 跨 Region 部署:将副本分布在不同地域,实现异地容灾
  • 备份恢复:定期备份数据,确保数据可恢复
  • TiCDC 同步:实时同步数据到其他集群,实现灾备

故障恢复

  • 节点故障:自动检测并处理节点故障,Raft 组重新选举 Leader
  • 网络分区:处理网络分区情况,保证数据一致性
  • 数据损坏:通过副本恢复损坏的数据
  • 集群恢复:支持从备份恢复整个集群

常见问题与排查

1. Raft 组 Leader 频繁切换

现象:Raft 组的 Leader 频繁切换,影响性能

排查步骤

  • 检查网络延迟:确认节点间网络延迟是否正常
  • 检查系统负载:确认节点 CPU、内存、磁盘 I/O 是否过高
  • 检查 Raft 配置:确认 Raft 选举超时时间是否合适
  • 检查日志:查看 TiKV 日志中关于 Raft 选举的记录

解决方案

  • 优化网络环境,降低节点间延迟
  • 增加节点资源,降低系统负载
  • 调整 Raft 选举超时时间:
    toml
    raft.raft-election-timeout = "15s"
  • 检查并修复硬件故障

2. 存储性能下降

现象:TiKV 存储性能下降,写入或读取延迟增加

排查步骤

  • 检查磁盘 I/O:确认磁盘 I/O 是否饱和
  • 检查 RocksDB 状态:使用 tikv-ctl 查看 RocksDB 状态
  • 检查 Region 分布:确认是否存在热点 Region
  • 检查系统资源:确认 CPU、内存使用情况

解决方案

  • 使用更高速的存储设备(如 NVMe SSD)
  • 优化 RocksDB 配置,调整缓存大小和压缩算法
  • 处理热点 Region,如调整数据分布、优化应用设计
  • 增加 TiKV 节点,分散负载

3. Region 数量过多

现象:集群中 Region 数量过多,影响元数据管理

排查步骤

  • 查看 Region 数量:使用 pd-ctl 查看集群 Region 数量
  • 检查 Region 大小:确认是否有大量小 Region
  • 检查分裂策略:确认 Region 分裂配置是否合适

解决方案

  • 调整 Region 大小阈值,减少 Region 数量:
    toml
    raftstore.region-max-size = "128MB"
  • 启用 Region 合并,合并小 Region:
    toml
    raftstore.enable-cross-table-merge = true
  • 优化表结构设计,减少热点数据

4. 事务冲突频繁

现象:事务冲突频繁,重试次数增加

排查步骤

  • 检查事务模式:确认当前使用的是乐观事务还是悲观事务
  • 分析业务逻辑:确认是否存在高冲突的业务场景
  • 检查事务大小:确认是否有过大的事务

解决方案

  • 切换到悲观事务模式:
    toml
    storage.txn.pessimistic-txn = true
  • 优化业务逻辑,减少事务冲突
  • 缩小事务范围,减少锁定资源
  • 增加事务重试次数:
    toml
    storage.txn.retry-limit = 20

5. 节点无法加入集群

现象:新节点无法加入集群,或现有节点无法正常启动

排查步骤

  • 检查网络连接:确认节点间网络是否正常
  • 检查节点配置:确认节点配置是否正确
  • 检查数据目录:确认数据目录权限和空间是否正常
  • 检查日志:查看 TiKV 日志中的错误信息

解决方案

  • 修复网络连接问题
  • 调整节点配置,确保与集群一致
  • 检查并修复数据目录权限问题
  • 根据日志错误信息进行针对性修复

最佳实践

1. 部署建议

  • 生产环境:建议部署至少 3 个 TiKV Server 节点,实现高可用性
  • 资源配置:每个 TiKV Server 节点建议配置 8C 16GB 内存起,配备高速 SSD
  • 存储选择:使用 NVMe SSD 获得最佳性能,使用普通 SSD 获得平衡的性能和成本
  • 网络配置:确保节点间网络延迟低,带宽充足
  • 跨 AZ 部署:将副本分布在不同可用区,提高容灾能力

2. 配置建议

  • Region 大小:根据业务场景调整,一般建议 64MB-128MB
  • Raft 副本数:生产环境建议 3 副本,对容灾要求高的场景建议 5 副本
  • 压缩算法:根据数据特点选择,建议默认使用 LZ4 或 ZSTD
  • 事务模式:根据业务冲突情况选择乐观事务或悲观事务
  • 日志级别:生产环境建议设置为 "info",避免过多日志影响性能

3. 监控建议

  • 核心指标:监控 Raft 状态、存储使用、事务性能、系统资源等
  • 告警配置:设置合理的告警阈值,及时发现问题
  • 日志管理:定期清理日志,避免磁盘空间不足
  • 定期巡检:定期检查集群状态,发现并解决潜在问题

4. 维护建议

  • 定期备份:使用 BR 工具定期备份数据
  • 定期升级:及时升级到最新版本,获取性能优化和 bug 修复
  • 定期检查:使用 tikv-ctlpd-ctl 定期检查集群状态
  • 文档记录:记录集群配置和维护操作,便于后续管理

常见问题(FAQ)

Q1: TiKV Server 与 RocksDB 是什么关系?

A1: TiKV Server 使用 RocksDB 作为本地存储引擎,将分布式键值对存储在本地 RocksDB 中。TiKV 对 RocksDB 进行了封装和优化,提供了分布式存储服务。

Q2: TiKV Server 如何实现强一致性?

A2: TiKV Server 基于 Raft 共识算法实现强一致性。每个 Region 的副本组成一个 Raft 组,只有当多数副本确认收到并提交日志后,才会将修改应用到状态机,从而保证数据的线性一致性。

Q3: TiKV Server 支持哪些压缩算法?

A3: TiKV Server 支持多种压缩算法,包括:

  • No:不压缩
  • Snappy:高压缩速度,中等压缩率
  • LZ4:更高的压缩速度,适合高写入场景
  • Zlib:高压缩率,较低的压缩速度
  • ZSTD:平衡的压缩速度和压缩率,适合大多数场景

Q4: 如何查看 TiKV Server 的版本?

A4: 可以通过以下方式查看 TiKV Server 版本:

  • 使用 tiup
    bash
    tiup cluster display <cluster-name> | grep Version
  • 查看日志:TiKV 启动日志中包含版本信息
  • 使用 tikv-ctl
    bash
    tikv-ctl version

Q5: TiKV Server 如何处理热点数据?

A5: TiKV Server 处理热点数据的机制包括:

  • 自动热点调度:PD 自动识别热点 Region,并将其分散到不同节点
  • 热点数据打散:支持将热点数据打散存储
  • 分区表:应用层可以使用分区表,将数据分散到不同分区
  • 主键设计:建议使用分布式主键,如 UUID 或雪花算法,避免热点

Q6: TiKV Server 支持多大的存储容量?

A6: TiKV Server 支持 PB 级存储容量:

  • 单个 TiKV 节点的存储容量取决于磁盘大小
  • 集群总容量 = 节点数 × 单节点存储容量 × (副本数 - 1) / 副本数
  • 已在生产环境中验证支持数 PB 级存储

Q7: 如何扩展 TiKV Server 集群?

A7: 扩展 TiKV Server 集群的步骤:

  1. 准备新的服务器节点,安装必要的依赖
  2. 编辑拓扑文件,添加新的 TiKV Server 节点配置
  3. 使用 TiUP 或 TiDB Operator 扩容集群
  4. PD 自动调度 Region 到新节点,平衡负载
  5. 监控新节点的性能和状态

Q8: TiKV Server 与其他分布式存储系统有什么区别?

A8: TiKV Server 与其他分布式存储系统的主要区别:

  • Raft 一致性:基于 Raft 协议实现强一致性
  • MySQL 兼容:与 TiDB Server 配合,提供 MySQL 兼容的分布式数据库
  • 分布式事务:完整支持 ACID 分布式事务
  • 云原生设计:原生支持 Kubernetes 部署和管理
  • HTAP 支持:与 TiFlash 配合,支持 HTAP 混合负载

Q9: TiKV Server 如何实现分布式事务?

A9: TiKV Server 基于 Percolator 模型实现分布式事务:

  • 支持乐观锁和悲观锁两种事务模式
  • 使用二阶段提交(2PC)实现分布式事务提交
  • 支持多版本并发控制(MVCC)
  • 支持异步提交和一阶段提交优化,提高性能

Q10: TiKV Server 的性能如何?

A10: TiKV Server 的性能表现优异:

  • 单节点写入性能可达 10 万 TPS
  • 随着节点增加,性能线性扩展
  • 点查延迟低,适合高频点查询场景
  • 支持高并发读写,适合各种业务场景
  • 通过优化配置,可以进一步提升性能