在分片群集上建立滚动索引

    在本页面

    索引构建会影响分片集群的性能。默认情况下,MongoDB 4.4及以后版本在所有承载数据的复制集成员上同时构建索引。基于分片集群的索引仅发生在那些包含被索引的集合数据的分片上。对于不能容忍由于索引构建而导致性能下降的工作负载,可以考虑使用以下过程以滚动方式构建索引。

    滚动索引构建一次最多取出一个碎片复制集成员(从辅助成员开始),并在该成员上作为一个独立的成员构建索引。构建滚动索引需要每个碎片至少进行一次复制集选择。

    注意事项

    唯一索引

    要使用以下过程创建唯一索引,必须在此过程中停止对集合的所有写操作。

    如果在此过程中无法停止对集合的所有写操作,请不要使用此页面上的过程。相反,可以通过db.collection.createIndex()在分片mongos群集上发出来在集合上构建唯一索引。

    Oplog大小

    确保您的oplog足够大,以允许索引或重新索引操作完成,而不会落后太多而无法跟上。参见oplog sizing文档了解更多信息。

    前提条件

    • 用于构建唯一索引

      1.要使用以下过程创建唯一索引,必须在索引生成期间停止对集合的所有写操作。否则,复制集成员之间的数据可能会不一致。如果 不能停止对集合的所有写操作,请不要使用以下过程创建唯一索引。

      警告

      如果不能停止对集合的所有写操作,请不要使用以下过程创建唯一索引。

      2.在创建索引之前,验证集合中没有文档违反索引约束。如果一个集合分布在多个切片上,而一个切片中包含有重复文档的块,那么 创建索引操作可能在没有重复的切片上成功,但在有重复的切片上失败。为了避免在多个碎片之间留下不一致的索引,可以从 mongos中发出db.collection.dropIndex()来从集合中删除索引。

      程序

    重要

    以下以滚动方式构建索引的过程适用于分片集群部署,而不适用于复制集部署。关于复制集的过程,请参见复制集上的滚动索引构建。

    A. 停止平衡器

    mongoshell连接到分片mongos 群集中的实例,然后运行sh.stopBalancer()以禁用平衡器:

    1. sh.stopBalancer()

    注意

    如果迁移正在进行中,系统将在停止平衡器之前完成迁移。

    要验证均衡器被禁用,运行sh.getBalancerState(),如果均衡器被禁用,将返回false:

    1. sh.getBalancerState()

    B. 确定集合的分布

    mongoshell连接程序 mongos,刷新缓存的路由表, mongos以免返回该集合的陈旧分发信息。刷新后,运行 db.collection.getShardDistribution()要构建索引的集合。

    例如,如果您想在test 数据库的records集合上使用升序索引:

    1. db.adminCommand( { flushRouterConfig: "test.records" } );
    2. db.records.getShardDistribution();

    该方法输出切分分布。例如,考虑一个分片集群,有3个分片‘ shardA ‘‘ shardB ‘‘ shardC ‘‘ db.collection.getShardDistribution() ‘返回以下结果:

    1. Shard shardA at shardA/s1-mongo1.example.net:27018,s1-mongo2.example.net:27018,s1-mongo3.example.net:27018
    2. data : 1KiB docs : 50 chunks : 1
    3. estimated data per chunk : 1KiB
    4. estimated docs per chunk : 50
    5. Shard shardC at shardC/s3-mongo1.example.net:27018,s3-mongo2.example.net:27018,s3-mongo3.example.net:27018
    6. data : 1KiB docs : 50 chunks : 1
    7. estimated data per chunk : 1KiB
    8. estimated docs per chunk : 50
    9. Totals
    10. data : 3KiB docs : 100 chunks : 2
    11. Shard shardA contains 50% data, 50% docs in cluster, avg obj size on shard : 40B
    12. Shard shardC contains 50% data, 50% docs in cluster, avg obj size on shard : 40B

    从输出中,您只为test构建索引。记录在shardAshardC

    C. 在包含集合块的碎片上构建索引

    对于包含集合块的每个分片,遵循以下过程在分片上构建索引。

    C1. 停止一个辅助设备并独立重启

    对于受影响的分片,停止mongod与其辅助节点之一相关联的过程。在进行以下配置更新后重新启动:

    • 配置文件

    如果您正在使用配置文件,请进行以下配置更新:

    例如,对于一个分片复制集成员,更新后的配置文件将包括如下示例所示的内容:

    1. net:
    2. bindIp: localhost,<hostname(s)|ip address(es)>
    3. port: 27218
    4. port: 27018
    5. replication:
    6. replSetName: shardA
    7. sharding:
    8. clusterRole: shardsvr
    9. setParameter:
    10. skipShardingConfigurationChecks: true
    11. disableLogicalSessionCacheRefresh: true

    并重新启动:

    1. mongod --config <path/To/ConfigFile>

    其他设置(例如‘ storage.dbPath ‘等)保持不变。

    • 命令行选项

    如果使用命令行选项,请进行以下配置更新:

    例如,重新启动不带--replSet--shardsvr选项的分片副本集成员。指定新的端口号,并将skipShardingConfigurationChecksdisableLogicalSessionCacheRefresh参数都设置 为true:

    1. mongod --port 27218 --setParameter skipShardingConfigurationChecks=true --setParameter disableLogicalSessionCacheRefresh=true

    其他设置(例如--dbpath等)保持不变。

    C2. 建立索引

    直接连接到‘ mongod ‘实例作为一个独立的运行在新的端口上,并为这个实例创建新的索引。

    例如,将mongoshell连接到实例,并使用db.collection.createIndex()方法usernamerecords 集合的字段上创建升序索引:

    1. db.records.createIndex( { username: 1 } )

    C3. 重新启动程序 mongod 作为复制集成员

    当索引构建完成时,关闭‘ mongod ‘实例。撤销作为独立启动时所做的配置更改,以返回原始配置并重新启动。

    重要

    一定要删除‘ skipShardingConfigurationChecks ‘参数和’ disableLogicalSessionCacheRefresh ‘参数。

    例如,重新启动你的复制集分片成员:

    • 配置文件

    如果您正在使用配置文件,请进行以下配置更新:

    1. net:
    2. bindIp: localhost,<hostname(s)|ip address(es)>
    3. port: 27018
    4. replication:
    5. replSetName: shardA
    6. sharding:
    7. clusterRole: shardsvr

    其他设置(例如‘ storage.dbPath ‘等)保持不变。

    并重新启动:

    1. mongod --config <path/To/ConfigFile>
    • 命令行选项

    如果使用命令行选项,请进行以下配置更新:

    例如:

    1. mongod --port 27018 --replSet shardA --shardsvr

    其他设置(例如--dbpath等)保持不变。

    C4. 对分片的其他次要数据重复此过程

    一旦该成员赶上了集合中的其他成员,就对分片中剩余的次要成员一次重复这个过程:

    1. C1.停止一台备用服务器并独立启动
    2. C2.建立索引
    3. C3.重新启动程序mongod作为副本集成员

      C5. 在主服务器上构建索引

    当分片的所有辅助数据库都具有新索引时,请降低分片的主数据库,使用上述步骤以独立方式重新启动它,然后在前一个主数据库上建立索引:

    1. 使用外壳程序中的rs.stepDown()方法mongo降低主数据库的性能。成功降级后,当前的主节点将成为辅助节点,复制集成员将选择新的主节点。
    2. C1.停止一台备用服务器并独立启动
    3. C2.建立索引
    4. C3.重新启动程序mongod作为副本集成员

      D. 对其他受影响的分片重复此操作

    在为切分构建完索引之后,重复C]。在包含集合块的切分上为其他受影响的切分构建索引

    一旦完成了为分片建立索引,请重复步骤 C .在包含集合块的碎片上构建索引为其他受影响的分片建立索引

    E.重新启动平衡器

    为受影响的分片完成滚动索引构建后,重新启动平衡器。

    mongoshell连接到分片mongos 群集中的实例,然后运行sh.startBalancer()

    1. sh.startBalancer()

    附加信息

    如果在包含集合块的每个分片上没有完全相同的索引(包括索引选项),则分片集合具有不一致的索引。虽然在正常操作中不应该出现索引不一致的情况,但也会出现索引不一致的情况,例如:

    • 当用户正在创建一个索引,一个“唯一”的关键约束和一个分片包含块与重复的文档。在这种情况下,创建索引操作可能在没有重复的分片上成功,但在有重复的切分上失败。
    • 当用户以滚动方式在多个切片之间创建索引,但要么未能为关联的切片建立索引,要么不正确地建立了不同规格的索引。

    从MongoDB 4.4(和4.2.6)开始,配置服务器服务器会定期检查分片集合中各分片之间的索引不一致。要配置这些定期检查,请参阅 enableShardedIndexConsistencyCheckshardedIndexConsistencyCheckIntervalMS

    当在配置服务器主服务器上运行时,该命令serverStatus返回该字段 shardedIndexConsistency以报告索引不一致情况。

    要检查分片集合是否具有不一致的索引,请参阅 查找分片中的不一致索引

    参见

    原文 - Rolling Index Builds on Sharded Clusters