我只是对分片和复制的工作方式感到困惑。
根据我在文档中找到的定义:

复制:MongoDB中的副本集是一组维护相同的mongod进程数据集。
共享:分片是一种用于在多台计算机之间存储数据的方法。

据我了解,如果我有75 GB的数据,那么通过使用复制(3台服务器),它将在每个服务器上存储75GB数据意味着在Server-1上为75GB,在Server-2上为75GB,在Server-3上为75GB。 (如果我错了,请纠正我)。
通过使用分片,它将以服务器1上的25GB数据,服务器2上的25Gb数据和服务器3上的25GB数据存储。 (对吗?)。
但是后来我在本教程中遇到了这一行:

分片存储数据。为了提供高可用性和数据
一致性,在生产分片群集中,每个分片都是一个副本


,因为一个副本集的大小为75GB,但分片为25GB。大小,那么它们怎么等效?
这让我很困惑。我想我缺少明显的东西。请帮助我。

#1 楼

副本集意味着您拥有MongoDB的多个实例,每个实例都相互镜像所有数据。一个副本集由一个主服务器(也称为“主服务器”)和一个或多个从属服务器(又称为“辅助服务器”)组成。读取操作可以由任何从属服务器提供服务,因此您可以通过向副本集添加更多从属服务器来提高读取性能(前提是您的客户端应用程序能够实际使用不同的集合成员)。但是写操作总是在副本集的主服务器上发生,然后传播到从属服务器,因此,当您添加更多从属服务器时,写操作将不会更快。

复制集还会带来故障-公差。当副本集的成员之一发生故障时,其他成员接任。当主机发生故障时,从机将选举一个新的主机。因此,建议进行生产性部署时,始终将MongoDB用作至少三台服务器的副本集,其中两台用于保存数据(第三台是无数据“仲裁器”,在确定新主服务器时需要使用“仲裁器”。

分片集群意味着集群的每个分片(也可以是副本集)负责处理部分数据。每个请求(包括读写)均由数据所在的集群服务。这意味着可以通过向群集添加更多分片来提高读写性能。哪个文档位于哪个分片上,取决于每个集合的分片键。应该以这样一种方式进行选择:数据可以均匀地分布在所有群集上,并且对于分片键所在的最常见查询是清楚的(例如:当您通过user_name频繁查询时,分片键应包括user_name字段,因此每个查询只能委派给具有该文档的一个分片。)

缺点是容错能力受损。当集群的一个分片出现故障时,该集群上的任何数据均不可访问。因此,群集的每个成员也应该是一个副本集。这不是必需的。如果您不关心高可用性,则分片也可以是一个没有复制的mongod实例。但是对于生产用途,您应该始终使用复制。

那对您的示例意味着什么?

                            Sharded Cluster             
             /                    |                    \
      Shard A                  Shard B                  Shard C
        / \                      / \                      / \
+-------+ +---------+    +-------+ +---------+    +-------+ +---------+
|Primary| |Secondary|    |Primary| |Secondary|    |Primary| |Secondary|
|  25GB |=| 25GB    |    | 25 GB |=| 25 GB   |    | 25GB  |=| 25GB    |   
+-------+ +---------+    +-------+ +---------+    +-------+ +---------+


要拆分时如果将75GB的数据分成3个25GB的碎片,则至少需要6个数据库服务器,这些服务器分为三个副本集。每个副本集由两个具有相同25GB数据的服务器组成。

您还需要用于三个副本集的仲裁器的服务器,以及用于群集的mongos路由器和配置服务器。仲裁器非常轻巧,仅在副本集成员出现故障时才需要,因此它们通常可以与其他设备共享同一硬件。但是Mongos路由器和config-server应该是冗余的,并且在它们自己的服务器上。

评论


非常感谢您提供详细的答案...另一个问题...如果在执行写入或读取操作时主数据库已关闭,则..1)从辅助数据库中选择主数据库的延迟是什么,以及2)在此延迟期间,数据将被临时存储在哪里?

– Saad Saadi
13年11月22日在6:58

@SaadSaadi文档中描述了主要的选举过程。辅助节点需要10到12秒的时间才能注意到辅助节点已关闭。初选本身通常只需几毫秒。没有主副本集时,副本集为只读。在此期间,任何来自应用程序的写数据尝试都将失败。

– Philipp
13年11月22日在8:23

@Philipp:仅有两条评论:(1)不能修改分片密钥(即,您不能使用其他密钥进行分片);(2)可以从副本集的辅助节点读取,但一致性取决于写操作(在为了保持一致,w选项应等于不可行的副本集sth,因为每个分片可能故意或由于节点故障而具有不同的副本集大小)。

–迈克·阿格里乌(Mike Argyriou)
2015年9月17日9:30



@Philipp您能否在dba.stackexchange.com/questions/208482/…上回答进一步的后续问题?

–user3198603
18年6月1日在13:37

#2 楼



阴影将数据集划分为离散的部分。

复制将数据集复制。

这两个东西可以堆叠,因为它们是不同。同时使用这两种方法意味着您将在多组副本之间共享数据集。换句话说,您可以复制分片。没有分片的数据集就是单个“分片”。

具有三个分片和3个副本的Mongo群集将具有9个节点。


3个集3个节点副本。
每个副本集都包含一个分片。


评论


对于一个大文件,它存储在一个分片中还是多个分片中(因此跨节点)?

–托尼
16-10-26在15:42

请注意,在MongoDB 3.4或更高版本中,您还将需要mongoDB服务器进行配置,并需要一个额外的服务器来充当mongos路由器。这样,示例中的3x3群集总数便达到了13台服务器。

–垃圾桶
17年11月13日在21:29

#3 楼

通过分片,您可以将集合分为几个部分。复制数据库意味着您可以镜像数据集。

#4 楼

就交付的功能而言。
共享提供可伸缩性和并行性。
复制提供可用性

评论


不会,复制还提供了可伸缩性和并行性,因为读取比写入更频繁

–KristófSzalay
17年3月21日在0:30