天天看點

mongodb叢集Replica Set +Sharding高可用叢集搭建(含認證)

一、概述

1、架構

<a href="http://s3.51cto.com/wyfs02/M00/43/D4/wKiom1PdqieR99GFAAHGncLefpc019.jpg" target="_blank"></a>

2、唠叨概念

Replica Set

中文翻譯:副本集

簡單的說叢集中包含了多份資料,保證主節點挂掉了,備用節點繼續提供資料服務,提供的前提就是資料需要主節點一緻

仲裁節點是一種特殊的節點,它本身不存儲資料,主要的作用是決定哪一個備用節點在主節點挂掉之後提升為主節點,是以用戶端不需要連接配接此節點。

這裡雖然隻有備節點,但是仍然需要一個仲裁節點來提升節點級别。我開始也不相信必須要有仲裁節點,但是自已也試過如果沒有仲裁節點的話

主節點挂掉後,備節點還是備節點,是以咱們還需要它的。

主節點和備用節點

主備節點存儲資料,仲裁節點不存儲資料

預設情況:主節點提供增删查改功能,備節點不提供任何服務。但是可以設定備節點提供查詢功能,這樣就可以減少主節點的壓力,當用戶端進行資料查詢時

請求自動轉到備用節點上,這個設定叫做Read Preference Modes,同時Java用戶端提供了簡單的配置方式,可以不必直接對資料庫操作。

二、位址和服務規劃

192.168.0.178 master mongos:20000 config:21000 shard1:22001 shard2:22002 shard3:22003

192.168.0.180 slave1 mongos:20000 config:21000 shard1:22001 shard2:22002 shard3:22003

192.168.0.181 slave2 mongos:20000 config:21000 shard1:22001 shard2:22002 shard3:22003

三、版本介紹

作業系統版本:CentOS 6.4 64bit

mongodb版本:2.6.1 二進制通用包

四、準備工作

1、關閉iptables和selinux防火牆

2、主機名互為解析(可參考,非必須)

3、伺服器之間時間同步(重點)

4、建立資料和日志存儲目錄

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<code>mkdir -p /data/mongodb</code>

<code>cd /data/mongodb</code>

<code>mkdir mongos</code>

<code>mkdir mongos/log</code>

<code>mkdir config</code>

<code>mkdir config/{data,log}</code>

<code>mkdir shard1</code>

<code>mkdir shard1/{data,log}</code>

<code>mkdir shard2</code>

<code>mkdir shard2/{data,log}</code>

<code>mkdir shard3</code>

<code>mkdir shard3/{data,log}   </code>

<code>cd ~</code>

五、mongodb安裝配置

1、下載下傳mongodb安裝包

2、下載下傳解壓mongodb二進制通用包,解壓後就能使用

tar xf mongodb-linux-x86_64-2.6.1.tgz -C /usr/local/

cd /usr/local/

ln -sv mongodb-linux-x86_64-2.6.1 mongodb

3、配置mongodb環境變量

cat &gt; /etc/profile.d/mongodb.sh &lt;&lt; EOF

export MONGODB_HOME=/usr/local/mongodb

export PATH=\$PATH:\$MONGODB_HOME/bin

EOF

source /etc/profile.d/mongodb.sh

六、啟動服務

1、分别在master、slave1和slave2伺服器上啟動配置伺服器

mongod --configsvr --dbpath /data/mongodb/config/data --port 21000 --logpath /data/mongodb/config/log/config.log --fork

2、分别在master、slave1和slave2伺服器上啟動mongos伺服器

mongos  --configdb 192.168.0.178:21000,192.168.0.180:21000,192.168.0.181:21000 --port 20000 --logpath  /data/mongodb/mongos/log/mongos.log --fork

3、分别在master、slave1和slave2伺服器上配置分片副本集

mongod --shardsvr --replSet shard1 --port 22001 --dbpath /data/mongodb/shard1/data  --logpath /data/mongodb/shard1/log/shard1.log --fork --nojournal  --oplogSize 10

mongod --shardsvr --replSet shard2 --port 22002 --dbpath /data/mongodb/shard2/data  --logpath /data/mongodb/shard1/log/shard2.log --fork --nojournal  --oplogSize 10

mongod --shardsvr --replSet shard3 --port 22003 --dbpath /data/mongodb/shard3/data  --logpath /data/mongodb/shard1/log/shard3.log --fork --nojournal  --oplogSize 10

4、登陸任意一台mongodb伺服器,比如

###設定第一個分片副本集,必須使用admin資料庫

mongo 192.168.0.178:22001/admin

#定義副本集

&gt; config = { _id:"shard1", members:[

                     {_id:0,host:"192.168.0.178:22001",priority:1},

                     {_id:1,host:"192.168.0.180:22001",priority:2},

                     {_id:2,host:"192.168.0.181:22001",arbiterOnly:true}

                ]

         }

#初始化副本集

&gt; rs.initiate(config);

###設定第二個分片副本集,必須使用admin資料庫

mongo 192.168.0.180:22002/admin

&gt; config = { _id:"shard2", members:[

                     {_id:0,host:"192.168.0.178:22002",arbiterOnly:true},

                     {_id:1,host:"192.168.0.180:22002",priority:1},

                     {_id:2,host:"192.168.0.181:22002",priority:2}

###設定第三個分片副本集,必須使用admin資料庫

mongo 192.168.0.181:22003/admin

&gt; config = { _id:"shard3", members:[

                     {_id:0,host:"192.168.0.178:22003",priority:2},

                     {_id:1,host:"192.168.0.180:22003",arbiterOnly:true},

                     {_id:2,host:"192.168.0.181:22003",priority:1}

5、目前搭建了mongodb配置伺服器、路由伺服器,各個分片伺服器,不過應用程式連接配接到 mongos 路由伺服器并不能使用分片機制,還需要在程式裡設定分片配置,讓分片生效。

mongo 192.168.0.178:20000/admin

#串聯路由伺服器與配置設定副本集1

db.runCommand( { addshard : "shard1/192.168.0.178:22001,192.168.0.180:22001,192.168.0.181:22001"});

#串聯路由伺服器與配置設定副本集2

db.runCommand( { addshard : "shard2/192.168.0.178:22002,192.168.0.180:22002,192.168.0.181:22002"});

#串聯路由伺服器與配置設定副本集3

db.runCommand( { addshard : "shard3/192.168.0.178:22003,192.168.0.180:22003,192.168.0.181:22003"});

6、檢視分片伺服器配置

db.runCommand({listshards : 1 });

指令輸出結果

mongos&gt; db.runCommand({listshards : 1 });

{

"shards" : [

"_id" : "shard1",

"host" : "shard1/192.168.0.178:22001,192.168.0.180:22001"

},

"_id" : "shard2",

"host" : "shard2/192.168.0.178:22002,192.168.0.180:22002"

"_id" : "shard3",

"host" : "shard3/192.168.0.178:22003,192.168.0.180:22003"

}

],

"ok" : 1

因為192.168.0.181是每個分片副本集的仲裁節點,是以在上面結果沒有列出來。

7、目前配置服務、路由服務、分片服務、副本集服務都已經串聯起來了,但我們的目的是希望插入資料,資料能夠自動分片,就差那麼一點點,一點點。。。

連接配接在mongos上,準備讓指定的資料庫、指定的集合分片生效。

#指定uba分片生效

db.runCommand( { enablesharding :"uba"});

#指定資料庫裡需要分片的集合和片鍵

db.runCommand( { shardcollection : "uba.table1",key : {id: 1} } )

我們設定uba的 table1 表需要分片,根據 id 自動分片到 shard1 ,shard2,shard3 上面去。要這樣設定是因為不是所有mongodb 的資料庫和表 都需要分片!

8、登陸mongos添加使用者

18

19

<code>[root@master ~]# mongo 192.168.0.178:20000/admin</code>

<code>MongoDB shell version: 2.6.1</code>

<code>connecting to: 192.168.0.178:20000/admin</code>

<code>mongos&gt; db</code>

<code>admin</code>

<code>mongos&gt; db.addUser(</code><code>'admin','allentuns')</code>

<code>WARNING: The </code><code>'addUser' shell helper is DEPRECATED. Please use 'createUser' instead</code>

<code>Successfully added user: { </code><code>"user"</code> <code>: </code><code>"admin"</code><code>, </code><code>"roles"</code> <code>: [ </code><code>"root"</code> <code>] }</code>

<code>mongos&gt; db.addUser(</code><code>'admin_read','allentuns_read',true)  #添加超級管理者可讀使用者</code>

<code>Successfully added user: { </code><code>"user"</code> <code>: </code><code>"admin_read"</code><code>, </code><code>"roles"</code> <code>: [ </code><code>"read"</code> <code>] }</code>

<code>mongos&gt; use uba</code>

<code>switched to db uba</code>

<code>mongos&gt; db.addUser(</code><code>'sa','123root')</code>

<code>Successfully added user: { </code><code>"user"</code> <code>: </code><code>"sa"</code><code>, </code><code>"roles"</code> <code>: [ </code><code>"dbOwner"</code> <code>] }</code>

<code>mongos&gt; db.addUser(</code><code>'sa_read','123root_read',true)   #添加uba管理者可讀使用者</code>

<code>Successfully added user: { </code><code>"user"</code> <code>: </code><code>"sa_read"</code><code>, </code><code>"roles"</code> <code>: [ </code><code>"read"</code> <code>] }</code>

9、關閉三台伺服器的mongod和mongos服務

killall mongos &amp;&amp; killall mongod

10、成keyfile:(每個程序的key file都保持一緻)

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

<code>[root</code><code>@master</code> <code>~]</code><code># openssl rand -base64 753 &gt;keyfile</code>

<code>[root</code><code>@master</code> <code>~]</code><code># chmod 600 keyfile #重點 必須</code>

<code>[root</code><code>@master</code> <code>~]</code><code># cat keyfile </code>

<code>4a7w479ouV6fY5CASqxeWzzPhPLzZgYnHKWOFSIxjMABjaWK7up6Keb2+ZKz1C2R</code>

<code>tfl7ukCBelW2xOL0h3gOSAdIhUi0j8IMBYZV/kbUSSf0987xIur3lHZqUINPVVyl</code>

<code>ib+XPrg3SO4IG25tCQbEf/twvS1CxiDmi/GtQZfqOjUX7MEJK3ynFBsB/9wU1nf1</code>

<code>6rLhBPIdmSnpNf5s9yGohx2wn6dQcJ8o0wn75oOBysX2mPkLI0tEu4//7x1PgY9Q</code>

<code>Ws4XdXs1MFqUYXkh8K6RFd/TKB2zs5fonzqiXrgwpaW1KUFZB1lAfQwWePmxsWul</code>

<code>HqR96/yTGPxQKOVpm1Zdj2LGa616X3Www16Td4c2UVoM7mPi+Js8R2Flc6oV9H+t</code>

<code>eEDLMIVRDAAuQBNZl1reye0iaL8F0SgoELPiEm4A2La+ovNrK6K+shV+jmvrOEIC</code>

<code>6KJly68ZX6x+Xd5qxfoREYKsrwMJJYY1tWesUE+26QUs4TJB17uQzc1wJaRQK0pz</code>

<code>4B3E4DFzJT72ybaGFpbP4v9gMfoXXc6pPWEJ1LMvhvv4vNl5vDSpbS3YNUQjaTcU</code>

<code>juM2FlcUeKe3VFdqHkvdrhORv52gcrqnXco7UojOYmOHRpefXmL49XLlqw9FOJ2u</code>

<code>giGKSs06OaK7kyiVayUT4fUR+OXVOAAbPRgaNbDcI9P5knWkYwNdAwP+jH9h73nI</code>

<code>ZqdZ7SvDW0/iT6zbPfeQubSYJw//NG5gfN5Rsd5oEpXXz8bFnuJSC1ltzJenTYYN</code>

<code>0vsS/8EpUKhbLYjo5c93SBjopODBfA5pqQ9hRoL36l9SfWnUVgYaqpJgvKUmwb9P</code>

<code>1Bz1YCLRo1cU9skz+chhRnZWp2c2ElMfdMD/XpcAbgY1KToEJFAkTiNRHvgPYjiw</code>

<code>eGgEBSXlMBlKDkNqmLZ6i/C5fCWsqDEDrMPtBM4Pp9SOPjbkwpwYHxBCUPM7oyQT</code>

<code>fCisA72oOBB5L4vO55soTzX+jBBrOTBaJhdsEUMC0rEq</code>

<code>#将生成的keyfile 拷貝到mongod/mongos/config 程序對應的檔案夾</code>

<code>[root</code><code>@master</code> <code>~]</code><code># cp keyfile /data/mongodb/config/data/</code>

<code>[root</code><code>@master</code> <code>~]</code><code># cp keyfile /data/mongodb/mongos/</code>

<code>[root</code><code>@master</code> <code>~]</code><code># cp keyfile /data/mongodb/shard1/data/</code>

<code>[root</code><code>@master</code> <code>~]</code><code># cp keyfile /data/mongodb/shard2/data/</code>

<code>[root</code><code>@master</code> <code>~]</code><code># cp keyfile /data/mongodb/shard3/data/</code>

<code>然後通過scp的方式把這個檔案分别拷貝到slave1和slave2機器的對應目錄中</code>

<code>驗證slave1伺服器的keyfile檔案</code>

<code>[root</code><code>@slave1</code> <code>~]</code><code># find /data/mongodb -name keyfile</code>

<code>/data/mongodb/shard2/data/keyfile</code>

<code>/data/mongodb/shard1/data/keyfile</code>

<code>/data/mongodb/shard3/data/keyfile</code>

<code>/data/mongodb/config/data/keyfile</code>

<code>/data/mongodb/mongos/keyfile</code>

<code>驗證slave2伺服器的keyfile檔案</code>

<code>[root</code><code>@slave2</code> <code>~]</code><code>#  find /data/mongodb -name keyfile</code>

使用--keyFile參數指定前面生成的keyfile檔案,重新開機三台機器全部mongod,mongos程序 

mongod --configsvr --dbpath /data/mongodb/config/data --port 21000 --logpath /data/mongodb/config/log/config.log --fork --keyFile /data/mongodb/config/data/keyfile

#注意在這個過程中,會報錯,隻需要再次執行chmod 600 /data/mongodb/config/data/keyfile 就可以

mongos  --configdb 192.168.0.178:21000,192.168.0.180:21000,192.168.0.181:21000 --port 20000  --keyFile /data/mongodb/mongos/keyfile --logpath  /data/mongodb/mongos/log/mongos.log --fork

#執行chmod 600 /data/mongodb/mongos/keyfile 

mongod --shardsvr --replSet shard1 --port 22001 --keyFile /data/mongodb/shard1/data/keyfile --dbpath /data/mongodb/shard1/data  --logpath /data/mongodb/shard1/log/shard1.log --fork --nojournal  --oplogSize 10

mongod --shardsvr --replSet shard2 --port 22002 --keyFile /data/mongodb/shard2/data/keyfile --dbpath /data/mongodb/shard2/data  --logpath /data/mongodb/shard1/log/shard2.log --fork --nojournal  --oplogSize 10

mongod --shardsvr --replSet shard3 --port 22003 --keyFile /data/mongodb/shard3/data/keyfile --dbpath /data/mongodb/shard3/data  --logpath /data/mongodb/shard1/log/shard3.log --fork --nojournal  --oplogSize 10

#執行以下

chmod 600 /data/mongodb/shard1/data/keyfile 

chmod 600 /data/mongodb/shard2/data/keyfile 

chmod 600 /data/mongodb/shard3/data/keyfile 

驗證認證

需要認證,沒有認證沒有任何權限

<code>[root@master ~]# mongo localhost:20000</code>

<code>connecting to: localhost:20000/test</code>

<code>Error while trying to show server startup warnings: not authorized on admin to execute command { getLog: "startupWarnings" }</code>

<code>mongos&gt; show collections;</code>

<code>2014-08-03T12:02:48.535+0800 error: {</code>

<code>    </code><code>"$err" : "not authorized for query on test.system.namespaces",</code>

<code>    </code><code>"code" : 13</code>

<code>} at src/mongo/shell/query.js:131</code>

<code>uba</code>

<code>2014-08-03T12:03:10.923+0800 error: { "$err" : "not authorized for query on uba.system.namespaces", "code" : 13 } at src/mongo/shell/query.js:131</code>

賬戶認證後狀态

44

45

46

47

48

49

50

51

52

53

54

55

56

57

<code>#admin庫認證</code>

<code>[root</code><code>@master</code> <code>~]</code><code># mongo localhost:20000/admin -u admin -p allentuns</code>

<code>connecting to: localhost:20000/admin</code>

<code>system.indexes</code>

<code>system.users</code>

<code>system.version</code>

<code>#uba庫認證 讀寫權限使用者</code>

<code>[root</code><code>@master</code> <code>~]</code><code># mongo localhost:20000/uba -u sa -p 123root</code>

<code>connecting to: localhost:20000/uba</code>

<code>Error </code><code>while</code> <code>trying to show server startup warnings: not authorized on admin to execute command { getLog: </code><code>"startupWarnings"</code> <code>}</code>

<code>table1</code>

<code>mongos&gt; db.table1.count()</code>

<code>0</code>

<code>mongos&gt; </code><code>for</code> <code>(var i = 1; i &lt;= 1000; i++)db.table1.save({id:i,name:</code><code>"username"</code><code>+i,age:i});</code>

<code>WriteResult({ </code><code>"nInserted"</code> <code>: 1 })</code>

<code>1000</code>

<code>mongos&gt; db.table1.findOne()</code>

<code>{</code>

<code>    </code><code>"_id"</code> <code>: ObjectId(</code><code>"53ddb52a65bb900f61e458a1"</code><code>),</code>

<code>    </code><code>"id"</code> <code>: 1,</code>

<code>    </code><code>"name"</code> <code>: </code><code>"username1"</code><code>,</code>

<code>    </code><code>"age"</code> <code>: 1</code>

<code>}</code>

<code>mongos&gt; db.auth(</code><code>'sa'</code><code>,</code><code>'123root'</code><code>)</code>

<code>1</code>

<code>#uba庫 隻讀權限使用者</code>

<code>[root</code><code>@master</code> <code>~]</code><code># mongo localhost:20000/uba -u sa_read -p 123root_read</code>

<code>mongos&gt; db.auth(</code><code>'sa_read'</code><code>,</code><code>'123root_read'</code><code>)</code>

<code>WriteResult({</code>

<code>    </code><code>"writeError"</code> <code>: {</code>

<code>        </code><code>"code"</code> <code>: 13,</code>

<code>        </code><code>"errmsg"</code> <code>: </code><code>"not authorized on uba to execute command { insert: \"</code><code>table1\</code><code>", documents: [ { id: 1000.0, name: \"</code><code>username1000\</code><code>", age: 1000.0, _id: ObjectId('53ddb5d62390d9a487087c87') } ], ordered: true }"</code>

<code>    </code><code>}</code>

<code>})</code>

<a href="http://s3.51cto.com/wyfs02/M01/43/D6/wKioL1PduAyhnmzZAAQPdFvKl0M958.jpg" target="_blank"></a>

驗證主從切換,現在在192.168.0.180 slave1叢集上停掉22001端口的服務,看master是否能接替slave1主的工作

<code>[root@slave1 ~]</code><code># netstat -tnlp |grep mongo</code>

<code>tcp        0      0 0.0.0.0:22001               0.0.0.0:*                   LISTEN      1955/mongod         </code>

<code>tcp        0      0 0.0.0.0:22002               0.0.0.0:*                   LISTEN      2019/mongod         </code>

<code>tcp        0      0 0.0.0.0:22003               0.0.0.0:*                   LISTEN      2081/mongod         </code>

<code>tcp        0      0 0.0.0.0:20000               0.0.0.0:*                   LISTEN      1870/mongos         </code>

<code>tcp        0      0 0.0.0.0:21000               0.0.0.0:*                   LISTEN      1847/mongod         </code>

<code>[root@slave1 ~]</code><code># kill 1955</code>

<code>tcp        0      0 0.0.0.0:21000               0.0.0.0:*                   LISTEN      1847/mongod    </code>

<code>[root@slave1 ~]</code><code># mongo 192.168.0.178:22001/admin</code>

<code>connecting to: 192.168.0.178:22001/admin</code>

<code>Welcome to the MongoDB shell.</code>

<code>For interactive help, type </code><code>"help"</code><code>.</code>

<code>For more comprehensive documentation, see</code>

<code>    </code><code>http:</code><code>//docs.mongodb.org/</code>

<code>Questions? Try the support group</code>

<code>    </code><code>http:</code><code>//groups.google.com/group/mongodb-user</code>

<code>shard1:PRIMARY&gt; ^C</code>

<code>bye</code>

<code>[root@slave1 ~]</code><code># mongo 192.168.0.178:22002/admin</code>

<code>connecting to: 192.168.0.178:22002/admin</code>

<code>shard2:ARBITER&gt; ^C</code>

<code>[root@slave1 ~]</code><code># mongod --shardsvr --replSet shard1 --port 22001 --keyFile /data/mongodb/shard1/data/keyfile --dbpath /data/mongodb/shard1/data  --logpath /data/mongodb/shard1/log/shard1.log --fork --nojournal  --oplogSize 10</code>

<code>about to fork child process, waiting until server is ready </code><code>for</code> <code>connections.</code>

<code>forked process: 2641</code>

<code>child process started successfully, parent exiting</code>

<code>[root@slave1 ~]</code><code># mongo 192.168.0.180:22001/admin</code>

<code>connecting to: 192.168.0.180:22001/admin</code>

<code>shard1:SECONDARY&gt;</code>

<code></code>

     本文轉自zys467754239 51CTO部落格,原文連結:http://blog.51cto.com/467754239/1534527,如需轉載請自行聯系原作者