在Mongo中,分片和复制有什么区别?

复制似乎比分片简单得多,除非我错过了分片实际上试图实现的好处。 难道他们都提供水平缩放?

在扩展MongoDB的上下文中:

  • 复制会创build数据的其他副本,并允许自动故障转移到另一个节点。 如果您可以读取可能不是最新的数据,则复制可能有助于读取的水平缩放。

  • 分片允许通过使用分片 在多个服务器之间分区数据来水平扩展数据写入。 select一个好的分片键很重要 。 例如,分片密钥的糟糕select可能导致数据的“热点”仅被写入单个分片中。

分片环境增加了更多的复杂性,因为MongoDB现在必须pipe理在分片之间分发数据和请求 – 添加额外的configuration和路由进程来pipe理这些方面。

通常将复制和分片组合在一起以创build分片集群 ,其中每个分片由副本集合支持。

从客户端应用程序的angular度来看,您还可以对复制/分片交互进行一些控制,特别是:

  • 阅读首选项
  • 写关心

复制是一个主要传统的主/从设置,数据同步到备份成员,如果主服务器失败,其中一个可以代替它。 这是一个相当简单的工具。 这主要是为了冗余,尽pipe您可以通过添加副本集成员来扩展读取。 这有点复杂,但对于某些应用程序来说效果很好。

分片通常位于复制之上。 MongoDB中的“Shards”只是在其前面有一些名为“router”的副本集。 您的应用程序将连接到路由器,发出查询,并将决定将哪些副本集(分片)转发到。 它比单个副本集复杂得多,因为你需要处理路由器和configuration服务器(这些服务器会跟踪哪些数据存储在哪里)。

如果你想水平缩放Mongo,你会碎片。 10gen喜欢调用路由器/configuration服务器设置自动分片。 有可能做一个更贫民区forms的分片,你应用程序决定哪个数据库也写入。

考虑到你的硬盘上有很棒的音乐collections,你可以根据发行年份将音乐存储在不同的文件夹中。 如果驱动器出现故障,您担心您的收集将会丢失。 所以你得到一个新的磁盘,并偶尔复制整个集合保持相同的文件夹结构。

分片>>将您的音乐文件保存在不同的文件夹中

复制>>将您的集合同步到其他驱动器

拆分

分片是在多个服务器之间分割大量集合的技术。 当我们分片时,我们部署了多个mongod服务器。 而在前面, mongos是一个路由器。 应用程序与此路由器进行通信。 这个路由器然后与各种服务器, mongod s。 应用程序和mongos通常位于同一台服务器上。 我们可以在同一台机器上运行多个mongos服务。 还build议保留多个mongod (一起被称为副本集 )的集合 ,而不是每个服务器上的单个mongod 。 副本集使数据在几个不同的实例中保持同步,因此如果其中一个发生故障,我们不会丢失任何数据。 从逻辑上讲,每个副本集可以看作是一个分片。 它对应用程序是透明的, MongoDBselect分片的方式是我们select分片

MongoDB分片

假设,对于studentcollections,我们将stdt_id作为分片键,或者可以是复合键。 而mongos服务器,这是一个基于范围的系统。 所以根据我们作为分片键发送的stdt_id ,它会将请求发送到正确的mongod实例。

那么,作为开发人员,我们需要真正了解什么?

  • insert必须包含一个分片键,所以如果它是一个多分片分片键,我们必须包含整个分片键
  • 我们必须了解集合本身的分片键
  • 对于updateremovefind – 如果mongos没有被赋予分片密钥 – 那么它将不得不将广播请求发送到覆盖集合的所有不同的分片。
  • 对于update – 如果我们不指定整个分片密钥,我们必须做一个多更新,以便它知道它需要广播它

每当你考虑分片或复制时,你都需要考虑作者/更新操作。 如果你不需要扩展写入,那么复制,因为它相当简单,是一个很好的select。

另一方面,如果你的工作量大部分是更新/写入,那么在某个时候你会遇到写瓶颈。 如果写请求来了,Mongo阻止其他的写请求。 那些写请求块直到第一个请求完成。 如果你想扩展这个写入并且想要并行化,那么你需要实现分片。