docker-compose搭建mongodb分片集群(單機版)


 

mongodb分片機制原理

 

一、概念

  分片(sharding)是指將數據庫拆分,將其分散在不同的機器上的過程。將數據分散到不同的機器上,不需要功能強大的服務器就可以存儲更多的數據和處理更大的負載。基本思想就是將集合切成小塊,這些塊分散到若干片里,每個片只負責總數據的一部分,最后通過一個均衡器來對各個分片進行均衡(數據遷移)。通過一個名為mongos的路由進程進行操作,mongos知道數據和片的對應關系(通過配置服務器)。大部分使用場景都是解決磁盤空間的問題,對於寫入有可能會變差,查詢則盡量避免跨分片查詢。使用分片的時機:

1,機器的磁盤不夠用了。使用分片解決磁盤空間的問題。

2,單個mongod已經不能滿足寫數據的性能要求。通過分片讓寫壓力分散到各個分片上面,使用分片服務器自身的資源。

3,想把大量數據放到內存里提高性能。和上面一樣,通過分片使用分片服務器自身的資源。

 

二、分片集群架構(來自官網)

上圖中主要有如下所述三個主要組件:

Shard:分片服務器

用於存儲實際的數據塊,實際生產環境中一個shard server角色可由幾台機器組個一個replica set承擔,防止主機單點故障

Config Server:配置服務器

mongod實例,存儲了整個 分片群集的配置信息,其中包括 chunk信息。

Query Routers:前端路由

客戶端由此接入,且讓整個集群看上去像單一數據庫,前端應用可以透明使用

這里的兩個shard(分片)相當於mongodb節點服務器,內部的塊是將order集合再切割的結果,隨着數據量的的增大,分片會分割和遷移,以滿足數據的均勻分布。

請求分流:通過路由節點將請求分發到對應的分片和塊中

數據分流:內部提供平衡器保證數據的均勻分布,這是數據平均分布式、請求平均分布的前提

塊的拆分:3.4版本塊的最大容量為64M或者10w的數據,當到達這個閾值,觸發塊的拆分,一分為二

塊的遷移:為保證數據在分片節點服務器分片節點服務器均勻分布,塊會在節點之間遷移。一般相差8個分塊的時候觸發

 

MongoDB分片優勢:

減少單個分片需要處理的請求數,提高群集的存儲容量和吞吐量 比如,當插入一條數據時,應用只需要訪問存儲這條數據的分片 減少單分片存儲的數據,提高數據可用性,提高大型數據庫查詢服務的性能。 當MongoDB單點數據庫服務器存儲和性能成為瓶頸,或者需要部署大型應用以充分利用內存時,可以使用分片技術

 

環境准備

  docker、docker-compose、lunux。版本問題應該不大,我用的是Docker version 18.09.0, build 4d60db4、docker-compose version 1.23.0-rc3, buildea3d406e、centos7.2。

  本套Mongodb搭建分片集群是基於mongodb4.0.5,直接從官方鏡像倉庫拉取docker pull mongo:4.0.5即可

       完成准備之后,docker images看一下,mongodb.鏡像是否搞定了。

 

1.編寫yaml文件,這里我命名fates-mongo-compose.yaml

version: '2'
services:
  shard1:
    image: mongo:4.0.5
    container_name: mongo_shard1
    # --shardsvr: 這個參數僅僅只是將默認的27017端口改為27018,如果指定--port參數,可用不需要這個參數
    # --directoryperdb:每個數據庫使用單獨的文件夾
    command: mongod --shardsvr --directoryperdb --replSet shard1
    volumes:
      - /etc/localtime:/etc/localtime
      - /data/base/fates/mongo/shard1:/data/db
    privileged: true
    mem_limit: 16000000000
    networks:
      - mongo   

  shard2:
    image: mongo:4.0.5
    container_name: mongo_shard2
    command: mongod --shardsvr --directoryperdb --replSet shard2
    volumes:
      - /etc/localtime:/etc/localtime
      - /data/base/fates/mongo/shard2:/data/db
    privileged: true
    mem_limit: 16000000000
    networks:
      - mongo

  shard3:
    image: mongo:4.0.5
    container_name: mongo_shard3
    command: mongod --shardsvr --directoryperdb --replSet shard3
    volumes:
      - /etc/localtime:/etc/localtime
      - /data/base/fates/mongo/shard3:/data/db
    privileged: true
    mem_limit: 16000000000
    networks:
      - mongo

  config1:
    image: mongo:4.0.5
    container_name: mongo_config1
    # --configsvr: 這個參數僅僅是將默認端口由27017改為27019, 如果指定--port可不添加該參數
    command: mongod --configsvr --directoryperdb --replSet fates-mongo-config --smallfiles
    volumes:
      - /etc/localtime:/etc/localtime
      - /data/base/fates/mongo/config1:/data/configdb
    networks:
      - mongo

  config2:
    image: mongo:4.0.5
    container_name: mongo_config2
    command: mongod --configsvr --directoryperdb --replSet fates-mongo-config --smallfiles
    volumes:
      - /etc/localtime:/etc/localtime
      - /data/base/fates/mongo/config2:/data/configdb
    networks:
      - mongo

  config3:
    image: mongo:4.0.5
    container_name: mongo_config3
    command: mongod --configsvr --directoryperdb --replSet fates-mongo-config --smallfiles
    volumes:
      - /etc/localtime:/etc/localtime
      - /data/base/fates/mongo/config3:/data/configdb
    networks:
      - mongo

  mongos:
    image: mongo:4.0.5
    container_name: mongo_mongos
    # mongo3.6版默認綁定IP為127.0.0.1,此處綁定0.0.0.0是允許其他容器或主機可以訪問
    command: mongos --configdb fates-mongo-config/config1:27019,config2:27019,config3:27019 --bind_ip 0.0.0.0 --port 27017
    ports:
     - 27017:27017
    volumes:
      - /etc/localtime:/etc/localtime
    depends_on:
      - config1
      - config2
      - config3
    networks:
      - mongo    
networks:
  mongo:
    external: true

具體含義看注釋

 

2.編寫deploy-and-start.sh腳本

#!/bin/sh

docker-compose -f fates-mongo-compose.yaml up -d

#睡眠兩分鍾,等待mongodb所有容器起來之后將它們配置加入分片
sleep 30s

docker-compose -f fates-mongo-compose.yaml exec config1 bash -c "echo 'rs.initiate({_id: \"fates-mongo-config\",configsvr: true, members: [{ _id : 0, host : \"config1:27019\" },{ _id : 1, host : \"config2:27019\" }, { _id : 2, host : \"config3:27019\" }]})' | mongo --port 27019"
docker-compose -f fates-mongo-compose.yaml exec shard1 bash -c "echo 'rs.initiate({_id: \"shard1\",members: [{ _id : 0, host : \"shard1:27018\" }]})' | mongo --port 27018"
docker-compose -f fates-mongo-compose.yaml exec shard2 bash -c "echo 'rs.initiate({_id: \"shard2\",members: [{ _id : 0, host : \"shard2:27018\" }]})' | mongo --port 27018"
docker-compose -f fates-mongo-compose.yaml exec shard3 bash -c "echo 'rs.initiate({_id: \"shard3\",members: [{ _id : 0, host : \"shard3:27018\" }]})' | mongo --port 27018"
docker-compose -f fates-mongo-compose.yaml exec mongos bash -c "echo 'sh.addShard(\"shard1/shard1:27018\")' | mongo"
docker-compose -f fates-mongo-compose.yaml exec mongos bash -c "echo 'sh.addShard(\"shard2/shard2:27018\")' | mongo"
docker-compose -f fates-mongo-compose.yaml exec mongos bash -c "echo 'sh.addShard(\"shard3/shard3:27018\")' | mongo"

該腳本流程詳細描述一下

1)先啟動mongodb分片容器組

2) 睡眠30s等待容器全部完全啟動(可能不需要30s)

3)操作config1,配置config副本集,將config*容器組作為config角色,此時config1作為config副本集里的主節點

4)操作shard1、shard2、shard3,將shard*容器組作為shard角色。

5)將shard1、shard2、shard3加入分片集群組。

 

3.運行

執行腳本

# sh deploy-and-start.sh 等待腳本啟動完成,如果出現connect fail報錯,檢查一下網絡,再次啟動一次腳本即可。

  到這里,單機版的mongodb的分片集群,就搭建好了,一般真正的運維環境,Mongodb集群應該分布在不同的機器,但是只要熟悉這套部署方案的機制,只要稍作修改,就可以實現。

但是,Mongodb庫默認是不會將你的表進行分片的,是需要手動配置的,如果不配置,數據都會全部存放在主節點,不會均勻分配到各個分片。

現在手動將一個表做分片,就拿um_t_staff表作為例子

//前提是分片的片鍵必須是索引

sh.enableSharding("'mongodbDemo")//先讓當前庫支持分片

sh.shardCollection('mongodbDemo.um_t_staff',{timestamp:1})//當前集合加入分片,遞增片鍵(timestamp已經作為索引了)

db.adminCommand("flushRouterConfig")//刷新路由

sh.enableBalancing("mongodbDemo.um_t_staff")//讓當前分片支持平衡

sh.startBalancer() //開啟平衡

sh.status({"verbose":1})//查看詳細分片信息

db.um_t_staff.getShardDistribution()//查看該表分片數據信息

 

OK 。docker-compose搭建分片集群已經大功告成了。

感謝前輩的技術輸出。參考博文https://juejin.im/post/5c3c3105f265da611b58909a#heading-14


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM