数据分区的目的是提高扩展性,目标是数据和负载能够均匀分布到所有节点。
键值分区
键值分区,可以理解为基于主键的分区
基于关键字的区间分区
也就是范围分区。如字面含义,范围查询效率会非常高,但固定key查询效率相对低一些。但相应的会造成一定的热点分区。比如按时间段分区,某项业务依赖于某个时间段分区会造成大量的请求负载,而其他分区则是空闲状态。一般解决的方式,是给时间戳再加一个关键字一起作为分区键,尽量的减轻数据倾斜与热点
基于关键字的哈希分区
这个不难理解 。利用一致性哈希进行分区。这种分区方式对区间查询支持较弱。也会有数据倾斜和热点问题。比如极端情况大量读写都针对同一个关键字,那么所有的请求都会集中到一个分区,也会造成数据倾斜和热点问题。
数据倾斜和热点问题目前并没有一个很好的解决方案。比如常用的随机数方式,某个关键字成了热点后,给关键字加随机数进一步打散。但是在读取的时候就比较麻烦了,需要一定的数据处理。
分区与二级索引
二级索引其实就是非主键索引。按照文章的分类方式,业务不一定用主键进行查询,更多时候会用非主键索引进行查询
基于文档分区
在关系型数据就是表。这块作者想表达的意思应该是维护一个索引表,但索引表的存储方式是特定。也就是每个分区各自维护自己的二级索引。这种方式对于写数据是有利的,不需要进行分布式事务处理,只要写入到本分区就可以。对于读数据,需要进行全区查询,效率稍低一些,但相比较分布式事务,基于文档分区大部分中间件都采用这种方式。
基于词条分区
同样,也是维护一个索引表,但索引表的存储方式,则是将某项关键字所有的索引信息存到一个节点,但全部项的关键字索引又进行了一定的分区,也就是不同分区存储一部分关键字的索引。这种方式和上面相反,写的时候要考虑分布式事务,读取的时候只要能找到某项索引在哪个分区,很快就能查到对应的全部信息,效率更高一些。
分区再平衡
分区再平衡的处理上面需要满足三点:数据和请求负载均匀分布,过程中正常提供服务,不引入更多的负载
固定分区数量
每个节点上的分区数量是固定的,新的数据写入时候一般使用一致性哈希方式。当新加入节点或减少节点,会对分区上的数据进行再平衡,和一致性哈希处理一致。如果采用范围方式写入,处理也是一样的
动态分区数量
每个节点都会预设分区。假定初始预设一个分区,那么一个节点就有一个分区。随着数据的写入。当分区内的数据达到一定阈值,进行分区分裂,对数据进行再平衡。同样的数据如果少到一定程度,进行分区合并。
请求路由
客户端直连
分两种情况
- 客户端随机连接任意节点,如果当前节点更好有相应的数据则返回结果,如果没有,那么会传递给下一个节点进行查找,最终返回结果
- 客户端预知数据与分区的关系,客户端直接命中数据分区,拿到查询结果
客户端连接路由层
路由层预知数据与分区关系,客户端连接路由层,之后发送的请求由路由层进行转发后命中数据分区。