MongoDB vs Elasticsearch | | MongoDB | ElasticSearch | 備註 | | | | | | | 定位 | (文檔型)資料庫 | (文檔型)搜索引擎 | 一個管理數據,一個檢索數據 | | 資源占用 | 一般 | 高 | mongo使用c++, es使用 ...
MongoDB vs Elasticsearch
MongoDB | ElasticSearch | 備註 | |
---|---|---|---|
定位 | (文檔型)資料庫 | (文檔型)搜索引擎 | 一個管理數據,一個檢索數據 |
資源占用 | 一般 | 高 | mongo使用c++, es使用Java開發 |
寫入延遲 | 低 | 高 | es的寫入延遲預設1s, 可配置, 但是要犧牲一些東西 |
全文索引支持度 | 一般 | 非常好 | es本來就是搜索引擎, 這個沒啥可比性 |
有無Schema | 無 | 無 | 兩者都是無Schema |
支持的數據量 | PB+ | TB+ ~ PB | 兩者支持的量並不好說的太死, 都支持分片和橫向擴展, 但是相對來說MongoDB的數據量支持要更大一點 |
性能 | 非常好 | 好 | MongoDB在大部分場景性能比es強的多得多 |
索引結構 | B樹 | LSM樹 | es追求寫入吞吐量, MongoDB讀寫比較均衡 |
操作介面 | TCP | Restful(Http) | |
是否支持分片 | 是 | 是 | |
是否支持副本 | 是 | 是 | |
選主演算法 | Bully(霸凌) | Bully(霸凌) | 相比於Paxos和Raft演算法實現更簡單並有一定可靠性上的妥協,但是選舉速度比較快 |
擴展難度 | 容易 | 非常容易 | es真的是我用過的擴展最方便的存儲系統之一 |
配置難度 | 難 | 非常容易 | |
地理位置 | 支持 | 支持 | |
運維工具 | 豐富 | 一般 | |
插件和引擎 | 有多個存儲引擎供選擇 | 有大量插件可以使用 | - |
兩者的定位
MongoDB
和Elasticsearch
都屬於NoSQL大家族, 且都屬於文檔型數據存儲
所以這兩者的很多功能和特性高度重合, 但其實兩者定位完全不同
MongoDB 是 文檔型資料庫, 提供 數據存儲和管理服務
Elasticsearch是搜索服務, 提供 數據檢索服務
兩者的很大區別在於源數據的存儲和管理
- MongoDB作為一個資料庫產品, 是擁有源數據管理能力的
- Elasticsearch作為一個搜索引擎, 定位是提供數據檢索服務, 也就是說我只管查, 不管寫 _, Elasticsearch的Mapping不可變也是為此服務的, 帶來的代價就是
es不適合作為數據管理者
, es可以從其他數據源同步數據過來提供查詢, 但是不適合自己對數據進行存儲和管理
es更側重數據的查詢, 各種複雜的花式查詢支持的很好, 相比來說 MongoDB的查詢能力就顯得比較平庸了
由此可見, 對於個人, 如果你有一批數據要看, 但是不經常進行修改, 這個時候毫無疑問可以用es, 但是如果你還打算繼續修改數據, 最好就是使用MongoDB,但其實對大多數人公司來講,這兩者的數據管理能力並沒有多大的影響
ps: es修改Mapping的代價非常高, 所以我們一般都是把新數據重新寫入一份新索引,然後直接切換讀取的別名到新的索引
兩者讀寫數據的異同
MongoDB
和ElasticSearch
都支持全文索引, 雖然MongoDB的全文索引效果完全無法跟es相比(es畢竟是專業的搜索引擎產品, 著重提供數據的檢所支持, 這方面弔打MongoDB也是可以理解的)
MongoDB雖然在支持的部分查詢功能上稍微弱於es, 但是在大部分場景下性能方面完爆es, 不管是讀性能, 還是寫性能
es的寫入延遲預設為1s, 這個雖然是寫入延遲的範疇, 但是毫無疑問是一大缺點, 雖然可以配置為更短的時間, 但是這樣就要犧牲一定的數據吞吐量, 會造成更頻繁的磁碟刷新操作
es底層使用Lucene
作為核心引擎, 很多es的設計就是為了匹配Lucene中的概念, 其實es可以看成一個lucene的proxy層包裝,將lucene的原生介面封裝的更好用, 同時還實現了很多管理和監控等輔助功能, 但是整體來說es上層的模塊和lucene的隔閡還是挺明顯的, 耦合度上有一定的欠缺
MongoDB則是完整的一個單體資料庫產品, 雖然內部的存儲引擎也是可插拔式的, 整體而言還是更加的渾然一體
MongoDB支持多種存儲引擎, 本文所有涉及mongo存儲引擎的只談預設的WiredTiger引擎, 其實還有某些方面更優秀的其他引擎,例如: MongoRocks等
部署和資源占用
單機部署的話其實MongoDB和Elasticsearch都十分的方便, 不過es相對來說資源占用更多一點, 性能也比MongoDB要弱一點
集群化的部署, 我們一般都會選擇分片+副本的部署方式, 這種方式下, es部署起來比MongoDB方便太多, MongoDB要部署一套完整的分片 + 副本模式還是比較麻煩的, 沒有經驗的人部署起來需要一定的學習成本
資源占用方面, MongoDB可以支持存儲文件類型的數據, 作為資料庫也有數據壓縮能力, es則因為大量的索引存在需要占用大量的磁碟和記憶體空間
可用性和容錯
MongoDB和ElasticSearch作為天生分散式的代表產品都支持數據分片和副本
兩者都通過分片支持水平擴展, 同時都通過副本來支持高可用(HA)
分片就是一個數據集的數據分為多份, 同時分佈在多個節點上存儲和管理, 主流分片方式有兩種: hash分片和range分片, 兩種分片方式各有優勢, 適合不同的場景
副本就是一份數據集同時有一個或者多個複製品(有些地方叫主從), 每份複製品都一模一樣, 但是為了保證數據的一致性, 往往多個副本中只有一個作為Primary副本(通過選主演算法從多個副本中選出Primary), 提供寫服務, 其他副本只提供讀, 或者只提供備份服務
ps:es和MongoDB都可以通過副本增強讀能力, 這與kafka很不一樣(kafka的副本只有備份功能)
兩者分散式方案的一些不同
MongoDB和Elasticsearch雖然都是分散式服務, 但是還是有一些不同方案的選擇的
- 分片和副本單位的劃分
MongoDB是以節點為單位劃分角色, 一旦一個節點被指定為副本, 其上面的數據都是副本
Elasticsearch是以分片為單位劃分角色, 一個節點上即可以擁有某分片的主分片和可以同時擁有另一個分片的副本分片, 同時es還支持自動的副本負載均衡, 如果一個新節點上面什麼數據都沒有, 系統會自動分配分片數據過來
- 架構模式
MongoDB的副本和分片是兩種不同的模式, 雖然可以同時使用但是依然有各自的架構設計, 用戶可以任意選擇選型進行搭配, 每個節點的職責更加專一, 方便據此調整機器配置和進行優化
Elasticsearch中的分片 + 副本是一套統一的架構設計, 每個節點具有接近同等的地位, 配置使用起來更加簡單, 但是如果要針對節點所負責的功能對機器進一步做定製就不如MongoDB靈活
文檔型資料庫的特點和問題
無schema
文檔型數據存儲既能享受無schema限制帶來的靈活, 又能享受索引查詢的快速和類SQL查詢的便捷
使他們用起來不像傳統的RDBMS那麼麻煩, 又不像 Redis,Hbase這種資料庫查詢功能不夠強大, 處在一個傳統RDBMS和經典K-V存儲之間的比較均衡的位置
我個人很喜歡這個特性, 沒有schema的限制, 存儲數據更方便也更靈活了, 但是有得有失, 很多固定schema的好處就無法享受到了, 比如: 對數據的高效壓縮
雞肋的Collection 和 Type
早期為了跟傳統rdbms資料庫保持概念一致 ,mongodb和elasticsearch都設計了跟傳統資料庫裡面的庫->表->記錄行
對應的概念,具體如下
RDBMS | MongoDB | Elasticsearch |
---|---|---|
庫 | 庫 | 索引 |
表 | 集合 | 類型 |
記錄 | 文檔 | 文檔 |
其實對於nosql資料庫來講, 集合/類型的意義其實不大, Nosql資料庫幾乎都是k-v類型的存儲結構,完全可以通過key進行業務隔離和區分,真的沒有必要為了跟傳統資料庫對應強行搞出來一個中間概念 _
Elasticsearch從6.x
版本開始強制只允許一個索引使用一個type, 其實就是意識到這個這個設計的失誤, 不想讓你用這個type類型, 因為type和傳統資料庫裡面的表概念其實是不一樣的,這種概念類比給人造成了誤解,到了es的7.x版本會預設取消type類型, 就說明這個type欄位真的是雞肋的不行
弱事務
MongoDB以前只是支持同一文檔內的原子更新, 以此來實現偽事務功能, 不過Mongo4.0支持Replica Set事務, 大大加強了事務方面的能力
es在這方面倒沒有什麼進展,因為從應用場景上es對事務的需求不高,不過用戶其實也可以使用同文檔更新或者通過程式自己來實現事務機制
無join支持
文檔型資料庫大多數都不支持join(也有少量支持的), 但是我一般也用不上多表join的功能, 即便真的需要使用join也可以通過應用層或者通過耦合數據來實現(不過據說未來Mongo4.2版本會帶來對join的支持)
不支持join帶來的問題就是我們需要自己對數據進行連接, 但是這在擅長使用分散式計算的大數據領域不算什麼問題, 相應的缺少join功能可能對善於使用SQL的數據分析師就不大友好
Bully的選主演算法的缺陷
elasticsearch和MongoDB選擇的選主演算法實現很簡單, 但是代價就是有幾率出現腦裂的情況, 當然, 具體情況跟配置也有關係(比如:你有三個es節點但是設置的最小主節點數為1, 將最小主節點數設置為2可以避免腦裂情況)
不過腦裂問題一方面發生概率較低,另一方面即使出現了腦裂的情況, 使用重啟大法
一般就能解決 _
總體來說, 這方面不如使用Paxos和Raft演算法或者使用zk做協調器的其他分散式系統靠譜
其他
- 運維工具
兩者背後都有商業公司的支持
MongoDB的很多客戶端和運維工具更豐富, 但是MongoDB作為一個資料庫產品, 相對應的對運維人員的要求也要更高一點
Elasticsearch則有整套的數據分析和收集工具提供, 配套的kibana就是一個很不錯的管控es的工具
- 操作介面
es使用Restful來提供統一的操作介面, 屏蔽了各種語言之間的障礙, 但是同樣帶來了表達能力和性能的損失
MongoDB則使用TCP, 降低了序列化和網路這一層的性能損耗, 並最大程度保留了介面的內容表達能力, 但是相對的使用起來就不如http那麼的方便
適用場景
兩者其實在很多使用場景上有重合之處, 是可以互相替代, 比如日誌收集
但是某些方面兩者又各有特色,比如: 如果打算使用一個文檔型的業務資料庫, 那最好還是選mongodb, 如果你有要求複雜查詢又併發性能要求高的場景,類似搜索服務,那最好的選擇是elasticsearch
除此之外:
MongoDB有多個存儲引擎可以選擇, 而且MongoDB不僅看重數據的分析, 對數據的管理同樣看重, 總的來說MongoDB更傾向於數據的存儲和管理, 可以作為數據源對外提供, 未來說不定還會有支持join和支持倒排索引的mongo引擎出現
Elasticsearch則有很多插件可以使用, 相對來講Elasticsearch更傾向於數據的查詢, 一般情況下elasticsearch僅作為數據檢索服務和數據分析平臺, 不直接作為源數據管理者
- MongoDB適合
- 對服務可用性和一致性有高要求
- 無schema的數據存儲 + 需要索引數據
- 高讀寫性能要求, 數據使用場景簡單的海量數據場景
- 有熱點數據, 有數據分片需求的數據存儲
- 日誌, html, 爬蟲數據等半結構化或圖片,視頻等非結構化數據的存儲
- 有js使用經驗的人員(MongoDB內置操作語言為js)
- Elasticsearch適合
- 已經有其他系統負責數據管理
- 對複雜場景下的查詢需求,對查詢性能有要求, 對寫入及時性要求不高的場景
- 監控信息/日誌信息檢索
- 小團隊但是有多語言服務,es擁有restful介面,用起來最方便
總結
MongoDB和Elasticsearch都是我比較喜歡的存儲產品
兩者的功能特性也存在很多重合的地方, 其實現在很多資料庫產品都在互相借(chao)鑒(xi), 功能和特性都在逐漸變得相似, 這也是未來很多存儲產品的發展趨勢, 大家都希望自己能覆蓋儘量多的場景和用戶群體
很多產品總是在不斷的從沒有
->有
->功能豐富
,但是功能豐富一定是做了很多的妥協, 於是又有了 功能眾多的單體服務
->多個功能單一的子服務
方向的轉變,就像三國裡面說的 “天下大勢, 分久必合合久必分”.
現在NoSQL資料庫產品就在這個路上, NoSQL歸根到底都是 RDBMS的某個方面的妥協, 現在各種NoSQL 也都在加入對經典SQL和傳統RDBMS的 join, 事務的支持, 但是我相信等到兩者區別足夠小的時候, 一定會有放棄了大而全, 而專註於某一場景的新的存儲產品出現,到時候搞不好又是一波新的Nosql潮流
轉載:https://blog.csdn.net/kongliand/article/details/108691847