docker-compose搭建mongo 高可用服務(路由+分片+副本集+仲裁)

1.概念介紹

組件 介紹
mongos 前端路由,分發請求,讓整個集羣看上去像單一數據庫
config servers 記錄全局配置信息,3.4開始必須部署兩個爲副本集
shard server 完成數據提取和查詢,實際的數據塊

2.環境準備

名稱 角色 IP 端口 副本集名稱
mongos mongos 172.20.0.15 27017
config_server_0 configsvr 172.20.0.13 27019 rs_config_server
config_server_1 configsvr 172.20.0.14 27019 rs_config_server
shard_server_0 shardsvr 172.20.0.11 27018/30001 shard_server0/shard_server1
shard_server_1 shardsvr 172.20.0.12 27018/30002 shard_server0/shard_server1
shard_server_2 shardsvr(仲裁) 172.20.0.16 27018/30003

目錄結構如下:

docker_mongo_swarm
├── data
└── docker-compose.yml

docker-compose.yml這裏使用mongo:4.0.19基礎鏡像,準備了3個副本集,2個配置服務器,1個mongos路由。由於不知道怎麼在yml裏配多個mongo守護進程,所以待會在鏡像裏面啓動多1個mongo。

version: '3.7'

services:
  shard_server_0:
    image: mongo:4.0.19
    container_name: shard_server_0
    networks:
          mongo_network:
              ipv4_address: 172.20.0.11
    ports:
      - 27018:27018
      - 30001:30001
    volumes:
      - ./data/shard_server_0/data/se0:/data/db
      - ./data/shard_server_0/data/se1:/data/set1
      - ./data/shard_server_0/data/configdb:/data/configdb
      - ./data/shard_server_0/data/backup:/data/backup
    command: --shardsvr --replSet=shard_server0 --bind_ip_all
    depends_on:
      - rs_config_server_0
      - rs_config_server_1

  shard_server_1:
    image: mongo:4.0.19
    container_name: shard_server_1
    networks:
          mongo_network:
              ipv4_address: 172.20.0.12
    ports:
      - 27028:27018
      - 30002:30002
    volumes:
      - ./data/shard_server_1/data/se0:/data/db
      - ./data/shard_server_1/data/se1:/data/set1
      - ./data/shard_server_1/data/configdb:/data/configdb
      - ./data/shard_server_1/data/backup:/data/backup
    command: --shardsvr --replSet=shard_server0 --bind_ip_all
    depends_on:
      - rs_config_server_0
      - rs_config_server_1

  shard_server_2:
    image: mongo:4.0.19
    container_name: shard_server_2
    networks:
          mongo_network:
              ipv4_address: 172.20.0.16
    ports:
      - 27038:27018
      - 30003:30003
    volumes:
      - ./data/shard_server_2/data/se0:/data/db
      - ./data/shard_server_2/data/se1:/data/set1
      - ./data/shard_server_2/data/configdb:/data/configdb
      - ./data/shard_server_2/data/backup:/data/backup
    command: --shardsvr --replSet=shard_server0 --bind_ip_all
    depends_on:
      - rs_config_server_0
      - rs_config_server_1

  rs_config_server_0:
      container_name: rs_config_server_0
      networks:
          mongo_network:
              ipv4_address: 172.20.0.13
      image: mongo:4.0.19
      volumes:
          - ./data/rs_config_server_0/data/db:/data/db
          - ./data/rs_config_server_0/data/configdb:/data/configdb
      ports:
          - 27030:27019
      command: --configsvr --replSet "rs_config_server" --bind_ip_all
      restart: always

  rs_config_server_1:
      container_name: rs_config_server_1
      networks:
          mongo_network:
              ipv4_address: 172.20.0.14
      image: mongo:4.0.19
      volumes:
          - ./data/rs_config_server_1/data/db:/data/db
          - ./data/rs_config_server_1/data/configdb:/data/configdb
      ports:
          - 27031:27019
      command: --configsvr --replSet "rs_config_server" --bind_ip_all
      restart: always

  mongos:
      container_name: mongos
      networks:
          mongo_network:
              ipv4_address: 172.20.0.15
      image: mongo:4.0.19
      ports:
          - 27017:27017
      volumes:
          - ./data/mongos/data/db:/data/db
          - ./data/mongos/data/configdb:/data/configdb
      entrypoint: mongos
      command: --configdb rs_config_server/172.20.0.13:27019,172.20.0.14:27019 --bind_ip_all
      depends_on:
          - shard_server_0
          - shard_server_1
          - shard_server_2
networks:
    mongo_network:
        driver: bridge
        ipam:
            config:
                - subnet: 172.20.0.10/24
~ docker-compose up -d  #啓動yml後臺掛起
~ docker stats -a #查看容器狀態 

在這裏插入圖片描述

3.配置mongo服務

1.配置服務器configsvr

先進入任意1臺配置服務器裏面關聯2臺配置服務器,不然mongos沒法用。

~ docker exec -it rs_config_server_1 /bin/bash
root@acca86ab949e:/# mongo 127.0.0.1:27019
> rs.initiate({
    _id: "rs_config_server",
    configsvr: true,
    members: [
        { _id : 0, host : "172.20.0.13:27019" },
        { _id : 1, host : "172.20.0.14:27019" }
    ]
});

2.在shard啓動2個mongo做分片

依次進入,主動掛起shard_server1的分片集羣。

#shard_server_0
~ docker exec -it shard_server_0 /bin/bash
root@acca86ab949e:/# mongod --port=30001 --dbpath=/data/set1 --shardsvr --replSet=shard_server1 --bind_ip_all >/dev/null 2>&1 &
#shard_server_1
~ docker exec -it shard_server_1 /bin/bash
root@acca86ab949e:/# mongod --port=30002 --dbpath=/data/set1 --shardsvr --replSet=shard_server1 --bind_ip_all >/dev/null 2>&1 &
#shard_server_2
~ docker exec -it shard_server_2 /bin/bash
root@acca86ab949e:/# mongod --port=30003 --dbpath=/data/set1 --shardsvr --replSet=shard_server1 --bind_ip_all >/dev/null 2>&1 &
#在任意容器可以看看有沒有啓動2個mongo,第1個是docker,第2個是剛剛啓動的。
root@acca86ab949e:/# ps aux

3關聯分片和設置仲裁節點

在任意shard容器都可以運行,我這裏再起了1個終端在shard_server_0容器裏面操作。

~ docker exec -it shard_server_0 /bin/bash
root@acca86ab949e:/# mongo 127.0.0.1:27018

> rs.initiate({
    _id: "shard_server0",
    members: [
        { _id : 0, host : "172.20.0.11:27018"},
        { _id : 1, host : "172.20.0.12:27018" },
        { _id : 2, host : "172.20.0.16:27018",arbiterOnly:true}
    ]
});
~ docker exec -it shard_server_0 /bin/bash
root@acca86ab949e:/# mongo 127.0.0.1:30001
> rs.initiate({
    _id: "shard_server1",
    members: [
        { _id : 0, host : "172.20.0.11:30001"},
        { _id : 1, host : "172.20.0.12:30002" },
        { _id : 2, host : "172.20.0.16:27018",arbiterOnly:true}
    ]
});
#關聯完可以看下副本集狀態,有1個PRIMARY,1個SECONDARY,1個ARBITER。
shard_server0:PRIMARY> rs.status()
shard_server1:PRIMARY> rs.status()

#如果是SECONDARY節點,用slaveOk命令允許查詢操作。
shard_server0:SECONDARY> rs.slaveOk()
shard_server0:SECONDARY> rs.status()

4.最後配置路由mongos

關聯前面配置的副本集和分片。

docker exec -it mongos /bin/bash
root@acca86ab949e:/# mongo 127.0.0.1:27017
sh.addShard("shard_server0/172.20.0.11:27018,172.20.0.12:27018")
sh.addShard("shard_server1/172.20.0.11:30001,172.20.0.12:30002")

配完結果如下:
在這裏插入圖片描述

4.分片+副本集數據測試

在mongos主路由裏,對age按hash作爲片鍵,輸入2W個數據,落到各個分片。

mongos> sh.enableSharding('testdb') 
mongos> use testdb
mongos> sh.shardCollection("testdb.test_shard",{"age": "hashed"}) 
mongos> for (i = 1; i <= 20000; i++) db.test_shard.insert({age:(i%100), name:"user"+i, create_at:new Date()})

mongos> db.test_shard.find().count() 
20000

mongos> db.stats() 

可以看到shard_server1落了11400條記錄,shard_server0落下了8600條記錄。
在這裏插入圖片描述

5.單點故障測試

1.停掉服務器

這裏主動讓作爲 PRIMARY 的 shard_server0 容器斷掉

~ docker stop shard_server_0
mongos> db.test_shard.find().count() 
20000

停掉shard_server_0後發現數據並沒有丟失,因爲shard_server_1保存了se0和se1完整的副本集,所以數據會同步。

~ docker exec -it shard_server_1 /bin/bash
root@acca86ab949e:/# mongo 127.0.0.1:27018
shard_server0:PRIMARY> rs.status() 

進入shard_server_1的se0的副本集查看,看到172.20.11:27018的健康狀態是no healthy,而172.20.12:27018已被仲裁節點自動選爲 PRIMARY(如果沒有仲裁節點,SECONDARY 不會自動變成 PRIMARY )。
在這裏插入圖片描述
在當前節點查看數據,發現只有8600,別緊張,這只是set0的數據,啓動另一個終端,再看看set1的數據11400。

shard_server1:PRIMARY> use testdb
shard_server0:PRIMARY> db.test_shard.find().count() 
8600

shard_server1:PRIMARY> use testdb
shard_server1:PRIMARY> db.test_shard.find().count() 
11400

2.故障恢復

啓動shard_server_0容器,再看看,發現172.20.0.11:27018已經變成了SECONDARY節點。

~ docker start shard_server_0

在這裏插入圖片描述

6.常用命令列表

#數據庫 命令
db.serverStatus().connections; //連接數查看
show collections  //查看錶信息
db.test_shard.find().count() //查看table1數據長度
db.test_shard.remove({}) //刪除數據表
db.stats()   //查看所有的分片服務器狀態
db.adminCommand( { listShards: 1 } ) //分片列表
db.test_shard.find({ age: 36 }).explain()   //精確查詢
db.test_shard.find({ age: { $gte : 36 ,$lt : 73 } }).explain() //範圍查詢

#分片 操作命令
sh.enableSharding('testdb')                //開啓數據庫testdb分片
sh.shardCollection('testdb.users',{uid:1})    //按testdb.users的uid字段分片
sh.shardCollection("testdb.test_shard",{"age": 1})     //按ranged分片
sh.shardCollection("testdb.test_shard2",{"age": "hashed"}) //按hash分片
sh.status()   //查看分片節點
sh.addShard() //向集羣中添加一個 shard
sh.getBalancerState()   //查看平衡器
sh.disableBalancing()   //禁用平衡器
sh.enableBalancing()    //啓用平衡器
db.runCommand( { removeShard: "mongodb0" } ) //刪除分片mongodb0,遷移數據查看命令
db.runCommand( { movePrimary: "test", to: "mongodb1" })   //將數據庫test未分片mongodb0的數據,遷移到mongodb1主分片。
db.adminCommand("flushRouterConfig") //處理分片後,刷新路由數據。

use config 
db.databases.find()  //查看所有數據庫使用分片
db.settings.save({_id:"chunksize",value:1}) //將 chunk 的大小調整爲 1MB
db.serverStatus().sharding


#副本集 操作命令
rs.status()   //查看成員的運行狀態等信息
rs.config()    //查看配置信息
rs.slaveOk()  //允許在SECONDARY節點上進行查詢操作,默認從節點不具有查詢功能
rs.isMaster()  //查詢該節點是否是主節點
rs.add({})   //添加新的節點到該副本集中
rs.remove()   //從副本集中刪除節點
rs.stepDown //降級節點
db.printSlaveReplicationInfo()  //查看同步情況
rs.addArb("172.20.0.16:27038") //添加仲裁節點

#強制加入仲裁節點:
config=rs.conf()
config.members=[config.members[0],config.members[1],{_id:5,host:"127.0.0.1:27023",priority:5,arbiterOnly:"true"}]
rs.reconfig(config,{force:true})

#強制主節點:
cfg = rs.conf()
cfg.members[0].priority = 0.5
cfg.members[1].priority = 0.5
cfg.members[2].priority = 1
rs.reconfig(cfg)

#備份/恢復
mongodump -h 127.0.0.1:27017 -d test -o /data/backup/
mongorestore -h 127.0.0.1:27017 -d test --dir /data/db/test



參考:
https://www.jianshu.com/p/7be177d669be
https://www.cnblogs.com/hukey/p/5774397.html
https://www.ibm.com/developerworks/cn/opensource/os-mongodb-sharded-cluster/index.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章