(数据库必知必会:TiDB(3)TiKV持久化)
TiKV架构和作用
TiDB Server是作为SQL层,对外暴露MySQL的协议,接收用户链接,接收用户SQL、解析SQL、优化SQL、生成执行计划。
TiKV是作为数据持久化层,主要用来存储K-V数据。TiKV支持分布式事务、MVCC等,TiKV中数据按Region进行数据存储。TiKV采用Raft共识算法实现数据的强一致性。
RocksDB
RocksDB针对Flash存储进行优化,延迟极小,使用LSM存储引擎。
- 高性能的K-V型数据库
- 完善的持久化机制,同时保证性能和安全
- 良好的支持范围查询
- 为需要存储TB级别数据到本地的应用服务器设计
- 针对存储在高速设备中的小键值进行优化
- 性能随CPU数量线性提升
写入
RocksDB采用LSM Tree的数据结构来存储K-V数据,LSM Tree首先将各种操作保存在内存中,达到一定的量之后再写入磁盘,写入过程中会与原来的数据做合并。写的时候是直接写新数据,不会更新原来的旧数据。LSM Tree横跨了内存和磁盘。
WAL预写日志:
先写磁盘,将所有操作先写一份到磁盘,磁盘写完再写内存,这样即使断电内存数据丢失,也可以从磁盘恢复。
Linux写数据到磁盘,一般是先写到系统缓存,再从缓存写入磁盘。这样也有问题,就是当数据还在操作系统的缓存、还没真正写入磁盘的时候宕机了,此时缓存的数据也会丢失。
sync_log如果设置为true,则会直接调用操作系统的fsync,直接将数据压入磁盘,而不是操作系统的缓存中
操作会先写到MemTable,当达到一定的量,大小为write_buffer_size的时候,MemTable的数据会转为immutable MemTable,此时MemTable就可以清空,以便继续接收用户的操作请求。immutable MemTable会往磁盘写数据,因为写磁盘会有延迟,这种设计可保证数据写入的同时接收用户的请求。当flush pipeline中有一个immutable MemTable的时候就可以写磁盘,当写磁盘太慢、用户请求太快,flush pipeline中包含的immutable MemTable的数量达到一定的数量,write_stall(5个)的时候,TiKV会进行限速,限制接收用户请求的速度。当immutable MemTable的内容写入到磁盘后,WAL中的数据就可以被覆盖了。
TiKV中数据在磁盘中是分层存储的。
Level 0中的数据就是immutable MemTable的一个复制版本,跟immutable MemTable数据一致。
Level 0中的数据达到4个最小单位,就会压缩成一个,叫做compaction,做好压缩并排序,放入下一层。
Level 1中的数据达到256MB的时候,就会做compaction,做好压缩并排序,放入下一层。
Level 2中的数据达到2.5GB的时候,就会做compaction。
Level 3中的数据达到25GB的时候,就会做compaction。
Level 4中的数据达到250GB的时候,就会做compaction。
因为存储的时候,compaction的时候是做了数据排序的,因此在查找数据的时候,按照二分查找法查找数据即可。
查询
Block Cache缓存,用于存放:最近最常读的数据,高频数据如果在Block Cache中则可直接快速返回,如果Block Cache没有命中,则往后找,数据越久越往后。
数据变更操作,都是按照新增最新状态记录的方式记录,所以按照时间先后顺序,最新时间的数数据就是数据的最新状态,旧数据只是历史版本。
在查找的时候,引入了一个布隆过滤器。当布隆过滤器判定数据块中不存在这个key值,则要查找的数据就一定不在这个数据块中。
列簇
不同的列簇可以用来存储不同的数据,在数据的存储、管理、读写上都可以将数据进行分开。
列簇可以方便对数据进行分片,存储数据时指定列簇,数据可以在内存、磁盘中分开存放。默认列簇是default。