在MongoDB中,分片和复制的区别是什么?

12
我对分片(Sharding)和复制(Replication)的工作原理感到困惑。根据定义:
复制:MongoDB中的复制集是一组维护相同数据集的mongod进程。
分片:分片是一种将数据存储在多台机器上的方法。
按照我的理解,如果有75GB的数据,那么通过复制(3个服务器),每个服务器将存储75GB的数据,即Server-1存储75GB,Server-2存储75GB,Server-3存储75GB...(如果我错了,请纠正我)而通过分片,则将25GB的数据存储在Server-1上,25GB的数据存储在Server-2上,25GB的数据存储在Server-3上。(对吗?)但是,在教程中我遇到了这样一句话:
分片存储数据。为了提供高可用性和数据一致性,在生产分片的群集中,每个分片都是一个复制集。
由于复制集的容量为75GB,但分片的容量为25GB,它们怎么能等价呢?这让我非常困惑......我觉得我在这方面有很大的缺失。请帮助我理解一下。
5个回答

29
让我们通过这个类比来理解。你在经营图书馆。
和经营图书馆的人一样,你的图书馆里有很多书。你把所有书都存放在书架上。这很好,但是你的图书馆变得如此出色,以至于你的竞争对手想要将它烧毁。因此,你决定在其他地方制作许多额外的书架。有一个最重要的书架,每当你添加一些新书时,就会迅速将相同的书籍添加到其他书架上。现在,如果对手摧毁了一个书架 - 这不是问题,你只需要打开另一个书架,并将书籍复制过去。
这就是“复制”(仅用应用程序替换图书馆,服务器替换书架,文档集合中的文件替换书籍,而你的竞争对手只是服务器上失败的硬盘驱动器)。它只是为数据制作附加副本,如果出现问题,它会自动选择另一个原始副本。
这个概念可能会有所帮助。
  • 想要扩展读取(但它们可能落后于主服务器)。
  • 进行一些离线读取,不触及主服务器。
  • 为特定区域的某些数据从该特定区域的服务器提供服务。
  • 但复制背后的主要原因是数据可用性。因此,在这里您是正确的:如果您有75GB的数据并将其与2个辅助副本一起复制-您将获得75 * 3GB的数据。

看另一个情况。没有竞争对手,因此您不想复制书架。但现在您有另一个问题。您变得如此出色以至于一个书架不够用了。您决定在许多书架之间分配您的书籍。您决定根据作者姓名将它们分配到书架上(这可能不是一个好主意,请阅读此处的select sharding key)。因此,所有以名称小于K开头的内容都放在一个书架上,而所有大于或等于K的内容都放在另一个书架上。这就是分片

这个概念可以帮助您:

  • 分配工作负载
  • 能够保存远超过单个服务器容量的数据
  • 执行MapReduce操作
  • 在RAM中存储更多数据以进行更快的查询

你部分正确,如果你有75GB,那么所有服务器上的总和仍然是75GB,但不一定平均分配。

但是,只有分片存在一个问题。现在你的竞争对手出现了,他来到你的一个架子上并将其烧毁。该架子上所有的数据都丢失了。因此,你需要为每个分片都复制一份。基本上,关于

每个分片都是一个副本集

这种观点是不正确的。但是如果你正在进行分片,你必须为每个分片创建一个副本。因为你拥有的分片越多,至少有一个分片死亡的可能性就越大。


哇...先生..太棒了...解释得非常清楚,消除了我很多的困惑,但是又产生了一个新的困惑...我在下面写出来,请看一下。 - Saad Saadi
@Salvador Dali,非常好的回答。非常感谢。这是否意味着所有节点将始终具有几乎相同的存储量,因为它们都包含相同数量的数据。每个集合都将具有相同的副本因子等效数量的副本集吗?https://stackoverflow.com/questions/64601659/mongodb-setting-the-replication-at-the-db-or-collection-level - Nag

4

回答Saad的跟进答案:

你也可以在同一台服务器上同时拥有片段和副本,但这不是推荐的做法。每个服务器应该在系统中扮演单一的角色。例如,如果您决定有2个片段并将其复制3次,则最终将得到6台机器。

我知道这听起来可能太昂贵了,但您必须记住,这是普通硬件,如果您提供的服务已经非常好,需要高可用性且不适合一个机器,那么与专用的大型机器相比,这是一个相当便宜的代价。


我完全理解了你的解释...非常感谢你详细的回复。 - Saad Saadi

2
我写这篇回答,但实际上是对@Salvador先生的回答提出的问题。
就像您所说的,在分片中,75GB的数据“可能”存储为25GB的数据在server-1上,25GB的数据在server-2上和25GB的数据在server-3上(这个分配取决于分片键)...然后为了防止它丢失,我们还需要复制分片。这意味着现在每个服务器都包含其自己的分片和其他服务器上存在的分片的复制...也就是说,Server-1将有
1) 自己的分片。 2) 存储在server-2上的分片的副本。 3) 存储在server-3上的分片的副本。
Server-2和Server-3同样如此。我对吗?如果是这种情况,那么每个服务器再次拥有75GB的数据,对吗?

0

由于我们想要创建3个分片并复制数据,因此以下是解决上述问题的方法。

如果r具有分片和副本集,则在这种情况下,该服务器的故障将导致副本集和分片的丢失。

但是,您可以将分片1和副本集(分片2和分片3的副本)放在同一台服务器上,但这不是建议的做法。


0

分片就像数据的分区。 假设您有大约3GB的数据,并且定义了3个分片,那么每个分片可能会占用1GB的数据(这确实取决于分片键) 为什么需要分片?从3GB中搜索特定数据要比在1GB的数据中搜索复杂3倍。所以它几乎类似于分区。分片有助于快速访问数据。

现在说到副本,假设您拥有相同的3GB数据,没有任何复制(这意味着只存在一个数据副本),因此如果该机器或驱动器发生故障,您的数据就消失了。所以复制出现来解决这个问题,假设您设置了DB时,已将复制设置为3,这意味着相同的3GB数据可用3次(因此总大小可以是9GB,每个3GB的副本)。复制有助于故障恢复。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接