魏世江 希雲聯合創始人、CTO,負責基於Docker的自動化服務管理平臺的後端研發工做。擅長Docker相關技術、PasS平臺架構及企業自動化運維繫統的設計及開發。創業以前在新浪SAE平臺任技術經理,從09年SAE立項至13年下半年的四年多時間裏,一直負責SAEPasS平臺各類基於Web的服務管理系統的設計及開發,在DevOps方面積累了豐富的經驗。Docker引擎代碼貢獻者,在Docker開源項目中代碼貢獻量全球排名50名左右。golang
Mongo在很早就支持了replication set和sharding集羣。通過了這麼多年的沉澱,Mongo集羣的成熟度已經很是穩定,被大量公司用到本身的生產環境下。如何使用容器技術來實現Mongo集羣的一鍵式交付部署,屏蔽底層實現的細節,是不少人關心的話題。mongodb
本文將給你們介紹基於進程的容器技術實現Mongo sharding集羣的一鍵部署,充分展示了容器的強大威力。數據庫
Mongo(mongodb.com)做爲流行的文檔數據庫,有不少有趣的特性,好比內置failover、支持文件存儲、支持mapreduce以及能夠在服務器端直接運行js腳本,固然咱們今天最關心的是它內置的sharding功能。分佈式系統的設計向來具備很高的挑戰,在最近一些年,隨着互聯網的發展,分佈式的實踐逐步開始獲得推廣和重視。express
若是要深刻了解Mongo sharding的原理,參考:編程
mongo集羣涉及到多個服務,包括:bash
本次部署,configdb3臺,mongo數據節點12臺,分紅4個分片,每一個分片1主2從服務器
Mongo官方已經提供了Mongo 3.2的鏡像,能夠用來做爲Mongo集羣的鏡像.爲了減小後續維護工做,咱們儘量不構建本身的鏡像。架構
下面咱們按照mongo sharding官方的部署文檔,一步步編排集羣。運維
https://docs.mongodb.com/manual/tutorial/deploy-shard-cluster/
部署的順序是:configdb -> mongos -> mongo-replicaset/mongo-slices -> mongo-express
# cat mongo-config.conf systemLog: verbosity: 0 operationProfiling: slowOpThresholdMs: 3000 processManagement: fork: false storage: dbPath: /data/db journal: enabled: true engine: wiredTiger replication: replSetName: {{.ReplSetName}} sharding: clusterRole: configsvr net: port: 27019
# cat configdb-init.js {{ $s := service "mongo-configsvr" }} config = { _id : "{{.ReplSetName}}", members : [ {{range $c := $s.Containers }}{_id : {{$c.Seq}}, host: "{{$c.Domain}}:27019"},{{end}} ] } rs.initiate(config) rs.status()
咱們經過添加一個one-off的服務configsvr-init
,該服務執行初始化動做後將會自動退出
至此,configdb的編排算是完成了。咱們接下來編排mongos服務
# cat mongos.conf replication: localPingThresholdMs: 2000 {{ $port := .CfgPort }} {{$s := service "mongo-configsvr"}} sharding: configDB: {{.ReplSetName}}/{{range $i,$c := $s.Containers}}{{if ne $i 0}},{{end}}{{$c.Domain}}:{{$port}}{{end}}
mongo的配置文件咱們通常放到/etc/下
注意cmd裏執行的是mongos
mongos必須在configdb集羣初始化後運行, 接下來咱們開始編排mongo的數據節點服務,這是集羣中最複雜的部分
cat mongo-shard.conf systemLog: verbosity: 0 operationProfiling: slowOpThresholdMs: 3000 processManagement: fork: false storage: dbPath: /data/db journal: enabled: true engine: wiredTiger {{ $num := (parseInt .REPLICA_NUM) |add 1 }} {{ $cn := (parseInt .Container.Seq) |subtract 1 }} {{ $rsn := $cn |divide $num }} replication: replSetName: RS{{$rsn}}
變量REPLICA_NUM
表示每一個主有幾個從,默認爲2 這裏將123個容器編爲RS0,456編爲RS1,789編爲RS2,10,11,12編爲RS3
有了上面的數據節點後,咱們發現,尚未初始化replset,也沒有將每一個replset加入到sharding裏,下面咱們來作shard初始化工做
#!/bin/bash set -e {{$s := service "mongo"}} {{$n := (parseInt .REPLICA_NUM) |add 1}} {{$slices := $s.ContainerNum |divide $n}} {{$port := .Port}} echo begin to init replica set ... for i in {0..{{$slices |subtract 1}}}; do bn=$(( $i * {{$n}} + 1 )) en=$(( $bn + {{.REPLICA_NUM}} )) RS_NODE= RS_NODE_CONFIG= ii=$bn while [ $ii -le $en ]; do RS_NODE=$RS_NODE$ii.mongo.{{.Instance.Name}}.csphere.local:{{$port}}, RS_NODE_CONFIG=$RS_NODE_CONFIG"{_id:$ii, host: \"$ii.mongo.{{.Instance.Name}}.csphere.local:{{$port}}\"}," ii=$(($ii + 1)) done RS_NODES=$(echo $RS_NODE|sed 's/,$//') RS_NODES_CONFIG=$(echo $RS_NODE_CONFIG|sed 's/,$//') cat > /tmp/RS$i.js <<EOF config = { _id : "RS$i", members : [ $RS_NODES_CONFIG ] } rs.initiate(config) rs.status() EOF ## connect to 0.mongo/3.mongo... begin_mongo=$bn.mongo.{{.Instance.Name}}.csphere.local mongo $begin_mongo /tmp/RS$i.js sleep 3 j=0 while [ $j -lt 10 ]; do mongo $begin_mongo --eval "rs.status()" | grep PRIMARY && break j=$(($j + 1)) sleep 2 done if [ $j -eq 10 ]; then echo RS$i initianized failed exit 1 fi echo RS$i initinized ok echo begin to add RS$i to sharding ... mongo --eval "sh.addShard(\"RS${i}/$RS_NODES\")" 1.mongos.{{.Instance.Name}}.csphere.local done
上面的腳本稍微有點複雜,基本邏輯就是,先初始化每一個replicaset集羣RS0..RS3,並將每一個RS加入到sharding集羣看成分片slices。具體能夠參考上面的部署拓撲圖。
該服務是one-off執行
到這裏mongo sharding集羣的編排工做基本就完成了。接下來咱們爲mongo服務添加一個可視化面板,方便咱們的使用
至此,編排工做所有完成。下面咱們來測試剛纔的工做成果。。
點擊部署,生成一個應用實例,咱們命名爲m
。
咱們看一下shard-init的初始化輸出:
咱們看一下面板express的輸出:
這是mongo express的首頁,能夠查看到該mongos上的訪問歸納
咱們查看config這個db下表裏的數據,特別是和集羣配置有關的:
mongos表:
有哪些分片呢?咱們看到了RS0 RS1 RS2 RS3:
咱們能夠建立一個名爲csphere的db試試:
後續,能夠參考mongo文檔,在開發中,設置您的sharding key等。更進一步的mongodb管理,請參考官方文檔
從mongodb集羣的自動化交付看整個編排過程,咱們發現背後的魔法關鍵是:DISCOVERY ALL,發現全部的東西並使之具備可編程特性。
Q1: 你好 目前這個的實際應用狀況如何?有何挑戰?
A1: 實際測試運行良好。挑戰在於編排過程,背後的discovery能力可否知足自動化的能力。在實際生產中,能夠優化您的配置文件,如挑戰timeout等,或日誌的loglevel
Q2: 模板文件經過什麼語言進行渲染,經過什麼流程發現啓動容器的信息?
A2: 希雲cSphere平臺背後有一套強大的配置模版引擎,golang模版。平臺的協調中心能夠發現各類參數並進行可編程去應對自動化挑戰
Q3: 你好 mongodb羣集性能瓶頸,監控指標你以爲最重要的是什麼,擴容的時候要注意什麼?
A3: mongo集羣在使用上注意存儲引擎的選擇,在3.2以前是mmap,3.2已經調整,新的默認引擎可以更好的處理大數據量的問題。mongo的水平擴展自己很好,注意mongos代理部署的多一點,避免流量從單個mongos流入流出