304、Sharding分片环境部署(详述)

Sharding分片环境部署(详述)

前言:

Sharding是一种可以将数据分发到不同主机上的方法,主要是用于解决MongoDB巨大数据量和高吞吐量的问题。我们一开始使用单机,但是为了安全和一些读写分离改为副本集,但是业务增长快速的情况下,可能遇到很多性能上的问题;例如巨大的查询频率可能会耗尽所有CPU资源,高吞吐量可能使得I/O成为瓶颈。对于这些问题其实我们有两种方案:垂直扩展 和 水平扩展

  • 垂直扩展:说白了就是增加单台机器的资源,用更多CPU,更大内存,使用SSD硬盘;但是硬件技术上的局限性可能导致最后还是无法满足你的业务需求
  • 水平扩展:通过分离数据集和多服务器负载来实现,按需添加额外服务器可以更好的解决大数据量和大吞吐量的问题;
    而分片就是为了实现水平扩展而生的集群架构

架构

Sharding分片架构一般由3部分组成:

  • mongos server:路由节点,作为一个查询路由而存在,承接client端与分片服务器之前的数据传输(或者叫分发)
  • config server: 配置节点,存储集群的配置信息,以及各个分片数据的元数据信息,3.2以后必须以replica set形式部署(简称CSRS)
  • shard server:分片节点,实际存储数据的服务器,每个分片节点根据片键的选择只持有集合的一部分数据。
    官方架构图:

部署架构:
config server:

  • 10.67.37.45:38001 (primary)
  • 10.67.37.46:38001 (secondary)
  • 10.67.37.47:38001 (secondary)

mongos server:

  • 10.67.37.45:37000
  • 10.67.37.46:37000
  • 10.67.37.47:37000

shard1:

  • 10.67.37.45:37001(primary)
  • 10.67.37.46:37001 (secondary)
  • 10.67.37.47:37001 (secondary)

shard2:

  • 10.67.37.45:37002 (secondary)
  • 10.67.37.46:37002 (primary)
  • 10.67.37.47:37002 (secondary)

shard3:

  • 10.67.37.45:37003 (secondary)
  • 10.67.37.46:37003 (secondary)
  • 10.67.37.47:37003 (primary)

部署步骤:

信息:

  • OS: Redhat 7.6
  • MongoDB version: mongod 4.0
  • CPU: 8
  • RAM: 48G
    注:由于是测试环境,机器数量受限,所以上述15个节点服务均部署在3台服务器上,生产环境的话可以根据自己情况部署;
    另:因为本教程部署的是开启认证模式的cluster sharding架构,所以要求cluster中的所有成员必须使用一致的内部认证机制和设定;
1.部署配置服务节点config server复制集
1.1 创建相应目录

(在10.67.37.45上执行下述操作)

[mongo@wqdcsrv090 shard]$ cd /data/johnny/shard
[mongo@wqdcsrv091 shard]$ mkdir cfg                           --配置文件存放目录
[mongo@wqdcsrv090 shard]$ mkdir -p configsvr/dbdata/    --数据目录
[mongo@wqdcsrv090 shard]$ mkdir -p configsvr/logs/      --日志目录
[mongo@wqdcsrv090 shard]$ mkdir -p configsvr/keyfile/   --keyfile文件目录
[mongo@wqdcsrv090 shard]$ mkdir -p configsvr/pid/       --进程id存放目录
1.2 配置启动文件

编辑config server的配置文件/data/johnny/shard/cfg/config.cnf,内容如下
除了参数bindIp需要根据不同服务器IP地址修改,其他不变。

storage:
   dbPath: /data/johnny/shard/configsvr/dbdata
   journal:
      enabled: true
      commitIntervalMs: 50
   directoryPerDB: true
   engine: wiredTiger
   wiredTiger:
      engineConfig:
         directoryForIndexes: true
systemLog:
   quiet: false
   path: /data/johnny/shard/configsvr/logs/configsvr.log
   destination: file
   logAppend: true
   logRotate: rename
processManagement:
    fork: true
    pidFilePath: /data/johnny/shard/configsvr/pid/configsvr.pid
net:
   port: 38001
   maxIncomingConnections: 1000
   wireObjectCheck: true
   bindIp: localhost,10.67.37.45            #注意此参数需要根据不同的服务器IP进行修改
security:
   keyFile: /data/johnny/shard/configsvr/keyfile/security
replication:
   oplogSizeMB: 3072
   replSetName: configsvr
sharding:
   clusterRole: configsvr

注:如果不太清楚上述参数的意义,请参考官方文档启动参数说明

1.3 创建keyfile文件
[mongo@wqdcsrv090 keyfile]$ pwd
/data/johnny/shard/configsvr/keyfile
[mongo@wqdcsrv090 keyfile]$ openssl rand -base64 756 > security
[mongo@wqdcsrv090 keyfile]$ chmod 400 security
[mongo@wqdcsrv090 keyfile]$ ls -l
total 4
-r-------- 1 mongo mongo 1024 Sep 25 15:53 security

注:分片架构中所有的节点必须使用相同内容的security文件,3.6版本后文件权限注意是400,之前版本是600;

1.4 启动config server进程
[mongo@wqdcsrv090 shard]$ /apps/mongodb4.0/bin/mongod -f /data/johnny/shard/cfg/config.cnf
about to fork child process, waiting until server is ready for connections.
forked process: 5652
child process started successfully, parent exiting

出现上述信息表示启动成功。

1.5 部署其他config server

请根据上述1.1 ~ 1.4步骤部署其他两个config server的节点(10.67.37.46:38001, 10.67.37.47:38001),务必注意security文件就不需要重新创建了直接copy到其他服务器即可;

1.6 初始化config server复制集

待上述3个config server节点都启动成功后,进行复制集初始化操作,请使用localhost接口登录任意一台38001端口实例(因为已经开启了keyfile内部认证,所以在没有创建任何管理员用户之前只能通过localhost接口特性来登录)

[mongo@wqdcsrv090 shard]$ /apps/mongodb4.0/bin/mongo localhost:38001/admin
MongoDB shell version v4.0.10
connecting to: mongodb://localhost:38001/admin?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("6ed4375b-a95c-47e6-8a03-f0ae04328b31") }
MongoDB server version: 4.0.10
> rs.initiate(
   {
     _id: "configsvr",
     configsvr: true,
     members: [
       { _id : 0, host : "10.67.37.45:38001",priority:2 },
       { _id : 1, host : "10.67.37.46:38001" },
       { _id : 2, host : "10.67.37.47:38001" }
     ]
   }
 )
configsvr:PRIMARY>

待10秒钟之后,将会选举出primary节点,此时config server的复制集部署完毕,可以通过命令rs.status()查看集群状态

2.部署分片服务节点shard

部署分片shard1
(在10.67.37.45上执行下述操作)

2.1 创建shard1文件目录
[mongo@wqdcsrv090 shard]$ cd /data/johnny/shard
[mongo@wqdcsrv090 shard]$ mkdir -p shard1/dbdata
[mongo@wqdcsrv090 shard]$ mkdir -p shard1/logs
[mongo@wqdcsrv090 shard]$ mkdir -p shard1/keyfile
[mongo@wqdcsrv090 shard]$ mkdir -p shard1/pid
2.2 shard1配置文件

配置shard2,shard3时注意修改文件目录名称,以及端口号

storage:
   dbPath: /data/johnny/shard/shard1/dbdata
   journal:
      enabled: true
      commitIntervalMs: 50
   directoryPerDB: true
   engine: wiredTiger
   wiredTiger:
      engineConfig:
         cacheSizeGB: 2
         directoryForIndexes: true
systemLog:
   quiet: false
   path: /data/johnny/shard/shard1/logs/shard1.log
   destination: file
   logAppend: true
   logRotate: rename
processManagement:
    fork: true
    pidFilePath: /data/johnny/shard/shard1/pid/shard1.pid
net:
   port: 37001
   maxIncomingConnections: 1000
   wireObjectCheck: true
   bindIp: localhost,10.67.37.45
security:
   keyFile: /data/johnny/shard/shard1/keyfile/security
replication:
   oplogSizeMB: 3072
   replSetName: shard1
sharding:
   clusterRole: shardsvr
2.3 启动shard1的mongod进程
[mongo@wqdcsrv090 shard]$ /apps/mongodb4.0/bin/mongod -f /data/johnny/shard/cfg/shard1.cnf
2.4 启动分片shard1的其他节点:

请根据上述2.1 ~ 2.3步骤部署shard1分片的其他两个节点(10.67.37.46:37001, 10.67.37.47:37001),务必注意security文件就不需要重新创建了直接copy到其他服务器即可;

2.5 初始化分片shard1的复制集

待上述shard1分片的3个server节点都启动成功后,进行shard1分片复制集的初始化操作
登录10.67.37.45上的37001实例

[mongo@wqdcsrv090 shard]$ /apps/mongodb4.0/bin/mongo localhost:37001/admin
MongoDB shell version v4.0.10
connecting to: mongodb://localhost:37001/admin?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("3f0b2538-c52a-4a1c-a601-92c44fb7a902") }
MongoDB server version: 4.0.10
> rs.initiate(
...   {
...     _id: "shard1",
...     members: [
...       { _id : 0, host : "10.67.37.45:37001",priority:2 },
...       { _id : 1, host : "10.67.37.46:37001" },
...       { _id : 2, host : "10.67.37.47:37001" }
...     ]
...   }
... )
{ "ok" : 1 }
shard1:PRIMARY>

可以通过命令rs.status查看复制集各个成员状态, 这里我们使用priority:2将10.67.37.45:37001节点优先指定为primary角色;

2.6 创建分片shard1的本地管理员

登录到主节点的admin库,利用localhost exception特性即 使用mongo -h localhost37001 登录数据库:,创建第一个用户(此用户至少包含userAdminAnyDatabase权限),此用户是为了对于以后单独维护分片复制集而用,请不要使用此用户单独登录某个分片进行数据的DML操作;

shard1:PRIMARY> db.createUser({
user:"dba",
pwd:"admin123",
roles:[{role:"root",db:"admin"}]
})
2.7 部署其他分片shard2,shard3

请根据步骤2.1 ~ 2.6, 部署分片shard2,shard3,注意在部署时修改对应复制集名称、目录名称等。
对于其他两个分片复制集,建议根据如下初始化方案:
shard2:

rs.initiate(
   {
     _id: "shard2",
     members: [
       { _id : 0, host : "10.67.37.45:37002" },
       { _id : 1, host : "10.67.37.46:37002",priority:2 },
       { _id : 2, host : "10.67.37.47:37002" }
     ]
   }
 )

shard3:

rs.initiate(
   {
     _id: "shard3",
     members: [
       { _id : 0, host : "10.67.37.45:37003" },
       { _id : 1, host : "10.67.37.46:37003" },
       { _id : 2, host : "10.67.37.47:37003",priority:2 }
     ]
   }
 )
  • shard2: 10.67.37.46:37002(primary)
  • shard3: 10.67.37.47:37003(primary)
    注:不同分片初始化时,请注意修改_id的名称,否则会报错;
3. 部署路由服务节点mongos
3.1 创建目录

mongos服务都是单独运行的,不需要也不能配置成复制集形式,但是为了路由节点的高可用性,最好建立多个mongos节点
如下操作在10.67.37.45上操作

[mongo@wqdcsrv090 shard]$ cd /data/johnny/shard
[mongo@wqdcsrv090 shard]$ mkdir -p mongos/logs
[mongo@wqdcsrv090 shard]$ mkdir -p mongos/keyfile
[mongo@wqdcsrv090 shard]$ mkdir -p mongos/pid

注:因为mongos服务不需要存储数据,所以我们不需要创建dbdata数据目录

3.2 mongos路由服务的配置文件
systemLog:
   quiet: false
   path: /data/johnny/shard/mongos/logs/mongos.log
   destination: file
   logAppend: true
   logRotate: rename
processManagement:
    fork: true
    pidFilePath: /data/johnny/shard/mongos/pid/mongos.pid
net:
   port: 37000
   maxIncomingConnections: 3000
   wireObjectCheck: true
   bindIp: localhost,10.67.37.45
security:
   keyFile: /data/johnny/shard/mongos/keyfile/security
sharding:
   configDB: configsvr/10.67.37.45:38001,10.67.37.46:38001,10.67.37.47:38001

注:configDB参数这里填写的是config server复制集的信息,configsvr是复制集名称;
因为mongos不存放数据,所以不需要storage的相关参数。

3.3 启动mongos进程
[mongo@wqdcsrv090 cfg]$ /apps/mongodb4.0/bin/mongos -f /data/johnny/shard/cfg/mongos.cnf
about to fork child process, waiting until server is ready for connections.
forked process: 25980
child process started successfully, parent exiting

注:路由服务进程启动时,使用的是mongos程序,而不是mongod,这里一定要注意;如果这里无法启动,请注意观看log日志文件;

3.4 部署其他mongos节点

请使用步骤3.1 ~ 3.3在其他两个服务器(10.67.37.46,10.67.37.47)上部署mongos进程,以提供路由的HA高可用;

3.5 创建cluster集群的管理员账号

注意,这次创建的管理员与上面创建的分片local账号dba不一样,下面要创建的账号是会存放到config server上,而并非在各个分片上;此账号是用来管理整个cluster集群的。

[mongo@wqdcsrv090 cfg]$ /apps/mongodb4.0/bin/mongo localhost:37000/admin
MongoDB shell version v4.0.10
connecting to: mongodb://localhost:37000/admin?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("2182380b-d614-42a0-8f9f-b1f760f2cc1e") }
MongoDB server version: 4.0.10
mongos> db.createUser({
... user:"root",
... pwd:"admin123",
... roles:[{role:"root",db:"admin"}]
... })
mongos>
4. 添加分片

虽然上述我们部署好了shard1,shard2,shard3的复制集架构,但是其实并没有加入到cluster集群中,我们需要通过mongos将各个分片节点加入到集群中;使用刚才创建的集群管理账号root,登录到mongos的实例(37000端口)

[mongo@wqdcsrv090 cfg]$ /apps/mongodb4.0/bin/mongo localhost:37000/admin -uroot -padmin123
MongoDB shell version v4.0.10
connecting to: mongodb://localhost:37000/admin?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("a2d6d30d-c0e3-4d18-be1f-22bdd9f118a6") }
MongoDB server version: 4.0.10
mongos> sh.addShard("shard1/10.67.37.45:37001,10.67.37.46:37001,10.67.37.47:37001")         //添加分片shard1
{
        "shardAdded" : "shard1",
        "ok" : 1,           //表示添加分片成功
        "operationTime" : Timestamp(1569479300, 8),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1569479300, 8),
                "signature" : {
                        "hash" : BinData(0,"soCeJXEgzeQlO8J7nJjGM3CjGcM="),
                        "keyId" : NumberLong("6740522498976120853")
                }
        }
}
mongos> sh.addShard("shard2/10.67.37.45:37002,10.67.37.46:37002,10.67.37.47:37002")             //添加分片shard2
mongos> sh.addShard("shard3/10.67.37.45:37003,10.67.37.46:37003,10.67.37.47:37003")             //添加分片shard3

当你完成添加分片后可以通过命令sh.status()查看集群状态

mongos> sh.status()
--- Sharding Status ---
  sharding version: {       //cluster配置的基本信息
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,       //当前config server的版本
        "clusterId" : ObjectId("5d8b2580cb888b1fa65f6ad6")  //整个cluster集群的一个标识符id
  }
  shards:   //当前各个分片的成员,state:1表示此分片可以被识别,否则为0
        {  "_id" : "shard1",  "host" : "shard1/10.67.37.45:37001,10.67.37.46:37001,10.67.37.47:37001",  "state" : 1 }
        {  "_id" : "shard2",  "host" : "shard2/10.67.37.45:37002,10.67.37.46:37002,10.67.37.47:37002",  "state" : 1 }
        {  "_id" : "shard3",  "host" : "shard3/10.67.37.45:37003,10.67.37.46:37003,10.67.37.47:37003",  "state" : 1 }
  active mongoses:
        "4.0.10" : 3        //表示当前活跃的mongos数量(最近60秒内ping的结果)
  autosplit:    //自动分裂是否开启
        Currently enabled: yes
  balancer:     //平衡器相关状态信息
        Currently enabled:  yes         //是否开启
        Currently running:  no          //当前是否在运行
        Failed balancer rounds in last 5 attempts:  0       //最近5分钟chunk迁移失败的次数
        Migration Results for the last 24 hours:            //最近24小时的迁移结果信息
                No recent migrations
  databases:    //当前启动分片的库信息
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard1  1
                        { "_id" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 } } on : shard1 Timestamp(1, 0)
5. 如何对表进行分片

上述所有操作都完成,我们的分片架构就算是部署完成了,但是如果想要使用上分片特性,我们需要对某个表进行开启分片的动作;

mongos> sh.enableSharding("testdb")         //需要首先对库进行分片功能启动
mongos> sh.shardCollection("testdb.t1",{age:1})     //对库下的某个表进行分片,片键选择是age:1,代表的是范围分片

当你对testdb.t1表进行insert操作时,会根据age值而被路由插入到不同的分片节点上,可以使用如下脚本简单循环插入一批数据

mongos> for(var i=2;i<100000;i++){var a = Math.floor((Math.random()*100)+1);db.t1.insert({_id:i,age:a,name:"johnny"});}

注:因为分片架构是以chunk为一个单元进行迁移的,默认chunkSize是64M,也就是说只有一个chunk块达到64M后才会进行分裂,而当不同分片间的chunk数量差达到2以上时才会引起balancer进行自动迁移;

参考官网地址:
Deploy a Sharding
Deploy a Sharding with Access Control

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在 Redis 中,Sharding 分片是一种水平扩展的方式,将数据分散存储在多个节点上,从而实现数据的分布式存储和查询,提高了 Redis 的性能和容量。 在引入 Sharding 分片之前,Redis 的数据存储是单机模式,所有的数据都存储在一个 Redis 实例中,随着数据量的增加,单机实例的容量和性能会受到限制。而通过 Sharding 分片,可以将数据分散存储在多个 Redis 实例中,每个实例只存储一部分数据,从而提高了 Redis 的容量和性能。 在 Sharding 分片中,数据被分成多个片段,每个片段被存储在不同的 Redis 节点上,通过对数据的 key 进行哈希,可以确定数据应该存储在哪个节点上。为了确保数据的可靠性,通常会将每个片段复制到多个节点上,从而实现数据的备份和容错。 需要注意的是,在 Redis 中使用 Sharding 分片需要考虑如下问题: - 数据一致性:由于数据被分散存储在多个节点上,因此需要考虑如何保证数据的一致性,通常使用分布式事务或者使用一致性哈希算法实现。 - 节点故障:由于每个片段被存储在多个节点上,因此需要考虑如何处理节点故障和数据的恢复问题,通常使用主从复制或者集群化技术实现。 - 扩展性:由于数据量的增加可能会导致单个节点的容量和性能受到限制,因此需要考虑如何动态地添加或删除节点,以便实现数据的扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值