因爲51cto的編輯不太好用,這是有道上的文檔http://note.youdao.com/noteshare?id=aedd53c99b4a97aebbe9af136104113a前端
在 MongoDB 中,有兩種數據冗餘方式,一種 是 Master-Slave 模式(主從複製),一種是 Replica Sets 模式(副本集)。 三種集羣:
一、 主從集羣(目前已經不推薦使用)
二、 副本集
三、 分片集羣
分片集羣是三種模式中最複雜的一種,副本集其實一種互爲主從的關係,可理解爲主主。
副本集指將數據複製,多份保存,不一樣服務器保存同一份數據,在出現故障時自動切換。對應的是數據冗餘、備份、鏡像、讀寫分離、高可用性等關鍵詞;
而分片則指爲處理大量數據,將數據分開存儲,不一樣服務器保存不一樣的數據,它們的數據總和即爲整個數據集。追求的是高性能。
在生產環境中,一般是這兩種技術結合使用,分片+副本集。node
下面的內容將介紹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 節點。這個過程對於應用是透明的。
mysql
一個副本集即爲服務於同一數據集的多個MongoDB實例,其中一個爲主節點,其他的都爲從節點。主節點上可以完成讀寫操做,從節點僅能用於讀操做。主節點須要記錄全部改變數據庫狀態的操做,這些記錄保存在oplog中,這個文件存儲在local數據庫,各個從節點經過此oplog來複制數據並應用於本地,保持本地的數據與主節點的一致。oplog具備冪等性,即不管執行幾回其結果一致,這個比mysql的二進制日誌更好用。集羣中的各節點還會經過傳遞心跳信息來檢測各自的健康情況。
當主節點故障時,多個從節點會觸發一次新的選舉操做,並選舉其中的一個成爲新的主節點(一般誰的優先級更高,誰就是新的主節點),心跳信息默認每2秒傳遞一次。客戶端鏈接到副本集後,不關心具體哪一臺機器是否掛掉。主服務器負責整個副本集的讀寫,副本集按期同步數據備份。一旦主節點掛掉,副本節點就會選舉一個新的主服務器。這一切對於應用服務器不須要關心。
linux
副本集中的副本節點在主節點掛掉後經過心跳機制檢測到後,就會在集羣內發起主節點的選舉機制,自動選舉出一位新的主服務器。
nginx
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模式中,同步延遲也常常是困擾使用者的一個大問題。c++
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 環境準備git
Centos7 64位系統 Mongodb 4.0版本 三臺虛擬機 192.168.1.182:27017 192.168.1.186:27017 192.168.1.122:27017
安裝包(三臺同樣)
下載地址github
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 搭建過程
一、 建立數據目錄(三臺建立)mkdir /data/mongodb/27017/ -p
二、 建立配置文件(三臺配置同樣)算法
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要同樣,才能加入到副本集。sql
replication: replSetName: data
三、 啓動
啓動三臺實例/usr/local/mongodb/bin/mongod -f /data/mongodb/27017/mongodb.conf
四、 初始化
登陸任意一臺實例,進行初始化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 會對結果進行歸併排序
2.1.5 分片的原理
分片,是指將數據拆分,將其分散到不一樣的機器上。這樣的好處就是,不須要功能強大的大型計算機也能夠存儲更多的數據,處理更大的負載。mongoDB 的分片,是將collection 的數據進行分割,而後將不一樣的部分分別存儲到不一樣的機器上。當 collection 所佔空間過大時,咱們須要增長一臺新的機器,分片會自動將 collection 的數據分發到新的機器上。
2.1.6 分片集羣的構造
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)
一、編輯文件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
二、啓動跟單例的啓動方式一致,都是使用mongod
三、配置角色副本集搭建,配置角色也是副本集,達到高可用
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)
一、 編輯配置文件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+端口。
二、 啓動/usr/local/mongodb/bin/mongos -f /usr/local/mongodb/conf/mongos.conf
#路由服務器的啓動和其餘角色不同。
2.2.4 數據角色搭建(shard)
三個shard,共有三個副本集。
##shard1
一、 編輯配置文件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名稱不一樣,如:data二、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() #查看狀態 至此搭建完成。
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 使用時機
一、 若是文件系統限制目錄中的文件數,則可使用GridFS根據須要存儲任意數量的文件。
二、 若是要從大型文件的各個部分訪問信息而無需將整個文件加載到內存中,可使用GridFS調用文件的各個部分,而無需將整個文件讀入內存。
三、 若是要保持文件和元數據在多個系統和工具中自動同步和部署,可使用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 實例
一、配置分片策略
#進入到路由服務器 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"}})
二、 上傳文件到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
一、安裝 nginx 須要的依賴
yum install -y zlib zlib-devel gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel
注意:編譯nginx過程當中,如在出現問題,自行安裝依賴。
二、下載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 問題處理
一、在make && make install的時候報錯:
ngx_http_gridfs_module.c:684:16: 錯誤:變量‘chunksize’被設定但未被使用
處理方法:進入nginx包目錄 vi nginx-1.12.0/objs/Makefile修改一個小錯誤,把第3行的-Werror錯誤去掉。
二、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 測試
一、上傳文件到mongodb,而後進行瀏覽器測試。
#命令行mongodb上傳文件
mongofiles put 1234.jpg --local ~/1234.jpg --host 172.0.0.1 --port 27017 --db testdb --type jpg
二、瀏覽器訪問
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名稱不一樣,如:data二、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