Mongodb項目實踐後的分享
前言
最近將前段時間做的日誌服務進行了改進,數據存儲改爲mongodb,數據流轉爲:
filebeats收集-->logstash過濾-->mongodb保存
mongodb摸索使用過程中總結了不少東西,分享給大家。如果文中有出入,還望各位指出。
這裏只分享一些重要的點,具體實施細節可以去官方網站或者這裏去看看
https://www.runoob.com/mongodb/mongodb-tutorial.html
1. Mongodb是什麼
1.1 概況
先來一個Google趨勢分析,這是2016年至今的Oracle與Mongodb熱度趨勢,可以發現,後者在穩步上升,前者逐步下降趨勢,下面的統計中國關注度很亮眼
再來看看國內趨勢分析,國內用的是百度趨勢,對比更加明顯了,從11年到現在,關注度越來越高,可見mongodb的熱度是不容忽視的,特別進來更新功能越來越給力,不僅支持分佈式部署,還支持分佈式事務,性能也是非常強悍。
1.2 詳述
它是一個文檔數據庫,號稱是最像關係型數據庫的非關係型數據庫,屬於NOSQL數據庫類,在MongoDB中的一條記錄就是一個文檔,是一個數據結構,由字段和值對組成。MongoDB文檔與JSON對象類似,叫做BSON。字段的值有可能包括其它文檔、數組以及文檔數組。
下面是他的數據結構:
{
"type":"book",
"title":"The Red Book",
"attributes": {
"color":"red",
"size":"large",
"inside": {
"bookmark":1,
"postitnote":2
},
"outside": {
"dustcover": "worn"
}
}
}
{
"type":"book",
"title":"The Blue Book",
"attributes": {
"color":"blue",
"size":"small",
"inside": {
"map":1
},
"outside": {
"librarystamp": "Local Library"
}
}
}
從上面可以看出,他的數據全是以鍵值對的形式出現,可能現在你還是對他的數據結構不太清楚,就拿後端最熟悉的關係型數據庫對比下一下就立馬明瞭了。
Oracle | MongoDB |
---|---|
ACID Transactions | ACID Transactions |
Table | Collection |
Row | Document |
Column | Field |
Secondary Index | Secondary Index |
GROUP_BY | Aggregation Pipeline |
Oracle的表(Table)就是它的集合(Collection),Oracle的行(Row)就是它的文檔(Document),Oracle的列(Column)就是它的字段(Field)。
需要注意的是:
文檔中的鍵/值對是有序的。
文檔中的值不僅可以是在雙引號裏面的字符串,還可以是其他幾種數據類型(甚至可以是整個嵌入的文檔)。
MongoDB區分類型和大小寫。
MongoDB的文檔不能有重複的鍵。
文檔的鍵是字符串。除了少數例外情況,鍵可以使用任意UTF-8字符。
文檔鍵命名規範:
鍵不能含有\0 (空字符)。這個字符用來表示鍵的結尾。
.和$有特別的意義,只有在特定環境下才能使用。
以下劃線"_"開頭的鍵是保留的(不是嚴格要求的)。
聚合查詢:Aggregation Pipeline
Aggregation Pipeline的功能類似於關係型數據庫的GROUP_BY,可以做很多統計查詢操作。
以下是mongodb的幾條基本操作對比:
2. 特點
2.1 大的不同點
mongodb與關係型數據庫有一個非常大的不同點,關係型數據庫的列都是固定的,無法實現對字段的任意擴展。而mongodb不同,它支持對字段的任意擴展,比如上文中提到過的
{
"type":"book",
"title":"The Red Book",
"attributes": {
"color":"red",
"size":"large",
"inside": {
"bookmark":1,
"postitnote":2
},
"outside": {
"dustcover": "worn"
}
}
}
{
"type":"book",
"title":"The Blue Book",
"attributes": {
"color":"blue",
"size":"small",
"inside": {
"map":1
},
"outside": {
"librarystamp": "Local Library"
}
}
}
可以發現:前後inside的屬性是不同的,可以隨意對錶結構進行靈活變換,增加/減少字段,所以非常適合那種對錶結構變動頻繁的場景。
2.2 事務
早前的Mongodb版本被人所詬病的就是無事務,抑或是事務很雞肋,但是今年新出的4.x版本已經解決了這些疑問,4.2版本已經可以完美支持分佈式事務,如果有事務方面需求的可以去關注一下他的新特性。
2.3 索引
索引通常能夠極大的提高查詢的效率,如果沒有索引,MongoDB在讀取數據時必須掃描集合中的每個文件並選取那些符合查詢條件的記錄。這種掃描全集合的查詢效率是非常低的,特別在處理大量的數據時,查詢可以要花費幾十秒甚至幾分鐘,這對網站的性能是非常致命的。索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中,索引是對數據庫表中一列或多列的值進行排序的一種結構
如何創建索引?
>db.collection.createIndex(keys, options)
3 MongoDB 複製(副本集)
MongoDB複製是將數據同步在多個服務器的過程。複製提供了數據的冗餘備份,並在多個服務器上存儲數據副本,提高了數據的可用性, 並可以保證數據的安全性。複製還允許從硬件故障和服務中斷中恢復數據。
3.1 什麼是副本集
保障數據的安全性
數據高可用性 (24*7)
災難恢復
無需停機維護(如備份,重建索引,壓縮)
分佈式讀取數據
3.2 MongoDB副本集原理
1)mongodb的副本集至少需要兩個節點。其中一個是主節點,負責處理客戶端請求,其餘的都是從節點,負責複製主節點上的數據。
2)mongodb各個節點常見的搭配方式爲:一主一從、一主多從。
3)主節點記錄在其上的所有操作oplog,從節點定期輪詢主節點獲取這些操作,然後對自己的數據副本執行這些操作,從而保證從節的數據與主節點一致。
(ps:話說這個同步過程還和redis主從同步過程蠻像的)
3.3 副本集特徵:
- N 個節點的集羣
- 任何節點可作爲主節點
- 所有寫入操作都在主節點上
- 自動故障轉移
- 自動恢復
4 MongoDB分片(Sharding)技術
- 分片(sharding) 是MongoDB用來將大型集合分割到不同服務器(或者說一個集羣)上所採用的方法。儘管分片起源於關係型 數據庫分區,但MongoDB分片完全又是另一回事。
- 和MySQL分區方案相比,MongoDB的最大區別在於它幾乎能自動完成所有事情,只要告訴MongoDB要分配數據,它就能自動維護數據在不同服務器之間的均衡。
4.1 分片的目的
https://docs.mongodb.com/manual/sharding/
分片是一種用於在多臺計算機之間分配數據的方法。MongoDB使用分片來支持具有非常大的數據集和高吞吐量操作的部署。具有大數據集或高吞吐量應用程序的數據庫系統可能會挑戰單個服務器的容量。例如,高查詢率可能會耗盡服務器的CPU容量。大於系統RAM的工作集大小會增加磁盤驅動器的I / O容量。
爲了解決這些問題,有兩個基本的方法: 垂直擴展和水平擴展。
垂直擴展:增加更多的CPU和存儲資源來擴展容量。
水平擴展:將數據集分佈在多個服務器上。水平擴展即分片。
MongoDB 通過分片支持水平擴展。
4.2 分片設計思想
分片爲應對高吞吐量與大數據量提供了方法。使用分片減少了每個分片需要處理的請求數,因此,通過水平擴展,集羣可以提高自己的存儲容量和吞吐量。舉例來說,當插入一條數據時,應用只需要訪問存儲這條數據的分片。使用分片減少了每個分片存儲的數據。
例如:
如果數據庫1tb的數據集,並有4個分片,然後每個分片可能僅持有256 GB的數據。如果有40個分片,那麼每個切分可能只有25GB的數據。
參考文獻及圖片出處
(1)https://www.runoob.com/mongodb/mongodb-tutorial.html
(2)https://www.cnblogs.com/duanxz/p/10730121.html
(3)https://docs.mongodb.com/manual/