MongoDB如何同时进行分片和复制?

11
为了扩展/故障转移mongodb使用“副本集”,其中有一个主服务器和一个或多个次要服务器。主服务器用于写入,次要服务器用于读取。这基本上是在SQL编程中使用的主从模式。如果主服务器崩溃,则群集中的某个次要服务器将接替其位置。因此,横向扩展和故障转移问题得以解决。但是,似乎这不是允许分片的解决方案。真正的分片仅保存整个数据的一部分,因此,如果副本集中的次要服务器进行了分片,那么当它没有所有需要为请求提供服务的数据时,如何将其作为主服务器呢?
难道我们不必为每个分片设置一个副本集吗?
显然,这是初学者的问题,因此有一个直观或以其他方式说明如何完成此操作的链接将会很有帮助。

该分片将拥有满足发送给它的请求所需的数据,是的,您可以为每个分片设置一个副本。这里有一个食谱教程:http://cookbook.mongodb.org/operations/convert-replica-set-to-replicated-shard-cluster/ - Sammaye
3个回答

8
您的假设是正确的,每个分片都包含一个单独的副本集。当写入请求到达时,MongoS根据分片键找到正确的分片,并将数据写入该分片中包含的副本集的主节点。这样可以实现写入扩展,因为(选择得当的)分片键应该将写入分布在所有分片上。

谢谢!它可以以相反的方式完成吗?复制集群中的每个服务器都被分片。详细描述:假设我们有一个副本集。很好,我们获得了处理更多读取请求的能力,我们也实现了故障转移。现在我们的问题是每台服务器(我称之为服务器)上的数据大小变得非常大。所以,我们将每个服务器上的数据进行分片。这不是和你描述的相反吗?还是从实现的角度来看,这是同样的“事情”? - alex sundukovskiy
@alexsundukovskiy 我不确定你的意思,但是你不能对副本集本身进行分片。 - Sammaye
@alexsundukovskiy 假设SHARD_KEY有可能的值为{A,B,C,D},而您有2个分片。每个分片都有由3台机器组成的副本集。现在,理论上,您的文档应该均匀分布在SHARD_KEY上,即到达SHARD_KEY = A、SHARD_KEY = B等的文档数量应该相等。假设这种幸福的情况持续了一段时间。然后,开始发生以下两件事之一:(下文继续) - Alptigin Jalayr
  1. 文档总数开始变得庞大,所有分片都开始填满。你可以选择:(a)获取更大的机器(b)将分片数量增加(例如从2个增加到4个)。
  2. 你最初对SHARD_KEY上文档的分布做出的假设是错误的,只有分片#1开始填满。在这种情况下,你需要选择一个新的键或选择一个复合键。迁移到新键/复合键的唯一方法(据我所知)是转储所有数据,基于新键创建新集合,并将其全部移回。
- Alptigin Jalayr
谢谢!感谢解释,现在我明白为什么设计师决定复制碎片而不是“复制”碎片了。 - alex sundukovskiy

1
一个 shard 是主节点和副本集(secondaries)的总和,因此,在每个 shard 中都必须有一个副本集。
整个数据的一部分由主节点持有,并与副本集共享以保持一致性。如果主节点出现故障,则会选举一个副本集作为新的主节点,并具有与其前任相同的数据以立即开始提供服务。这意味着分片数据仍然存在,而不会丢失。

1
分片是分片集合数据的范围,副本可以存在而没有分片,分片也可以存在而没有副本。 - Sammaye
@Sammaye,我不明白在分片环境中如何可以存在一个独立的副本集。(你是不是指在非分片环境中它不必成为一个分片?)当我们说“分片”时,难道不是指副本集是更大数据范围的一部分吗?关于分片能够在没有副本集的情况下存在,我同意。但这并不是他提出的情况,因此我调整了我的答案来适应他涉及副本而不是单个单位的场景。 - Alderis Shyti
分片的定义并不总是在复制环境中,听起来像是“分片”的定义是存在于副本中。我仍然不确定你所说的“主分片和次分片之和”的意思,因为如果是这样的话,主分片就会有重复的数据。次分片是主分片的副本,也就是分片,但这取决于复制。 - Sammaye
@Sammaye 是的,我用“sum”来解释可能有点混淆。我主要是指“sum”实体层面上的而不是数据层面上的,因为我想反驳那个问问题的人说“如果副本集中的辅助节点是分片的,它如何能够被视为主节点”。辅助节点并不是真正的分片,整个集合被认为是一个分片,但只有一个实体提供数据。谢天谢地,他搞清楚了。 - Alderis Shyti
好的,没问题,听起来不错 :) - Sammaye

0

谢谢,我想知道是否有可能反过来。换句话说,我们能否将副本集中的每个节点分片?如果不行,那么这样做有什么问题吗? - alex sundukovskiy
我不确定我理解你的问题。在数据库中,您可以共享集合,并且分片运行在副本集之上。MongoDB没有节点分片的概念。您可以选择在所有数据库中分片所有集合,但这可能会因工作负载而过度使用。 - epc
假设我们有一个副本集。太棒了,我们获得了更多读取的能力,还有容错处理。现在我们的问题是每个服务器(我将其称为节点)上的数据大小变得相当大。所以我们将数据在每个服务器上进行分片。这难道不是你所描述的相反吗?或者从实现的角度来看,它只是同一件事的不同表现方式? - alex sundukovskiy

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