首頁>技術>

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都設計了跟傳統資料庫裡面的庫->表->記錄行對應的概念,具體如下

其實對於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潮流

7
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Elasticsearch的安裝