魏世江
希云聯(lián)合開創(chuàng)人、CTO,負(fù)責(zé)基于Docker的自動化服務(wù)管理平臺的后端研發(fā)工作。善于Docker相干技術(shù)、PasS平臺架構(gòu)及企業(yè)自動化運(yùn)維系統(tǒng)的設(shè)計(jì)及開發(fā)。創(chuàng)業(yè)之前在新浪SAE平臺任技術(shù)經(jīng)理,從09年SAE立項(xiàng)至13年下半年的4年多時(shí)間里,1直負(fù)責(zé)SAEPasS平臺各種基于Web的服務(wù)管理系統(tǒng)的設(shè)計(jì)及開發(fā),在DevOps方面積累了豐富的經(jīng)驗(yàn)。Docker引擎代碼貢獻(xiàn)者,在Docker開源項(xiàng)目中代碼貢獻(xiàn)量全球排名50名左右。
Mongo在很早就支持了replication set和sharding集群。經(jīng)過了這么多年的沉淀,Mongo集群的成熟度已非常穩(wěn)定,被大量公司用到自己的生產(chǎn)環(huán)境下。如何使用容器技術(shù)來實(shí)現(xiàn)Mongo集群的1鍵式交付部署,屏蔽底層實(shí)現(xiàn)的細(xì)節(jié),是很多人關(guān)心的話題。
本文將給大家介紹基于進(jìn)程的容器技術(shù)實(shí)現(xiàn)Mongo sharding集群的1鍵部署,充分展現(xiàn)了容器的強(qiáng)大威力。
Mongo(mongodb.com)作為流行的文檔數(shù)據(jù)庫,有很多有趣的特性,比如內(nèi)置failover、支持文件存儲、支持mapreduce和可以在服務(wù)器端直接運(yùn)行js腳本,固然我們今天最關(guān)心的是它內(nèi)置的sharding功能。散布式系統(tǒng)的設(shè)計(jì)向來具有很高的挑戰(zhàn),在最近1些年,隨著互聯(lián)網(wǎng)的發(fā)展,散布式的實(shí)踐逐漸開始得到推行和重視。
如果要深入了解Mongo sharding的原理,參考:
https://docs.mongodb.com/manual/sharding
mongo集群觸及到多個(gè)服務(wù),包括:
本次部署,configdb3臺,mongo數(shù)據(jù)節(jié)點(diǎn)12臺,分成4個(gè)分片,每一個(gè)分片1主2從
Mongo官方已提供了Mongo 3.2的鏡像,可以用來作為Mongo集群的鏡像.為了減少后續(xù)保護(hù)工作,我們盡量不構(gòu)建自己的鏡像。
下面我們依照mongo sharding官方的部署文檔,1步步編排集群。
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()
我們通過添加1個(gè)one-off的服務(wù)configsvr-init
,該服務(wù)履行初始化動作后將會自動退出
至此,configdb的編排算是完成了。我們接下來編排mongos服務(wù)
# 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的配置文件我們1般放到/etc/下
注意cmd里履行的是mongos
mongos必須在configdb集群初始化后運(yùn)行, 接下來我們開始編排mongo的數(shù)據(jù)節(jié)點(diǎn)服務(wù),這是集群中最復(fù)雜的部份
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
表示每一個(gè)主有幾個(gè)從,默許為2
這里將123個(gè)容器編為RS0,456編為RS1,789編為RS2,10,11,12編為RS3
有了上面的數(shù)據(jù)節(jié)點(diǎn)后,我們發(fā)現(xiàn),還沒有初始化replset,也未將每一個(gè)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
上面的腳本略微有點(diǎn)復(fù)雜,基本邏輯就是,先初始化每一個(gè)replicaset集群RS0..RS3,并將每一個(gè)RS加入到sharding集群當(dāng)作分片slices。具體可以參考上面的部署拓?fù)鋱D。
該服務(wù)是one-off履行
到這里mongo sharding集群的編排工作基本就完成了。接下來我們?yōu)閙ongo服務(wù)添加1個(gè)可視化面板,方便我們的使用
至此,編排工作全部完成。下面我們來測試剛才的工作成果。。
點(diǎn)擊部署,生成1個(gè)利用實(shí)例,我們命名為m
。
我們看1下shard-init的初始化輸出:
我們看1下面板e(cuò)xpress的輸出:
這是mongo express的首頁,可以查看到該mongos上的訪問概括
我們查看config這個(gè)db下表里的數(shù)據(jù),特別是和集群配置有關(guān)的:
mongos表:
有哪些分片呢?我們看到了RS0 RS1 RS2 RS3:
我們可以創(chuàng)建1個(gè)名為csphere的db試試:
后續(xù),可以參考mongo文檔,在開發(fā)中,設(shè)置您的sharding key等。更進(jìn)1步的mongodb管理,請參考官方文檔
從mongodb集群的自動化交付看全部編排進(jìn)程,我們發(fā)現(xiàn)背后的魔法關(guān)鍵是:DISCOVERY ALL,發(fā)現(xiàn)所有的東西并使之具有可編程特性。
Q1: 你好 目前這個(gè)的實(shí)際利用情況如何?有何挑戰(zhàn)?
A1: 實(shí)際測試運(yùn)行良好。挑戰(zhàn)在于編排進(jìn)程,背后的discovery能力能否滿足自動化的能力。在實(shí)際生產(chǎn)中,可以優(yōu)化您的配置文件,如挑戰(zhàn)timeout等,或日志的loglevel
Q2: 模板文件通過甚么語言進(jìn)行渲染,通過甚么流程發(fā)現(xiàn)啟動容器的信息?
A2: 希云cSphere平臺背后有1套強(qiáng)大的配置模版引擎,golang模版。平臺的調(diào)和中心可以發(fā)現(xiàn)各種參數(shù)并進(jìn)行可編程去應(yīng)對自動化挑戰(zhàn)
Q3: 你好 mongodb群集性能瓶頸,監(jiān)控指標(biāo)你覺得最重要的是甚么,擴(kuò)容的時(shí)候要注意甚么?
A3: mongo集群在使用上注意存儲引擎的選擇,在3.2之前是mmap,3.2已調(diào)劑,新的默許引擎能夠更好的處理大數(shù)據(jù)量的問題。mongo的水平擴(kuò)大本身很好,注意mongos代理部署的多1點(diǎn),避免流量從單個(gè)mongos流入流出
電話 010⑹2249349
郵箱 docker@csphere.cn
官網(wǎng) http://csphere.cn