1.分區
分區是什麼。分區就是將資料存放區在多個機器上。當資料集超過單台伺服器的容量,伺服器的記憶體,磁碟IO都會有問題,即超過單台伺服器的效能瓶頸。此時有兩種解決方案,垂直擴充和水平擴充(分區)。
垂直擴充就是增加CPU,增加容量,但高效能系統的CPU和容量不成比例,這樣擴充成本大,並且有上限。
水平擴充分區,將資料分發到多個伺服器,每個伺服器是一個單獨的資料庫,各個伺服器加起來組成一個邏輯資料庫,把寫壓力和操作分流到不同伺服器,提高容量和輸送量。
MongoDB的文檔是無模式的,不固定結構,因此只能進行水平分區。當塊超過指定大小或者文檔數超過最大文檔數,MongoDB嘗試分割這個塊,若分割成功,把它標記為一個大塊避免重複分割。拆分塊的關鍵就是片鍵,下面介紹常見片鍵的種類。
2.片鍵種類
片鍵是文檔的一個屬性欄位或者一個複合索引欄位,一旦建立不能改變。片鍵是分區拆分資料的關鍵,片鍵的選擇直接影響叢集的效能。
MongoDB首先根據片鍵劃分塊chunks當塊超過指定大小(預設64M),然後把塊分到其他的分區上,片鍵類型主要有以下幾種:
注意:片鍵也是查詢時常用的一個索引。
(1) 遞增片鍵
這類片鍵比較常見,比如使用時間戳,日期,自增的主鍵,ObjectId,_id等,此類片鍵的寫入操作集中在一個分區伺服器上,寫入不具有分散性,這會導致單台伺服器壓力較大,但分割比較容易,這台伺服器可能會成為效能瓶頸。
遞增片鍵的建立,對foo資料庫的bar集合使用timestamp時間戳記分區
mongos> use foomongos> db.bar.ensureIndex({"timestamp":1})mongos> sh.enableSharding("foo"){ "ok" : 1 }mongos> sh.shardCollection("foo.bar",{"timestamp":1}){ "collectionsharded" : "foo.bar", "ok" : 1 }
(2) 雜湊片鍵
使用一個雜湊索引欄位作為片鍵,優點是使資料在各節點分布比較均勻,資料寫入可隨機分發到每個分區伺服器上,把寫入的壓力分散到了各個伺服器上。但是讀也是隨機的,可能會命中更多的分區,一般具有隨機性的片鍵(如密碼,雜湊,MD5)查詢隔離效能比較差。
雜湊片鍵的建立,對GridFS的chunks集合使用files_id雜湊分區
mongos> db.bar.ensureIndex({"files_id":"hashed"})mongos> sh.enableSharding("foo"){ "ok" : 1 }mongos> sh.shardCollection("foo.fs.chunks",{"files_id":"hashed"}){ "collectionsharded" : " foo.fs.chunks ", "ok" : 1 }
(3) 組合片鍵
資料庫中沒有比較合適的片鍵供選擇,或者是打算使用的片鍵基數太小(即變化少如星期只有7天可變化),可以選另一個欄位使用組合片鍵,甚至可以添加冗餘欄位來組合。一般是粗粒度+細粒度進行組合。
組合片鍵的建立,對GridFS的chunks集合使用files_id和n組合分區
mongos> sh.enableSharding("foo"){ "ok" : 1 }mongos> sh.shardCollection("foo.fs.chunks",{"files_id":1, "n":1}){ "collectionsharded" : " foo.fs.chunks ", "ok" : 1 }
(4) 標籤分區
資料存放區在指定的分區伺服器上,可以為分區添加tag標籤,然後指定相應的tag,比如讓10.*.*.*(T)出現在shard0000上,11.*.*.*(Q)出現在shard0001或shard0002上,就可以使用tag讓均衡器指定分發。
標籤分區的建立
mongos > sh.addShardTag("shard0000", "T")mongos > sh.addShardTag("shard0001", "Q")mongos > sh.addShardTag("shard0002", "Q")mongos> sh.addTagRange("foo.ips",{ "ip": "010.000.000.000 ", … , "ip": "011.000.000.000 "}}, "T")mongos> sh.addTagRange("foo.ips",{ "ip": "011.000.000.000 ", … , "ip": "012.000.000.000 "}}, "Q")
3.片鍵選擇策略
大致瞭解了片鍵的種類,那麼怎麼選擇片鍵呢。無非從兩個方面考慮,資料的查詢和寫入,最好的效果就是資料查詢時能命中更少的分區,資料寫入時能夠隨機的寫入每個分區,關鍵在於如何權衡效能和負載。
如何選擇片鍵主要從下面幾個問題考慮:
(1)首先確定一個經常性查詢的欄位
(2)找到影響這些操作效能的關鍵點