MongoDB的分片Sharding
MongoDB的分片
一、 分片簇综述
分片是mongoDB扩展的一种方式。分片分割一个collection并将不同的部分存储在不同的机器上。当一个数据库的collections相对于当前空间过大时,你需要增加一个新的机器。分片会自动的将collection数据分发到新的服务器上。
分片自动的均衡数据并在机器间进行负载。分片通过将写操作分发到一定数量的mongod实例上来提供额外的写能力。分片允许用户在工作集中增加潜在数量的数据。
1. 分片
分片发生在分片簇中。一个分片簇由一下组件组成:
- shards:一个分片是一个保存一个collection子集数据的容器。每个分片可以是一个单独的mongod,也可以是一个副本集。在生产环境中,分片应该是一个副本集。
应用不能直接访问分片,而是通过访问mongos实例。
- Config Server:每个config server是一个保存该簇meta数据的mongod实例。meta数据将块映射到分片。
- mongos 实例:mongos实例将应用的读写操作路由到对应的分片上。
在一个分片簇中,你可以以每个数据库为基础进行分片。当你在一个数据库上打开分片功能,MongoDB会将collections分发到分片上。MongoDB没有对一个collection的数据进行分发。
在打开分片功能后,你需要选择哪些collections需要分片。对于每个要分片的collection,需要指定一个片键。
2. 片键
collection中的文档由片键决定了被分发到簇中的某些分片上。片键是一个在存在于该collection中每个文档的一个域。MongoDB片键所在的范围值进行文档分发。一个给定的分片保存片键落在指定范围值内的文档。与索引类似,片键可以是一个单独的域,也可以是一个组合的域。
3. 散列分片
散列片键使用一个单独的列的散列索引,因为片键用于在片簇中分割数据。
选择作为散列片键的域应该有很好的基数,或者大量不同的值。散列键适合工作在单调增的域中,类似于ObjectId值或时间戳。
如果使用一个散列片键分片一个空的collection,MongoDB将自动的创建并移动块,使每个分片都有两个块。你能通过创建shardCollection的numInitialChunks参数来控制MongoDB的块,或者使用split命令在空collection上人为的创建块。
4. 分片均衡
平衡是MongoDB用来在分片簇中重新分发数据的过程。当一个分片相对于其他分片有过多的块时,MongoDB自动的平衡分片。MongoDB的分片不需要应用层的干预。
平衡过程试图通过以下方式尽可能小的影响簇:
- 一次只移动一个块
- 只有在最多块的分片和最少块的分片的差超过门限值时才会触发平衡过程
你能够在一个临时的基础维护时禁用平衡,并限制窗口,以此防止平衡过程影响正常的生产流量。
5. 分片的用处
- 你的数据接近或超过一个单独节点的存储能力
- 系统有效工作集的大小将要超过系统的最大RAM
- 系统有大量的写操作,一个单MongoDB实例不能足够快的支持写数据,并且没有其它办法减少资源的抢占。
二、 分片簇架构
1. 分片簇的基础需求
一个分片簇由以下组件:
- 三个config服务
这些特定的mongod实例用来存储簇的meta数据。Mongos实例会缓存这些数据并用于判断哪些分片负责哪些块。
为了开发测试目的,可以只为簇部署一个config服务,但在生产阶段则需要三个config服务为了冗余和安全。
- 两个以上的分片。每个分片由一个或多个mongod实例组成,用于存储分片的数据。
这些普通的mongod实例保存了簇中所有的真实数据。典型的分片是一个副本集,副本集中有多个mongod实例,副本集中的成员为分片提供了冗余和高可用性。
- 一个以上的mongos
这些实例直接向存储数据的分片提交应用的查询请求。Mongos实例没有持久的状态或者数据文件,它只将从config服务得到的meta数据缓存在RAM中。
注意:在大多数情况下,mongos实例使用少量的资源,并且在不影响应用性能的情况下运行在应用服务器上。然而,如果使用聚合框架,mongos实例上回运行一些进程,这会导致mongos使用更多的系统资源。
2. 分片簇的数据量需求
你的簇必须管理相当数量的数据,以至于分片能够对collection有效。默认的块大小为64MB,并且平衡器会在簇中不平衡的块数超过迁移门限值时才会移动数据。
实际中,这意味着除非你的簇有上百兆的数据,否则块会保存在一个分片上。
除非有特殊的情况,如额外的并发量或者能力,否则对小的collection进行分片会增加系统的复杂度。
3. 限制使用locaohost接口
由于所有的分片簇成员都必须通过网络与其它成员进行通信,所以对于localhost地址的使用有特殊的限制:
如果使用localhost或者127.0.0.1作为主机标识,你必须对任意MongoDB实例的所有主机设置使用localhost或127.0.0.1。这适用于addShard的host参数和mongos –configdb的运行选项值。如果你混合使用localhost地址和远程host地址,那MongoDB会产生错误。
4. 测试簇架构
你可以部署一个很小的簇用于测试和开发。这些非生产环境的簇有以下成员:
- 一个config服务
- 至少有一个mongod实例
- 一个mongos实例
5. 生产簇架构
在一个生产簇中,你必须确定数据有冗余并且你的系统高可用。为了这个目的,一个生产级别的簇必须包含下面成员:
- 三个config服务,每个驻于一个独立的系统
一个单一的分片簇必须由其专属的config服务。如果你有多个分片簇,则每个簇都需要一组config服务。
- 两个或以上的副本集作为分片服务。
- 两个或以上的mongos实例。典型的,我们在每个应用服务器上部署一个单一的mongos实例。或者,可以部署几个mongos节点,并让你的应用通过负载均衡连接这些点。
6. 分片和不分片数据
分片操作在collection层上。你能分片一个数据库中的多个collection,或者使多个数据库启用分片。然而,在生产环境下,一些数据库和collections会使用分片,同时,另外一些数据库和collections只存在一个单一的数据库实例或者副本集上。
不管分片簇的架构,要确认所有的请求和操作都要用mongos路由到数据簇中。
每个数据库都有一个主分片,它保存着那些没有进行分片的collections。使用movePrimary命令可以改变数据库的主分片。使用db.printShardingStatus()命令或者sh.status()命令可以查看簇的概要,它包含了簇中块和数据库分布的信息。
当你部署一个新的分片簇时,在启用分片之前,第一个分片将成为所有数据库的主分片。随后创建的数据库可能会存在簇中任意的分片上
7. 高可用和MongoDB
- 应用服务或者mongos实例不可用
如果每个应用服务有自己的mongos实例,其它的应用服务能继续访问数据库。此外,mongos实例不会保持持久的状态,他们能够不丢失任何状态和数据的情况下重启和变为不可用。当一个mongos实例启动,它从config数据库中进行恢复看,并能够开始路由请求。
- 一个分片中的单一mongod不可用
副本集为分片提供了高可用性。如果不可用的mongod是primary,则副本集会选举出一个新的primary。如果不可用的mongod是secondary,并且它与primary无法连接,secondary继续存储所有数据。在三成员副本集中,尽管集合中一个单独的成员经历了灾难性的失败,另外两个成员依旧保存了所有的数据。
要一直关注可用性中断和失败。如果一个系统不可恢复,移除它并尽快创建一个新的副本集成员来代替失去的冗余。
- 所有的副本集成员都不可用
如果一个分片的副本集成员都不可用,则这个分片保存的所有数据都不可用。然而,其它分片上的数据保持可用,能够读数据,且可以向其它分片上写数据。然而你的应用必须能够处理局部结果,并且你应该调查中断的原因并尽可能恢复那个分片。
- 一到两个config数据库不可用
三个特殊的mongod实例提供config数据库,使用专用的双向提交来保证不同mongod实例间的一致性。簇操作会继续标准的进行除了块迁移,并且簇能够创建任何新分裂块。尽快替换config服务。如果所有的config数据库都不可用,则簇将不能使用。
三、 分片簇中的查询路由
MongoDB提供mongos进程来处理分片簇中的查询路由。
1. Mongos操作概述
Mongos进程给分片簇提供了一个单一的共同的接口。一个应用不能直接访问分片,而是访问mongos。Mongos路由请求并返回结果。
Mongos会根据从config服务上缓存的meta数据信息跟踪数据在哪些分片上。Mongos使用meta数据将应用的操作路由到mongod实例上。一个mongos没有持久的状态,且只占用少量的系统资源。
2. 广播选项VS定向选项
通常,一个分片环境下的操作分为两种:
- 向一个保存文档的collection的簇中的所有分片进行广播
- 通过片键定向到一个单独的分片或一组分片
3. 广播选项
如果mongos不能判断出哪个分片保存了这个暑假,一个查询操作则会被广播到所有分片上。
并发更新操作总是广播选项。
Remove()操作总是广播选项,除非操作指定了全部的片键。
4. 定向选项
- 所有的insert()操作都定向到一个分片。
- 所有的单个update()操作都定向到一个分片,这包括upsert操作。
- 如果查询包含片键,则mongos能够将查询定向到指定的一个分片或分片集上。这种情况只有在部分片键作为一个片键的前缀包含在查询中。
Mongos进程能够路由包含整个片键或者是指定分片或者分片集的片键前缀的查询。
5. Mongos查询路由
Mongos实例使用下面的方法将一个查询路由到一个簇中。
- 确定分片列表中必须接收查询的请求。
- 在所有的定向分片中维护一个光标
6. Mongos判断哪个分片接收请求
在一些情况下,当片键或者片键的前缀是查询的一部分,mongos能够将查询路由到分片的子集中,否则mongos必须直接将请求发送到包含一个collection文档的所有分片中。
7. Mongos在目标分片上建立一个游标
当第一个批处理结果从游标返回时:
对于排序的查询结果,mongos实例会执行一个合并所有查询的结果
对于非排序的查询结果,mongos实例从所有分片的游标中返回一个循环结果游标。
四、 分片簇的安全实践
MongoDB通过保存验证信息的授权文件控制分片簇的访问。分片簇的组件使用授权文件中的秘钥进行相互的验证。创建一个授权文件并在文件中指定mongos和mongod的实例。
除了这里描述的验证机制,更多的是将分片簇运行在一个安全的网络环境中,可以通过网络规则进行访问控制。网络环境可以强制限制以确保只有已知的通信可以到达mongos和mongods。
1. 分片簇的访问控制权限
在分片簇中,mongoDB对整个簇和每个分片提供了不同的管理权限。除了这些管理权限,分片簇与其它mongoDB部署的权限完全相同。
对于分片簇,MongoDB提供了两种管理权限:
- 分片簇的管理权限
这些权限提供了对config服务器中admin的读写访问权限。这些用户能够运行所有的管理命令。管理权限也给了用户整个簇数据库的读写访问权限。
管理权限的证书存放在config服务器上。为了接收管理访问集群,必须在连接mongos实例时使用admin数据库验证每个会话。
- Mongod实例或者副本集的管理权限
每个分片有自己的admin数据库,用于存储对于该分片的管理证书和访问权限。这些证书与整个簇的管理证书是完全分开的。
2. 使用验证访问一个分片簇
作为一个验证用户访问一个分片簇,要使用mongo中适当的验证选项。
非管理用户作为一个验证用户访问一个分片簇,使用authenicate或者db.auth()进行验证。
五、 分片簇的内部组成
1. 片键
片键是分片簇用来将一个collection中的documents分成不同片的字段。
基数
MongoDB中的基数是指系统将数据分成块的能力。举个例子,将一个数据集看成一本通信录,其中存放着记录:
- 使用表示州的字段作为一个片键
州的字段值存储了一个给定地址文档中的州名。这个字段有一个较低的基数,因为所有拥有相同州字段值得的文档必须被分到同一个分片上,虽然一个特殊的州的块有可能超过最大的块大小。
因为州字段只有有限个值,所以MongoDB可能会不均匀的将数据分发到少数量的固定块上。这可能有一些影响:
■ 如果由于块本身的文档都有相同的片键,进而MongoDB不能将块进行分割,移动这些不可分割的块会消耗更惨的实际,并且更难使数据达到平衡。
■ 如果有一个固定的最大数量的块,你将不能使用更多的分片存储这个数据集。
- 使用邮编字段作为片键
当一个字段有大量可能的值时,就会有更高的基数。大量的用户可能有相同的片键,这样就使这个用户块无法进行分割。
在这些情况下,基数取决于数据。如果通信录中的记录在地理上很分散,则使用像邮编这样的值就能够满足需要;如果通信录中的记录在地理上很几种,则可能有一个更低的基数。
- 使用电话号码字段作为片键
电话号码有较高的基数,因为用户的这个字段都不太会相同,MongoDB能够分割成尽可能多的块。
高基数对确保分割数据是必要的,但是不能保证满足独立查询或者适当的写扩展。
(1) 写扩展
一些可能的片键能够使被利用于提高集群的写能力,而另一些则不能。考虑下面的使用默认的_id作为片键的例子,_id类型为ObjectID。
ObjectID在文档创建时计算出来,是一个对象的唯一标识。然而,这个值中最有意义的位用于表示时间戳,意味着它们定期的和可预期的增长。尽管这个值有很高的基数,当使用这个、任意的日期或者单调递增的数作为片键时,所有的插入操作会将数据存放到一个块中,也就是一个分片。结果就是,这个分片的写能力就是这个集群的写能力。
在低插入率时,或者大多数写操作都是分发到整个数据集上的更新操作,一个单调递增的片键都不会影响性能。通常,选择片键既要有高基数,也要能将写操作分发到整个集群。
通常情况下,一个计算出的片键要有一定的随机性,例如,包含一个文档中其它内容的密码散列值(如:MD5或SHA1),这会将写操作分发到整个集群。然而,随机片键不能典型的用于查询隔离,它是另一种重要的片键特征。
(2) 查询
Mongos为应用提供了一个操作分片集群的接口,并隐藏了其数据分区的复杂性。一个mongos接收到应用的查询后,使用config服务器的meta数据,将查询路由到包含相近数据的mongod实例上。Mongos成功的处理分片环境下的所有查询操作时,片键的选择会对查询的性能有很深的影响。
查询隔离
分片环境下最快的查询是mongos使用片键和从config服务器获得的集群meta信息将其路由到一个单独的分片上。如果查询不包含片键,则mongos会查询所有分片,等待它们的响应,然后将响应返回给应用。这种分发/收集查询会长时间运行。
如果查询包含了组合片键的第一部分,则mongos能够将查询直接路由到单一的或者小数量的分片上,这样提供了更好的性能。尽管查询的片键值存在不同的数据块上,mongos同样会将其直接路由到特定的分片上。
如何为一个数据集选择一个片键:
n 确定查询中最常见的被包含的字段
n 找出哪些操作是最依赖性能的
如果这个字段是低技术的,则可以增加第二个字段成为一个组合片键。数据使用组合分片更易分割。
排序
在分片系统中,mongos会对所有从分片处获得的排序查询结果做一个合并和排序操作。
(3) 操作和可靠性
在选择片键时最重要的考虑因素是:
- 确定MongoDB能够在分片中均匀的分布
- 能够在整个集群中扩展写操作
- 确定mongos能够将大多数请求隔离到一个指定的mongod上
此外:
- 每个分片都应该是一个副本集,如果其中一个mongod实例出错,副本集的成员会选举其它成员成为primary,并继续操作。然而,如果整个分片都不可达或者出错,则数据不可用。
- 如果片键允许mongos隔离大多数操作到一个单独的分片,如果单独的分片失败,则只会使部分数据不可用。
- 如果片键使每个操作所需要的数据分布到整个集群,则整个分片的错误会使整个集群的数据不可用。
本质上,这里所关心的可靠性就是简单的强度在选择片键时,使片键能够将请求隔离到一个单独的分片的重要性。
(4) 选择一个片键
对于大多数数据集来说,collection没有一个单独的、原始的key具有所有好的片键的属性。这些情况下,需要选择以下某种策略:
- 在应用层计算出一个更理想的片键,并存储到文档中,可能在_id字段中。
- 使用一个由2-3个文档中的值组合的片键,可以提供一个适合扩展写和隔离读的基数。
- 确定使用一个不够理想的片键所造成的影响,对你的用例无关紧要的:
■ 限制写的数量
■ 可预期的数据量
■ 查询模式和需求
- 新版本2.4使用了散列片键。使用散列片键,可以选择一个有高基数的字段,并对这个字段创建一个散列索引。MongoDB使用这个散列索引值作为片键,因此能够保证均匀的分布到整个分片集群中。
(5) 片键索引
所有分片的collections集合必须由一个以片键开头的索引。如果对一个没有文档和没有索引的集合进行分片,shardCollection命令会在片键上创建一个索引。如果集合已经包含文档,则在使用shardCollection之前必须创建一个合适的索引。
版本2.2的变化:片键上的索引不再需要与片键完全相同。索引可以使片键本身的索引,也可以使一个以片键为前缀的组合索引。这个索引不能是多键索引。
如果有一个名为people的集合,使用字段{ zipcode : 1 }进行分片,并且你想使用字段{ zipcode : 1, username : 1 }的索引替换它,则:
- 在{ zipcode : 1, username : 1 }上创建一个索引
db.people.ensureIndex( { zipcode : 1, username : 1 } );
- 当MongoDB创建完这个索引时,你可以安全的删除在{ zipcode : 1 }上已存在的索引。
db.people.dropIndex( { zipcode : 1, username : 1 } );
警告:片键上的索引不能是一个多键索引。
如上所说,在 { zipcode : 1, username : 1 } 上的索引只能替换 zipcode 上面的索引,如果 username 字段没有数组值。
注:多值索引( multikey index )和组合索引( compound index )的区别在于前者建立索引的某个列可能是一个数组值,而后者只是多个列组成的索引。
(6) 散列片键
散列片键使用一个指定的散列索引类型存储片键字段的散列值以对集群的数据进行分区。
当你使用一个单调递增,像ObjectId或者高基数但是不均匀分布的字段进行分片时,可以使用散列片键。
例子:一个ObjectId的散列索引将引起文档在集群中均匀的分布,因为连续的文档的散列值是完全不同的。
注:散列分片不支持打标签分片。
警告:散列索引在哈希前会将浮点型数转换成为 64 位整数。举个例子,一个散列索引会将一个字段中的 2.3,2.2 和 2.9 视为同一个值。为了避免这种冲突,不要再不能转换成 64 位整数的浮点型字段上使用散列索引,散列索引不支持大于 2^53 的浮点数。
2. 集群平衡器
平衡器子进程是负责将块均匀的重新在片间分配,并确保集群中的每个成员负责相同量的数据。
(1) 平衡的内部构成
平衡开始于一个任意的mongos实例。当一个平衡器进程是活跃的,负责mongos从配置数据库中的一个锁集合里获取修改一个文档的锁。
默认情况下,平衡器进程总是在运行。当一个集合的块数不均匀的分布在片上时,平衡器开始从有较多块的分片上迁移数据块到较少的分片上。平衡器持续的移动数据块,每次只移动一块,直到数据块在份上均匀的分布。
这些块自动的移动对数据分布十分重要,但它们也带来了一些带宽和负载上的瓶颈,这两者都会影响数据库的性能。最终,MongoDB试图将将迁移数据块的影响降到最低,只在块分布超过迁移门限时才会移动数据块。
迁移进程确保平衡期间的一致性和块的最大可用性:当MongoDB开始迁移一个块时,数据块开始向一个新服务器复制数据,并将新来的写操作保留下来。在块迁移后,块移出的mongod会将所有新的写操作发向移入的服务器。最后,mongos更新配置数据库中块的记录以反映块的新地址。
注:版本 2.0 的变化:在 MongoDB2.0 以前, mongos 实例间的时间差过大会导致分布式锁失败,这可能会导致数据丢失,特别是在差距 5 分钟以上。总是使用 NTP 来最小化时钟差距。
(2) 迁移门限
版本2.2的变化:下面的门限值最早出现的2.2,,在这个版本之前,平衡行为只在最多块的分片多于最少块的分片8块以上时才会开始。
为了最小化平衡行为带给集群的影响,平衡器在到达指定的门限值之前不会开始平衡行为。这些门限值在对应于最多块的分片和最少块的分片的不同块数。平衡器有以下门限值:
Number of Chunks | Migration Threshold |
Less than 20 | 2 |
21-80 | 4 |
Greater than 80 | 8 |
一旦平衡行为开始,平衡器在块差距小于2个前不会停止。
注:你可以限制平衡器使其只在具体的时间开始和结束。这个特殊的平衡窗口是针对于整个分片集群的所有 mongos 实例的时区的。
(3) 块大小
MongoDB中默认的块大小为64MB。
当块增长到指定块大小时,mongos实例会将块分为两块。当块在集群中分布变得不均匀时,最终会引起迁移。Mongos实例会发起一轮迁移将数据重新分布在集群中。
块大小是任意的,且必须解释如下:
- 小的块会一起更多的均匀分布,代价就是更高频率的迁移,这会增加查询路由层的开销。
- 大的块会减少迁移,从网络角度和查询路由层的方面来说是更有效的。大块可能会以潜在的更多不均匀的数据分布为代价。
对于大多数部署来说,需要防止频繁的和潜在的以牺牲均匀为代价的假的迁移,但是这个值是可配置的。在修改块大小时需要注意一下限制:
- 自动分配只会发生在插入或者更新已经存在的文档时;如果你降低了块大小,它将花费时间对所有的块进行分片。
- 分片不能被撤消。如果你增加了块大小,已存在的块必须通过插入或更新操作以增长到新的大小。
注:块范围包含了下边界,但不包含上边界。
(4) 片大小
默认情况下,MongoDB试图随着数据集的增加填满每个分片的可用磁盘空间。监控磁盘使用率是额外的性能标准,为了确定集群总是有能力存放额外的数据。
你可以为任何分片配置一个最大值,当你使用addShard命令的maxSize参数。这将会在映射值超过maxSize设置时防止平衡器将块迁移到分片上。
(5) 块迁移
MongoDB在集群中移动块使数据均匀的分布在片上。迁移可能是:
- 人工的。在这些迁移过程中,你必须制定你想移动的块和目标片。只有在初始化分片后才会进行人工的块迁移,通过大量的插入操作分配数据,或者如果集群不均匀。
- 自动的。当片间的块分布变得不均匀时,平衡器进程处理大多数的迁移。
所有的块迁移都遵守下面的流程:
- 平衡器进程向块的源分片发送moveChunk命令。在这个操作中,平衡器将目标分片的名字发给源分片。
- 源分片通过目标分片内部的moveChunk命令开始移动。
- 目标分片开始请求块中的文档,并开始接收这些块。
- 在接收完块中的最后一个文档后,目标分片开始一个同步进程,用来确保在目标分片进行迁移的过程中,源分片上所有块中的文档变化。
完全同步后,目标分片连接配置数据库,并更新集群元数据中的块位置信息。在完成这个操作后,一旦块上没有打开的游标,源分片将删除移动块的副本文档。
如果启动_secondaryThrottle设置,则会使平衡器等待复制到副本中。
(6) 探测到mongos实例的连接
如果你的应用必须探测,如果MongoDB实例连接到一个mongos,则使用isMaster命令。当客户端连接一个mongos时,isMaster会返回一个包含msg字段的文档,msg包含isdbgrid字符串。如:
{
"ismaster" : true,
"msg" : "isdbgrid",
"maxBsonObjectSize" : 16777216,
"ok" : 1
}
如果应用连接一个mongod,则返回的文档不包含isdbgrid字符串。
3. 分片集群的元数据(Metadata)
分片集群元数据包含在配置数据库中,并且包含分片集群分区数据集的信息。配数据库存放了块和其存放在集群中位置的关系。没有配置数据库,mongos实例无法将查询或写操作路由到集群中。
(1) 配置数据库
配置数据库包含分片配置的信息,并包含用于分片的collections集合的信息。
重要:在配置服务器上执行任何维护之前要备份配置数据库。
可以在mongo shell下使用下面的命令进入config数据库:
use config
通常,你不应该直接操作配置文件的内容。配置数据库包含下面的collections:
l chunks
l locks
l mongos
l settings
l shards
l version
(2) 配置服务器
配置服务器是特定的mongod实例,在配置数据库中保存了分片集群的元数据。一个分片集群运行一组包含三个的配置服务器,使用双向的提交过程,以确保强一致性和可靠性。配置服务器不能以副本集方式运行。
以测试为目的的集群部署一个配置服务器,但在生产环境下不推荐这样做。
所有的配置服务器在集群初始化设置时必须可用。每个mongos实例必须能够对config.version集合进行写操作。
(3) 配置服务器上的读写操作
配置服务器上的负载很小,因为每个mongos实例都保留着一个配置数据库的缓存。MongoDB只在写数据时向配置服务器:
- 发生一个存在的块的数据超过最大的块大小时,创建一个已存块的分裂。
- 在分片间迁移一个块
如果一个或两个配置实例不可用,集群的元数据将变为只读。它依然可能从分片上读写数据,但是在三个服务器可用之前,没有块进行迁移或者发生分裂。同时,配置服务器数据在下面的情况下只读:
- 一个新的mongos第一次启动,或者已存的mongos重启
- 在一个块迁移后,mongos实例使用新的元数据更新自身
如果三个配置服务器都不可达,只要你不重启mongos实例就能继续使用簇,知道配置服务器再次可达。如果重启了mongos实例,并且没有可达的配置服务器,mongos将不能将查询或者写操作指向集群。
因为配置数据对于整个集群中的数据来说比较小,活跃的数量相对较低,并且100%不会需要分片功能。因此,配置服务器的备份并不负责。配置服务器的备份非常严格,因为当你丢失所有的配置实例和数据时,整个集群将不可用。预防措施,确保配置服务器的可用和完整是非常必要的。