MongoDB 4.2 部署分片群集

it2024-01-02  67

分片群集

MongoDB分片群集由以下组件组成:

(一)shard:每个分片包含分片数据的子集。每个分片都可以部署为副本集。 (二)mongos:mongos充当查询路由器,在客户端应用程序和分片群集之间提供接口。从MongoDB 4.4开始,mongos可以支持 hedged reads 以最大程度地减少延迟。 (三)config servers:配置服务器存储集群的元数据和配置设置。

环境信息

这里准备三台虚拟机就可以了, 可以搭建“四套”副本集,各互为主从关系。 实际生产环境你可以根据成本投入或业务并发量评估下需要多少台资源配置。 实验环境参考如下:

栏目服务器一服务器二服务器三端口操作系统Ubuntu 16.04.3 LTSUbuntu 16.04.3 LTSUbuntu 16.04.3 LTS/IP地址192.168.0.1192.168.0.2192.168.0.3/主机名ubuntu1ubuntu2ubuntu3/mongos路由器mongos 节点一mongos 节点二mongos 节点三20000配置服务器 (副本集) config_rsconfig server 节点一config server 节点二config server 节点三20001分片集群一 (副本集) shard1_rsshard1_rs 节点一shard1_rs 节点二shard1_rs 节点三27017分片集群二 (副本集) shard2_rsshard2_rs 节点一shard2_rs 节点二shard2_rs 节点三27018分片集群三 (副本集) shard3_rsshard3_rs 节点一shard3_rs 节点二shard3_rs 节点三27019

主机名和配置 如果可能,请使用逻辑DNS主机名而不是IP地址,尤其是在配置副本集成员或分片群集成员时。逻辑DNS主机名的使用避免了由于IP地址更改而导致的配置更改。

安全 在生产环境中,分片群集应至少采用x.509安全性进行内部身份验证和客户端访问。

配置 在生产集群中,请确保数据是冗余的,并且您的系统具有高可用性。对于生产分片群集部署,请考虑以下事项: (一)将配置服务器部署为3个成员副本集 (二)将每个分片部署为3个成员副本集 (三)部署一个或多个mongos路由器

部署开始

在开始之前, 我们了解了需要安装4套副本集,副本集的安装可以使用一主两从,或者是一主一从,再加一下Arbiter仲裁节点(不存数据的节点)。

安装顺序: 分片副本集(共三套) --> 配置副本集 (一套) -> mongos路由器(三个)

接下来我们按照上面的顺序依次来安装部署分布集群:

步骤一:分片副本集

副本集的安装其实步骤一样的,只要安装了一套(三个节点),另外两套大同小异,只需要修改下配置和端口等,副本集的安装可以参考以下链接: MongoDB使用Arbiter搭建Replica Set

一些关键参数配置

sharding: clusterRole: shardsvr replication: replSetName: <replSetName> net: bindIp: localhost,<ip address>

安装完成后,检查分片副本集状态:

分片一: 副本集名称: shard1_rs root@ubuntu1:~# echo -n "rs.conf()" | /usr/local/mongodb/bin/mongo --authenticationDatabase admin --host 192.168.0.1 --port 27017 MongoDB shell version v4.2.2 connecting to: mongodb://192.168.0.1:27017/?authSource=admin&compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("efa7b74a-c2f4-44cf-a626-c116211b5392") } MongoDB server version: 4.2.2 { "_id" : "shard1_rs", "version" : 1, "protocolVersion" : NumberLong(1), "writeConcernMajorityJournalDefault" : true, "members" : [ { "_id" : 0, "host" : "192.168.0.1:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "192.168.0.2:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "192.168.0.3:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : -1, "catchUpTakeoverDelayMillis" : 30000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("5f92930f55849a7a702d7d16") } } 分片二:副本集名称: shard2_rs root@ubuntu1:~# echo -n "rs.conf()" | /usr/local/mongodb/bin/mongo --authenticationDatabase admin --host 192.168.0.1 --port 27018 MongoDB shell version v4.2.2 connecting to: mongodb://192.168.0.1:27018/?authSource=admin&compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("6319fc25-53ed-4872-a533-bd70d6decc7a") } MongoDB server version: 4.2.2 { "_id" : "shard2_rs", "version" : 1, "protocolVersion" : NumberLong(1), "writeConcernMajorityJournalDefault" : true, "members" : [ { "_id" : 0, "host" : "192.168.0.1:27018", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "192.168.0.2:27018", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "192.168.0.3:27018", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : -1, "catchUpTakeoverDelayMillis" : 30000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("5f9295715df0f1454709997d") } } bye 分片三:副本集名称: shard3_rs root@ubuntu1:~# echo -n "rs.conf()" | /usr/local/mongodb/bin/mongo --authenticationDatabase admin --host 192.168.0.1 --port 27019 MongoDB shell version v4.2.2 connecting to: mongodb://192.168.0.1:27019/?authSource=admin&compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("4bd0f60e-69f2-4625-b45c-1ce661c57e44") } MongoDB server version: 4.2.2 { "_id" : "shard3_rs", "version" : 1, "protocolVersion" : NumberLong(1), "writeConcernMajorityJournalDefault" : true, "members" : [ { "_id" : 0, "host" : "192.168.0.1:27019", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "192.168.0.2:27019", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "192.168.0.3:27019", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : -1, "catchUpTakeoverDelayMillis" : 30000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("5f92961e06bffa61b967a20c") } } bye

步骤二: 配置服务器:

副本集名称: config_rs 从3.4开始,必须将配置服务器部署为副本集。mongod不再支持将已弃用的镜像实例用作配置服务器 注意配置服务器,比较特殊,在初始化的时候,要加一个参数:configsvr: true

rs.initiate( { _id: "config_rs", configsvr: true, members: [ { _id : 0, host : "192.168.0.1:20001" }, { _id : 1, host : "192.168.0.2:20001" }, { _id : 2, host : "192.168.0.3:20001" } ] } )

检查副本集配置

root@ubuntu1:~# echo -n "rs.conf()" | /usr/local/mongodb/bin/mongo --authenticationDatabase admin --host 192.168.0.1 --port 20001 MongoDB shell version v4.2.2 connecting to: mongodb://192.168.0.1:20001/?authSource=admin&compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("71ba5ae0-fb47-4e47-a8e9-29e67b4aac61") } MongoDB server version: 4.2.2 { "_id" : "config_rs", "version" : 1, "protocolVersion" : NumberLong(1), "writeConcernMajorityJournalDefault" : true, "members" : [ { "_id" : 0, "host" : "192.168.0.1:20001", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "192.168.0.2:20001", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "192.168.0.3:20001", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : -1, "catchUpTakeoverDelayMillis" : 30000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("5f929a27e80f2e026dcc3029") } } bye

步骤三: mongos路由器

mongos实例路由查询并将操作写入分片群集中的分片。mongos从应用程序的角度来看,它提供了分片群集的唯一接口。应用程序永远不会与分片直接连接或通信。

用mongo shell 接到后 mongos,继续执行下一个步骤,将分片添加到集群。

将分片添加到群集中 在mongo连接到的Shell中 mongos,使用sh.addShard()方法将每个分片添加到集群。

root@ubuntu1:~# /usr/local/mongodb/bin/mongo --host localhost --port 20000 MongoDB shell version v4.2.2 connecting to: mongodb://localhost:20000/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("8b5d3c43-c14b-4a85-b87b-96210258e231") } MongoDB server version: 4.2.2 mongos> mongos> mongos> use admin switched to db admin ### 把 “路由器” 和 “分片副本集” 关联起来 mongos> sh.addShard("shard1_rs/192.168.0.1:27017,192.168.0.2:27017,192.168.0.3:27017") { "shardAdded" : "shard1_rs", "ok" : 1, "operationTime" : Timestamp(1603783946, 8), "$clusterTime" : { "clusterTime" : Timestamp(1603783946, 8), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } mongos> mongos> mongos> sh.addShard("shard2_rs/192.168.0.1:27018,192.168.0.2:27018,192.168.0.3:27018") { "shardAdded" : "shard2_rs", "ok" : 1, "operationTime" : Timestamp(1603783955, 7), "$clusterTime" : { "clusterTime" : Timestamp(1603783955, 7), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } mongos> mongos> mongos> sh.addShard("shard3_rs/192.168.0.1:27019,192.168.0.2:27019,192.168.0.3:27019") { "shardAdded" : "shard3_rs", "ok" : 1, "operationTime" : Timestamp(1603783959, 7), "$clusterTime" : { "clusterTime" : Timestamp(1603783959, 7), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } ### 查看 分片集群 的状态 ### mongos> sh.status() --- Sharding Status --- sharding version: { "_id" : 1, "minCompatibleVersion" : 5, "currentVersion" : 6, "clusterId" : ObjectId("5f92a3e402361de9898f4aa7") } shards: { "_id" : "shard1_rs", "host" : "shard1_rs/192.168.0.1:27017,192.168.0.2:27017,192.168.0.3:27017", "state" : 1 } { "_id" : "shard2_rs", "host" : "shard2_rs/192.168.0.1:27018,192.168.0.2:27018,192.168.0.3:27018", "state" : 1 } { "_id" : "shard3_rs", "host" : "shard3_rs/192.168.0.1:27019,192.168.0.2:27019,192.168.0.3:27019", "state" : 1 } active mongoses: "4.2.2" : 3 autosplit: Currently enabled: yes balancer: Currently enabled: yes Currently running: no Failed balancer rounds in last 5 attempts: 0 Migration Results for the last 24 hours: No recent migrations databases: { "_id" : "config", "primary" : "config", "partitioned" : true }

测试

连接在mongos上,准备让指定的数据库、指定的集合分片生效。

启用数据库分片

在分片集合之前,必须为集合的数据库启用分片。对数据库启用分片并不会重新分发数据,但可以在该数据库中分片集合。

在mongo连接到的外壳程序上 mongos,使用sh.enableSharding()方法在目标数据库上启用分片。在数据库上启用分片可以在数据库中分片集合。

MongoDB提供了两种分片收集策略:

散列分片使用单个字段的 哈希索引作为 分片键,以跨分片群集对数据进行分区。

sh.shardCollection("<database>.<collection>", { <shard key field> : "hashed" } )

基于范围的分片可以使用多个字段作为分片键,并将数据划分为由分片键值确定的连续范围。

sh.shardCollection("<database>.<collection>", { <shard key field> : 1, ... } )

这里我们使用 hashed的分片策略:

mongos> show dbs; admin 0.000GB config 0.001GB mongos> mongos> use test; switched to db test mongos> mongos> sh.enableSharding("test") { "ok" : 1, "operationTime" : Timestamp(1603785131, 3), "$clusterTime" : { "clusterTime" : Timestamp(1603785131, 3), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } mongos> mongos> mongos> mongos> sh.shardCollection("test.table1", { id : "hashed" } ) { "collectionsharded" : "test.table1", "collectionUUID" : UUID("02a3a0f5-e462-4e0a-ac05-0a1c09a5f1bc"), "ok" : 1, "operationTime" : Timestamp(1603785146, 44), "$clusterTime" : { "clusterTime" : Timestamp(1603785146, 44), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } mongos>

压测插入数据

mongos> for (var i = 1; i <= 5000; i++){db.table1.save({id:i,"test":"test"});} WriteResult({ "nInserted" : 1 }) mongos>

查询分片集群状态,返回类似于以下原型的文档:

mongos> db.table1.stats(); { "sharded" : true, "capped" : false, "wiredTiger" : { ...... }, "ns" : "test.table1", "count" : 5000, "size" : 245000, "storageSize" : 122880, "totalIndexSize" : 245760, "indexSizes" : { "_id_" : 98304, "id_hashed" : 147456 }, "avgObjSize" : 49, "maxSize" : NumberLong(0), "nindexes" : 2, "nchunks" : 6, "shards" : { "shard2_rs" : { "ns" : "test.table1", "size" : 82516, "count" : 1684, "avgObjSize" : 49, "storageSize" : 40960, "capped" : false, "wiredTiger" : { ...... }, ...... }, "shard3_rs" : { "ns" : "test.table1", "size" : 80948, "count" : 1652, "avgObjSize" : 49, "storageSize" : 40960, "capped" : false, "wiredTiger" : { ...... }, ...... }, "shard1_rs" : { "ns" : "test.table1", "size" : 81536, "count" : 1664, "avgObjSize" : 49, "storageSize" : 40960, "capped" : false, "wiredTiger" : { ...... }, ...... } }, "ok" : 1, "operationTime" : Timestamp(1603785504, 1), "$clusterTime" : { "clusterTime" : Timestamp(1603785507, 3), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }

总结

分片是一种用于在多台计算机之间分配数据的方法。MongoDB使用分片来支持具有非常大的数据集和高吞吐量操作的部署。

具有大数据集或高吞吐量应用程序的数据库系统可能会挑战单个服务器的容量。例如,高查询率可能会耗尽服务器的CPU容量。大于系统RAM的工作集大小会增加磁盘驱动器的I / O容量。

解决系统增长的方法有两种:垂直缩放和水平缩放。

垂直扩展涉及增加单个服务器的容量,例如使用功能更强大的CPU,添加更多RAM或增加存储空间量。可用技术的局限性可能会限制一台计算机对于给定的工作负载没有足够的功能。此外,基于云的提供程序具有基于可用硬件配置的严格上限。垂直缩放有一个实际的最大值。

水平扩展涉及划分系统数据集并在多台服务器上加载,并添加其他服务器以根据需要增加容量。虽然单台计算机的整体速度或容量可能不高,但是每台计算机只能处理一部分整体工作负载,因此与单台高速大容量服务器相比,可能提供更高的效率。扩展部署的容量仅需要根据需要添加其他服务器,这可以比单台机器的高端硬件降低总体成本。折衷方案是增加基础结构和部署维护的复杂性。

最新回复(0)