簡介
NOSQL有這些優勢:
- 大數據量,可以通過廉價服務器存儲大量的數據,輕松擺脫傳統mysql單表存儲量級限制。
- 高擴展性,Nosql去掉了關系數據庫的關系型特性,很容易橫向擴展,擺脫了以往老是縱向擴展的詬病。
- 高性能,Nosql通過簡單的key-value方式獲取數據,非常快速。還有NoSQL的Cache是記錄級的,是一種細粒度的Cache,所以NoSQL在這個層面上來說就要性能高很多。
- 靈活的數據模型,NoSQL無需事先為要存儲的數據建立字段,隨時可以存儲自定義的數據格式。而在關系數據庫里,增刪字段是一件非常麻煩的事情。如果是非常大數據量的表,增加字段簡直就是一個噩夢。
- 高可用,NoSQL在不太影響性能的情況,就可以方便的實現高可用的架構。比如mongodb通過mongos、mongo分片就可以快速配置出高可用配置。
- 支持查詢、聚合、完全索引,包含內部對象
- 支持復制和故障轉移、自動恢復
- 易擴展
在nosql數據庫里,大部分的查詢都是鍵值對(key、value)的方式。MongoDB是一個介於關系數據庫和非關系數據庫之間的產品,是非關系數據庫當中最像關系數據庫的。支持類似於面向對象的查詢語言,幾乎可以實現類似關系數據庫單表查詢的絕大部分功能,而且還支持對數據建立索引。所以這個非常方便,我們可以用sql操作MongoDB,從關系型數據庫遷移過來,開發人員學習成本會大大減少。如果再對底層的sql API做一層封裝,開發基本可以感覺不到mongodb和關系型數據庫的區別。
MongoDB是一個基於分布式文件存儲的數據庫。由C++語言編寫;旨在為WEB應用提供可擴展的高性能數據存儲解決方案。
安裝mongodb
安裝環境
操作系統:Centos7.2
mongodb版本: v3.6.1
下載安裝
wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-amazon-3.6.1.tgz tar zxvf mongodb-linux-x86_64-amazon-3.6.1.tgz mv /root/mongodb-linux-x86_64-amazon-3.6.1 /usr/local/mongodb/
創建數據/日志目錄
mkdir -p /data/mongodb/{data, logs} mkdir /data/mongodb/data/mongod touch /data/mongodb/logs/mongo.logs
創建配置文件
mkdir /usr/local/mongodb/config cd /usr/local/mongodb/config && touch mongo.conf
配置文件
1. 普通配置文件示例
dbpath=/data/mongodb/data/mongod logpath=/data/mongodb/logs/mongo.log logappend=true replSet=mongo-rs bind_ip=0.0.0.0 port=27017 fork=true journal=true
mongodb3.x版本后就是要yaml語法格式的配置文件,下面是yaml配置文件格式如下:
官方yaml配置文件選項參考:https://docs.mongodb.org/manual/reference/configuration-options/#configuration-file
注意:只能使用空格,不支持tab鍵
2.yaml格式配置文件示例
storage:
dbPath: /data/mongodb/data/mongod
journal:
enabled: true
systemLog:
destination: file
path: /data/mongodb/logs/mongo.log
logAppend: true
logRotate: rename
net:
bindIp: 0.0.0.0
port: 27017
processManagement:
pidFilePath: /var/run/pid/mongodb.pid
fork: true
replication:
oplogSizeMB: 20480
replSetName: mongo-rs
配置文件參數說明
1.基本參數
--quiet # 安靜輸出 --port arg # 指定服務端口號,默認端口27017 --bind_ip arg # 綁定服務IP,若綁定127.0.0.1,則只能本機訪問,不指定默認本地所有IP --logpath arg # 指定MongoDB日志文件,注意是指定文件不是目錄 --logappend # 使用追加的方式寫日志 --pidfilepath arg # PID File 的完整路徑,如果沒有設置,則沒有PID文件 --keyFile arg # 集群的私鑰的完整路徑,只對於Replica Set 架構有效 --unixSocketPrefix arg # UNIX域套接字替代目錄,(默認為 /tmp) --fork # 以守護進程的方式運行MongoDB,創建服務器進程 --auth # 啟用驗證 --cpu # 定期顯示CPU的CPU利用率和iowait --dbpath arg # 指定數據庫路徑 --diaglog arg # diaglog選項 0=off 1=W 2=R 3=both 7=W+some reads --directoryperdb # 設置每個數據庫將被保存在一個單獨的目錄 --journal # 啟用日志選項,MongoDB的數據操作將會寫入到journal文件夾的文件里 --journalOptions arg # 啟用日志診斷選項 --ipv6 # 啟用IPv6選項 --jsonp # 允許JSONP形式通過HTTP訪問(有安全影響) --maxConns arg # 最大同時連接數 默認2000 --noauth # 不啟用驗證 --nohttpinterface # 關閉http接口,默認關閉27018端口訪問 --noprealloc # 禁用數據文件預分配(往往影響性能) --noscripting # 禁用腳本引擎 --notablescan # 不允許表掃描 --nounixsocket # 禁用Unix套接字監聽 --nssize arg (=16) # 設置信數據庫.ns文件大小(MB) --objcheck # 在收到客戶數據,檢查的有效性, --profile arg # 檔案參數 0=off 1=slow, 2=all --quota # 限制每個數據庫的文件數,設置默認為8 --quotaFiles arg # number of files allower per db, requires --quota --rest # 開啟簡單的rest API --repair # 修復所有數據庫run repair on all dbs --repairpath arg # 修復庫生成的文件的目錄,默認為目錄名稱dbpath --slowms arg (=100) # value of slow for profile and console log --smallfiles # 使用較小的默認文件 --syncdelay arg (=60) # 數據寫入磁盤的時間秒數(0=never,不推薦) --sysinfo # 打印一些診斷系統信息 --upgrade # 如果需要升級數據庫
2.Replicaton 參數
--fastsync # 從一個dbpath里啟用從庫復制服務,該dbpath的數據庫是主庫的快照,可用於快速啟用同步 --autoresync # 如果從庫與主庫同步數據差得多,自動重新同步, --oplogSize arg # 設置oplog的大小(MB)
3.主/從參數
--master # 主庫模式 --slave # 從庫模式 --source arg # 從庫 端口號 --only arg # 指定單一的數據庫復制 --slavedelay arg # 設置從庫同步主庫的延遲時間
4.Replica set(副本集)選項
--replSet arg # 設置副本集名稱 Sharding(分片)選項 --configsvr # 聲明這是一個集群的config服務,默認端口27019,默認目錄/data/configdb --shardsvr # 聲明這是一個集群的分片,默認端口27018 --noMoveParanoia # 關閉偏執為moveChunk數據保存
啟動
mongod --quiet -f /usr/local/mongodb/config/mongo.conf
配置文件里設置里fork:true,所以會在后台啟動,值得注意的是,用到了”–fork”參數就必須啟用”–logpath”參數,如不指定配置文件啟動,如下:
mongod --dbpath=/data/mongodb/data/mongod --fork --logpath=/data/mongodb/logs/mongo.logs
集群搭建
官方不建議再使用主從集群模式,推薦的集群方式是Replica Set(副本集),主從模式其實就是一個單副本的應用,沒有很好的擴展性和容錯性。而副本集具有多個副本保證了容錯性,就算一個副本掛掉了還有很多副本存在,並且解決了上面第一個問題“主節點掛掉了,整個集群內會自動切換”。
副本集的設計結構
由圖可以看到客戶端連接到整個副本集,不關心具體哪一台機器是否掛掉。主服務器負責整個副本集的讀寫,副本集定期同步數據備份,一但主節點掛掉,副本節點就會選舉一個新的主服務器,這一切對於應用服務器不需要關心。
注意:
仲裁節點是一種特殊的節點,它本身並不存儲數據,主要的作用是決定哪一個備節點在主節點掛掉之后提升為主節點,所以客戶端不需要連接此節點。這里雖然只有一個備節點,但是仍然需要一個仲裁節點來提升備節點級別。
必須要有仲裁節點,沒仲裁節點的話,主節點掛了備節點還是備節點。
配置步驟
准備三台機器
172.29.142.17 主 172.29.142.18 備 172.28.226.199 仲裁
按照第二步安裝依次在三台機器上安裝並啟動
/usr/local/mongodb/bin/mongod --quiet -f /usr/local/mongodb/config/mongo.conf
初始化集群配置
三台服務啟動並不能表示他們在一個集群,因此需要將集群初始化。連接任意一個節點(不要是仲裁點),執行如下:
rs.initiate({ _id:"mongo-rs", #集群名稱 members:[ {_id:0,host:'172.29.142.18:27017',priority:2}, #主 {_id:1,host:'172.29.142.17:27017',priority:1}, #備 {_id:2,host:'172.28.226.199:27017',arbiterOnly:true}] #仲裁節點 })
成功上面會返回OK,然后查看集群狀態,下面是在備節點上執行的
rs.status()
返回集群的名稱和members信息,如:

{ "set" : "mongo-rs", "date" : ISODate("2018-06-26T14:56:08.032Z"), "myState" : 2, "term" : NumberLong(2), "syncingTo" : "172.29.142.18:27017", "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1530024958, 1), "t" : NumberLong(2) }, "appliedOpTime" : { "ts" : Timestamp(1530024958, 1), "t" : NumberLong(2) }, "durableOpTime" : { "ts" : Timestamp(1530024958, 1), "t" : NumberLong(2) } }, "members" : [ { "_id" : 0, "name" : "172.29.142.18:27017", "health" : 1.0, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 382251, "optime" : { "ts" : Timestamp(1530024958, 1), "t" : NumberLong(2) }, "optimeDurable" : { "ts" : Timestamp(1530024958, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2018-06-26T14:55:58.000Z"), "optimeDurableDate" : ISODate("2018-06-26T14:55:58.000Z"), "lastHeartbeat" : ISODate("2018-06-26T14:56:07.329Z"), "lastHeartbeatRecv" : ISODate("2018-06-26T14:56:06.453Z"), "pingMs" : NumberLong(0), "electionTime" : Timestamp(1529642739, 1), "electionDate" : ISODate("2018-06-22T04:45:39.000Z"), "configVersion" : 1 }, { "_id" : 1, "name" : "172.29.142.17:27017", "health" : 1.0, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 382552, "optime" : { "ts" : Timestamp(1530024958, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2018-06-26T14:55:58.000Z"), "syncingTo" : "172.29.142.18:27017", "configVersion" : 1, "self" : true }, { "_id" : 2, "name" : "172.28.226.199:27017", "health" : 1.0, "state" : 7, "stateStr" : "ARBITER", "uptime" : 168617, "lastHeartbeat" : ISODate("2018-06-26T14:56:06.895Z"), "lastHeartbeatRecv" : ISODate("2018-06-26T14:56:04.092Z"), "pingMs" : NumberLong(35), "configVersion" : 1 } ], "ok" : 1.0 }
返回參數說明
“health” : 1, #代表機器正常
“stteStr” : “PRIMARY”, #代表是主節點,可讀寫,其中有以下幾下狀態:
STARTUP:剛加入到復制集中,配置還未加載
STARTUP2:配置已加載完,初始化狀態
RECOVERING:正在恢復,不適用讀
ARBITER: 仲裁者
DOWN:節點不可到達
UNKNOWN:未獲取其他節點狀態而不知是什么狀態,一般發生在只有兩個成員的架構,腦裂
REMOVED:移除復制集
ROLLBACK:數據回滾,在回滾結束時,轉移到RECOVERING或SECONDARY狀態
FATAL:出錯。查看日志grep “replSet FATAL”找出錯原因,重新做同步
PRIMARY:主節點
SECONDARY:備份節點
測試副本集數據復制
注意:mongodb默認是從主節點讀寫數據的,副本節點上不允許讀,需要設置副本節點可以讀:
repset:SECONDARY> db.getMongo().setSlaveOk();
這個很好測試,直接在主節點插入一條數據,在備節點查詢即可
或者可以使用客戶端以集群模式連接mongo集群:
點Test 測試連接:
三個節點的數據是同步的。
測試副本集故障轉移功能
1.查看集群當前狀態,如上返回
當前172.29.142.18是Primary, 172.29.142.17是Secondary
2.停掉主節點172.29.142.18,查看另兩台的選票結果
此時17變成了主節點,原先的仲裁節點不變,重新啟動第一次的Primary,則主節點又發生變化,不再截圖,整個過程業務是不中斷的。只要有一台可用即可。
Nodejs連接mongo集群示例
這里強烈不推薦連接單台mongo服務,因為如果一個mongo節點掛掉,業務就掛了,連接集群的話有一台可用就行。
下面舉了個nodejs連接mongo集群的示例:
const mongoose = require('mongoose'); let url = "mongodb://172.29.142.17:27017/testdb,mongodb://172.29.142.18:27017/testdb,mongodb://172.28.226.199:27017/testdb"; let options = { "replset": { "ha": true, "haInterval": 1000, "replicaSet": "mongo-rs", "connectWithNoPrimary": true, "auto_reconnect": true, "socketOptions": { "keepAlive": 120, connectTimeoutMS: 30000 } } } mongoose.connect(url, options).connection .on('error', function (error) { console.log('mongo 連接錯誤', error) }).on('disconnected', mongoConnect).once('open', function () { console.log('mongo 連接成功'); })
reference:
https://blog.csdn.net/luonanqin/article/details/8497860
https://blog.csdn.net/wangshuang1631/article/details/53857319