设计数据密集型应用—分区( 6)


在这里插入图片描述

1. 写在最前面

之前读这一章节的时候没有认真思考过序言这句话,这次写章节笔记的时候,突然有被震惊到。是不是有写了很多年代码的人,都没人认真思考过最初学的的「面向对象」和「面向过程」底层的区别。(ps 又是学到就是赚到的一天

注 :我们必须跳出电脑指令序列的窠臼。叙述定义、描述元数据、梳理关系,而不是编写过程

​ —— 葛丽丝·穆雷·霍普

世界上最早一批的程序员,也是最早的女性程序员之一。她创造了现在第一个编译器 A-0 系统,以及商用电脑编程语言 「COBOL」

问:从目的开始思考🤔?

答:分区的主要是为了可伸缩性。不同的分区可以放在不共享集群中的不同节点上。因此,大数据集可以分布在多个磁盘上,并且查询负载可以分布在多个处理器上。

2. 分区与复制

分区通常与复制结合使用,这意味着,即使每条记录属于一个分区,它仍然可以存储在多个不同的节点以获得容错能力。

组合使用复制与分区的例子:每个节点充当某些分区的领导者,其他分区充当追随者。

在这里插入图片描述

3. 键值数据的分区

假设你有大量的数据并需要分区,如何决定在哪些节点存储哪些记录呢?

  • 随机分配,好处是均衡不会有偏斜的问题产生,坏处是查询指定记录的时候必须要遍历所有的分区 ❎
  • 根据键值的范围分区 ✅

注:分区不公平,一些分区比其他分区有更多的数据或查询,我们称之为偏斜(skew)。不均衡的高负载的分区被称之为热点(hot spot)

3.1 根据键的范围分区

一种分区的方法是为每个分区指定一块连续的键范围(最大值和最小值),如纸百科全书的卷。如果知道范围之间的边界,则可以轻松确定哪个分区包含某个值。比如:百科全书按照关键字进行分区

在这里插入图片描述

注:键的范围不一定均匀分布,因此数据也很可能不均匀分布。比如,第一卷包含的单词少,而第二卷包含的单词多。因为只是简单的规定每个卷包含两个字母会导致一些卷比其他卷大。为了均匀分配数据,分区的边界需要依据数据调整。

分区边界可以由管理员手动选择,也可以由数据库自动选择。

3.1.1 根据键的散列分区

由于偏斜和热点的风险,许多分布式数据存储使用散列函数来确定给定键的分区。

一个好的散列函数可以将偏斜的数据均匀分布,选择了合适的键散列函数,就可以为每个分区分配一个散列范围(不是键的范围),如下图所示:

在这里插入图片描述

注:使用 Key 散列进行分区,是去了键范围分区的一个很好的属性:高效执行范围查询的能力。曾经相邻的密钥现在分散在所有分区中,所以它们之间的顺序也就丢失了。

3.1.2 负载倾斜和消除热点

「现在的数据系统无法自动监测和补偿倾斜的工作负载,需要自动自动调整」

一个简单的方法是在主键的开始或结尾添加一个随机数。只要一个两位的十进制随机数就可以将主键分散为 100 种不同的主键,从而存储在不同的分区中。

注:将主键进行分割之后,任何读取都必须要做额外的工作,因此在读取的时候也必须从 100 个主键分布中读取数据并将其合并。

4. 分区与次级索引

次级索引是关系数据库的基础,并且在文档数据库中也很普遍。许多键值存储(如HBase 和 Volde-mort)为了减少实现复杂度而放弃了次级索引,但是一些(如Riak)已经开始添加它们,因为它们对数据模型实在是太有用了。

次级索引的问题是不能整齐地映射到分区。有两种用二级索引对数据库进行分区的方法:基于文档的分区和基于关键词的分区。

4.1 基于文档的二级索引进行分区

每个列表都有一个唯一的 ID——称之为文档 ID——并且用文档 ID 对数据库进行分区。基于文档的二级索引进行分区:

  • 在这种索引方法中,每个分区是完全独立的
  • 每个分区维护自己的二级索引,仅覆盖该分区中的文档。它不关心存储在其他分区的数据
  • 写入数据库(添加、删除或更新文档),只需要处理包含正在编写的文档 ID 的分区即可
  • 查询则需要发送到所有分区,并合并所有返回的结果

在这里插入图片描述

4.2 基于关键词(Term)的二级索引进行分区

可以构建一个覆盖所有分区数据的全局索引,而不是给每个分区创建自己的次级索引(本地索引)。

注:不能只把这个索引存储在一个节点上,因为它可能会成为瓶颈,违背了分区的目的。全局索引也必须进行分区,但是可以采用与主键不同的分区方式。

在这里插入图片描述

优点:它的读取效率更高,不需要分散/收集所有分区,客户端只包含关键词分区发出请求

缺点:写入操作比较慢,因为写入单个文档可能会影响索引的多个分区

5. 分区再平衡

随着时间的推移,数据库会有各种变化

  • 查询吞吐量增加,所以需要增加更多 CPU 来处理负载
  • 数据集大小增加,所以需要增加更多的磁盘和 RAM 来存储它
  • 机器出现故障,其他机器需要接管故障机器的责任

所有这些更改都需要数据和请求从一个节点移动到另一个节点。将负载从集群中的一个节点向另一个节点移动的过程称之为再平衡。

无论使用哪种分区方案,再平衡通常都满足一些最低要求:

  • 再平衡之后,负载应该在集群中的节点之间公平的共享
  • 再平衡发生时,数据库应该继续接受读取和写入
  • 节点之间只移动必须的数据,以便快速再平衡,并减少网络和磁盘 I/O 负载
5.1 平衡策略

**hash mod N ** : 优点是简单方便实现;缺点是该方法使得重新平衡过于昂贵

固定数量的分区

  • 创建比节点更多分区,并为每个节点分配多个分区。例子,运行在 10 个节点的集群上的数据库可能会从一开始就被拆分为 1000 个分区,因此大约有 100 个分区被分配给每个节点。
  • 如果一个节点被添加到集群中,新节点可以从当前每个节点窃取一些分区,直到分区再次公平分配。

动态分区

  • 对于使用键范围分区的数据库,具有固定边界的固定数量的分区将非常不便,「如果出现边界错误,则可能会导致一个分区中的所有数据或者其他分区中国的所有数据为空。」手动重新配置分区边界将非常繁琐。
  • 按键的范围进行分区的数据库会动态创建分区。当分区增长到超过配置的大小时,会被分成两个分区,每个分区约占一半的数据。与之相反,如果大量数据被删除并且分区缩小到某个阈值以下,则可以将其与相邻分区合并。

按节点比例分区

  • 使分区数与节点数成正比——每个节点具有固定数量的分区。在这种情况下,每个分区的大小与数据集大小成比例地增长,而节点数量保持不变,但是当增加节点数时,分区将再次变小。
5.2 运维:手动还是自动平衡
  • 全自动重新平衡:系统自动决定何时将分区从一个节点移动到另一个节点
  • 完全手动:分区指派给节点管理员明确配置,仅在管理员明确重新配置时才会更改

「再平衡的过程中有人参与是一件好事。这比完全自动的过程慢,但可以帮助防止运维意外」

6. 请求路由

现在将数据集分割到多个机器上运行的多个节点上。但是仍然存在一个未解决的问题:当客户想要发出请求时,如何知道要连接哪个节点?

当前存在三种成熟的解决方案:

  • 允许客户请求任何节点。如果该节点恰好拥有请求的分区,则它可以直接处理该请求;否则,它将转发请求到适当的节点,接收回复并传递给客户端
  • 首先将所有来自客户端的请求发送到路由层,它决定应该处理请求的节点,并相应地转发。此路由层本身不处理任何请求;它仅负责分区的负载均衡
  • 要求客户端知道分区和节点的分配。在这种情况下,客户端可以直接连接适当的节点,而不需要任何中介

在这里插入图片描述

7.碎碎念

应该是最没有拖延症的一个月了

  • 不可否认,生活磨掉了我们一部分的勇气和温柔。但我也相信,因为我们还很年轻,所以失去的还会长出来,而新的部分一定终将闪闪发亮。

  • 你看这个世界上的女孩子

    有的在为名校的 offer 拼命努力

    有的在为自己的事业发展工作到凌晨

    有的在为自己的爱人孩子做好一日三餐

    还有在为自己的身材容貌努力做运动,流汗水,克制自己只吃健康的食物

    但是无论哪一种,都是美好的女孩

有边写边思考应该是一种很好的进步了吧,别急走的慢一点,但是也走的稳一点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值