部署模型java
可複製集node
可複製集是跨多個MongDB服務器(節點)分佈和維護數據的方法。mongoDB能夠把數據從一個節點複製到其餘節點並在修改時進行同步,集羣中的節點配置爲自動同步數據;舊方法叫作主從複製,mongoDB 3.0之後推薦使用可複製集;算法
爲何要用可複製集?它有什麼重要性?mongodb
避免數據丟失,保障數據安全,提升系統安全性;
(最少3節點,最大50節點)
自動化災備機制,主節點宕機後經過選舉產生新主機;提升系統健壯性;
(7個選舉節點上限)
讀寫分離,負載均衡,提升系統性能;
生產環境推薦的部署模式;數據庫
可複製集架構以及原理apache
oplog( 操做日誌) :保存操做記錄、時間戳
數據同步:從節點與主節點保持長輪詢;1.從節點查詢本機oplog最新時間戳;2.查詢主節點oplog於此時間戳的全部文檔;3.加載這些文檔,並根據log執行寫操做;
阻塞複製: 與writeconcern相關,不須要同步到從節點的策略(如: acknowledgedUnacknowledged 、w1),數據同步都是異步的,其餘狀況都是同步;
心跳機制:成員之間會每2s 進行一次心跳檢測(ping操做),發現故障後進行選舉和故障轉移;
選舉制度:主節點故障後,其他節點根據優先級和bully算法選舉出新的主節點,在選出主節點以前,集羣服務是隻讀的數組
可複製集的搭建過程安全
1. 安裝好3個以上節點的mongoDB;
2. 配置mongodb.conf,增長跟複製相關的配置以下:服務器
replication: replSetName: configRS //集羣名稱 oplogSizeMB: 50 //oplog集合大小
3. 在primary節點上運行可複製集的初始化命令,初始化可複製集,命令以下:架構
//複製集初始化,在主節點上執行,ip禁止使用localhost rs.initiate({ _id: "configRS", version: 1, members: [{ _id: 0, host : "192.168.1.142:27017" }]}); rs.add("192.168.1.142:27018");//有幾個節點就執行幾回方法 rs.add("192.168.1.142:27019");//有幾個節點就執行幾回方法
4. 在每一個節點運行rs.status()或isMaster()命令查看複製集狀態;
5. 測試數據複製集效果;
6. 測試故障失效轉移效果;
Tips:
只能在主節點查詢數據,但若是
想在副節點查詢到數據需運行
rs.slaveOk(); //每一個節點都運行一次 確保java代碼能操做mondodb
代碼鏈接複製集
MongoDB 複製集裏Primary 節點是不固定的, 不固定的, 不固定的!因此生產環境千萬不要直連Primary, 千萬不要直連Primary, 千萬不要直連Primary !重要的事情說3 遍!
java原生驅動開發
List<ServerAddress> asList = Arrays.asList( new ServerAddress("192.168.1.142", 27018), new ServerAddress("192.168.1.142", 27017), new ServerAddress("192.168.1.142", 27019)); client = new MongoClient(asList);
Spring配置開發
<mongo:mongo-client replica-set="192.168.1.142:27017,192.168.1.142:27018,192.168.1.142:27017"> </mongo:mongo-client>
配置Tips:
1. 關注Write Concern參數的設置,默認值1能夠知足大多數場景的需求。W值大於1能夠提升數據的可靠持久化,但會下降寫性能。
2. 在options裏添加readPreference=secondaryPreferred並打開rs.slaveOk()便可實現讀寫分離,讀請求優先到Secondary節點,從而實現讀寫分離的功能
分片集羣
分片是把大型數據集進行分區成更小的可管理的片,這些數據片分散到不一樣的mongoDB節點,這些節點組成了分片集羣。
爲何要用分片集羣?
數據海量增加,須要更大的讀寫吞吐量 → 存儲分佈式
單臺服務器內存、cpu等資源是有瓶頸的 → 負載分佈式
Tips: 分片集羣是個雙刃劍,在提升系統可擴展性和性能的同時,增大了系統的複雜性,因此在實施以前請肯定是必須的。
什麼是分片?
數據庫?集合?文檔?mongoDB分片集羣推薦的模式是:分片集合,它是一種基於分片鍵的邏輯對文檔進行分組,分片鍵的選擇對分片很是重要,分片鍵一旦肯定,mongoDB對數據的分片對應用是透明的;
Tips:隨着數據量的的增大,分片會分割和遷移,以知足數據的均勻分佈。
請求分流:經過路由節點將請求分發到對應的分片和塊中;
數據分流:內部提供平衡器保證數據的均勻分佈,數據平均分佈式請求平均分佈的前提;
塊的拆分:3.4版本塊的最大容量爲64M或者10w的數據,當到達這個閾值,觸發塊的拆分,一分爲二;
塊的遷移:爲保證數據在分片節點服務器分片節點服務器均勻分佈,塊會在節點之間遷移。通常相差8個分塊的時候觸發;
分片集羣架構圖與組件
分片:在集羣中惟一存儲數據的位置,能夠是單個mongo服務器,也能夠是可複製集,每一個分區上存儲部分數據;生產環境推薦使用可複製集
mongos路由:因爲分片之存儲部分數據,須要mongos路由將讀寫操做路由到對應的分區上;mongos提供了單點鏈接集羣的方式,輕量級、非持久化因此一般mongos和應用部署在同一臺服務器上;
配置服務器:存儲集羣的元數據,元數據包括:數據庫、集合、分片的範圍位置以及跨片數據分割和遷移的日誌信息;mongos啓動時會從配置服務器讀取元數據信息在內存中;配置服務器最低3臺
分片搭建過程
配置步驟:
1. 分片服務器配置:給27020、27021以及複製集(2701七、2701八、27019)的配置文件增長:
sharding: clusterRole: shardsvr
2. config服務器配置:給複製集(2702二、2702三、27024)的配置文件增長:
sharding: clusterRole: configsvr
3. 啓動mongos路由以下:
./mongos --configdb shardingConfig/192.168.1.142:27022,192.168.1.142:27023, 192.168.1.142:27024 --port 27025 -- logpath=/usr/local/apache/mongoDB/sharding/rounter/ mongodb-rounter1/logs/mongodb.log ……
課堂筆記
一.複製集初始化 rs.initiate({ _id: "configRS", version: 1, members: [{ _id: 0, host : "192.168.1.142:27017" }]}); rs.add("192.168.1.142:27018");//有幾個節點就執行幾回方法 rs.add("192.168.1.142:27019");//有幾個節點就執行幾回方法 二.分片config複製集初始化 rs.initiate({ _id: "shardingConfig", version: 1, members: [{ _id: 0, host : "192.168.1.142:27023" }]}); rs.add("192.168.1.142:27022");//有幾個節點就執行幾回方法 rs.add("192.168.1.142:27024");//有幾個節點就執行幾回方法 三.分片配置步驟 1.分片服務器配置:給27020、27021以及複製集(2701七、2701八、27019)的配置文件增長: sharding: clusterRole: shardsvr 2.config服務器配置:給複製集(2702二、2702三、27024)的配置文件增長: sharding: clusterRole: configsvr 3.啓動mongos路由以下: ./mongos --configdb shardingConfig/192.168.1.142:27022,192.168.1.142:27023,192.168.1.142:27024 --port 27025 --logpath=/usr/local/apache/mongoDB/sharding/rounter/mongodb-rounter1/logs/mongodb.log 4.配置sharding 1)鏈接mongos: mongo --port 27025 2)增長分區: use admin; sh.addShard("192.168.1.142:27020"); sh.addShard("192.168.1.142:27021"); //configRS這個是複製集的名稱 sh.addShard("configRS/192.168.1.142:27017,192.168.1.142:27018,192.168.1.142:27019"); 3)經過sh.status()或圖形化工具查看分片結果 4)對lison數據庫啓用分片:sh.enableSharding("lison") 5)對ordersTest集合進行分片,分片鍵爲{"useCode":1,"_id":1} sh.shardCollection("lison.orders",{"useCode":1,"_id":1});
分片注意點與建議
分片注意點:
熱點 :某些分片鍵會致使全部的讀或者寫請求都操做在單個數據塊或者分片上,致使單個分片服務器嚴重不堪重負。自增加的分片鍵容易致使寫熱點問題;
不可分割數據塊:過於粗粒度的分片鍵可能致使許多文檔使用相同的分片鍵,這意味着這些文檔不能被分割爲多個數據塊,限制了mongoDB均勻分佈數據的能力;
查詢障礙:分片鍵與查詢沒有關聯,形成糟糕的查詢性能。
建議:
不要使用自增加的字段做爲分片鍵,避免熱點問題;
不能使用粗粒度的分片鍵,避免數據塊沒法分割;
不能使用徹底隨機的分片鍵值,形成查詢性能低下;
使用與經常使用查詢相關的字段做爲分片鍵,並且包含惟一字段(如業務主鍵,id等);
索引對於分區一樣重要,每一個分片集合上要有一樣的索引,分片鍵默認成爲索引;分片集合只容許在id和分片鍵上建立惟一索引;
最佳實踐
1. 儘可能選取穩定新版本64位的mongodb;
2. 數據模式設計;提倡單文檔設計,將關聯關係做爲內嵌文檔或者內嵌數組;當關聯數據量較大時,考慮經過表關聯實現,dbref或者自定義實現關聯;
3. 避免使用skip跳過大量數據;(1)經過查詢條件儘可能縮小數據範圍;(2)利用上一次的結果做爲條件來查詢下一頁的結果;
4. 避免單獨使用不適用索引的查詢符($ne、$nin、$where等)
5. 根據業務場景,選擇合適的寫入策略,在數據安全和性能之間找到平衡點;
6. 索引建議很重要;
7. 生產環境中建議打開profile,便於優化系統性能;
8. 生產環境中建議打開auth模式,保障系統安全;
9. 不要將mongoDB和其餘服務部署在同一臺機器上(mongodb佔用的最大內存是能夠配置的);
10. 單機必定要開啓journal日誌,數據量不太大的業務場景中,推薦多機器使用副本集,並開啓讀寫分離;
11. 分片鍵的注意事項
mongodb.conf
storage: dbPath: "/usr/local/apache/mongoDB/sharding/replication/primary/data" journal: enabled: true directoryPerDB: true engine: wiredTiger wiredTiger: engineConfig: cacheSizeGB: 1 journalCompressor: snappy directoryForIndexes: false collectionConfig: blockCompressor: snappy indexConfig: prefixCompression: true systemLog: destination: file path: "/usr/local/apache/mongoDB/sharding/replication/primary/logs/mongodb.logs" net: port: 27017 http: RESTInterfaceEnabled: true processManagement: fork: false replication: replSetName: configRS oplogSizeMB: 50 sharding: clusterRole: shardsvr
start-sharding-mongodb.sh 啓動腳本(測試的mongodb都在同一臺機器上的)
nohup ./replication/primary/bin/mongod -f ./replication/primary/bin/mongodb.conf >./logs/primary.log 2>&1 & nohup ./replication/secondary1/bin/mongod -f ./replication/secondary1/bin/mongodb.conf >./logs/secondary1.log 2>&1 & nohup ./replication/secondary2/bin/mongod -f ./replication/secondary2/bin/mongodb.conf >./logs/secondary2.log 2>&1 & nohup ./mongodb-node1/bin/mongod -f ./mongodb-node1/bin/mongodb.conf >./logs/mongodb-node1.log 2>&1 & nohup ./mongodb-node2/bin/mongod -f ./mongodb-node2/bin/mongodb.conf >./logs/mongodb-node2.log 2>&1 & nohup ./config/mongodb-config1/bin/mongod -f ./config/mongodb-config1/bin/mongodb.conf >./logs/config1.log 2>&1 & nohup ./config/mongodb-config2/bin/mongod -f ./config/mongodb-config2/bin/mongodb.conf >./logs/config2.log 2>&1 & nohup ./config/mongodb-config3/bin/mongod -f ./config/mongodb-config3/bin/mongodb.conf >./logs/config3.log 2>&1 & nohup ./rounter/mongodb-rounter1/bin/mongos --configdb shardingConfig/192.168.1.142:27022,192.168.1.142:27023,192.168.1.142:27024 --port 27025 --logpath=/usr/local/apache/mongoDB/sharding/rounter/mongodb-rounter1/logs/mongodb.log >./logs/rounter.log 2>&1 &