OPTIONS
翻译或纠错本页面

FAQ:MongoDB 分片

这篇文档回答了关于使用MongoDB 分片 水平扩展的常见问题。

如果你在这里没有找到你寻找的答案, 请检查 常见 问题列表 或发布你的问题到 MongoDB 用户邮件列表.

分片适用于新的部署吗?

有时适用。

如果你的数据集适合在单一的服务器上部署,你应该以一个无分片的方式开始部署。

从一个无分片的数据库转换到 分片集群 是简单并且无缝的。所以在你的数据集比较小情况下配置分片只有微弱的优势。

尽管如此,所有的生产环境部署都应当使用 复制集 来提供高可用性和灾难恢复。

分片是如何与复制一起工作的?

若分片和复制一同使用,则在每个 分片 上部署 副本集

我可以在一个集合分片后更改片键吗?

不可以。

在MongoDB中,目前不自动支持集合分片后修改片键。这个事实凸显了选择一个好的 片键 的重要性。如果你 一定要 在集合分片后更改片键,最好的办法是:

  • 从MongoDB中导出所有的数据到外部存储格式。

  • 删除原始的分片集合。

  • 使用更理想的片键配置分片。

  • 预分裂 片键区间以确保初始均匀分布。

  • 还原转储的数据到MongoDB。

See shardCollection, sh.shardCollection(), the Shard Key, 部署一个集群, and SERVER-4000 以获得更多信息.

非共享集合在分片数据库中会发生什么?

在当前的实现方法中,所有 分片集合 中的数据库都有一个”主分片 shard。”该数据库中所有的非共享集合将驻留在相同的分片中。

MongoDB如何通过分片来分布数据?

分片必须明确的在集合上启用。在一个集合上启用分片之后,MongoDB将分配不同范围中的集合数据到集合中不同的分片上。分片集自动通过数据迁移范围调整分片之间的不平衡的数据,从一个分片到其他的分片。

如果客户端在数据块迁移的过程中更新文档会发生什么?

mongos 将这个操作分发到 “旧的” 分片,在那个分片上它会立即成功完成。然后在:term:分片集 更新那个数据块的 “所有权” ,即有效的完成迁移过程之前,分片 mongod 实例会复制这个更改到 “新的” 分片

如果在一个分片很慢或者无法访问时查询,会发生什么?

如果 分片 无法访问或者不可用,查询将会返回一个错误信息。

然而,客户端可以设定 partial 查询位,它会从所有的有效分片返回结果,无论给定的分片是否可用。

如果分片响应过慢, mongos 将仅会等待这个分片返回结果。

MongoDB是如何在分片间分配查询的?

在 2.0 版更改.

在:term:分片集 <sharded cluster> 中的 分片 分布查询的确切方法依赖于查询的性质和分片集的配置。考虑这样的一个分片集合,使用 片键 user_id, 它具有 last_login and email 属性:

  • 通过 user_id 键查询选择一个或多个值:

    mongos 基于分片集的元数据确定在哪个分片或包含相关数据的分片组,直接引导至需要的分片或分片组中查询,并将这些结果返回到客户端。

  • 对于一个选择了 user_id 并且对其执行排序的查询:

    mongos 能将这个操作简单翻译成许多针对相关分片的按``user_id``排序的查询。当这个排序查询从所有的分片返回,mongos 合并这些排序结果并返回完整的结果到客户端。

  • 对于在 last_login 上选择查询:

    这些查询必须在所有的分片上运行: mongos 必须在分片上并行执行这个查询并在找到的文档中的 email 运行合并-排序。

MongoDB在分片环境中查询如何排序?

如果你在一个分片环境查询中调用 cursor.sort() 方法,每一个分片上的 mongod 都会把结果排序,并且在结果返回客户端之前, mongos 会合并每一个分片上的结果。

MongoDB 在使用非 _id``键作为片键时如何确保 ``_id 键的值是唯一的?

如果你不使用 _id 键作为片键,你的 应用程序/客户端 层必须确保 _id 字段的唯一性。这是集合的 _id 字段有重复的值的问题。

如果你没有通过 _id 字段分片你的集合,你应该确保存储一个全局唯一标识在该字段中。默认的:doc:`BSON ObjectId </reference/object-id>`可以在这种情况下工作的很好。

我已经启用了分片并且添加了第二个分片,但是所有的数据仍然在一个服务器上,为什么?

首先,确保你已经在你的集合中声明了一个 片键 。MongoDB不会创建:term:数据块 <chunk>分片 也不会发生,直到你配置了这个片键。

接下来,请记住默认的数据块大小为 64 MB。因此,在大多数情况下,集合在发生迁移前至少需要有 64 MB的数据。

此外,在服务器之间的平衡数据块系统会尝试避免多余的迁移。根据分片的数量,片键和数据量,系统通常需要至少10个数据块来触发迁移。

你可以运行 db.printShardingStatus() 来查看你当前集群中的所有数据块。

删除 moveChunk 目录中的旧文件安全吗?

是的。 mongod 在:term:分片 平衡操作的过程中,创建这些文件作为备份。

一旦这些迁移工作完成,你可以删除这些文件。

mongos 如何使用连接?

每一个客户端都保持一个到 mongos 实例的连接。每一个:program:mongos 实例都保持一个到支持分片集的复制集的连接池。客户端每次使用一个 mongos 实例和 mongod 实例之间的连接。请求不采用多路复用和管道。当客户端请求完毕, mongos 将连接返回到连接池中。

参见: System Resource Utilization 部分于 UNIX系统下 ulimit 的设置 文档中。

为什么 mongos 保持连接打开?

mongos 使用一组连接池与每个:term:`分片`通信。这些连接池在客户端连接数量减少的情况下不会减少。

这可能会导致一个 mongos 未使用却保持大量的打开连接。如果:program:mongos 不再使用,重新启动进程来关闭现存的连接是安全的。

MongoDB 在哪报告 mongos 使用的连接?

使用 mongo 命令行连接到 mongos ,运行命令:

db._adminCommand("connPoolStats");

writebacklisten 在日志中意味着什么?

在数据迁移之后,确认数据没有发送到错误的服务器, mongod 或者 mongos 会转发回写,回写监听器就是为之打开一个长轮询进程。如果有必要,回写监听器会发送一个回写到正确的服务器。

这些消息是分片基本架构的关键部分,不会造成顾虑。

管理员应如何处理失败的迁移?

失败的迁移不需要管理的干预。数据块迁移总是保持一致性状态。如果因为某些原因导致迁移失败, 集群 会重试这个操作。当迁移完全成功,数据只在新的分片上保留。

移动,重命名,或者改变配置服务器的数目的流程是什么?

参见 集群教程 获得迁移和更换配置服务器的信息。

什么时候 mongos 服务器能监测到配置服务器的更改?

mongos 实例维持一个 config database 的缓存,它包含了 分片集`的元数据。这个元数据包括 :term:`数据块 到 :term:`分片 <shard>`的映射。

当请求发送到一个分片并且发现它的元数据过时了,mongos 懒惰的(lazily)更新它的缓存。没有方法从客户端控制这个行为,但是你可以执行:dbcommand:flushRouterConfig 命令对任何 mongos 使用以强制它 刷新它的缓存。

更新复制集配置之后有没有可能快速的更新 mongos 服务器?

随着时间推移,mongos 实例会检测这些变化而无需干预,然而,如果你想强制 mongos 重新加载它的配置,在每个 mongos 上直接运行:dbcommand:flushRouterConfig 命令。

mongosmaxConns 设置是做什么的?

maxIncomingConnections 选项限制 :program:`mongos`接受连接的数量。

如果你的客户端驱动或应用程序建立了大量的连接,不是显示关闭而是允许他们超时,这时限制 mongos 层的连接数量将变得有意义。

将:setting:~net.maxIncomingConnections 设置为一个略高于客户端创建的最大数量或者连接池的最大数量。这个设置可以防止 mongos 造成个别 分片 <shard>`上的连接尖峰。这些尖峰可能会扰乱:term:`分片集 的内存分配操作。

索引在分片系统查询中产生什么影响?

如果查询中没有包含 片键mongos 一定会发送所有的查询到所有的分片,就像”分散/集中”操作。每个分片将轮流的使用片键索引或者其他的更高效的索引其中的一种索引方式来实现查询。

如果查询中包含了多个引用片键索引*和*辅助索引的子表达式,:program:`mongos`能够路由这个查询到一个指定的分片,这个分片将使用它并允许它实现最有效的索引。 See `这个演示文档 <http://www.slideshare.net/mongodb/how-queries-work-with-sharding>`_ 以 获得更多的信息。

片键可以随机生成吗?

片键 可以随机生成。随机片键确保跨集群数据最优分布。

分片集 会尝试发送参数中包含片键的查询到 指定 的分片,因为这些定向的查询更加高效。在许多情况下,随机片键很难做到向指定分片定向查询。

片键可以有非均匀分布的值吗?

可以。这里对片键均匀的分发文档没有要求。

然而,具有相同片键的文档必须保存在同一个数据块,所以在同一个服务器上。如果你分片后的数据集有太多具有精确的相同片键的文档,你将不能通过分片集分布文档。

你能用 _id 字段分片吗?

你可以用任何字段作为片键。 _id 字段是常用的片键。

请注意 ObjectId() 的值,即``_id``字段的默认值,使用时间戳递增。因此,当它作为片键使用,所有插入到集合中的新文档将在一个单一分片上最初属于同一个数据块。虽然系统将最终等分这些数据块并且迁移其内容来更均匀的分发数据,在任何时刻,集群只能定向一个插入操作到单一的分片。这会限制插入操作的吞吐量。如果你的大部分写操作是更新操作,这些限制将不会影响你的性能。然而,如果你插入操作数量很高,这可能是一个局限。

为了解决这个问题,MongoDB 2.4 提供了 哈希片键.

错误 moveChunk commit failed 是什么意思?

数据块迁移 <sharding-chunk-migration>`结束的时候,:term:`分片 一定会连接到 配置数据库 更新数据块在集群元数据中的记录。如果 分片 连接到 配置数据库 失败,MongoDB会报告如下错误:

ERROR: moveChunk commit failed: version is at <n>|<nn> instead of
<N>|<NN>" and "ERROR: TERMINATING"

当这种情况发生时,复制集中分片的 主节点 终止运行以保护数据的一致性。如果一个 子节点 成员能够访问配置数据库,在投票后,分片上的数据能够再次访问。

用户需要独立的解决数据块迁移失败的问题。如果你遇到这个问题,请联系 MongoDB 用户组 or MongoDB 支持 来解决这个问题。

清空一个分片如何影响不平均的数据块分布的平衡?

分片集的平衡进程控制,即是从停止使用的分片(即 清空的分片)迁移数据块,也是正常的集群平衡活动。在你从具有不平衡数据块分布的集群中移除了一个分片,请考虑不同版本的MongoDB在这种情况下的行为:

  • MongoDB 2.2 版本以上,平衡器首先从清空的分片移除数据块,然后平衡器平衡剩余的不平衡的数据块分布。

  • MongoDB 2.2 版本以前,平衡器首先处理不平衡的数据块分布,然后从清空的分片移除数据块。

ON THIS PAGE