TIDB——TIKV——RocksDB

一、TIKV的作用

  1. 数据持久化 :TiKV 借助 RocksDB 实现单机高效持久化
  2. 分布式事务 :依托Raft 强一致性与 TiKV 机制,支撑跨节点的分布式事务 ACID 特性
  3. 计算下推优化:通过 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 阻塞,顺序写入)

  1. 数据先写入 WAL(预写日志) :参数 sync_log=TRUE 时,WAL 直接将数据写入磁盘而不经过内存 作用:防止故障丢失数据,后续可重读日志恢复

  2. 再写入内存 MemTable内:场景:当用户读与取时都是在这,因为MemTable 中的数据是最新版本

  3. MemTable 转 Immutable MemTable :当数据追加至MemTable 参数 write_buffer_size 设置值时,MemTable 转为不可修改 的 Immutable MemTable;同时空的 MemTable 接收新写入

    • 注意:Immutable MemTable 数量有多个,默认1个时,就可以刷入磁盘sst文件 中,达到阈值(默认 2 个,非 5 个)触发 write stall,限制 MemTable 刷入磁盘的速度,避免写与读的差速太大以及内存溢出
    • 要是memtable直接刷入磁盘会导致io(读写)阻塞,本质是同步刷盘的问题
  4. 异步刷盘SST 文件 :后台线程将 Immutable MemTable 刷入磁盘, Level 0 层内的sst文件复刻 Immutable MemTable内的数据

    • 优势:仅需一次磁盘 IO + 一次内存 IO,相比 B+ 树多次随机 IO,大大提高效率
    • 异步刷盘是 "前台写入不等待,后台线程单独处理刷盘",具体流程:前台写入无感知 :Immutable MemTable 生成后, MemTable 接收新写入,写入请求正常返回,完全不等待刷盘 后台线程异步处理 :RocksDB 启动独立的后台刷盘线程,在 "不占用前台资源" 的情况下,慢慢把 Immutable MemTable 刷入 Level 0 的 SST 文件;可靠性有兜底:WAL
  5. 分层 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+树,效率较低)

  1. 读取优先级:Block Cache(存储经常读取的热点数据块) → MemTable(最新的数据) → Immutable MemTable → Level 0 SST → Level 1 SST → ... → Level n SST
  2. 加速机制 :每个 SST 文件内置布隆过滤器(bloomfilter)
    • 作用:快速判断 key 是否存在 ------ 返回不存在则一定不存在,返回存在则可能存在(假阳性),避免无效磁盘 IO
  3. 终止条件 :直至读到第一个匹配的 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)------ 数据分片技术

  1. 核心逻辑:一个 RocksDB 实例可以包含多个 CF,每个 CF 独立拥有一套 MemTable、Block Cache、SST 分层,但是WAL只有一套!!!!
  2. 作用:实现数据逻辑分片,避免不同类型数据的资源竞争 eg:要是我的key都一样,但value性质不一样,只有一个CF全乱了,对吧,就比如学号,姓名与学号,班级,这样查找费劲吼
  3. 使用方式:写操作格式为 write(CF , key,value),不指定列簇时默认使用 default 列簇

四、分布式协同补充(Raft+Region)

  1. 强一致性实现:Region 及其副本构成 Raft 集群,仅 Leader 节点处理读写请求,日志需同步至多数副本才返回成功
  2. 容灾与扩展:支持 Leader 自动选举,节点故障时快速切换;Region 支持自动分裂与合并,支撑 TiKV 集群横向扩容
相关推荐
xuefeiniao17 小时前
使用宝塔安装RabbitMQ,启动不起来
分布式·rabbitmq·ruby
heRs BART17 小时前
【Flask】四、flask连接并操作数据库
数据库·python·flask
Lucifer三思而后行17 小时前
一次 Oracle RAC 归档告警排查
数据库·oracle
zhuiyisuifeng17 小时前
PostgreSQL常用时间函数与时间计算提取示例说明
数据库·postgresql
wellc17 小时前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
Irissgwe18 小时前
redis之常见数据类型
数据库·redis·缓存
2301_7735536218 小时前
CSS如何对用户访问过的链接进行降级颜色处理_使用-visited伪类改变颜色
jvm·数据库·python
2301_8152795218 小时前
Golang怎么理解Go的sync.Pool底层_Golang如何理解Pool的本地缓存和GC清理机制【详解】
jvm·数据库·python
2301_7641505618 小时前
MySQL迁移过程如何避免数据不一致_利用强一致性备份方案
jvm·数据库·python
m0_7164300718 小时前
Redis如何处理预热失效引起的开局雪崩
jvm·数据库·python