MongoDB復制集技術
第1章 MongoDB復制集簡介:
一組MongoDB復制集,就是一組MongoDB進程,這些進程維護同一個數據集合,復制集提供了數據冗余和高等級的可靠性,這是生產部署的基礎
1.1 復制集的目的:
保證數據在生產部署是的冗余和可靠性,通過在不同的機器上保存副本來保證數據的不會因為單間損壞而丟失,能夠隨時應對數據丟失或者機器損壞帶來的風險
還可以提高用戶讀寫數據的性能,提高整個系統的負載
1.2 簡單介紹:
1. 一組復制集就是一組MongoDB實例掌管同一個數據集,實例可以在不同的機器上面,實例中包含一個主導,接受客戶端所有的寫入操作,其他都是副本實例,從主服務器上獲得數據並保持同步
2. 主服務器很重要,包含了所有的改變操作的日誌,但是副本服務器集群包含所有的主服務器數據,因此當主服務器掛掉了,就會在副本服務器上重新選取一個成為主服務器
3. 每個復制集還有一個仲裁者,仲裁者不存儲數據,只是負責通過心跳包來確認集群中集合的數量,並在主服務器選舉的時候作為仲裁決定結果
1.3 復制集的基本架構:
基本的架構由三臺服務器組成,一個三成員的復制集,由三個有數據,或者兩個有數據,一個作為仲裁者
1.3.1 三個存儲數據的復制集:
主庫宕機時,兩個從都可以被選為主庫
當主庫宕機後,兩個從庫都會進行競選,其中一個變為主庫,當原主恢復後,作為從庫加入當前的復制集群即可
1.1.1 存在 arbiter節點的復制集:
兩個正常的主從,及一臺arbiter節點
當主庫宕機時,從庫成為主,主庫修復後,將其加入現有的復制集群即可
1.1 復制集中成員說明:
成員 | 說明 |
Secondary | 正常情況下,復制集的Seconary會參與Primary選舉(自身也可能會被選為Primary),並從Primary同步最新寫入的數據,以保證與Primary存儲相同的數據。 Secondary可以提供讀服務,增加Secondary節點可以提供復制集的讀服務能力,同時提升復制集的可用性。另外,Mongodb支持對復制集的Secondary節點進行靈活的配置,以適應多種場景的需求。 |
Arbiter | Arbiter節點只參與投票,不能被選為 比如你部署了一個2個節點的復制集,1個Primary,1個Secondary,任意節點宕機,復制集將不能提供服務了(無法選出Primary),這時可以給復制集添加一個Arbiter節點,即使有節點宕機,仍能選出Primary。 Arbiter本身不存儲數據,是非常輕量級的服務,當復制集成員為偶數時,最好加入一個Arbiter節點,以提升復制集可用性。 |
Priority0 | Priority0節點的選舉優先級為0,不會被選舉為Primary 比如你跨機房A、B部署了一個復制集,並且想指定Primary必須在A機房,這時可以將B機房的復制集成員Priority設置為0,這樣Primary就一定會是A機房的成員。 (註意:如果這樣部署,最好將『大多數』節點部署在A機房,否則網絡分區時可能無法選出Primary) |
Vote0 | Mongodb 3.0裏,復制集成員最多50個,參與Primary選舉投票的成員最多7個,其他成員(Vote0)的vote屬性必須設置為0,即不參與投票。 |
Hidden | Hidden節點不能被選為主(Priority為0),並且對Driver不可見。因Hidden節點不會接受Driver的請求,可使用Hidden節點做一些數據備份、離線計算的任務,不會影響復制集的服務。 |
Delayed | Delayed節點必須是Hidden節點,並且其數據落後與Primary一段時間(可配置,比如1個小時)。 因Delayed節點的數據比Primary落後一段時間,當錯誤或者無效的數據寫入Primary時,可通過Delayed節點的數據來恢復到之前的時間點。 |
1.1.1 Priority 節點
作為一個輔助可以作為一個備用,調整選主的權重
1.1.1 hidden隱藏節點
客戶端將不會把讀請求分發到隱藏節點上,即使我們設定了讀選項,這些隱藏節點將不會收到應用程序的請求,因此隱藏節點一般用與報表節點或者備份節點,延時節點也應該是一個隱藏節點
1.1.1 Delayed延時節點
延時節點的數據集是延時的,因此它可以幫助我們在人為誤操作或其他意外情況下恢復數據
例如當應用升級失敗,或者誤操作時,我們可以通過延時節點進行恢復數據
第1章 復制集架構實現:
1.1 準備多實例環境:
在mongod用戶下操作:
for i in 280{17..20} ; do
mkdir -p /mongodb/$i/conf
mkdir -p /mongodb/$i/data
mkdir -p /mongodb/$i/log
done
1.1.1 編寫配置文件:
systemLog:
destination: file
path: /mongodb/28017/log/mongodb.log
logAppend: true
storage:
journal:
enabled: true
dbPath: /mongodb/28017/data
directoryPerDB: true
#engine: wiredTiger
wiredTiger:
engineConfig:
# cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
processManagement:
fork: true
net:
port: 28017
replication:
oplogSizeMB: 2048
replSetName: my_repl
1.1.2 啟動實例:
for i in 280{17..20}; do mongod -f /mongodb/$i/conf/mongod.conf ; done
停止服務命令
for i in 280{17..20}; do mongod –shutdown -f /mongodb/$i/conf/mongod.conf ; done
1.1.3 配置復制集:
隨便登錄一臺機器執行即可
config = {_id: 'my_repl', members: [
{_id: 0, host: '10.0.0.18:28017'},
{_id: 1, host: '10.0.0.18:28018'},
{_id: 2, host: '10.0.0.18:28019'}]
}
1.1.4 初始化配置
> rs.initiate(config)
{ "ok" : 1 }
my_repl:OTHER>
my_repl:SECONDARY>
1.2 主從復制測試:
1.2.1 主節點插入數據
db.movies.insert([ { "title" : "Jaws", "year" : 1975, "imdb_rating" : 8.1 },
... { "title" : "Batman", "year" : 1989, "imdb_rating" : 7.6 },
... ] );
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 2,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
1.2.2 主節點查看數據
my_repl:PRIMARY> db.movies.find().pretty();
{
"_id" : ObjectId("5ad6c085a2054234c1597506"),
"title" : "Jaws",
"year" : 1975,
"imdb_rating" : 8.1
}
{
"_id" : ObjectId("5ad6c085a2054234c1597507"),
"title" : "Batman",
"year" : 1989,
"imdb_rating" : 7.6
}
1.2.3 登錄從庫打開從庫可讀配置
默認從庫是不允許讀操作的
my_repl:SECONDARY> rs.slaveOk();
my_repl:SECONDARY> db.movies.find().pretty();
{
"_id" : ObjectId("5ad6c201afd69acbffc224f5"),
"title" : "Jaws",
"year" : 1975,
"imdb_rating" : 8.1
}
{
"_id" : ObjectId("5ad6c201afd69acbffc224f6"),
"title" : "Batman",
"year" : 1989,
"imdb_rating" : 7.6
}
1.3 故障切換測試:
mongod --shutdown -f /mongodb/28017/conf/mongod.conf
killing process with pid: 2493
[mongod@web04 mongodb]$ mongo --port 28018
MongoDB shell version: 3.2.8
connecting to: 127.0.0.1:28018/test
my_repl:SECONDARY> exit
bye
[mongod@web04 mongodb]$ mongo --port 28018
MongoDB shell version: 3.2.8
connecting to: 127.0.0.1:28018/test
my_repl:PRIMARY>
第2章 復制集管理操作:
2.1 (1)查看復制集狀態:
rs.status(); # 查看整體復制集狀態
rs.isMaster(); # 查看當前是否是主節點
2.2 (2)添加刪除節點
rs.add("ip:port"); # 新增從節點
rs.addArb("ip:port"); # 新增仲裁節點
rs.remove("ip:port"); # 刪除一個節點
2.3 ( 3 ) 配置延時節點:
my_repl:PRIMARY> cfg=rs.conf()
{
"_id" : "my_repl",
"version" : 1,
"protocolVersion" : NumberLong(1),
"members" : [
{
"_id" : 0,
"host" : "10.0.0.18:28017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "10.0.0.18:28018",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "10.0.0.18:28019",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("5ad6bfb3db15e96a59976d12")
}
}
註:這裏的[2]是rs.conf顯示的順序(除主庫外),非ID
my_repl:PRIMARY> cfg.members[2].priority=0
0
my_repl:PRIMARY> cfg.members[2].slaveDelay=120
120
my_repl:PRIMARY> cfg.members[2].hidden=true
true
my_repl:PRIMARY> rs.reconfig(cfg)
{ "ok" : 1 }
2.4 副本集其他操作命令:
查看副本集配置信息:
rs.config()
查看副本集成員的狀態:
rs.status()
副本集角色切換:由主降為從
rs.stepDown()
鎖定從,使其不會轉變成主
rs.freeze(300)
設置副節點可讀
rs.slaveOk()
查看副本節點
rs.printSlaveReplicationInfo()
MongoDB復制集技術