分区,又称为分片,是解决大数据存储的常见解决方案,大数据存储量超过了单节点的存储上限,因此需要进行分区操作将数据分散存储在不同节点上,通常每个单个分区可以理解成一个小型的数据库,尽管数据库能同时支持多个分区操作;分区引入多分区概念,可以同时对外服务提高性能。
常常和分区一并提及的概念是复制,分区通常与复制结合使?,使得每个分区的副本存储在多个节点上。 这意味着,即使每条记录属于?个分区,它仍然可以存储在多个不同的节点上以获得容错能?。分区在许多技术或框架中都有体现,例如MQ中topic下的分区消息实现,如kafka中的partion、rocketmq中的queue等;例如SQL/NoSQL中分区数据储存实现,如ElascticSearch中的Shards分片、MySQL中的分表等。
关于分区,本文主要讨论下键值分区的几种方式、分区再平衡策略和请求路由处理机制等,最后以ES(ElascticSearch)的查询请求处理为例,分析分区下查询的请求处理流程。话不多说,Let's Go~
键值分区的几种方式
如果有大量数据需要分散存储,应该如何进行分区呢?分区的目前就是将数据均衡的分散在各节点,这样同时也能分散对数据的处理请求,如果分区不均衡,那么会造成某些分区有大量的数据或查询请求,这就是常说的倾斜。数据倾斜会造成高负载节点形成热点,避免热点可以使用随机路由方式将数据散列到各分区中。对数据进行分区操作,不能仅仅是随机数据存储,因为存储之后肯定还是要进行查询的,所以要按照固定键值来进行散列分区操作,方便后续查询请求的路由。常见的键值分区方式有按照范围分区、按照键的散列分区:
按照范围分区
按照范围分区就是每个分区存储指定一段连续的数据,比如按照时间戳来存储数据,最简单常见的日志按照时间分割为不同的文件;按照编号id来存储数据,如图书馆书籍陈列,编号连续数据存放在同一个书架上。按照范围分区有时候会造成分区数据不均衡,比如按照时间戳,可能某段时间内数据比较少而某些时间段数据较多而造成分区不均衡。
键值散列分区
由于按照范围分区容易造成数据负载不均衡问题,所以一般应用场景下(非顺序类型数据)为了避免偏斜和热点的?险,会使?散列函数来确定给定键的分区。一个好的散列函数会尽量随机分区,许多语言内都内置了散列函数,但是有些可能不太适合分区场景,比如Java的 Object.hashCode()和Ruby的 Object#hash,其同?个键可能在不同的进程中有不同的哈希值。
有了合适的散列函数,有时候想要让一定散列范围内的数据分布在同一分区,此时可使用一致性哈希,一致性哈希可减小因为分区变动造成会已有数据分区映射的影响。
热点问题
哈希分区可帮助减少热点,但是无法避免,极端情况下可能存在所有请求都打到同一分区中。热点分区问题解决思路是:一种是给热点分区再分区操作,比如针对热点数据的key再路由分散多个分区中;还有一种是热点数据增加冗余(也就是复制),增加热点数据的复制节点,一同对外提供服务。
分区再平衡
随着时间的推移,分区数据会有以下变化:
- 查询吞吐量增加,所以您想要添加更多的CPU来处理负载。
- 数据集??增加,所以您想添加更多的磁盘和RAM来存储它。
- 机器出现故障,其他机器需要接管故障机器的责任。
所有这些更改都需要数据和请求从?个节点移动到另?个节点。 将负载从集群中的?个节点向另?个节点移动的过程称为再平衡(reblancing),再平衡过程一般要求如下:再平衡之后数据尽量均衡、在平衡时分区要正常地外提供服务、节点之间只移动必要数据以加快再平衡进度。(一般来说直接使用取余方式散列的分区再平衡时大都需要将所有数据重新取余再分区,成本较大。)
固定数目的分区
为了避免分区的扩容再平衡操作,可以创建?节点更多的分区,并为每个节点分配多个分区。例如,运?在10个节点的集群上的数据库可能会从?开始就被拆分为1000个分区,因此?约有100个分区被分配给每个节点。比如ES就是用了这种再平衡方式,ES中的shards分片在运行时是无法更改的,因此生产环境一般会建议针对分区数设定留一定的余量,方便后续扩容操作。这样的话,分区的数量不会变化,知识分区数据会在节点间移动而已,键所指定的分区也不会改变。唯?改变的是分区所在的节点。这种变更并不是即时的,在?络上传输?量的数据需要?些时间,所以在传输过程中,原有分区仍然会接受读写操作。如下图所示:
本文暂时没有评论,来添加一个吧(●'◡'●)