mongodb分片+副本集總覽

由於51cto的編輯不太好用,這是有道上的文檔http://note.youdao.com/noteshare?id=aedd53c99b4a97aebbe9af136104113a

在 MongoDB 中,有兩種數據冗餘方式,一種 是 Master-Slave 模式(主從複製),一種是 Replica Sets 模式(副本集)。
三種集羣:

1、 主從集羣(目前已經不推薦使用)
2、 副本集
3、 分片集羣
分片集羣是三種模式中最複雜的一種,副本集其實一種互爲主從的關係,可理解爲主主。
副本集指將數據複製,多份保存,不同服務器保存同一份數據,在出現故障時自動切換。對應的是數據冗餘、備份、鏡像、讀寫分離、高可用性等關鍵詞;
而分片則指爲處理大量數據,將數據分開存儲,不同服務器保存不同的數據,它們的數據總和即爲整個數據集。追求的是高性能。
在生產環境中,通常是這兩種技術結合使用,分片+副本集。

下面的內容將介紹mongodb副本集、分片集羣、拆分gridfs上傳的文件、利用nginx-gridfs結合mongodb分片集羣,並且在瀏覽器顯示拆分的文件,四大類。
第1章 Mongodb副本集集羣介紹
1.1 簡介
爲什麼介紹副本集,因爲在3.6版本後,分片集羣搭建和副本集一起使用。
副本集實現了mongodb集羣的高可用。
副本集是一種在多臺機器同步數據的進程,副本集體提供了數據冗餘,擴展了數據可用性。在多臺服務器保存數據可以避免因爲一臺服務器導致的數據丟失。
也可以從硬件故障或服務中斷解脫出來,利用額外的數據副本,可以從一臺機器致力於災難恢復或者備份。
在一些場景,可以使用副本集來擴展讀性能,客戶端有能力發送讀寫操作給不同的服務器。也可以在不同的數據中心獲取不同的副本來擴展分佈式應用的能力。
mongodb副本集是一組擁有相同數據的mongodb實例,主mongodb接受所有的寫操作,所有的其他實例可以接受主實例的操作以保持數據同步。
主實例接受客戶的寫操作,副本集只能有一個主實例,因爲爲了維持數據一致性,只有一個實例可寫,主實例的日誌保存在oplog。
1.2 原理
MongoDB 的副本集不同於以往的主從模式。
在集羣Master故障的時候,副本集可以自動投票,選舉出新的Master,並引導其餘的Slave服務器連接新的Master,而這個過程對於應用是透明的。可以說MongoDB的副本集是自帶故障轉移功能的主從複製。
相對於傳統主從模式的優勢
傳統的主從模式,需要手工指定集羣中的 Master。如果 Master 發生故障,一般都是人工介入,指定新的 Master。 這個過程對於應用一般不是透明的,往往伴隨着應用重
新修改配置文件,重啓應用服務器等。而 MongoDB 副本集,集羣中的任何節點都可能成爲 Master 節點。一旦 Master 節點故障,則會在其餘節點中選舉出一個新的 Master 節點。 並引導剩餘節點連接到新的 Master 節點。這個過程對於應用是透明的。
mongodb分片+副本集總覽

一個副本集即爲服務於同一數據集的多個MongoDB實例,其中一個爲主節點,其餘的都爲從節點。主節點上能夠完成讀寫操作,從節點僅能用於讀操作。主節點需要記錄所有改變數據庫狀態的操作,這些記錄保存在oplog中,這個文件存儲在local數據庫,各個從節點通過此oplog來複制數據並應用於本地,保持本地的數據與主節點的一致。oplog具有冪等性,即無論執行幾次其結果一致,這個比mysql的二進制日誌更好用。集羣中的各節點還會通過傳遞心跳信息來檢測各自的健康狀況。
當主節點故障時,多個從節點會觸發一次新的選舉操作,並選舉其中的一個成爲新的主節點(通常誰的優先級更高,誰就是新的主節點),心跳信息默認每2秒傳遞一次。客戶端連接到副本集後,不關心具體哪一臺機器是否掛掉。主服務器負責整個副本集的讀寫,副本集定期同步數據備份。一旦主節點掛掉,副本節點就會選舉一個新的主服務器。這一切對於應用服務器不需要關心。
mongodb分片+副本集總覽
mongodb分片+副本集總覽

副本集中的副本節點在主節點掛掉後通過心跳機制檢測到後,就會在集羣內發起主節點的選舉機制,自動選舉出一位新的主服務器。
mongodb分片+副本集總覽

1.3 節點
副本集擁有三種節點:主節點、從節點、仲裁節點
1)主節點負責處理客戶端請求,讀、寫數據, 記錄在其上所有操作的oplog;
2)從節點定期輪詢主節點獲取這些操作,然後對自己的數據副本執行這些操作,從而保證從節點的數據與主節點一致。默認情況下,從節點不支持外部讀取,但可以設置;副本集的機制在於主節點出現故障的時候,餘下的節點會選舉出一個新的主節點,從而保證系統可以正常運行。
3)仲裁節點不復制數據,僅參與投票。由於它沒有訪問的壓力,比較空閒,因此不容易出故障。由於副本集出現故障的時候,存活的節點必須大於副本集節點總數的一半,否則無法選舉主節點,或者主節點會自動降級爲從節點,整個副本集變爲只讀。因此,增加一個不容易出故障的仲裁節點,可以增加有效選票,降低整個副本集不可用的風險。仲裁節點可多於一個。也就是說只參與投票,不接收復制的數據,也不能成爲活躍節點。
注意:
官方推薦MongoDB副本節點最少爲3臺,建議副本集成員爲奇數,最多12個副本節點,最多7個節點參與選舉。限制副本節點的數量,主要是因爲一個集羣中過多的副本節點,增加了複製的成本,反而拖累了集羣的整體性能。太多的副本節點參與選舉,也會增加選舉的時間。而官方建議奇數的節點,是爲了避免腦裂 的發生。
1.4 工作流程
在MongoDB副本集中,主節點負責處理客戶端的讀寫請求,備份節點則負責映射主節點的數據。備份節點的工作原理過程可以大致描述爲,備份節點定期輪詢主節點上的數據操作,從而保證跟主節點的數據同步。至於主節點上的所有數據庫狀態改變的操作,都會存放在一張特定的系統表中。備份節點則是根據這些數據進行自己的數據更新。
1.4.1 Oplog
上面提到的數據庫狀態改變的操作,稱爲 oplog(operationlog,主節點操作記錄。oplog 存儲在local數據庫的"oplog.rs"表中。副本集中備份節點異步的從主節點同步oplog,然後重新執行它記錄的操作,以此達到了數據同步的作用。
關於 oplog 有幾個注意的地方:
1)oplog 只記錄改變數據庫狀態的操作
2)存儲在oplog 中的操作並不是和主節點執行的操作完全一樣,例如"$inc"操作就會轉化爲"$set"操作
3)oplog 存儲在固定集合中(capped collection),當oplog的數量超過oplogSize,新的操作就會覆蓋舊的操作
1.4.2 數據同步
在副本集中,有兩種數據同步的方式:
1)initial sync(初始化):這個過程發生在當副本集中創建一個新的數據庫或其中某個節點剛從宕機中恢復,或者向副本集中添加新的成員的時候,默認的,副本集中的節點會從離它最近的節點複製oplog來同步數據,這個最近的節點可以是primary也可以是擁有最新oplog副本的 secondary節點。該操作一般會重新初始化備份節點,開銷較大。
2)replication(複製):在初始化後這個操作會一直持續的進行着,以保持各個secondary節點之間的數據同步。
當遇到無法同步的問題時,只能使用以下兩種方式進行initial sync了
1)第一種方式就是停止該節點,然後刪除目錄中的文件,重新啓動該節點。這樣,這個節點就會執行 initial sync
注意:通過這種方式,sync的時間是根據數據量大小的,如果數據量過大,sync時間就會很長同時會有很多網絡傳輸,可能會影響其他節點的工作
2)第二種方式,停止該節點,然後刪除目錄中的文件,找一個比較新的節點,然後把該節點目錄中的文件拷貝到要 sync 的節點目錄中
1.5 副本集選舉過程
Mongodb副本集選舉採用的是Bully算法,這是一種協調者(主節點)競選算法,主要思想是集羣的每個成員都可以聲明它是主節點並通知其他節點。別的節點可以選擇接受這個聲稱或是拒絕並進入主節點競爭,被其他所有節點接受的節點才能成爲主節點。
節點按照一些屬性來判斷誰應該勝出,這個屬性可以是一個靜態ID,也可以是更新的度量像最近一次事務ID(最新的節點會勝出)
1.5.1 副本集的選舉過程
1)得到每個服務器節點的最後操作時間戳。每個 mongodb 都有 oplog 機制會記錄本機的操作,方便和主服 務器進行對比數據是否同步還可以用於錯誤恢復。
2)如果集羣中大部分服務器 down 機了,保留活着的節點都爲 secondary 狀態並停止,不選舉了。
3)如果集羣中選舉出來的主節點或者所有從節點最後一次同步時間看起來很舊了,停止選舉等待人來操作。
4)如果上面都沒有問題就選擇最後操作時間戳最新(保證數據是最新的)的服務器節點作爲主節點。
1.5.2 副本集選舉的特點
選舉還有個前提條件,參與選舉的節點數量必須大於副本集總節點數量的一半(建議副本集成員爲奇數。最多12個副本節點,最多7個節點參與選舉)如果已經小於一半了所有節點保持只讀狀態。集合中的成員一定要有大部分成員(即超過一半數量)是保持正常在線狀態,3個成員的副本集,需要至少2個從屬節點是正常狀態。
如果一個從屬節點掛掉,那麼當主節點down掉 產生故障切換時,由於副本集中只有一個節點是正常的,少於一半,則選舉失敗。
4個成員的副本集,則需要3個成員是正常狀態(先關閉一個從屬節點,然後再關閉主節點,產生故障切換,此時副本集中只有2個節點正常,則無法成功選舉出新主節點)。
1.6 MongoDB 同步延遲問題
當你的用戶抱怨修改過的信息不改變,刪除掉的數據還在顯示,你掐指一算,估計是數據庫主從不同步。與其他提供數據同步的數據庫一樣,MongoDB 也會遇到同步延遲的問題,在MongoDB的Replica Sets模式中,同步延遲也經常是困擾使用者的一個大問題。

1.6.1 什麼是同步延遲
首先,要出現同步延遲,必然是在有數據同步的場合,在 MongoDB 中,有兩種數據冗餘方式,一種是Master-Slave 模式,一種是Replica Sets模式。這兩個模式本質上都是在一個節點上執行寫操作, 另外的節點將主節點上的寫操作同步到自己這邊再進行執行。在MongoDB中,所有寫操作都會產生 oplog,oplog是每修改一條數據都會生成一條,如果你採用一個批量 update 命令更新了 N 多條數據, 那麼,oplog會有很多條,而不是一條。所以同步延遲就是寫操作在主節點上執行完後,從節點還沒有把 oplog拿過來再執行一次。而這個寫操作的量越大,主節點與從節點的差別也就越大,同步延遲也就越大了。
1.6.2 同步延遲帶來的問題
首先,同步操作通常有兩個效果,一是讀寫分離,將讀操作放到從節點上來執行,從而減少主節點的 壓力。對於大多數場景來說,讀多寫少是基本特性,所以這一點是很有用的。
另一個作用是數據備份, 同一個寫操作除了在主節點執行之外,在從節點上也同樣執行,這樣我們就有多份同樣的數據,一旦 主節點的數據因爲各種天災人禍無法恢復的時候,我們至少還有從節點可以依賴。但是主從延遲問題 可能會對上面兩個效果都產生不好的影響。
如果主從延遲過大,主節點上會有很多數據更改沒有同步到從節點上。這時候如果主節點故障,就有 兩種情況:
1)主節點故障並且無法恢復,如果應用上又無法忍受這部分數據的丟失,我們就得想各種辦法將這部 數據更改找回來,再寫入到從節點中去。可以想象,即使是有可能,那這也絕對是一件非常噁心的活。
2)主節點能夠恢復,但是需要花的時間比較長,這種情況如果應用能忍受,我們可以直接讓從節點提 供服務,只是對用戶來說,有一段時間的數據丟失了,而如果應用不能接受數據的不一致,那麼就只能下線整個業務,等主節點恢復後再提供服務了。
如果你只有一個從節點,當主從延遲過大時,由於主節點只保存最近的一部分 oplog,可能會導致從 節點青黃不接,不得不進行 resync 操作,全量從主節點同步數據。
帶來的問題是:當從節點全量同步的時候,實際只有主節點保存了完整的數據,這時候如果主節點故障,很可能全部數據都丟掉了。
1.7 副本集搭建過程
1.7.1 環境準備

Centos7  64位系統
Mongodb 4.0版本
三臺虛擬機
192.168.1.182:27017
192.168.1.186:27017
192.168.1.122:27017

安裝包(三臺一樣)
下載地址

https://www.mongodb.com/download-center?jmp=nav#community
https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.2.tgz

解壓到/usr/local/mongodb/目錄下
1.7.2 搭建過程
1、 創建數據目錄(三臺創建)
mkdir /data/mongodb/27017/ -p
2、 創建配置文件(三臺配置一樣)

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/27017/mongodb.log
storage:
  dbPath: /data/mongodb/27017/
  journal:
    enabled: true
processManagement:
  fork: true
net:
  port: 27017
  bindIp: 0.0.0.0

#副本集標誌,三臺name要一樣,才能加入到副本集。

replication:
  replSetName: data

3、 啓動
啓動三臺實例
/usr/local/mongodb/bin/mongod -f /data/mongodb/27017/mongodb.conf
4、 初始化
登錄任意一臺實例,進行初始化sql語句,三大步sql。

config = { _id:"data", members:[
  {_id:0,host:"192.168.1.182:27017"},
  {_id:1,host:"192.168.1.186:27017"},
  {_id:2,host:"192.168.1.122:27017"}]
}

進入到admin,進行初始化
use admin
初始化需要時間
rs.initiate( config )
查看狀態
rs.status() #副本集狀態,一個primary,其它SECONDARY。primary是主,只有primary能寫入。
注意:-id,爲副本集配置文件裏面的name一致。
1.7.3 優先級設置
primary的選舉依賴於各個實例的優先權重,默認權重都是1
複本集的主挑選權重最高的,權重一樣的無法控制誰爲主
設置各個實例的優先權重,挑選自己想要的實例爲主,只有primary可以更改權重配置

conf = rs.config()   #獲取副本集的配置,默認權重都是1
conf.members[0].priority = 10 #索引號從0開始,每次遞增1,類似數組
conf.members[1].priority = 5
conf.members[2].priority = 2
rs.reconfig(conf)   #更新mongodb副本集的配置,優先權重最高的提升爲primary。

關閉啓動後也爲主
至此,副本集搭建介紹完成

第2章 Mongodb分片集羣介紹
Sharding cluster是一種可以水平擴展的模式,在數據量很大時特給力,實際大規模應用一般會採用這種架構去構建。sharding分片很好的解決了單臺服務器磁盤空間、內存、cpu等硬件資源的限制問題,把數據水平拆分出去,降低單節點的訪問壓力。每個分片都是一個獨立的數據庫,所有的分片組合起來構成一個邏輯上的完整的數據庫。因此,分片機制降低了每個分片的數據操作量及需要存儲的數據量,達到多臺服務器來應對不斷增加的負載和數據的效果。
2.1 Sharding分區概念
將數據分散到不同的機器上,不需要功能強大的服務器就可以存儲更多的數據和處理更大的負載。
2.1.1 分片的基本思想
將集合切成小塊,這些塊分散到若干片裏,每個片只負責總數據的一部分。通過一個名爲mongos的路由進程進行操作,mongos知道數據和片的對應關係(通過配置服務器)。大部分使用場景都是解決磁盤空間的問題,對於寫入有可能會變差(+++裏面的說明+++),查 詢則儘量避免跨分片查詢。
2.1.2 使用分片的時機
1)機器的磁盤不夠用了。使用分片解決磁盤空間的問題。
2)單個mongod已經不能滿足寫數據的性能要求。通過分片讓寫壓力分散到各個分片上面,使用分片服務器自身的資源。
3)想把大量數據放到內存裏提高性能。和上面一樣,通過分片使用分片服務器自身的資源。

2.1.3 三種角色
1)分片服務器(Shard Server)
mongod實例,用於存儲實際的數據塊,實際生產環境中一個 shard server 角色可由幾臺機器組個一個 relica set 承擔,防止主機單點故障。
這是一個獨立普通的mongod進程,保存數據信息。可以是一個副本集也可以是單獨的一臺服務器(生產環境都是副本集)。
2)配置服務器(Config Server)
mongod 實例,存儲了整個 Cluster Metadata,其中包括 chunk 信息。
這是一個獨立的mongod進程,保存集羣和分片的元數據,即各分片包含了哪些數據的信息。最先開始建立,啓用日誌功能。像啓動普通的 mongod 一樣啓動。
配置服務器,指定configsvr 選項。不需要太多的空間和資源,配置服務器的 1KB 空間相當於真是數據的 200MB。保存的只是數據的分佈表。
3)路由服務器(Route Server)
mongos實例,前端路由,客戶端由此接入,且讓整個集羣看上去像單一數據庫,前端應用
起到一個路由的功能,供程序連接。本身不保存數據,在啓動時從配置服務器加載集羣信息,開啓 mongos 進程需要知道配置服務器的地址,指定configdb選項。
2.1.4 片鍵的意義
一個好的片鍵對分片至關重要。片鍵必須是一個索引,通過sh.shardCollection 加會自動創建索引。一個自增的片鍵對寫入和數據均勻分佈就不是很好, 因爲自增的片鍵總會在一個分片上寫入,後續達到某個閥值可能會寫到別的分片。但是按照片鍵查詢會非常高效。隨機片鍵對數據的均勻分佈效果很好。注意儘量避免在多個分片上進行查詢。
在所有分片上查詢,mongos 會對結果進行歸併排序

mongodb分片+副本集總覽
mongodb分片+副本集總覽

2.1.5 分片的原理
分片,是指將數據拆分,將其分散到不同的機器上。這樣的好處就是,不需要功能強大的大型計算機也可以存儲更多的數據,處理更大的負載。mongoDB 的分片,是將collection 的數據進行分割,然後將不同的部分分別存儲到不同的機器上。當 collection 所佔空間過大時,我們需要增加一臺新的機器,分片會自動將 collection 的數據分發到新的機器上。
2.1.6 分片集羣的構造
mongodb分片+副本集總覽
2.2 分片集羣的搭建
2.2.1 環境準備
Centos7 64位系統
Mongodb 4.0版本
三臺虛擬機

##三臺路由服務器
192.168.1.182:20000
192.168.1.186:20000
192.168.1.122:20000
##三臺配置服務器
192.168.1.182:21000
192.168.1.186:21000
192.168.1.122:21000
##九個分片數據服務器(測試複用三臺),三組分片數據,各組爲副本集。
192.168.1.182:27001
192.168.1.186:27001
192.168.1.122:27001
192.168.1.182:27002
192.168.1.186:27002
192.168.1.122:27002
192.168.1.182:27003
192.168.1.186:27003
192.168.1.122:27003

###創建數據目錄

#三臺服務器,創建路由配置目錄
mkdir /data/mongodb/20000 –p
#三臺服務器,創建配置服務器目錄
mkdir /data/mongodb/21000 –p
#三臺服務器,創建shard目錄
mkdir /data/mongodb/27001 –p
mkdir /data/mongodb/27002 –p
mkdir /data/mongodb/27003 –p

安裝包
三臺服務下載安裝包,解壓到/usr/local/mongodb目錄

https://www.mongodb.com/download-center?jmp=nav#community
https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.2.tgz

解壓到/usr/local/mongodb/目錄下
2.2.2 配置角色搭建(configsvr)
1、編輯文件vim /usr/local/mongodb/conf/config.conf,三臺服務器配置一樣。

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/21000/mongodb.log
storage:
  dbPath: /data/mongodb/21000/
  journal:
    enabled: true
processManagement:
  fork: true
net:
  port: 21000
  bindIp: 127.0.0.1
replication:
  replSetName: conf
sharding:
  clusterRole: configsvr

2、啓動跟單例的啓動方式一致,都是使用mongod
3、配置角色副本集搭建,配置角色也是副本集,達到高可用

config = { _id:"conf ", 
  configsvr: true,
  members:[
    {_id:0,host:"192.168.1.182:21000"},
    {_id:1,host:"192.168.1.186:21000"},
    {_id:2,host:"192.168.1.122:21000"}
  ]
}
rs.initiate(config)
rs.status() #查看狀態

2.2.3 路由角色搭建(mongos)
1、 編輯配置文件vim /usr/local/mongodb/conf/mongos.conf,三臺一樣配置,配置多個router,任何一個都能正常的獲取數據

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/20000/mongodb.log
processManagement:
  fork: true
net:
  port: 20000
  bindIp: 0.0.0.0
sharding:
  configDB: config/192.168.1.182:21000,192.168.1.186:21000,192.168.1.122:21000

##文件最後指定,配置角色的ip+端口。
2、 啓動
/usr/local/mongodb/bin/mongos -f /usr/local/mongodb/conf/mongos.conf
#路由服務器的啓動和其他角色不一樣。
2.2.4 數據角色搭建(shard)
三個shard,共有三個副本集。
##shard1
1、 編輯配置文件vim /usr/local/mongodb/conf/shard1.conf,三臺shard1,配置一樣。

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/27001/mongodb.log
storage:
  dbPath: /data/mongodb/27001/
  journal:
    enabled: true
processManagement:
  fork: true
net:
  port: 27001
  bindIp: 0.0.0.0
replication:
  replSetName: data1
#name三臺一致,副本集。不同的shard名稱不同,如:data2、data3
sharding:
  clusterRole: shardsvr
2、  啓動

3、 配置副本集

config = { _id:"data1", 
  members:[
    {_id:0,host:"192.168.1.182:27001"},
    {_id:1,host:"192.168.1.186:27001"},
    {_id:2,host:"192.168.1.122:27001"}
  ]
}
#初始化
rs.initiate(config)
rs.status() #查看狀態
至此搭建完成。

2.3 驗證
2.3.1 分片集羣添加數據角色

#連接路由角色
sh.addShard("data1/192.168.1.182:27001,192.168.1.186:27001,192.168.1.122:27001");
sh.addShard("data2/192.168.1.182:27002,192.168.1.186:27002,192.168.1.122:27002");
sh.addShard("data3/192.168.1.182:27003,192.168.1.186:27003,192.168.1.122:27003");
sh.status()

2.3.2 分片策略設置
默認添加數據沒有分片存儲,操作都是在路由角色裏面
針對某個數據庫的某個表使用hash分片存儲,分片存儲就會同一個colloection分配兩個數據角色

use admin
db.runCommand( { enablesharding :"malin"});
db.runCommand( { shardcollection : "malin.myuser",key : {_id: "hashed"} } )

2.3.3 插入數據進行分片

use malin
for(i=1; i<=500;i++){
  db.myuser.insert( {name:'mytest'+i, age:i} )
}

查看三個shard是否有數據。
第3章 Mongodb gridfs介紹
GridFS是用於存儲和檢索超過 BSON -文檔大小限制爲16 MB的文件的規範。

GridFS不是將文件存儲在單個文檔中,而是將文件分成多個部分或塊[1],並將每個塊存儲爲單獨的文檔。默認情況下,GridFS使用默認的塊大小255 kB; 也就是說,GridFS將文件分成255 kB的塊,但最後一個塊除外。最後一個塊只有必要的大小。同樣,不大於塊大小的文件只有最終的塊,只使用所需的空間和一些額外的元數據。
GridFS使用兩個集合來存儲文件。一個集合存儲文件塊(chunks),另一個存儲文件元數據(files)。
GridFS不僅可用於存儲超過16 MB的文件,還可用於存儲您想要訪問的任何文件,而無需將整個文件加載到內存中。
3.1 使用時機
1、 如果文件系統限制目錄中的文件數,則可以使用GridFS根據需要存儲任意數量的文件。
2、 如果要從大型文件的各個部分訪問信息而無需將整個文件加載到內存中,可以使用GridFS調用文件的各個部分,而無需將整個文件讀入內存。
3、 如果要保持文件和元數據在多個系統和工具中自動同步和部署,可以使用GridFS。使用地理位置分散的副本集時,MongoDB可以自動將文件及其元數據分發到多個 mongod實例和工具中。
3.2 Gridfs集合
chunks存儲二進制塊。默認是fs.chunks
#字段

{ 
  “  _ id ” : < ObjectId > ,
  “files_id”  : < ObjectId > ,
  “n”  : < num > ,
  “data”  : < binary > 
}

files存儲文件的元數據。默認是fs.files
#字段
{
"_id" : <ObjectId>,
"length" : <num>,
"chunkSize" : <num>,
"uploadDate" : <timestamp>,
"md5" : <hash>,
"filename" : <string>,
"contentType" : <string>,
"aliases" : <string array>,
"metadata" : <any>,
}

3.3 拆分GridFS
3.3.1 拆分chunks
對chunks集合進行分片,使用files_id字段,利用哈希進行分片
3.3.2 拆分files
對files集合進行分片,使用_id字段,利用哈希進行分片
3.4 實例
1、配置分片策略

#進入到路由服務器
use admin
#指定拆分的數據庫test
db.runCommand( { enablesharding :"test"});
#指定拆分的files,test數據庫中的test-file.files集合,利用_id字段
db.runCommand( { shardcollection : "test.test-file.files",key : {_id: "hashed"} } )
#指定拆分的chunks,test數據庫中的test.test-file.chunks集合,利用files_id,字段
db.runCommand( { shardcollection : "test.test-file.chunks",key : {files_id: "hashed"}})

2、 上傳文件到test庫中的test-file集合
命令行

mongofiles -d test1 -h 127.0.0.1 --port 20000 --prefix test-file put 1553.png
-d指定數據庫
-h主機
--port端口(路由角色)
--prefix 指定集合
Put 上傳

第4章 Nginx GridFS介紹
mongodb分片已經搭建完成,利用nginx的GridFS模塊,實現nginx直接連接到mongodb數據庫讀取文件、圖片。
4.1 下載nginx
1、安裝 nginx 需要的依賴
yum install -y zlib zlib-devel gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel
注意:編譯nginx過程中,如在出現問題,自行安裝依賴。
2、下載nginx
wget -c https://nginx.org/download/nginx-1.12.1.tar.gz
tar -zxvf nginx-1.12.1.tar.gz -C /usr/local/nginx
4.2 下載nginx-gridfs模塊
nginx通過該模塊和mongodb的gridfs進行整合
wget -c https://github.com/mdirolf/nginx-gridfs/archive/v0.8.tar.gz -O nginx-gridfs-0.8.tar.gz
tar -xzvf ./nginx-gridfs-0.8.tar.gz
4.3 下載nginx的mongodb驅動
將這個驅動下的所有移動到nginx-gridfs模塊目錄下的mongo-c-driver目錄,爲了後期編譯
wget https://github.com/mongodb/mongo-c-driver/archive/v0.3.1.tar.gz
tar -zxvf v0.3.1.tar.gz
cd /root/mongo-c-driver-0.3.1
#將驅動下的所有移動到nginx-gridfs目錄下的mongo-c-driver目錄下。
mv ./* /root/nginx-gridfs-0.8/mongo-c-driver/
[root@hadoop-namenode mongo-c-driver]# ll
total 36
-rw-rw-r-- 1 root root 11358 May 13 2011 APACHE-2.0.txt
drwxrwxr-x 2 root root 40 May 13 2011 buildscripts
drwxrwxr-x 2 root root 41 May 13 2011 docs
-rw-rw-r-- 1 root root 10760 May 13 2011 doxygenConfig
-rw-rw-r-- 1 root root 363 May 13 2011 HISTORY.md
-rw-rw-r-- 1 root root 3024 May 13 2011 README.md
-rw-rw-r-- 1 root root 4090 May 13 2011 SConstruct
drwxrwxr-x 2 root root 185 May 13 2011 src
drwxrwxr-x 2 root root 282 May 13 2011 test
4.4 編譯安裝
#進入到nginx包目錄下

cd nginx-1.12.0  
#開始編譯,--add-module=/root/nginx-gridfs-0.8。這個目錄就是nginx-gridfs模塊的位置。
./configure --user=nginx --group=nginx --prefix=/usr/local/nginx/ --with-http_v2_module --with-http_ssl_module --with-http_sub_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --add-module=/root/nginx-gridfs-0.8/
make && make install

4.5 問題處理
1、在make && make install的時候報錯:
ngx_http_gridfs_module.c:684:16: 錯誤:變量‘chunksize’被設定但未被使用
處理方法:進入nginx包目錄 vi nginx-1.12.0/objs/Makefile修改一個小錯誤,把第3行的-Werror錯誤去掉。
2、not exist /root/nginx-gridfs-0.8/mongo-c-driver/src/*.h,表示nginx的mongodb驅動沒有安裝。
處理方法:安裝驅動,下載nginx的mongodb驅動。
至此nginx和nginx-gridfs模塊編譯成功,下面是配置文件的修改。
4.6 nginx-gridfs配置文件
#進入安裝好的nginx配置文件conf目錄下

 server{
        listen       80;
        server_name  192.168.60.235;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
        location /pics/ {
        gridfs  test
        field=_id
        type=objectid;
         mongo  192.168.xx.2x7:27017;
       }
     }

4.7 配置文件參數詳解
gridfs:nginx識別插件的關鍵字
edusns:db名
[root_collection]: 選擇collection,如root_collection=blog, mongod就會去找blog.files與blog.chunks兩個塊,默認是fs
[field]: 查詢字段,保證mongdb裏有這個字段名,支持_id, filename, 可省略, 默認是_id
[type]: 解釋field的數據類型,支持objectid, int, string, 可省略, 默認是int
[user]: 用戶名, 可省略
[pass]: 密碼, 可省略
mongo: mongodb 路由地址(集羣中)
4.8 測試
1、上傳文件到mongodb,然後進行瀏覽器測試。
#命令行mongodb上傳文件
mongofiles put 1234.jpg --local ~/1234.jpg --host 172.0.0.1 --port 27017 --db testdb --type jpg
2、瀏覽器訪問
ip/pics/1234.jpg
#nginx地址
第5章 總結
5.1 分片集羣搭建
5.1.1 Config角色
配置文件(三臺都配置)

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/21000/mongodb.log
storage:
  dbPath: /data/mongodb/21000/
  journal:
    enabled: true
processManagement:
  fork: true
net:
  port: 21000
  bindIp: 127.0.0.1
replication:
  replSetName: conf
sharding:
  clusterRole: configsvr
#只需修改端口即可,三臺一致。

配置副本集
啓動進入到任意一臺實例進行配置

config = { _id:"conf ", 
  configsvr: true,
  members:[
    {_id:0,host:"192.168.1.182:21000"},
    {_id:1,host:"192.168.1.186:21000"},
    {_id:2,host:"192.168.1.122:21000"}
  ]
}
rs.initiate(config)
rs.status() #查看狀態
#注意:_id爲副本集名稱

5.1.2 mongos角色
配置文件(三臺一樣配置文件)

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/20000/mongodb.log
processManagement:
  fork: true
net:
  port: 20000
  bindIp: 0.0.0.0
sharding:
  configDB: config/192.168.1.182:21000,192.168.1.186:21000,192.168.1.122:21000
#指定配置角色位置

5.1.3 shard角色
配置文件(九個實例,三個爲一組副本集),只需修改端口和副本集名稱

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/27001/mongodb.log
storage:
  dbPath: /data/mongodb/27001/
  journal:
    enabled: true
processManagement:
  fork: true
net:
  port: 27001
  bindIp: 0.0.0.0
replication:
  replSetName: data1
#name三臺一致,副本集。不同的shard名稱不同,如:data2、data3
sharding:
  clusterRole: shardsvr
#配置副本集
啓動,進入到任意一臺分片實例,進行副本集配置。
config = { _id:"data1", 
  members:[
    {_id:0,host:"192.168.1.182:27001"},
    {_id:1,host:"192.168.1.186:27001"},
    {_id:2,host:"192.168.1.122:27001"}
  ]
}
rs.initiate(config)
rs.status() #查看狀態
#注意:_id爲副本集名稱

5.1.4 將數據角色添加到分片集羣中
進入到路由角色實例

sh.addShard("data1/192.168.1.182:27001,192.168.1.186:27001,192.168.1.122:27001");
sh.addShard("data2/192.168.1.182:27002,192.168.1.186:27002,192.168.1.122:27002");
sh.addShard("data3/192.168.1.182:27003,192.168.1.186:27003,192.168.1.122:27003");
sh.status()
#三個shard分片。

5.1.5 拆分Gridfs上傳的文件
#進入到路由服務器
use admin
#指定拆分的數據庫test
db.runCommand( { enablesharding :"test"});
#指定拆分的files,test數據庫中的test-file.files集合,利用_id字段
db.runCommand( { shardcollection : "test.test-file.files",key : {_id: "hashed"} } )
#指定拆分的chunks,test數據庫中的test.test-file.chunks集合,利用files_id,字段
db.runCommand( { shardcollection : "test.test-file.chunks",key : {files_id: "hashed"}})
#命令行上傳測試
mongofiles -d test1 -h 127.0.0.1 --port 20000 --prefix test-file put 1553.png
5.2 Nginx-gridfs搭建
5.2.1 下載nginx包及依賴
yum install -y zlib zlib-devel gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel
wget -c https://nginx.org/download/nginx-1.12.1.tar.gz
tar -zxvf nginx-1.12.1.tar.gz -C /usr/local/nginx
5.2.2 下載nginx-gridfs模塊
wget -c https://github.com/mdirolf/nginx-gridfs/archive/v0.8.tar.gz -O nginx-gridfs-0.8.tar.gz
tar -xzvf ./nginx-gridfs-0.8.tar.gz
5.2.3 下載nginx的mongodb驅動,並移動到nginx-gridfs模塊下
wget https://github.com/mongodb/mongo-c-driver/archive/v0.3.1.tar.gz
tar -zxvf v0.3.1.tar.gz
cd /root/mongo-c-driver-0.3.1
mv ./* /root/nginx-gridfs-0.8/mongo-c-driver/
5.2.4 編譯安裝nginx
./configure --user=nginx --group=nginx --prefix=/usr/local/nginx/ --with-http_v2_module --with-http_ssl_module --with-http_sub_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --add-module=/root/nginx-gridfs-0.8/
5.2.5 配置文件

server{
        listen       80;
        server_name  192.168.60.235;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
        location /pics/ {
        gridfs  test
        field=_id
        type=objectid;
         mongo  192.168.xx.2x7:27017;
       }
     }

5.2.6 命令行測試。上傳文件
mongofiles put 1234.jpg --local ~/1234.jpg --host 172.0.0.1 --port 27017 --db testdb --type jpg

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章