关于Region的有序存储的一些疑问

在阅读了PingCAP社区中的《三篇文章了解TiDB技术内幕-说存储》中,有一段如下:

  1. 这是一个巨大的 Map,也就是存储的是 Key-Value pair
  2. 这个 Map 中的 Key-Value pair 按照 Key 的二进制顺序有序,也就是我们可以 Seek 到某一个 Key 的位置,然后不断的调用 Next 方法以递增的顺序获取比这个 Key 大的 Key-Value

关于Region的有序存储,我有一些疑问,希望能得到贵单位的指点,谢谢!

1、假设默认Region是64M,此时有一个表,数据量大概为640M,假设分为10个Region,想请问下,对于这一个表所涉及的10个Region,是全局有序的存储,还是只保证单个Region内的数据是有序排列存储的?因为有序,这些Region会不会集中储存于同一个KITV中?

2、当后期往表中增加数据时,例如插入10条新数据,当新插入数据的主键值刚好在之前的某一个Region的范围中,假设那个Region刚好又放不下新的数据时,是不是会将该Region分裂成两个,来保证整个表,所有的Region全局有序存储?还是会另存储在一个新的Region中?

问题 1, TiKV 的数据在 Region 是有序存储的,但是 PD 的最小调度单位是 Region,也就是说 10 个 Region 并不一定会被调度在一个 TiKV 中,这个 PD 会自动根据负载以及其他的一些情况来做出调度。所以你可以认为只是在单个 Region 内有序排列存储

  1. 是的,放不下了会逻辑上把 Region 分裂成两个,这样的话,两个 Region 就又有空间可以写入值了。

TiDB 中数据的Key并不等同于业务表主键。如果业务表主键是自增序列号,则主键列会作为Key的一部分;如果业务表主键不是自增序列号(如UUID),则TiDB会自行生成Key。Region中按Key有序,不是按业务主键有序,所以不存在楼主所说的问题2。

如果对表的某一行进行更新,要是业务key和主键key是同一个含义,是不是就会出现2的情况,追加写的话,是不是按照楼上说的,直接找到原始的region ,但是发现region 满了,就会进行分裂,但是新分裂的region 只有新的这一行数据,方便后续进行mvcc,或者后续GC的时候,这个过于空的region 会和以前的region进行合并??

是的,空的也会发生合并,这个也是 TiDB 具备的功能。

其实这个不完全是,作为主键是 int 的类型,如果是自增的话,还是会存在自增的 Region Key,会带来自增的热点问题。

即使非 int 主键,如果主键是自增的,在 Encoded 为索引 key 这一部分,依然也是顺序的。

当然,上面说的很多情况在目前 TiDB 5.0 的一个新特性 Cluster index 中会发生一些变化(https://github.com/pingcap/tidb/projects/45)

欢迎大家更深入的了解 TiDB 代码,这部分是非常有意思的话题。