键值存储系统设计(第二部分)

这是“设计键值存储”系列文章的第二篇。如果您还没有阅读第一篇文章,请检查一下。

在之前的文章中,我们主要关注键值存储的基本概念,尤其是单机方案。当涉及到扩展问题时,我们需要按照一些规则将所有数据分发到多台计算机中,并且协调器计算机可以将客户端定向到具有请求资源的计算机。

设计分布式系统时,您需要考虑很多事情。将数据拆分到多台计算机时,平衡流量非常重要。这就是为什么最好确保密钥是随机分布的。

在本文中,我们将继续关于分布式键值存储系统的讨论。我们将涵盖诸如系统可用性,一致性等主题。

系统可用性

为了评估分布式系统,一个关键指标是系统可用性。例如,假设我们的一台计算机由于某种原因(可能是硬件问题或程序错误)而崩溃,这如何影响我们的键值存储系统?

显然,如果有人从此机器请求资源,我们将无法返回正确的响应。构建辅助项目时,您可能不会考虑此问题。但是,如果您要为数百万的用户提供大量的服务器,则这种情况经常发生,您无须每次都手动重新启动服务器。这就是为什么在当今的每个分布式系统中必不可少的原因。那么您将如何解决这个问题?

当然,您可以使用测试用例编写更强大的代码。但是,您的程序将始终存在错误。此外,硬件问题甚至更难保护。最常见的解决方案是副本。通过设置具有重复资源的计算机,我们可以大大减少系统停机时间。如果一台计算机每个月有10%的崩溃机会,那么对于一台备份计算机,当两台计算机都宕机时,我们将该概率降低到1%。

副本VS分片

乍一看,副本与分片非常相似。那么,这两者之间是什么关系?在设计分布式键值存储时,如何在副本和分片之间进行选择?

首先,我们需要明确这两种技术的目的。分片基本上用于将数据拆分到多台计算机,因为单台计算机不能存储太多数据。副本是一种保护系统免于停机的方法。考虑到这一点,如果一台计算机无法存储所有数据,则副本将无济于事。

一致性

通过引入副本,我们可以使系统更强大。然而,一个问题是关于一致性。假设对于机器A1,我们有副本A2。如何确保A1和A2的数据相同?例如,当插入新条目时,我们需要更新两台计算机。但是有可能其中之一发生写操作失败。因此,随着时间的流逝,A1和A2可能会有很多不一致的数据,这是一个大问题。

这里有几种解决方案。第一种方法是将本地副本保留在协调器中。每当更新资源时,协调器都会保留更新版本的副本。因此,如果更新失败,则协调器可以重新执行该操作。

另一种方法是提交日志。如果您一直在使用Git,则您应该非常熟悉提交日志的概念。基本上,对于每个节点计算机,它将保留每个操作的提交日志,就像所有更新的历史一样。因此,当我们要更新机器A中的条目时,它将首先将此请求存储在提交日志中。然后,一个单独的程序将按顺序(在队列中)处理所有提交日志。每当操作失败时,我们都可以轻松地恢复,因为我们可以查找提交日志。

我想介绍的最后一种方法是解决阅读冲突。假设当请求的资源位于A1,A2和A3中时,协调器可以向所有三台机器进行询问。如果数据不同,系统可以即时解决冲突。

值得注意的是,所有这些方法都不是互斥的。您绝对可以根据应用程序使用多个。

读取吞吐量

我还想在这篇文章中简要提及读取吞吐量。通常,键值存储系统应该能够支持大量的读取请求。那么,您将使用哪些方法来提高读取吞吐量?

为了提高读取吞吐量,通常的方法总是利用内存。如果数据存储在每个节点计算机内部的磁盘中,我们可以将它们的一部分移动到内存中。一个更一般的想法是使用缓存。由于“后一个设计缓存系统 ”对此主题进行了深入分析,因此我在这里不再赘述。

摘要

不要在这里将分析作为标准答案。相反,这些常见的解决方案应该给您启发,以帮助您提出不同的想法。

没有适用于每个系统的解决方案,您应该始终根据特定方案调整方法。

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×