Linux Centos MongoDB分片集群搭建:分片+副本集

1.mongodb环境配置

mongodb 下载地址:https://www.mongodb.org/dl/linux/x86_64

解压mongodb      tar -xf mongodb*.tar
移动到安装目录   mv mongodb-linux-x86_64-xxx    /usr/local/mongodb

添加环境变量      echo "export PATH=$PATH:/usr/local/mongodb/bin > /etc/profile

使环境变量生效   source /etc/profile


2.节点角色规划

Linux Centos MongoDB分片集群搭建:分片+副本集

从图中可以看到有四个组件:mongos、config server、shard、replica set。

mongos,数据库集群请求的入口,所有的请求都通过mongos进行协调,不需要在应用程序添加一个路由选择器,mongos自己就是一个请求分发中心,它负责把对应的数据请求请求转发到对应的shard服务器上。在生产环境通常有多mongos作为请求的入口,防止其中一个挂掉所有的mongodb请求都没有办法操作。

config server,顾名思义为配置服务器,存储所有数据库元信息(路由、分片)的配置。mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,配置服务器则实际存储这些数据。mongos第一次启动或者关掉重启就会从 config server 加载配置信息,以后如果配置服务器信息变化会通知到所有的 mongos 更新自己的状态,这样 mongos 就能继续准确路由。在生产环境通常有多个 config server 配置服务器,因为它存储了分片路由的元数据,防止数据丢失!

shard,分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程。将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载。基本思想就是将集合切成小块,这些块分散到若干片里,每个片只负责总数据的一部分,最后通过一个均衡器来对各个分片进行均衡(数据迁移)。

replica set,中文翻译副本集,其实就是shard的备份,防止shard挂掉之后数据丢失。复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。

仲裁者(Arbiter),是复制集中的一个MongoDB实例,它并不保存数据。仲裁节点使用最小的资源并且不要求硬件设备,不能将Arbiter部署在同一个数据集节点中,可以部署在其他应用服务器或者监视服务器中,也可部署在单独的虚拟机中。为了确保复制集中有奇数的投票成员(包括primary),需要添加仲裁节点做为投票,否则primary不能运行时不会自动切换primary。
 

规划如下:

主机名 主机IP 组件mongos 组件configserver shard
mongodb1

172.30.2.185

port:20000

port:21000 port:22001,22002,22003
mongodb2

172.30.2.186

port:20000 port:21000 port:22001,22002,22003
mongodb3

172.30.2.187

port:20000 port:21000 port:22001,22002,22003

3.搭建集群

1)创建目录

分别在mongodb-1/mongodb-2/mongodb-3创建目录及日志文件

mkdir -p /data/mongodb/mongos/{log,conf}

mkdir -p /data/mongodb/mongoconf/{data,log,conf}

mkdir -p /data/mongodb/shard1/{data,log,conf}

mkdir -p /data/mongodb/shard2/{data,log,conf}

mkdir -p /data/mongodb/shard3/{data,log,conf}

touch /data/mongodb/mongos/log/mongos.log

touch /data/mongodb/mongoconf/log/mongoconf.log

touch /data/mongodb/shard1/log/shard1.log

touch /data/mongodb/shard2/log/shard2.log

touch /data/mongodb/shard3/log/shard3.log

2)配置config server 副本集
在三台服务器上配置config server副本集配置文件mongoconf.conf,并启动服务。

注意配置文件行尾空格

dbpath=/data/mongodb/mongoconf/data   
logpath=/data/mongodb/mongoconf/log/mongoconf.log
logappend=true
bind_ip=0.0.0.0
port=21000
journal=true
fork=true
syncdelay=60
oplogSize=1000
configsvr=true

#config server配置集replconf
replSet=replconf

启动config server
mongod -f  /data/mongodb/mongoconf/conf/mongoconf.conf

登录一台服务器进行配置服务器副本集初始化
mongo 172.30.2.185:21000

>use admin

>config={_id:"replconf",members:[{_id:0,host:"172.30.2.185:21000"},{_id:1,host:"172.30.2.186:21000"},{_id:2,host:"172.30.2.187:21000"},]}

>rs.initiate(config);

查看集群配置
>rs.status()

3)配置shard集群
三台服务器均进行shard集群配置,在shard1的conf中创建文件shard1.conf

dbpath=/data/mongodb/shard1/data
logpath=/data/mongodb/shard1/log/shard1.log
bind_ip=0.0.0.0
port=22001
logappend=true
#nohttpinterface=true
fork=true
oplogSize=4096
journal=true
#engine=wiredTiger
#cacheSizeGB=38G
smallfiles=true
shardsvr=true
replSet=shard1

启动shard服务:

mongod -f /data/mongodb/shard1/conf/shard1.conf
查看此时服务已经正常启动,shard1的22001端口已经正常监听,接下来登录mongodb2服务器进行shard1副本集初始化

mongo 172.30.2.186:22001
> use admin;
switched to db admin
>config={_id:"shard1",members:[{_id:0,host:"172.30.2.185:22001"},{_id:1,host:"172.30.2.186:22001",},{_id:2,host:"172.30.2.187:22001",arbiterOnly:true},]}

{
    "_id" : "shard1",
    "members" : [
        {
            "_id" : 0,
            "host" : "172.30.2.185:22001"
        },
        {
            "_id" : 1,
            "host" : "172.30.2.186:22001"
        },
        {
            "_id" : 2,
            "host" : "172.30.2.187:22001",
            "arbiterOnly" : true
        }
    ]
}

> rs.initiate(config);
{ "ok" : 1 }
查看集群状态:

shard1:SECONDARY> rs.status();

同样的操作进行shard2配置和shard3配置,在mongo1上进行shard2的副本集初始化,在mongo3上进行 初始化shard3副本集初始化。

shard2配置文件

dbpath=/data/mongodb/shard2/data
logpath=/data/mongodb/shard2/log/shard2.log
bind_ip=0.0.0.0
port=22002
logappend=true
#nohttpinterface = true
fork=true
oplogSize=4096
journal=true
#engine=wiredTiger
#cacheSizeGB=38G
smallfiles=true
shardsvr=true
replSet=shard2

启动服务:

mongod -f /data/mongodb/shard2/conf/shard2.conf

在mongo1上进行shard2的副本集初始化:

> use admin;
switched to db admin
>config={_id:"shard2",members:[{_id:0,host:"172.30.2.185:22002"},{_id:1,host:"172.30.2.186:22002",arbiterOnly:true},{_id:2,host:"172.30.2.187:22002"},]}

{
    "_id" : "shard2",
    "members" : [
        {
            "_id" : 0,
            "host" : "172.30.2.185:22002"
        },
        {
            "_id" : 1,
            "host" : "172.30.2.186:22002",
            "arbiterOnly" : true
        },
        {
            "_id" : 2,
            "host" : "172.30.2.187:22002"
        }
    ]
}

使配置生效
>rs.initiate(config);

查看集群状态:

shard2:SECONDARY> rs.status()

 

shard3配置文件:

dbpath=/data/mongodb/shard3/data
logpath=/data/mongodb/shard3/log/shard3.log
bind_ip=0.0.0.0
port=22003
logappend=true
#nohttpinterface = true
fork=true
oplogSize=4096
journal=true
#engine=wiredTiger
#cacheSizeGB=38G
smallfiles=true
shardsvr=true
replSet=shard3
 

在mongo3上进行 初始化shard3副本集初始化:
在三台虚机上分别启动mongodb服务
mongod -f /data/mongodb/shard3/conf/shard3.conf

登录mongodb
mongo 172.30.2.187:22003

> use admin;
switched to db admin


>config={_id:"shard3",members:[{_id:0,host:"172.30.2.185:22003",arbiterOnly:true},{_id:1,host:"172.30.2.186:22003"},{_id:2,host:"172.30.2.187:22003"},]}

{
    "_id" : "shard3",
    "members" : [
        {
            "_id" : 0,
            "host" : "172.30.2.185:22003",
            "arbiterOnly" : true
        },
        {
            "_id" : 1,
            "host" : "172.30.2.186:22003"
        },
        {
            "_id" : 2,
            "host" : "172.30.2.187:22003"
        }
    ]
}

使配置生效
>rs.initiate(config);

查询集群状态
shard3:SECONDARY> rs.status();
 

4)配置路由服务器mongos
目前三台服务器的配置服务器和分片服务器均已启动,配置三台mongos服务器,由于mongos服务器的配置是从内存中加载,所以自己没有存在数据目录configdb连接为配置服务器集群。
vim mongos.conf

logpath=/data/mongodb/mongos/log/mongos.log
logappend=true
bind_ip=0.0.0.0
port=20000
maxConns=10000
configdb=replconf/172.30.2.185:21000,172.30.2.186:21000,172.30.2.187:21000
fork=true

分别启动mongos服务:

mongos -f /data/mongodb/mongos/conf/mongos.conf

登录任意一台mongos:
mongo 172.30.2.186:20000

mongos> use admin;
switched to db admin
mongos> db.runCommand({addshard:"shard1/172.30.2.185:22001,172.30.2.186:22001,172.30.2.187:22001"})
{
    "shardAdded" : "shard1",
    "ok" : 1,
    "operationTime" : Timestamp(1594375652, 5),
    "$clusterTime" : {
        "clusterTime" : Timestamp(1594375652, 5),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}


mongos> db.runCommand({addshard:"shard2/172.30.2.185:22002,172.30.2.186:22002,172.30.2.187:22002"})

{
    "shardAdded" : "shard2",
    "ok" : 1,
    "operationTime" : Timestamp(1594375772, 2),
    "$clusterTime" : {
        "clusterTime" : Timestamp(1594375772, 2),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}


mongos> db.runCommand({addshard:"shard3/172.30.2.185:22003,172.30.2.186:22003,172.30.2.187:22003"})

{
    "shardAdded" : "shard3",
    "ok" : 1,
    "operationTime" : Timestamp(1594375798, 3),
    "$clusterTime" : {
        "clusterTime" : Timestamp(1594375798, 3),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}


查看集群:

mongos> sh.status();
mongos> sh.status();
--- Sharding Status --- 
  sharding version: {
      "_id" : 1,
      "minCompatibleVersion" : 5,
      "currentVersion" : 6,
      "clusterId" : ObjectId("5f0828d222393252fd6930d7")
  }
  shards:
        {  "_id" : "shard1",  "host" : "shard1/172.30.2.185:22001,172.30.2.186:22001",  "state" : 1 }
        {  "_id" : "shard2",  "host" : "shard2/172.30.2.185:22002,172.30.2.187:22002",  "state" : 1 }
        {  "_id" : "shard3",  "host" : "shard3/172.30.2.186:22003,172.30.2.187:22003",  "state" : 1 }
  active mongoses:
        "4.0.10" : 1
  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 }

5)测试
目前配置服务、路由服务、分片服务、副本集服务都已经串联起来了,此时进行数据插入,数据能够自动分片。连接在mongos上让指定的数据库、指定的集合分片生效。注意:设置分片需要在admin数据库进行。

use admin
db.runCommand( { enablesharding :"testdb"});    #开启database-testdb  库分片功能
db.runCommand( { shardcollection : "testdb.table1",key : {_id:"hashed"} } )    #指定数据库里需要分片的集合tables和片键_id
设置testdb的 table1 表需要分片,根据 _id 自动分片到 shard1 ,shard2,shard3 上面去。

查看分片信息:

mongos> db.runCommand({listshards:1})
{
    "shards" : [
        {
            "_id" : "shard1",
            "host" : "shard1/172.30.2.185:22001,172.30.2.186:22001",
            "state" : 1
        },
        {
            "_id" : "shard2",
            "host" : "shard2/172.30.2.185:22002,172.30.2.187:22002",
            "state" : 1
        },
        {
            "_id" : "shard3",
            "host" : "shard3/172.30.2.186:22003,172.30.2.187:22003",
            "state" : 1
        }
    ],
    "ok" : 1,
    "operationTime" : Timestamp(1594376024, 1),
    "$clusterTime" : {
        "clusterTime" : Timestamp(1594376024, 1),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    }
}

测试插入数据:

use testdb;
for (var i = 1; i <= 100000; i++) db.table1.save({_id:i,"test1":"testval1"});
查看分片情况:

db.table1.stats()
此时架构中的mongos,config server,shard集群均已经搭建部署完毕,在实际生成环境话需要对前端的mongos做高可用来提示整体高可用。

注意:mongodb的启动顺序是,先启动所有节点配置服务器,在启动所有节点的分片,最后启动所有节点的mongos

mongod -f  /data/mongodb/mongoconf/conf/mongoconf.conf
mongod -f /data/mongodb/shard1/conf/shard1.conf
mongod -f /data/mongodb/shard2/conf/shard2.conf
mongod -f /data/mongodb/shard3/conf/shard3.conf
mongos -f /data/mongodb/mongos/conf/mongos.conf