選單

日均500萬資料,如何進行資料儲存選型?

技術乾貨,第一時間推送

日均500萬資料,如何進行資料儲存選型?

作者:麥田裡的老農

小編公司有一個訊息平臺,目前單表日均產生 500 萬訊息記錄。隨著業務不斷髮展,目前單表的容量已經突破 6 億。原先的 MySQL 儲存方式面臨越來越大的瓶頸,合適的資料儲存框架便成了一個非常重要的問題。

MongoDB、ElasitcSearch、Redis、HBase 是現今最火的四款 NoSQL 資料庫產品。在實際的開發中,這四種資料庫有什麼區別?我到底該選哪個?想必這是很多網際網路開發都遇到過的難題。下面就給大家總結下這四種資料庫產品的特點和應用場景,希望能夠幫助你更深刻的理解這四種資料庫的特點,好幫助你作出正確的資料庫選擇。

01 MongoDB

MongoDB 是當今最火爆的 NoSQL 資料庫。MongoDB 最早在 09 年釋出,算得上是早期大資料時代的資料庫代表作了。隨著 MongoDB 的火爆,研發 MongoDB 的團隊還專門成立了 MongoDB 公司來對 MongoDB 進行維護和推廣,現在這個公司已經在納斯達克上市,市值達到十幾億美元,算得上是技術變現的典範了。

MongoDB 最大的特點是表結構靈活可變,欄位型別可以隨時修改。

MongoDB 中的每一行資料只是簡單的被轉化成 Json 格式後儲存,因此 MongoDB 中壓根沒有 MySQL 中表結構這樣的概念,你可以直接簡單粗暴的將任意結構的資料塞入同一個表中,壓根不必考慮表結構的限制,更不必像 MySQL 一樣因為要修改資料表結構而大費周折。簡而言之,往 MySQL 寫資料像是在做填空題,你寫入的資料必須與最早定義的表結構一致,而往 MongoDB 寫資料就像是在做問答題,想怎麼寫就怎麼寫,這靈活度不要爽太多。

說完 MongoDB 的優點也該說一說它的缺點了。

MongoDB 不需要定義表結構這個特點給表結構的修改帶來了極大的方便,但是也給多表查詢、複雜事務等高階操作帶來了阻礙。

因此,如果你的資料的邏輯結構非常複雜,經常需要進行復雜的多表查詢或者事務操作,那顯然還是 MySQL 這類關係型資料庫更合適。

得益於 MongoDB 的這些特點,

MongoDB 很適合那些表結構經常改變,資料的邏輯結構沒又沒那麼複雜不需要多表查詢操作,資料量又比較大的應用場景。

例如,有一個遊戲應用,需要儲存每個使用者的資訊,使用者分為法師、戰士等具有不同屬性的角色,還有裝備、技能等很多結構複雜的資訊,遊戲每次更新還可能會引入很多新的使用者屬性,這時如果你使用 MySQL,那麼你可能需要建立很多個表,定義很多個表結構,並且遊戲的每次更新也可能會給你帶來重定義表結構等一堆麻煩事,而如果使用 MongoDB 則這些麻煩統統不存在,因為你可以定義只一張表便可以容納所有的資訊,而且可以隨時根據新的需求增減欄位。

02 Redis

日均500萬資料,如何進行資料儲存選型?

Redis 是現在最熱門的 key-value 資料庫。它與 MongoDB 同在 2009 年釋出,也同樣是早期大資料時代的資料庫代表作。

Redis 的最大特點當然就是 key-value 儲存所帶來的簡單和高效能了。

所謂 key-value 儲存,就是每一條記錄只包含一個用於查詢資料的 Key,以及與之對應的儲存資料的 value,就如同現實生活中的門牌號與住戶,而沒有諸如表、欄位這些常規資料庫中必需有的複雜概念,所有的查詢都僅僅依賴於 key 值。因此,key-value 資料庫可謂是資料庫中資料結構最簡單的一種,也得益於這種簡單的結構,再加上 Redis 會把所有資料載入到記憶體中的,Redis 能得到遠高於 MongoDB 這類常規資料庫的讀寫效能。當然,Redis 的功能還不止 key-value 儲存這麼簡單,相較它的 key-value 前輩 Memcached,Redis 還支援資料持久化,list、set 等多種資料結構,主從複製備份等一些列功能,因此 Redis 絕對稱得上是 key-value 資料庫中功能最全面、最簡單易用的款。

Redis 的 key-valule 儲存帶來了效能這個優勢,但是也給複雜查詢帶來了很多侷限。

由於閹割掉了資料表、欄位這樣的重要特性,且所有的查詢都依賴 key,因此 Redis 無法提供常規資料庫所具備的多列查詢、區段查詢等複雜查詢功能。同時,由於 Redis 需要把資料存在記憶體中,這也大大限制了 Redis 可儲存的資料量,這也決定了 Redis 難以用在資料規模很大的應用場景中。

Redis 犧牲了常規資料庫中的資料表、複雜查詢等功能,換來了很大的效能提升,

特別適合那些對讀寫效能要求極高,且資料表結構簡單(key-value、list、set 之類)、查詢條件也同樣簡單的應用場景。

如果你的資料表結構還挺複雜,你還經常需要做一些複雜查詢操作,那你最好還是老老實實用 MongoDB 或者 SQL 吧。

03 ElasticSearch

日均500萬資料,如何進行資料儲存選型?

相較於 MongoDB 和 Redis,晚一年釋出的 ES 可能知名度要低一些,但是 ES 在搜尋引擎領域的名聲絕對是是響噹噹的。相較於其他高大上的資料庫產品,ES 的出身要屌絲很多。ES 的建立者 Shay Banon 曾經是一個失業的屌絲程式設計師,在無事可幹的時候為了方便老婆搜尋食譜而建立了 ES(當然,當時還不叫 ES)。

不料無心插柳柳成蔭,成就了今天最熱門的搜尋引擎資料庫,果然妹子才是程式設計師工作的最大動力啊!ES 也專門成立了自己的 Elastic 公司已經獲得數億美金融資,當年的屌絲程式設計師 Shay Banon 也早已逆襲成為 CEO 並走上人生巔峰。諸位程式設計師看官讀完這個故事是不是也已經開始內心澎湃的想象自己出任 CEO 迎娶白富美那一天了?

ES 的特點,正如其名,那就是搜尋。

嚴格的說,ES 不是一個數據庫,而是一個搜尋引擎,ES 的方方面面也都是圍繞搜尋設計的。ES 支援全文搜尋,這裡簡單解釋下什麼是全文搜尋:對於 “我在北京的一家網際網路公司工作” 這樣的資料,如果你搜索 “北京”、“網際網路”、“工作” 這些關鍵詞都能命中這條資料的話,這就是全文搜尋,你每天都在用的百度、Google 都屬於全文搜尋。值得一提的是,ES 的全文搜尋對中文也有很好的支援(單是中文分詞器就有很多種),絕對能夠滿足國內大多數人的全文搜尋需求。除了搜尋之外,ES 還會自動的替你對所有欄位建立索引,以實現高效能的複雜聚合查詢,因此只要是存入 ES 的資料,無論再複雜的聚合查詢也可以得到不錯的效能,而且你再也不用為如何建立各種複雜索引而頭痛了。

說了這麼多 ES 的優點,你是不是覺得 ES 簡直萬能了?

可惜不是的,ES 也有很多的短處,最明顯的就是欄位型別無法修改、寫入效能較低和高硬體資源消耗。

前邊講到 ES 會自動的替你建立索引,儘管這能給全文搜尋以及聚合查詢帶來很多好處還能替你省了建索引這一麻煩事,但是這個特性也會帶來一堆問題。ES 需要在建立欄位前要預先建立 Mapping,Mapping 中包含每個欄位的型別資訊,ES 需要根據 Mapping 為欄位建立合適的索引。由於這個 Mapping 的存在,ES 中的欄位一但建立就不能再修改型別了。

例如,你建的資料表的某個欄位忘了加全文搜尋,你想臨時加上,但是表已經建好並且已經有很多資料了,這時候該怎麼辦呢?不好意思,你只能把整個資料表刪了再重建一遍!因此,ES 在資料結構靈活度上高於 MySQL 但遠不如 MongoDB。ES 的缺點還不止這些,自動建立索引使得 ES 的寫入效能也收到了影響,要明顯低於 MongoDB。

對於同樣的資料 ES 佔用的儲存空間也要明顯大於 MongoDB(建那麼多索引能不佔空間嗎?),對硬體資源的消耗也是非常厲害,大資料量下 64G 記憶體 + SSD 基本是標配,算得上是資料庫中的貴族服務了,因此如果你的老闆很小氣,對於 ES 的選用可要慎重嘍!

ES 的全文搜尋特性使它成為構建搜尋引擎的利器。除此之外,ES 很好的支援了複雜聚合查詢這一特點還使得 ES 非常適合拿來作資料分析使用。

其實,ES 還專門做了與自己配套的 ELK 套裝,給你提供從日誌收集到資料視覺化分析的一條龍服務,絕對是構建高大上資料分析平臺的利器。但是,ES 的高成本和低寫入效能這些缺點也註定了它不適合用在那些資料價值不高、對寫入效能有要求、資料量大而成本受限的場景中。

04 HBase

HBase 是 Hadoop 專案的一部分,而且是當年谷歌大資料三駕馬車之一的 BigTable 方案的實現,因此絕對算得上是大資料時代最有代表性的技術之一了。

作為 Hadoop 系列產品之一,

HBase 也繼承了 Hadoop 專案的最大優點,那就是對海量資料的支援,以及極強的橫向(儲存容量)擴充套件能力。

和 Redis 類似,HBase 也需要為每一行資料定義一個 key,之後所有的查詢都依賴這個 key 進行。但是不同的地方在於,HBase 中的一行資料還可以有非常多的列項(類似 MongoDB 欄位),資料會按照列進行分組和儲存,同一列的資料儲存在同一個地方,這也是 HBase 被稱為列式儲存資料庫的原因。其實從本質上來說,HBase 相當於是把邏輯上的一張大表按照列族分拆成若干張小表分別進行儲存,不僅是列,資料的行數到達一定數量後表也會再被拆分。因此,HBase 能夠把巨大的表分佈到很多臺機器上,從而容納規模近乎無限的資料。同時,對 HBase 進行橫向擴充套件也非常方便,你基本只需要新增新的機器,而不用對資料做任何改動,就可以實現資料庫容量線性的增長,這在其他 SQL 資料庫中是難以做到的(儘管其他資料庫也有諸如 MongoDB 分片叢集之類的功能幫助你進行資料規模橫向擴充套件,但是無論是在實施的難度上還是在對資料的影響方面這些都無法跟 HBase 相提並論。)

HBase 的列式儲存特性帶來了海量資料規模的支援和極強的擴充套件能力,但是也給資料的讀取帶來很大的侷限。由於只有同一列族的資料才會被存放在一起,而且所有的查詢都必須要依賴 Key,這就使得很多複雜查詢難以進行。例如,如果你的查詢條件涉及多個列項,或者你無法獲取要查詢資料的 key,那麼查詢效率將會非常低下。因此,HBase 僅僅適合。

HBase 的列式儲存特點帶來了對海量資料的容納能力,因此非常適合資料量極大,查詢條件簡單,列與列之間聯絡不大的輕查詢應用場景。最典型的比如搜尋引擎所使用的網頁資料庫。HBase 不適合資料結構複雜,且需要複雜查詢的應用場景。另外值得一提的是,HBase 是很重的一款產品,需要依賴很多的 Hadoop 元件,因此如果你的資料規模不大,那就完全沒必要殺雞用牛刀,MongoDB 這類產品完全可以更好的滿足你的需求。

總結

以上四種資料庫是當今 NoSQL 中最火爆的幾款,掌握了它們,你基本就能 cover 住網際網路開發中的絕大多數資料儲存需求。這裡還想強調的一點是,如同買衣服一樣,沒有最好的資料庫,只有最適合你的應用場景的資料庫,因此選用一款資料庫前一定要想清楚自己的應用場景是否合適。再給大家總結下這些資料庫的適用場景:

如果你對資料的讀寫要求極高,並且你的資料規模不大,也不需要長期儲存,選 redis;

如果你的資料規模較大,對資料的讀效能要求很高,資料表的結構需要經常變,有時還需要做一些聚合查詢,選 MongoDB;

如果你需要構造一個搜尋引擎或者你想搞一個看著高大上的資料視覺化平臺,並且你的資料有一定的分析價值或者你的老闆是土豪,選 ElasticSearch;

如果你需要儲存海量資料,連你自己都不知道你的資料規模將來會增長多麼大,那麼選 HBase。

-深入原理-

知其然並知其所以然