MongoDB 集群配置筆記
配置一個含有主從機制、自動分片、去中心化的MongoDB集群
一、配置文件說明
必備的配置項知曉,在命令行啟動時只需要指定配置文件地址即可,如:
mongod -port=27017 -f /path/db/conf/mongodb.conf
用這種方式可以減少因命令行啟動時參數(shù)缺失導(dǎo)致的問題,常用的參數(shù)都需要寫入配置文件,詳細(xì)的配置項如下表示:
1.基礎(chǔ)參數(shù)表
| 參數(shù)名 | 默認(rèn)值 | 備注 |
|---|---|---|
| dbpath | /[path] | 數(shù)據(jù)庫路徑,不指定則默認(rèn)在/data/db |
| verbose | false | 是否打印詳細(xì)記錄到logpath中,如要啟動需指定vvvv參數(shù)。默認(rèn)false |
| vvvv | true | 日志級別,vv~vvvvv,v越多越詳細(xì) |
| port | 27017 | 端口,推薦寫到命令行 |
| bind_ip | 127.0.0.1 | 綁定的IP,非此IP不可訪問。多個用,分隔。綁定的地址并不是客戶端的IP而是MongoDB所在的服務(wù)器的IP。 |
| maxConns | 1000000 | 最大連接數(shù),具體值取決于系統(tǒng)和mongodb版本。 |
| objcheck | true | 2.4版后默認(rèn)為true,開啟時保證客戶端插入到庫中的數(shù)據(jù)都是有效的,但會降低性能 |
| noobjcheck | false | 與objcheck互斥,明示關(guān)閉對象校驗 |
| logappend | true | true表示追加,否則為覆蓋 |
| syslog | true | 輸出到主機的syslog系統(tǒng)而非logpath的路徑。syslog與logpath不能一起用 |
| pidfilepath | /[path] | 指定PID文件位置 |
| keyFile | /[path] | 身份驗證的密鑰信息文件 |
| fork | true | 后臺運行,默認(rèn)true |
| auth | false | 開啟身份驗證,啟動時應(yīng)增加賬號、密碼、目標(biāo)庫。如:mongo -utest -ppwd test,表示test用戶用pwd密碼登錄test庫。默認(rèn)false |
| noauth | true | 不認(rèn)證用戶 |
| cpu | false | true會強制每4秒記錄一次CPU利用率和IO等待并寫到日志 |
| dbpath | /[path] | 指定數(shù)據(jù)庫位置,必要項 |
| dialog | 0 | 輸出錯誤日志到dialog.*文件,0=關(guān)閉、1=寫操作、2=讀操作、3=讀寫、7=寫+部分讀 |
| directoryperdb | false | 如果開啟則將數(shù)據(jù)存到不同的磁盤上以提高讀寫速度,需要在第一次啟動前就要確認(rèn)此值。否則一旦改變會導(dǎo)致數(shù)據(jù)丟失(改回去可恢復(fù))。 |
| journal | 64bit=true,32bit=false | 是否啟用確保一致性的操作日志 |
| nojournal | true | 關(guān)閉操作日志,64位系統(tǒng)需要強制開啟 |
| journalCommitInterval | 100 | 寫刷新間隔,默認(rèn)100毫秒。數(shù)值越小越影響IO,取值范圍2-300. |
| ipv6 | false | 開啟ipv6支持,默認(rèn)false |
| jsonp | false | 是否允許jsonp方位http接口 |
| nohttpinterface | false | 是否禁止http接口,即28017端口服務(wù)。默認(rèn)比port大1000 |
| noprealloc | false | 如果是寫頻繁的系統(tǒng)開啟的話會提升性能。開啟時會在后臺提前分配一定空間(0填充)來降低動態(tài)分配導(dǎo)致的低效率問題,但啟動時會慢點。 |
| noscripting | false | 關(guān)閉腳本引擎,默認(rèn)false |
| notablescan | false | 禁止全表掃描,開啟時會提示"table scans not allow" |
| nssize | 16 | 塊大小,16M(默認(rèn))-2G |
| profile | 0 | 數(shù)據(jù)庫分析等級。0=關(guān)、1=慢操作、2=所有操作 |
| slowms | 200 | 慢查詢的時間,默認(rèn)200ms |
| quota | false | 是否限制庫文件數(shù) |
| quotaFiles | 8 | quota開啟時,此值表示最大庫文件數(shù) |
| rest | false | 開啟RESTful API。開啟時將啟用一個比port大1000端口的服務(wù),可以查詢數(shù)據(jù)。 |
| repair | false | 默認(rèn)false,修復(fù)數(shù)據(jù)庫。此值應(yīng)該在命令行明示,修復(fù)是需要關(guān)閉journal。 |
| repairpath | _tmp | 修復(fù)路徑,默認(rèn)在dbpath下 |
| smallfiles | false | 啟用小文件模式,開啟時最大為512M的塊文件。太小會影響IO。默認(rèn)false |
| sysinfo | false | 開啟時啟動mongod會顯示系統(tǒng)信息而不是啟動mongodb,應(yīng)該在命令行用 |
| traceExceptions | false | 啟動內(nèi)部診斷,默認(rèn)false |
| quiet | false | 安靜模式,命令行用。默認(rèn)false |
2.復(fù)制項(Replication)
| 參數(shù)名 | 默認(rèn)值 | 備注 |
|---|---|---|
| replSet | - | 命令行參數(shù),啟用時表示要復(fù)制副本集。副本名[/主機地址:端口] |
| fastsync | false | 副本集下設(shè)置true將通過快照同步 |
| replIndexPrefetch | all | 默認(rèn)all、none、id_only,只能在副本集(replSet)中使用。默認(rèn)情況下,secondary副本集的成員將加載所有索引到內(nèi)存中(從OPLOG之前的操作有關(guān)的)。您可以修改此行為,使secondary只會加載_id索引。指定id或none,防止mongod的任何索引加載到內(nèi)存。 |
3.主從復(fù)制(Replica set options)
| 參數(shù)名 | 默認(rèn)值 | 備注 |
|---|---|---|
| master | true | 表示此節(jié)點為master,應(yīng)該命令行用 |
| slave | true | 表示此節(jié)點為slave,應(yīng)該在命令行用,需要指定source |
| source | host:port | 從節(jié)點是,表示其主節(jié)點,即從此節(jié)點復(fù)制數(shù)據(jù) |
| only | xxx | 只復(fù)制此指定數(shù)據(jù)庫,默認(rèn)空 |
| slavedelay | 0 | 用于從庫,指定其與主庫復(fù)制數(shù)據(jù)的間隔,秒計。默認(rèn)0 |
| autoresync | false | 從庫配置,true表示自動同步,如落后主超過10秒則強制同步。 |
4.分片(Shard options)
| 參數(shù)名 | 默認(rèn)值 | 備注 |
|---|---|---|
| configsvr | false | 表示此節(jié)點為配置庫,默認(rèn)端口27019,默認(rèn)目錄/data/configdb。應(yīng)該在命令行使用 |
| shardsvr | false | 表示為分片節(jié)點,默認(rèn)端口27018 |
二、主從配置流程(Master & Slave)
主從配置有如下優(yōu)點:
大數(shù)據(jù)量,可以通過廉價服務(wù)器存儲大量的數(shù)據(jù),輕松擺脫傳統(tǒng)mysql單表存儲量級限制。
高擴展性,Nosql去掉了關(guān)系數(shù)據(jù)庫的關(guān)系型特性,很容易橫向擴展,擺脫了以往老是縱向擴展的詬病。
高性能,Nosql通過簡單的key-value方式獲取數(shù)據(jù),非??焖?。還有NoSQL的Cache是記錄級的,是一種細(xì)粒度的Cache,所以NoSQL在這個層面上來說就要性能高很多。
靈活的數(shù)據(jù)模型,NoSQL無需事先為要存儲的數(shù)據(jù)建立字段,隨時可以存儲自定義的數(shù)據(jù)格式。而在關(guān)系數(shù)據(jù)庫里,增刪字段是一件非常麻煩的事情。如果是非常大數(shù)據(jù)量的表,增加字段簡直就是一個噩夢。
高可用,NoSQL在不太影響性能的情況,就可以方便的實現(xiàn)高可用的架構(gòu)。比如mongodb通過mongos、mongo分片就可以快速配置出高可用配置。
此處在明文寫到命令行參數(shù),這樣便于確認(rèn)進程。假設(shè)目錄放到了 /data/db/ 下
- 啟動進程
# master的mongod.conf配置
master=true
logpath=/data/db/mongodbMaster/logs/mongod.log
logappend=true
fork=true
port=27017
dbpath=/data/db/mongodbMaster/data/
pidfilepath=/data/db/mongodbMaster/conf/mongod.pid
bind_ip=127.0.0.1
noauth=true
directoryperdb=true
# 主節(jié)點增加master參數(shù)
mongod -f /data/db/mongodbMaster/conf/mongod.conf --master --port=27017
# slave的mongod.conf配置
slave=true
source=127.0.0.1:27017
logpath=/data/db/mongodbSlave/logs/mongod.log
logappend=true
fork=true
port=27018
dbpath=/data/db/mongodbMaster/data/
pidfilepath=/data/db/mongodbSlave/conf/mongod.pid
bind_ip=127.0.0.1
noauth=true
directoryperdb=true
# slave 增加slave參數(shù)外,還需要指定source
mongod -f /data/db/mongodbSlave/conf/mongod.conf --slave --source 127.0.0.1:27017
登錄到slave后輸入 db.printReplicationInfo();查看
> db.printReplicationInfo();
this is a slave, printing slave replication info.
source: 127.0.0.1:27017
syncedTo: Fri Mar 09 2018 08:41:41 GMT-0800 (PST)
3 secs (0 hrs) behind the freshest member (no primary available at the moment)
>
- 初始化集群
登錄任意主機執(zhí)行如下配置
use admin
config = {
"_id":"bsbgpsrs",
"members":[
{"_id":0,"host":"192.168.198.224:27017"},
{"_id":1,"host":"192.168.198.225:27017"},
{"_id":2,"host":"192.168.198.226:27017",arbiterOnly:true}
]
}
rs.initiate(config); # 初始化配置
- 通過實例查看主從是否可用
# master上插入數(shù)據(jù)
use test
db.test.insert({"name":"master1"});
直接在從庫上查看數(shù)據(jù)時會報錯
show dbs;
2018-03-09T07:45:34.493-0800 E QUERY [thread1] Error: listCollections failed: {
"ok" : 0,
"errmsg" : "not master and slaveOk=false",
"code" : 13435,
"codeName" : "NotMasterNoSlaveOk"
} ...
db.mydata.insert({"name":"im slave"});
WriteResult({ "writeError" : { "code" : 10107, "errmsg" : "not master" } })
==原因 mongoDB默認(rèn)由master讀取數(shù)據(jù),因此不能直接從slave讀取數(shù)據(jù)。需要設(shè)置slave狀態(tài)==
# 查詢前執(zhí)行此操作即可
db.getMongo().setSlaveOk();
# 執(zhí)行查詢
use test
db.test.find();
{ "_id" : ObjectId("5aa2abeb37bdc4baca1798a0"), "name" : "master1" }
可以看到從庫上已經(jīng)有了數(shù)據(jù)
- 主從切換試驗
如果有必要增加以下參數(shù)來設(shè)置同步規(guī)則
--slavedelay 10 #延時復(fù)制 單位為秒
--autoresync #自動重新同步
--only #復(fù)制指定的數(shù)據(jù)庫,默認(rèn)復(fù)制所有的庫
--oplogSize #主節(jié)點的oplog日志大小,單位為M,建議設(shè)大點(更改oplog大小時,只需停主庫,刪除local.*,然后加--oplogSize=* 重新啟動即可,*代表大小)
如果不能同步,可以手動試下
db.runCommand({"resync":1})
在slave上執(zhí)行如下命令可以查看狀態(tài)
db.runCommand({"isMaster":1})
{
"ismaster" : false,
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 1000,
"localTime" : ISODate("2018-03-09T16:58:32.845Z"),
"maxWireVersion" : 5,
"minWireVersion" : 0,
"readOnly" : false,
"ok" : 1
}
查看從服指向的主服狀態(tài)(數(shù)據(jù)源)
> use local
switched to db local
> db.sources.find();
{ "_id" : ObjectId("5aa2b9250eedef392722326e"), "host" : "127.0.0.1:27017", "source" : "main", "syncedTo" : Timestamp(1520614901, 1) }
# 動態(tài)增加一個
db.sources.insert({"host": "10.0.0.11:27001"});
# 移除它
db.sources.remove({"host": "10.0.0.11:27001"});
查看主從復(fù)制狀態(tài)
db.printReplicationInfo();
==后記:目前這種方式還不能實現(xiàn)自動主掛切從==
Replica Set集群模式
多機熱備構(gòu)成的集群的解決了其中一臺掛掉后,系統(tǒng)自動切換到另一臺從而保證服務(wù)可用。根據(jù)需求預(yù)先設(shè)定最少3臺機器:
- 主節(jié)點:承擔(dān)所有CRUD操作
- 備節(jié)點:承擔(dān)查詢的任務(wù),主節(jié)點不可用時切換成主節(jié)點
- 仲裁節(jié)點:無業(yè)務(wù)任務(wù),僅承擔(dān)投票選舉主節(jié)點的功能
準(zhǔn)備三份配置,簡單如下:
- 配置并啟動集群
# 主及節(jié)點
dbpath=/data/db/mongodbMaster/data
logpath=/data/db/mongodbMaster/logs/mongod.log
port=27017
fork=true
#這里指定了備機的位置
replSet=mtest/127.0.0.1:27018
# 備節(jié)點
dbpath=/data/db/mongodbSlave/data
logpath=/data/db/mongodbSlave/logs/mongod.log
port=27018
fork=true
#這里指定了主機的位置
replSet=mtest/127.0.0.1:27017
# 仲裁節(jié)點
dbpath=/data/db/mongodbArbiter/data
logpath=/data/db/mongodbArbiter/logs/mongod.log
port=27018
fork=true
#這里指定了主機的位置
replSet=mtest/127.0.0.1:27017
- 配置關(guān)系節(jié)點,用mongo連接到任意節(jié)點后執(zhí)行如下命令
cfg={
_id:"mtest",
members:[
{
_id:0,
host:'127.0.0.1:27017',priority:2
}, {
_id:1,
host:'127.0.0.1:27018',priority:1
}, {
_id:2,host:'127.0.0.1:27019',arbiterOnly:true}
] };
rs.initiate(cfg);
# priority:優(yōu)先級,越高越先成為主節(jié)點。0時不會參選
# arbiterOnly: true表示仲裁節(jié)點
# 執(zhí)行成功時返回
{ "ok" : 1 }
# 如果其中備份節(jié)點有數(shù)據(jù)會造成啟動失敗并提示
{
"ok" : 0,
"errmsg" : "'127.0.0.1:27018' has data already, cannot initiate set.",
"code" : 110,
"codeName" : "CannotInitializeNodeWithData"
}
# 此時刪掉備份節(jié)點的data再次執(zhí)行即可
注意,一旦配置成功你會發(fā)現(xiàn)提示符變成了 mtest:PRIMARY>,對應(yīng)的27018節(jié)點為mtest:SECONDARY> 、27019節(jié)點為mtest:ARBITER>
# 查詢狀態(tài)
rs.status();
{
"set" : "mtest",
"date" : ISODate("2018-03-09T18:25:20.896Z"),
"myState" : 1,
"term" : NumberLong(1),
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1520619920, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1520619920, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1520619920, 1),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 0,
"name" : "127.0.0.1:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2491,
"optime" : {
"ts" : Timestamp(1520619920, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-03-09T18:25:20Z"),
"electionTime" : Timestamp(1520619569, 1),
"electionDate" : ISODate("2018-03-09T18:19:29Z"),
"configVersion" : 1,
"self" : true
},
{
"_id" : 1,
"name" : "127.0.0.1:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 362,
"optime" : {
"ts" : Timestamp(1520619910, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1520619910, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-03-09T18:25:10Z"),
"optimeDurableDate" : ISODate("2018-03-09T18:25:10Z"),
"lastHeartbeat" : ISODate("2018-03-09T18:25:19.307Z"),
"lastHeartbeatRecv" : ISODate("2018-03-09T18:25:19.607Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "127.0.0.1:27017",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "127.0.0.1:27019",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 362,
"lastHeartbeat" : ISODate("2018-03-09T18:25:19.307Z"),
"lastHeartbeatRecv" : ISODate("2018-03-09T18:25:20.234Z"),
"pingMs" : NumberLong(0),
"configVersion" : 1
}
],
"ok" : 1
}
注意看,member中的項目有個stateStr字段表示節(jié)點角色,其值為
- PRIMARY: 表示主節(jié)點
- SECONDARY: 表示從節(jié)點
- ARBITER: 表示仲裁節(jié)點
接下來殺掉主服,看看備份節(jié)點是否會自動切換到主節(jié)點
kill -9 PRIMARY_PID
來到從節(jié)點執(zhí)行
rs.status();
# 可以看到提示符變成 mtest:PRIMARY>
#
...
{
"_id" : 1,
"name" : "127.0.0.1:27018",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 922,
"optime" : {
"ts" : Timestamp(1520620472, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2018-03-09T18:34:32Z"),
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1520620450, 1),
"electionDate" : ISODate("2018-03-09T18:34:10Z"),
"configVersion" : 1,
"self" : true
},
...
# 在從節(jié)點執(zhí)行如下命令即可實現(xiàn)從節(jié)點的讀取
db.getMongo().setSlaveOk();
# Arbiter上執(zhí)行查詢時會返回
Error: error: {
"ok" : 0,
"errmsg" : "node is not in primary or recovering state",
"code" : 13436,
"codeName" : "NotMasterOrSecondary"
}
# 即便是setSlaveOk()了也不成
如果后原主機27017恢復(fù)后仍然會是PRIMARY節(jié)點。
Replica 模式總結(jié)
- PRIMARY只有一個,它負(fù)責(zé)讀寫。只有它掛掉時才會選舉新的PRIMARY。
- SECONDARY在成為PRIMARY時會異步復(fù)制Oplog中的記錄,這會導(dǎo)致數(shù)據(jù)并不是最新的
- ARBITER只會投票并無數(shù)據(jù)需求,配置可以低點
- priority=0時表示此節(jié)點僅作備份節(jié)點
- 為了分擔(dān)PRIMARY的讀壓力應(yīng)該開啟從SECONDARY讀的,開啟slave讀的另一種辦法是
# 修改/root/.mongorc.js,并加入
rs.slaveOk();
注意這個文件是隱藏的需要用ls -a查看,此方法僅適用于命令行