MongoDB創建副本集

CentOS6平臺安裝MongoDB3.2副本集


一,3臺機器全部安裝部署mongod

1,下載安裝包,並解壓tgz

curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.10.tgz

tar xf mongodb-linux-x86_64-3.2.10.tgz

mv mongodb-linux-x86_64-3.2.10 /usr/local/mongodb


2,,可執行文件添加到 PATH 路徑中:

export PATH=/usr/local/mongodb/bin:$PATH

echo 'export PATH=/usr/local/mongodb/bin:$PATH' > /etc/profile.d/mongodb.sh


3,關閉大頁面內存

echo never > /sys/kernel/mm/transparent_hugepage/enabled

echo never > /sys/kernel/mm/transparent_hugepage/defrag

echo "if test -f /sys/kernel/mm/transparent_hugepage/enabled;then    

   echo never > /sys/kernel/mm/transparent_hugepage/enabled

fi

if test -f /sys/kernel/mm/transparent_hugepage/defrag;then

   echo never > /sys/kernel/mm/transparent_hugepage/defrag

fi" >> /etc/rc.d/rc.local


4,限制

ulimit -f unlimited  

ulimit -t unlimited  

ulimit -v unlimited  

ulimit -n 64000  

ulimit -m unlimited  

ulimit -u 64000  


5,創建數據庫目錄

mkdir -p /data0/mongodb/shardA/data

mkdir -p /data0/logs/mongodb/


6,運行MongoDB服務  

(1)編寫配置文件

cat /data0/mongodb/shardA/mongo27017.conf

#mongodb shardA 27017


replSet=shardA

dbpath=/data0/mongodb/shardA/data

logpath=/data0/logs/mongodb/27017.log

#bind=192.168.9.168,127.0.0.1

port=27017

fork=true

maxConns=20000

logappend=true

smallfiles=true

(2)啓動

/usr/local/mongodb/bin/mongod -f /data0/mongodb/shardA/mongo27017.conf


#其他方式啓動

命令行指定dbpath和port

/usr/local/mongodb/bin/mongod --dbpath=/data0/mongodb/shardA --port 27017 &# 默認端口爲27017

命令行指定dbpath和port,並啓動web界面

/usr/local/mongodb/bin/mongod --dbpath=/data0/mongodb/shardA --port 27017 --rest &      #web默認端口爲28017


7,查看是否啓動正常

netstat -lnptu | grep 27017

ps auxf | grep mongod | grep -v grep

MongoDB後臺管理shell

/usr/local/mongodb/bin/mongo 127.0.0.1:27017/test

/usr/local/mongodb/bin/mongo  --port 27017


二,配置副本集

1,#連接一臺mongo

# /usr/local/mongodb/bin/mongo 192.168.9.168:27017

MongoDB shell version: 3.2.10

2,# 配置168爲主,176爲從,225爲仲裁節點,priority最大爲主節點,arbiterOnly僅作爲仲裁

> cfg={_id:"shardA", members:[{_id:0,host:'192.168.9.168:27017',priority:2},{_id:1,host:'192.168.9.176:27017',priority:1},{_id:2,host:'192.168.9.225:27017',arbiterOnly:true}]};

{

"_id" : "shardA",

"members" : [

{

"_id" : 0,

"host" : "192.168.9.168:27017",

"priority" : 2

},

{

"_id" : 1,

"host" : "192.168.9.176:27017",

"priority" : 1

},

{

"_id" : 2,

"host" : "192.168.9.225:27017",

"arbiterOnly" : true

}

]

}

# 初始化

> rs.initiate(cfg)

{ "ok" : 1 }


# 也可以手動添加

> rs.initiate()

> rs.add("192.168.9.176:27017")

> rs.add("192.168.9.225:27017",{arbiterOnly:true})

{ "ok" : 1 }

# 刪除節點

> rs.remove()


3,查看狀態

#查看配置內容

> rs.conf()

#查看狀態信息

> rs.status()

#查看是否爲主節點

> db.isMaster()


4,主節點插入數據

mongo 192.168.9.176:27017

> show dbs

> use Atest

> for (i=0;i<=1000;i++) db.coltest.insert({count:i})

> show tables

> db.coltest.count()

> db.coltest.find()


mongo 192.168.9.168:27017

> rs.slaveOk()

> show dbs

> show tables

> db.coltest.count()

> db.coltest.find()

shardA:SECONDARY> db.coltest.insert({"count":"10003"})

WriteResult({ "writeError" : { "code" : 10107, "errmsg" : "not master" } })



三,故障轉移測試

1,關閉主節點

mongo 192.168.9.176:27017

shardA:PRIMARY> use admin

switched to db admin

shardA:PRIMARY> db.shutdownServer()

server should be down...

2017-11-30T14:13:23.223+0800 I NETWORK  [thread1] trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed

2017-11-30T14:13:24.116+0800 I NETWORK  [thread1] Socket recv() errno:104 Connection reset by peer 127.0.0.1:27017

2017-11-30T14:13:24.116+0800 I NETWORK  [thread1] SocketException: remote: (NONE):0 error: 9001 socket exception [RECV_ERROR] server [127.0.0.1:27017]

2017-11-30T14:13:24.116+0800 I NETWORK  [thread1] reconnect 127.0.0.1:27017 (127.0.0.1) failed failed

2017-11-30T14:13:24.118+0800 I NETWORK  [thread1] trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed

2017-11-30T14:13:24.118+0800 W NETWORK  [thread1] Failed to connect to 127.0.0.1:27017, reason: errno:111 Connection refused

2017-11-30T14:13:24.118+0800 I NETWORK  [thread1] reconnect 127.0.0.1:27017 (127.0.0.1) failed failed

>


2,查看備用節點會成爲主節點

shardA:SECONDARY>

shardA:PRIMARY> rs.status()

{

"set" : "shardA",

"date" : ISODate("2017-11-30T06:13:57.404Z"),

"myState" : 1,

"term" : NumberLong(3),

"heartbeatIntervalMillis" : NumberLong(2000),

"members" : [

{

"_id" : 0,

"name" : "192.168.9.168:27017",

"health" : 1,

"state" : 1,

"stateStr" : "PRIMARY",

"uptime" : 74322,

"optime" : {

"ts" : Timestamp(1512022413, 1),

"t" : NumberLong(3)

},

"optimeDate" : ISODate("2017-11-30T06:13:33Z"),

"infoMessage" : "could not find member to sync from",

"electionTime" : Timestamp(1512022412, 1),

"electionDate" : ISODate("2017-11-30T06:13:32Z"),

"configVersion" : 1,

"self" : true

},

{

"_id" : 1,

"name" : "192.168.9.176:27017",

"health" : 0,

"state" : 8,

"stateStr" : "(not reachable/healthy)",

"uptime" : 0,

"optime" : {

"ts" : Timestamp(0, 0),

"t" : NumberLong(-1)

},

"optimeDate" : ISODate("1970-01-01T00:00:00Z"),

"lastHeartbeat" : ISODate("2017-11-30T06:13:56.562Z"),

"lastHeartbeatRecv" : ISODate("2017-11-30T06:13:21.617Z"),

"pingMs" : NumberLong(0),

"lastHeartbeatMessage" : "Connection refused",

"configVersion" : -1

},

{

"_id" : 2,

"name" : "192.168.9.225:27017",

"health" : 1,

"state" : 7,

"stateStr" : "ARBITER",

"uptime" : 70496,

"lastHeartbeat" : ISODate("2017-11-30T06:13:56.543Z"),

"lastHeartbeatRecv" : ISODate("2017-11-30T06:13:52.776Z"),

"pingMs" : NumberLong(0),

"configVersion" : 1

}

],

"ok" : 1

}

shardA:PRIMARY>


3,重新啓動原主節點,現主節點還會切過去

shardA:SECONDARY> db.isMaster()

{

"hosts" : [

"192.168.9.168:27017",

"192.168.9.176:27017"

],

"arbiters" : [

"192.168.9.225:27017"

],

"setName" : "shardA",

"setVersion" : 1,

"ismaster" : false,

"secondary" : true,

"primary" : "192.168.9.176:27017",

"me" : "192.168.9.168:27017",

"maxBsonObjectSize" : 16777216,

"maxMessageSizeBytes" : 48000000,

"maxWriteBatchSize" : 1000,

"localTime" : ISODate("2017-11-30T06:20:47.355Z"),

"maxWireVersion" : 4,

"minWireVersion" : 0,

"ok" : 1

}


4,關閉副本集


五,維護相關

1,先關閉從節點、仲裁節點。或者先關閉仲裁節點,最後關閉從節點。則:主節點自動變爲從節點

2,先關閉主節點,則從節點自動變爲主節點,在仲裁節點關閉之前,新主節點不能關閉


初始化的時候主備節點受priority的影響

priority: 是優先級,默認爲1,優先級0爲被動節點,不能成爲活躍節點。優先級不爲0則按照由大到小選出活躍節點。


rs輔助函數

> rs.help()

rs.status()                                { replSetGetStatus : 1 } checks repl set status

rs.initiate()                              { replSetInitiate : null } initiates set with default settings

rs.initiate(cfg)                           { replSetInitiate : cfg } initiates set with configuration cfg

rs.conf()                                  get the current configuration object from local.system.replset

rs.reconfig(cfg)                           updates the configuration of a running replica set with cfg (disconnects)

rs.add(hostportstr)                        add a new member to the set with default attributes (disconnects)

rs.add(membercfgobj)                       add a new member to the set with extra attributes (disconnects)

rs.addArb(hostportstr)                     add a new member which is arbiterOnly:true (disconnects)

rs.stepDown([stepdownSecs, catchUpSecs])   step down as primary (disconnects)

rs.syncFrom(hostportstr)                   make a secondary sync from the given member

rs.freeze(secs)                            make a node ineligible to become primary for the time specified

rs.remove(hostportstr)                     remove a host from the replica set (disconnects)

rs.slaveOk()                               allow queries on secondary nodes


rs.printReplicationInfo()                  check oplog size and time range

rs.printSlaveReplicationInfo()             check replica set members and replication lag

db.isMaster()                              check who is primary


reconfiguration helpers disconnect from the database so the shell will display

an error, even if the command succeeds.


六,設計副本集

1,副本集重要的一個概念是"大多數",大多數爲一半以上的成員

比如5個成員的副本集,有3個爲網絡不可達,仍有二個可以正常工作,但達不到大多數的要求,所以無法選出主節點,如果 有個是主節點,會切換爲備節點;

主要防止,3個網絡不可達,爲3個可通信,防止出現2個主節點;


2,推薦模式有:

一個數據中心奇數成員

倆個數據中心奇數成員,將大多數放在一個數據中心

三個數據中心,倆個相等數量成員的數據中心,一個爲決定主節點的數據中心


3,選舉機制

當一個備份節點無法與主節點連通時,它會聯繫並請求其他的副本集成員將自己選舉爲自己。

其它成員會做幾項理性的檢查:

(1)自身是否能夠與主節點通信

(2)希望被選舉爲主節點的備份節點的數據是否爲最新

(3)有沒有其他更高優先級的成員可以被選舉爲主節點


七,成員配置項

1,選舉仲裁者

只參與選舉,並不保存數據

(1)最多只能有一個仲裁者

(2)如果節點數爲奇數,則不需要仲裁者

# 添加仲裁成員

rs.addArb("192.168.9.168:27017")

rs.add({_id:2,host:'192.168.9.225:27017',arbiterOnly:true})

2,優先級

優先級取值範圍0-100,默認爲1,0爲永遠不可以成爲主節點,這樣的稱爲被動成員

優先級越高,且擁有最新的數據,那麼會被選舉爲主節點

3,隱藏成員

客戶端不會向隱藏成員發送請求,隱藏成員也不會作爲複製源

hidden:true 只有優先級0的成員 才能被隱藏

4,延遲備份節點


八,同步

複製用於多臺服務器之間的備份數據。使用操作日誌oplog實現的。

oplog是主節點local數據庫中一個固定集合,備份節點通過查詢這個集合就可以知道需要進行復制的操作

1,初始化同步

(1)成員會做一些記錄前的準備工作:選擇一個成員作爲同步源,在local.me中爲自己創建一個標識符,刪除所有已存在的數據庫,重新同步

(2)克隆,將同步源的所有記錄全部複製到本地

(3)進入oplog同步的第一步,克隆中的所有操作都會被記錄到oplog中

(4)oplog同步的第二步,用於將第一個oplog同步中的操作記錄下來

(5)本地數據應該與主節點在某個時間點的數據集完全一致了,可以創建索引

(6)當前節點的數據如果仍落後於同步源,那麼oplog同步過程的最後一步就是將創建索引期間的所有操作全部同步過來,防止該成員成爲備份節點

(7)當前成員完成初始化同步,切換到普通同步狀態


九,心跳

成員每隔2s會向其他成員發送一個心跳請求

成員狀態:

1,STARTUP    

成員剛啓動時處於這個狀態。mongodb會嘗試加載成員的副本集配置。加載成功後,會進入STARTUP2

2,STARTUP2    

整個初始化同步過程 都處於這個狀態

3,RECOVERING

4,ARBITER

5,DOWN

6,UNKNOWN

7,REMOVED

8,ROLLBACK

9,FATAL


十,管理

1,以單機模式啓動成員

(1)查看命令行參數

> db.serverCmdLineOpts()

(1)如果要對這臺服務器維護,可以重啓;重啓時不適用 replSet選項。這樣會成爲一個單機的mongod,可以進行讀和寫

(2)可以改變監聽端口,dbpath值不變

(3)維護完後,以最原始的參數重新啓動後會自動與副本集的其他成員進行同步。


2,副本集配置

(1)創建副本集

# 配置168爲主,176爲從,225爲仲裁節點,priority最大爲主節點,arbiterOnly僅作爲仲裁

> cfg={_id:"shardA", members:[{_id:0,host:'192.168.9.168:27017',priority:2},{_id:1,host:'192.168.9.176:27017',priority:1},{_id:2,host:'192.168.9.225:27017',arbiterOnly:true}]};

# 初始化

> rs.initiate(cfg)

(2)修改副本集成員

a)增加成員

rs.add("192.168.9.169:27017")

文檔形式添加指定複雜的配置

rs.add({_id:4,host:'192.168.9.169:27017',priority:1})

b)移除成員

rs.remove("192.168.9.169:27017")

c)通過rs.config修改

> var config = rs.config()

> config.members[0].host = "192.168.9.179:27017"

> rs.reconfig(config)

注意點:

不能修改成員的_id字段

不能將接收rs.reconfig命令的成員的優先級設爲0

不能將仲裁成員變爲非仲裁成員

不能將"buildIndexes":false的成員修改爲"buildIndexes":true


3,創建比較大的副本集

副本集的最多隻能擁有12個成員,其中只有7個成員擁有投票權

如果要創建7個以上成員的副本集,只有7個成員可以擁有投票權,需要其他成員的投票數量設置爲0

> rs.add({"_id":7,"host":server-7:27017,"votes":0})


4,修改成員狀態

# 主節點變爲備節點

# 默認爲60s

> rs.stepDown(time)

# 阻止選舉,始終處於備節點

> rs.freeze(time)

# 強制進入維護模式

> db.adminCommand({"replSetMaintenance":true})

# 退出進入維護模式

> db.adminCommand({"replSetMaintenance":false})


5,狀態

# 查看同步狀態

> db.printSlaveReplicationInfo()

# 查看同步源

> db.adminCommand({"replSetGetStatus":1}).syncingTo

192.168.9.176:27017

# 指定複製源

> secondary.adminCommand({"replSetSyncFrom":"server0:27017"})

# 禁用複製鏈


# 複製延遲查看

#  主節點上

> db.printReplicationInfo()

# 備節點上

> db.printSlaveReplicationInfo()





報錯:

shardA:SECONDARY> show dbs

2017-11-30T13:57:10.376+0800 E QUERY    [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435 } :

_getErrorWithCode@src/mongo/shell/utils.js:25:13

Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1

shellHelper.show@src/mongo/shell/utils.js:761:19

shellHelper@src/mongo/shell/utils.js:651:15

@(shellhelp2):1:1


原因:爲了保護應用程序,以免意外連接到備節點,讀取到過期數據。備份節點默認會拒絕請求。


解決:設置從備份節點讀取數據沒有問題.salveOk是對連接設置的,不是對數據庫設置的。。

> rs.slaveOk()



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