分布式数据库难题(一):数据分区

1. 分区的目的

    面对海量数据或者非常高的查询压力,我们需要将数据拆分成分区,采用分区的目的主要是提高可扩展性,将数据和查询负载均匀分布在所有节点上。如果节点平均分担负载,那么理论上10个节点应该能够处理10倍的数据量和10倍于单个节点的读写吞吐量。而如果分布不均匀,则会出现某些分区节点比其它分区承担更多的数据量或查询负载,称之为写倾斜。

2. 常见的两种分区方法

    有两种常见的分区方法,分别是基于关键字区间的分区,另外一种是基于关键字哈希值分区,下面我们依次介绍。

2.1 基于关键字区间的分区

  • 方法:为每个分区分配一段连续的关键字或者关键字区间范围(以最小值和最大值来指示)。如果知道关键字区间的上下限,就可以轻松确定哪个分区包含哪些关键字。分区边界可以由管理员手动指定或者由数据库自动选择。例如,我们可以选择时间戳作为关键字,这样就可以根据时间戳进行分区。
  • 优点:每个分区内可以按照关键字排序保存,这样可以轻松支持区间查询。
  • 缺点:某些访问模式会导致热点。例如关键字是时间戳时,分区对应一个时间范围。当处理某一天的请求时,会导致某个分区负载过高,而其它分区处于空闲状态。

2.2. 基于关键字哈希值分区

  • 方法:找到一个合适的关键字哈希函数,为每个分区分配一个哈希范围(而不是直接作用于关键字范围),关键字根据其哈希值的范围划分到不同的分区中。
  • 优点:可以很好的将关键字均衡分配到多个分区中,避免了热点问题。
  • 缺点:哈希值分区丧失了良好的区间查询特性,即使关键字相邻,但是经过哈希后会分散在不同的分区中。

3. 分区再平衡

     随着时间的推移,数据库可能出现些变化:

  • 查询压力增加,因此需要更多的CPU来处理负载
  • 数据规模增加,因此需要更多的磁盘和内存来存储数据
  • 节点可能出现故障,因此需要其他机器来接管失效的节点

    而这些情况出现后,我们都需要进行扩容。

3.1 动态再平衡策略

(1)固定数量的分区

    创建远超实际节点数的分区数,然后为每个节点分配多个分区。例如对于一个10个节点的集群,数据库可以从一开始就创建1000个分区,这样每个节点承担100个分区。

    如果集群中添加了一个新节点,该新节点可以从每个现有的节点上匀走几个分区,直到分区再次达到全局平衡。如果集群中某个节点掉线,则该节点的分区会迁移到其余的可用节点上,从而达到新的全局平衡。

    采用固定数量的分区策略时,不支持分区的拆分功能,在初始化时已经充分考虑将扩容增长的需求(未来可能拥有的最大节点数),设置一个足够大的分区数。

(2)动态分区

    采用固定数量的分区又一个缺点是,有可能所有数据都挤在一个分区,而其它分区为空,这种情况下分区的作用就基本没有发挥出来。而动态分区不像固定数量分区那样一开始就创建固定数量的分区,而是当分区的数量增长超过一个可配的参数阈值时,它就拆分为两个分区,一个承担一半的数据量。相反,如果大量数据被删除,并且分区的数据量缩小到某个阈值之下,则将其与相邻的分区进行合并。

    采用动态分区的优点是,分区数量可以适配数据总量。如果只有少量数据,少量的分区就够了,这样系统开销很小。如果有大量数据,每个分区的大小则被限制在一个可配的最大值。

(3)按节点比例分区

    固定数量分区的分区数量固定,而动态分区的分区数量随着数据量的增多而增加,两种情况下,分区都和节点数量无关。而第三种分区方式则是让分区数量和节点数成正比。

    换句话说,每个节点具有固定数量的分区。此时,当节点数不变时,每个分区的大小和数据集大小保持正比的增长关系,当节点数增多,分区则会调整变得更小。

    当一个新节点加入集群时,它随机选择固定数量的现有分区进行分裂,然后拿走这些分区的一半数据量,将另一半数据留在原节点。

3.2 自动与手动再平衡操作

    分区扩展时动态平衡是手动执行还是自动执行呢,需要进行一些权衡:

(1)自动再平衡会更加方便,但是也有可能出现难以预测的情况。再平衡是个比较昂贵的操作,它需要重新路由请求并将大量数据从一个节点迁移到另一个节点。

    将自动平衡和自动故障检测结合也可能存在一些风险,例如,假设某个节点负载过重,对请求的响应暂时受到影响,而其它节点可能会得到结论:该节点已经失效,接下来激活自动平衡来转移其负载。客观上这会加重该节点、其它节点以及网络的负载,可能会使得总体的情况变得更糟糕。

(2)手动介入进行自动再平衡要比自动再平衡更慢一些,但是它可以有效的防止意外发生。

4. 请求路由 

  我们进行分区之后,请求的数据如何转发到对应的分区上呢,常见的路由策略有这么几种:

(1)允许客户端链接任意的节点,如果某节点恰好拥有所请求的分区,则直接处理该请求,否则将该请求转发到下一个合适的节点。

(2)将所有客户端的请求都发送到一个路由层,由后者将请求转发到对应的分区节点上。路由层并不处理任何请求,它仅充当一个分区感知的负载均衡器。

(3)客户端感知分区和节点的分配关系。此时,客户端可以直接连接到目标节点,而不需要任何中介。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值