TiKV 架构和作用
- TiKV通过rocksdb进行持久化,其中有两个rocks实例,一个rocksdb kv用来以region为单位存储数据,一个rocksdb raft 用来存储指令。
- raft共识算法为多个TiKV存储节点生成副本。
- Coprocessor算子下推。
Rocks DB
RocksDB针对Flash存储进行优化,延迟极小,使用LSM存储引擎。
- 高性能的Key-Value数据库
- 完善的持久化机制,同时保证性能和安全性
- 良好的支持范围查询
- 为需要存储TB级别数据到本地FLASH护欧哲RAM的应用服务器设计
- 针对存储在高速设备的中小键值进行优化-可以存储在FLASH或者直接存储在内存
- 性能随CPU数量线性提升,对多核系统友好
写入
- 采用LSM树的形式插入数据,首先将数据存储在MemTable,达到一定量之后再写入磁盘。
- LSM树横跨内存和磁盘,MemTable,immutable MemTable和SST
- 写数据之前预写入日志文件,WAL(write ahead logging),之后再将数据写到内存中。sync_log=true,让写入直接写入磁盘,跳过操作系统缓存。
- MemTable中数据大小达到write_buffer_size的时候,旧将数据转存immutable MemTbale,另外再开辟新MemTable。
- immutable MemTable是MemTable写入磁盘的中间站,MemTable写入磁盘的时候会阻塞读写,所以使用immutable MemTable作为中间站。
- 如果写入速度特别块,刷磁盘速度跟不上,immutable MemTable数量达到五个,则触发流控(write stall)。客户端写入速度变慢。流控会写入日志。
- Level0是immutable MemTable的复刻,内容与其完全一样。
- Level 0中文件达到四个之后,就写入下一层。Level1开始,key都是排好序的。查找的时候使用二分查找即可。
- 删除操作,是写入一条删除操作的数据。更新也是这样。
- 每次写入的时候不用考虑数据在哪,直接写入MemTable即可。
查询
- Block Cache:最近最常读的数据缓存。
- Block Cache没有命中就去MemTable中查询,如果没有继续向后。
- 布隆过滤器:每个文件都有一个布隆过滤器,判断元素是否在集合中。过滤器说不在一定不在,说在不一定在。
列簇(Column Families CF)
- 将不同类型 数据分开。
- 写入log的时候:write(cf1,数据)
- 如果没有指定写入哪个列簇,就写入默认列簇Default
- 日志文件(WAL)是列簇共享的。
分布式事务
- begin:从PD组件获得开始时间TSO start timestamp。事务commit之后进入两阶段提交
- prewrite:将修改的数据和锁信息写到TiKV节点。
- TiKV节点使用三个列簇来存,Lock存储锁信息。只给事务第一行加一把主锁(pk),其他的锁(@主锁id)都指向这个锁。
- commit:到PD组件获得结束时间commit timestamp。在write列簇中写入提交信息,<事务id_结束时间,开始时间>。在Lock列簇中,写入删除锁的信息。
- 读取的时候,先到write列簇中查找,获得事务开始时间之后,到default列簇中查看数据。如果write列簇中没有数据,而lock列簇中有锁,则该数据正在修改。
【注意】
- write列簇:当用户写入一行数据时,如果该行数据长度小于255字节,那么会被存储到write列中,否则的化该行数据会被存入到default列中。
- Default列簇:用于存储超过255字节的长度的数据。
MVCC
- 修改数据的时候不修改原数据,而是生成副本,给每个版本一个时间戳。
- 写不阻塞读,阻塞写
Raft与Multi Raft
- leader:所有读写都在leader节点进行,写操作日志,周期性向follower发送心跳。
- follower:长时间收不到leader的心跳信息,身份就变成candidate,发起投票重新选举leader。
- region是键值对的集合,其中key顺序排序。达到96M之后,会另起一个region。region长到144M时候,会自动分裂。过小的时候会进行合并。
Raft日志复制
- Propose:leader写入一条raft日志
- Append:将日志持久化到raftdb raft中
- Replicate:将日志复制到其他节点中,其他节点接收到日志之后,将日志append持久化,之后给leader一个响应。
- Committed:超过一半节点发回响应之后,进入commited。这个只是raft日志的commited
- Apply:把数据写到rockdb kv中
数据的写入
- raftstore pool:收到写请求后,将请求转为日志
- apply pool:将数据持久化到rocksdb kv。在apply完之后,用户的commit才算成功。