一、TIKV的作用
- 数据持久化 :TiKV 借助 RocksDB 实现单机高效持久化
- 分布式事务 :依托Raft 强一致性与 TiKV 锁机制,支撑跨节点的分布式事务 ACID 特性
- 计算下推优化:通过 Coprocessor 将部分过滤 / 聚合/计算任务交给 TiKV 节点,降低 TiDB 层 CPU 负载与网络带宽消耗
二、具体流程介绍
数据持久化:使用RocksDB模块实现
(一)纵向(单机维度)------ RocksDB 单机存储
- 定位:开源单机存储引擎,SSD/Flash 存储,负责 TiKV 单 个节点的数据持久化
- 核心:仅处理本地数据的读写、刷盘、分层存储,不涉及任何分布式逻辑
注:RocksDB分为RocksDBraft和RocksDBkv,前者负责存取日志;后者负责存取键值对,以region为单位,分布式存储
(二)横向(分布式维度)------ Raft(共识算法实现)+Region
- 数据分片:全局数据按固定大小划分为 Region,以 Region 为单位分布式存储
- 强一致性保障:每个 Region 及其多副本组成 Raft集群,实现读取,写入同步、Leader 选举、Region 分裂 / 合并等
- 计算优化:Coprocessor 协同处理器,将部分过滤 / 计算任务交给 TiKV,减少 CPU 负载和网络带宽影响
三、流程
RocksDB 存储流程(核心)
(一)写入流程(规避随机 IO 阻塞,顺序写入)
-
数据先写入 WAL(预写日志) :参数
sync_log=TRUE时,WAL 直接将数据写入磁盘而不经过内存 作用:防止故障丢失数据,后续可重读日志恢复 -
再写入内存 MemTable内:场景:当用户读与取时都是在这,因为MemTable 中的数据是最新版本
-
MemTable 转 Immutable MemTable :当数据追加至MemTable 参数
write_buffer_size设置值时,MemTable 转为不可修改 的 Immutable MemTable;同时空的 MemTable 接收新写入- 注意:Immutable MemTable 数量有多个,默认1个时,就可以刷入磁盘sst文件 中,达到阈值(默认 2 个,非 5 个)触发
write stall,限制 MemTable 刷入磁盘的速度,避免写与读的差速太大以及内存溢出 - 要是memtable直接刷入磁盘会导致io(读写)阻塞,本质是同步刷盘的问题
- 注意:Immutable MemTable 数量有多个,默认1个时,就可以刷入磁盘sst文件 中,达到阈值(默认 2 个,非 5 个)触发
-
异步刷盘 至 SST 文件 :后台线程将 Immutable MemTable 刷入磁盘, Level 0 层内的sst文件复刻 Immutable MemTable内的数据
- 优势:仅需一次磁盘 IO + 一次内存 IO,相比 B+ 树多次随机 IO,大大提高效率
- 异步刷盘是 "前台写入不等待,后台线程单独处理刷盘",具体流程:前台写入无感知 :Immutable MemTable 生成后, MemTable 接收新写入,写入请求正常返回,完全不等待刷盘 后台线程异步处理 :RocksDB 启动独立的后台刷盘线程,在 "不占用前台资源" 的情况下,慢慢把 Immutable MemTable 刷入 Level 0 的 SST 文件;可靠性有兜底:WAL
-
分层 Compaction 压缩 :磁盘(SST 文件)按层级存储
- Level 0:Immutable MemTable 刷盘生成,当达到 4 个文件,向level1的一个文件写入(这个过程叫compaction压缩)
- Level 1:当达到256MB后继续向level2的一个文件写入,形成有序sst文件
- Level 2:当达到2.5G后继续向level3的一个文件写入,形成有序sst文件
- Level 3:当达到25G后继续向level4的一个文件写入
- Level 4:存储上限 250G
所有层级的 SST 文件均为键值对有序存储,查找使用二分查找
(二)查询流程(相比较b+树,效率较低)
- 读取优先级:Block Cache(存储经常读取的热点数据块) → MemTable(最新的数据) → Immutable MemTable → Level 0 SST → Level 1 SST → ... → Level n SST
- 加速机制 :每个 SST 文件内置布隆过滤器(bloomfilter)
- 作用:快速判断 key 是否存在 ------ 返回不存在则一定不存在,返回存在则可能存在(假阳性),避免无效磁盘 IO
- 终止条件 :直至读到第一个匹配的 key 就停止查询,因为 LSM-Tree(日志结构合并树) 是写时追加模式(也就是数据有旧的,也有新的),先找到的就是最新数据
随:假设你要更新 key=1 的值,从 100 改成 200:
- B+ 树:先找到磁盘上 key=1 的存储位置,直接覆盖成 200(需要随机 IO 定位,可能阻塞);
- LSM-Tree:直接在 MemTable 中追加一条
(1, 200)的新记录,原(1, 100)还留在旧的 SST 文件里
(三)删除操作逻辑
删除不会直接清理磁盘数据 (不管具体位置 ),而是向 MemTable 写入墓碑标记,后续 Compaction 阶段才会物理清除对应的 SST 数据
(四)关键概念:Column Families(列簇 CF)------ 数据分片技术
- 核心逻辑:一个 RocksDB 实例可以包含多个 CF,每个 CF 独立拥有一套 MemTable、Block Cache、SST 分层,但是WAL只有一套!!!!
- 作用:实现数据逻辑分片,避免不同类型数据的资源竞争 eg:要是我的key都一样,但value性质不一样,只有一个CF全乱了,对吧,就比如学号,姓名与学号,班级,这样查找费劲吼
- 使用方式:写操作格式为 write(CF
, key,value),不指定列簇时默认使用default列簇
四、分布式协同补充(Raft+Region)
- 强一致性实现:Region 及其副本构成 Raft 集群,仅 Leader 节点处理读写请求,日志需同步至多数副本才返回成功
- 容灾与扩展:支持 Leader 自动选举,节点故障时快速切换;Region 支持自动分裂与合并,支撑 TiKV 集群横向扩容