9090
9191> #### 一致性哈希
9292>
93- > 一致性哈希由 Karger 等人定义。【7】 用于跨互联网级别的缓存系统,例如 CDN 中,是一种能均匀分配负载的方法。它使用随机选择的 ** 分区边界(partition boundaries)** 来避免中央控制或分布式共识的需要。 请注意,这里的一致性与复制一致性(请参阅 [ 第五章] ( ch5.md ) )或 ACID 一致性(请参阅 [ 第七章] ( ch7.md ) )无关,而只是描述了一种重新平衡(reblancing )的特定方法。
93+ > 一致性哈希由 Karger 等人定义。【7】 用于跨互联网级别的缓存系统,例如 CDN 中,是一种能均匀分配负载的方法。它使用随机选择的 ** 分区边界(partition boundaries)** 来避免中央控制或分布式共识的需要。 请注意,这里的一致性与复制一致性(请参阅 [ 第五章] ( ch5.md ) )或 ACID 一致性(请参阅 [ 第七章] ( ch7.md ) )无关,而只是描述了一种再平衡(rebalancing )的特定方法。
9494>
9595> 正如我们将在 “[ 分区再平衡] ( #分区再平衡 ) ” 中所看到的,这种特殊的方法对于数据库实际上并不是很好,所以在实际中很少使用(某些数据库的文档仍然会使用一致性哈希的说法,但是它往往是不准确的)。 因为有可能产生混淆,所以最好避免使用一致性哈希这个术语,而只是把它称为 ** 散列分区(hash partitioning)** 。
9696
@@ -193,7 +193,7 @@ Cassandra 采取了折衷的策略【11, 12, 13】。 Cassandra 中的表可以
193193
194194也许你想知道为什么我们不使用 *** 取模(mod)*** (许多编程语言中的 % 运算符)。例如,` hash(key) mod 10 ` 会返回一个介于 0 和 9 之间的数字(如果我们将散列写为十进制数,散列模 10 将是最后一个数字)。如果我们有 10 个节点,编号为 0 到 9,这似乎是将每个键分配给一个节点的简单方法。
195195
196- 模 N($mod N$)方法的问题是,如果节点数量 N 发生变化,大多数键将需要从一个节点移动到另一个节点。例如,假设 $hash(key)=123456$。如果最初有 10 个节点,那么这个键一开始放在节点 6 上(因为 $123456\ mod\ 10 = 6$)。当你增长到 11 个节点时,键需要移动到节点 3($123456\ mod\ 11 = 3$),当你增长到 12 个节点时,需要移动到节点 0($123456\ mod\ 12 = 0$)。这种频繁的举动使得重新平衡过于昂贵 。
196+ 模 N($mod N$)方法的问题是,如果节点数量 N 发生变化,大多数键将需要从一个节点移动到另一个节点。例如,假设 $hash(key)=123456$。如果最初有 10 个节点,那么这个键一开始放在节点 6 上(因为 $123456\ mod\ 10 = 6$)。当你增长到 11 个节点时,键需要移动到节点 3($123456\ mod\ 11 = 3$),当你增长到 12 个节点时,需要移动到节点 0($123456\ mod\ 12 = 0$)。这种频繁的举动使得再平衡的成本过高 。
197197
198198我们需要一种只移动必需数据的方法。
199199
@@ -243,17 +243,17 @@ Cassandra 和 Ketama 使用的第三种方法是使分区数与节点数成正
243243
244244关于再平衡有一个重要问题:自动还是手动进行?
245245
246- 在全自动重新平衡 (系统自动决定何时将分区从一个节点移动到另一个节点,无须人工干预)和完全手动(分区指派给节点由管理员明确配置,仅在管理员明确重新配置时才会更改)之间有一个权衡。例如,Couchbase、Riak 和 Voldemort 会自动生成建议的分区分配,但需要管理员提交才能生效。
246+ 在全自动再平衡 (系统自动决定何时将分区从一个节点移动到另一个节点,无须人工干预)和完全手动(分区指派给节点由管理员明确配置,仅在管理员明确重新配置时才会更改)之间有一个权衡。例如,Couchbase、Riak 和 Voldemort 会自动生成建议的分区分配,但需要管理员提交才能生效。
247247
248- 全自动重新平衡可以很方便 ,因为正常维护的操作工作较少。但是,这可能是不可预测的 。再平衡是一个昂贵的操作,因为它需要重新路由请求并将大量数据从一个节点移动到另一个节点。如果没有做好,这个过程可能会使网络或节点负载过重,降低其他请求的性能。
248+ 全自动再平衡可以很方便 ,因为正常维护的操作工作较少。然而,它可能是不可预测的 。再平衡是一个昂贵的操作,因为它需要重新路由请求并将大量数据从一个节点移动到另一个节点。如果没有做好,这个过程可能会使网络或节点负载过重,降低其他请求的性能。
249249
250250这种自动化与自动故障检测相结合可能十分危险。例如,假设一个节点过载,并且对请求的响应暂时很慢。其他节点得出结论:过载的节点已经死亡,并自动重新平衡集群,使负载离开它。这会对已经超负荷的节点,其他节点和网络造成额外的负载,从而使情况变得更糟,并可能导致级联失败。
251251
252- 出于这个原因,再平衡的过程中有人参与是一件好事。这比完全自动的过程慢 ,但可以帮助防止运维意外。
252+ 出于这个原因,再平衡的过程中有人参与是一件好事。这比全自动的过程慢 ,但可以帮助防止运维意外。
253253
254254## 请求路由
255255
256- 现在我们已经将数据集分割到多个机器上运行的多个节点上。但是仍然存在一个悬而未决的问题:当客户想要发出请求时,如何知道要连接哪个节点?随着分区重新平衡 ,分区对节点的分配也发生变化。为了回答这个问题,需要有人知晓这些变化:如果我想读或写键 “foo”,需要连接哪个 IP 地址和端口号?
256+ 现在我们已经将数据集分割到多个机器上运行的多个节点上。但是仍然存在一个悬而未决的问题:当客户想要发出请求时,如何知道要连接哪个节点?随着分区的重新平衡 ,分区对节点的分配也发生变化。为了回答这个问题,需要有人知晓这些变化:如果我想读或写键 “foo”,需要连接哪个 IP 地址和端口号?
257257
258258这个问题可以概括为 ** 服务发现(service discovery)** ,它不仅限于数据库。任何可通过网络访问的软件都有这个问题,特别是如果它的目标是高可用性(在多台机器上运行冗余配置)。许多公司已经编写了自己的内部服务发现工具,其中许多已经作为开源发布【30】。
259259
@@ -281,7 +281,7 @@ Cassandra 和 Ketama 使用的第三种方法是使分区数与节点数成正
281281
282282Cassandra 和 Riak 采取不同的方法:他们在节点之间使用 ** 流言协议(gossip protocol)** 来传播集群状态的变化。请求可以发送到任意节点,该节点会转发到包含所请求的分区的适当节点([ 图 6-7] ( img/fig6-7.png ) 中的方法 1)。这个模型在数据库节点中增加了更多的复杂性,但是避免了对像 ZooKeeper 这样的外部协调服务的依赖。
283283
284- Couchbase 不会自动重新平衡 ,这简化了设计。通常情况下,它配置了一个名为 moxi 的路由层,它会从集群节点了解路由变化【32】。
284+ Couchbase 不会自动进行再平衡 ,这简化了设计。通常情况下,它配置了一个名为 moxi 的路由层,它会从集群节点了解路由变化【32】。
285285
286286当使用路由层或向随机节点发送请求时,客户端仍然需要找到要连接的 IP 地址。这些地址并不像分区的节点分布变化的那么快,所以使用 DNS 通常就足够了。
287287
@@ -295,15 +295,15 @@ Couchbase 不会自动重新平衡,这简化了设计。通常情况下,它
295295
296296## 本章小结
297297
298- 在本章中,我们探讨了将大数据集划分成更小的子集的不同方法。数据量非常大的时候,在单台机器上存储和处理不再可行,而分区则十分必要。分区的目标是在多台机器上均匀分布数据和查询负载,避免出现热点(负载不成比例的节点)。这需要选择适合于你的数据的分区方案,并在将节点添加到集群或从集群删除时进行分区再平衡 。
298+ 在本章中,我们探讨了将大数据集划分成更小的子集的不同方法。数据量非常大的时候,在单台机器上存储和处理不再可行,而分区则十分必要。分区的目标是在多台机器上均匀分布数据和查询负载,避免出现热点(负载不成比例的节点)。这需要选择适合于你的数据的分区方案,并在将节点添加到集群或从集群删除时重新平衡分区 。
299299
300300我们讨论了两种主要的分区方法:
301301
302302* 键范围分区
303303
304304 其中键是有序的,并且分区拥有从某个最小值到某个最大值的所有键。排序的优势在于可以进行有效的范围查询,但是如果应用程序经常访问相邻的键,则存在热点的风险。
305305
306- 在这种方法中,当分区变得太大时,通常将分区分成两个子分区,动态地再平衡分区 。
306+ 在这种方法中,当分区变得太大时,通常将分区分成两个子分区来动态地重新平衡分区 。
307307
308308* 散列分区
309309
0 commit comments