一線互聯網大企業,每天面對【千萬級】海量數據,是如何快速查詢的呢? 一、常用的分析類系統應該如何選擇存儲? 二、轉變你的思想:根據查詢來選擇存儲系統 三、總結

本文和大家分享一下如何來保存原始數據,我們知道,原始數據的數據量太大,能存下來就很不容易了,這個數據是沒法直接來給業務系統查詢和分析的。有兩個原因,一是數據量太大了,二是也沒有很好的數據結構和查詢能力,來支持業務系統查詢。

所以一般的做法是,用流計算或者是批計算,把原始數據再進行一次或者多次的過濾、匯聚和計算,把計算結果落到另外一個存儲系統中去,由這個存儲再給業務系統提供查詢支持。這裏的“流計算”,指的是 Flink、Storm 這類的實時計算,批計算是 Map-Reduce 或者Spark 這類的非實時計算。

像點擊流、監控和日誌這些原始數據是“海量數據中的海量數據”,這些原始數據經過過濾彙總和計算之後,大多數情況下數據量會有量級的下降,比如說從 TB 級別的數據量,減少到 GB 級別。

有的業務,計算後的數據非常少,比如說一些按天粒度的彙總數據,或者排行榜類的數據,用什麼存儲都能滿足要求。那有一些業務,沒法通過事先計算的方式解決全部的問題。原始數據經過計算後產生的計算結果,數據量相比原始數據會減少一些,但仍然是海量數據。並且,我們還要在這個海量數據上,提供性能可以接受的查詢服務。

本文就來聊一聊,面對這樣的海量數據,如何才能讓查詢更快一些。

一、常用的分析類系統應該如何選擇存儲?

查詢海量數據的系統,大多都是離線分析類系統,你可以簡單地理解爲類似於做報表的系統,也就是那些主要功能是對數據做統計分析的系統。這類系統是重度依賴於存儲的。選擇什麼樣的存儲系統、使用什麼樣的數據結構來存儲數據,直接決定了數據查詢、聚合和分析的性能。

分析類系統對存儲的需求一般是這樣的:

1 、一般用於分析的數據量都會比在線業務大出幾個數量級,這需要存儲系統能保存海量數據;
2、能在海量的數據上做快速的聚合、分析和查詢。注意這裏面所說的“快速”,前提是處理 GB、TB 甚至 PB 級別的海量數據,在這麼大的數據量上做分析,幾十秒甚至幾分鐘都算很快了,和在線業務要求的毫秒級速度是不一樣的;
3、由於數據大多數情況下都是異步寫入,對於寫入性能和響應時延,一般要求不高;
4、分析類系統不直接支撐前端業務,所以也不要求高併發。

然後我們看有哪些可供選擇的存儲產品。如果你的系統的數據量在 GB 量級以下,MySQL仍然是可以考慮的,因爲它的查詢能力足以應付大部分分析系統的業務需求。並且可以和在線業務系統合用一個數據庫,不用做 ETL(數據抽取),省事兒並且實時性好。這裏還是要提醒你,最好給分析系統配置單獨的 MySQL 實例,避免影響線上業務。

如果數據量級已經超過 MySQL 極限,可以選擇一些列式數據庫,比如:HBase、Cassandra、ClickHouse,這些產品對海量數據,都有非常好的查詢性能,在正確使用的前提下,10GB 量級的數據查詢基本上可以做到秒級返回。高性能的代價是功能上的縮水,這些數據庫對數據的組織方式都有一些限制,查詢方式上也沒有 MySQL 那麼靈活。大多都需要你非常瞭解這些產品的脾氣秉性,按照預定的姿勢使用,才能達到預期的性能。

另外一個值得考慮的選擇是 Elasticsearch(ES),ES 本來是一個爲了搜索而生的存儲產品,但是也支持結構化數據的存儲和查詢。由於它的數據都存儲在內存中,並且也支持類似於 Map-Reduce 方式的分佈式並行查詢,所以對海量結構化數據的查詢性能也非常好。

最重要的是,ES 對數據組織方式和查詢方式的限制,沒有其他列式數據庫那麼死板。也就是說,ES 的查詢能力和靈活性是要強於上述這些列式數據庫的。在這個級別的幾個選手中,我個人強烈建議你優先考慮 ES。但是 ES 有一個缺點,就是你需要給它準備大內存的服務器,硬件成本有點兒高。

數據量級超過 TB 級的時候,對這麼大量級的數據做統計分析,無論使用什麼存儲系統,都快不到哪兒去。這個時候的性能瓶頸已經是磁盤 IO 和網絡帶寬了。這種情況下,實時的查詢和分析肯定做不了。解決的辦法都是,定期把數據聚合和計算好,然後把結果保存起來,在需要時對結果再進行二次查詢。這麼大量級的數據,一般都選擇保存在 HDFS 中,配合Map-Reduce、Spark、Hive 等等這些大數據生態圈產品做數據聚合和計算。

二、轉變你的思想:根據查詢來選擇存儲系統

面對海量數據,僅僅是根據數據量級來選擇存儲系統,是遠遠不夠的。

經常有朋友會問:“我的系統,每天都產生幾個 GB 的數據量,現在基本已經慢得查不出來了,你說我換個什麼數據庫能解決問題呢?”那我的回答都是,對不起,換什麼數據庫也解決不了你的問題。爲什麼這麼說呢?

因爲在過去的幾十年裏面,存儲技術和分佈式技術,在基礎理論方面並沒有什麼本質上突破。技術發展更多的是體現在應用層面上,比如說,集羣管理簡單,查詢更加自動化,像Map-Reduce 這些。不同的存儲系統之間,並沒有本質的差異。它們的區別只是,存儲引擎的數據結構、存儲集羣的構建方式,以及提供的查詢能力,這些方面的差異。這些差異,使得每一種存儲,在它擅長的一些領域或者場景下,會有很好的性能表現。

比如說,最近很火的 RocksDB、LevelDB,它們的存儲結構 LSM-Tree,其實就是日誌和跳錶的組合,單從數據結構的時間複雜度上來說,和“老傢伙”MySQL 採用的 B+ 樹,有本質的提升嗎?沒有吧,時間複雜度都是 O(log n)。但是,LSM-Tree 在某些情況下,它利用日誌有更好的寫性能表現。沒有哪種存儲能在所有情況下,都具有明顯的性能優勢,所以說,存儲系統沒有銀彈,不要指望簡單地更換一種數據庫,就可以解決數據量大,查詢慢的問題。

但是,在特定的場景下,通過一些優化方法,把查詢性能提升幾十倍甚至幾百倍,這個都是有可能的。這裏面有個很重要的思想就是,根據查詢來選擇存儲系統和數據結構。ES 採用的倒排索引的數據結構,並沒有比 MySQL 的 B+ 樹更快或者說是更先進,但是面對“全文搜索”這個查詢需求,選擇使用 ES 的倒排索引,就比使用其他的存儲系統和數據結構,性能上要高出幾十倍。

再舉個例子,大家都知道,京東的物流速度是非常快的。經常是,一件挺貴的衣服,下單之後,還沒來得及後悔,已經送到了。京東的物流之所以能做到這麼快,有一個很重要的原因是,它有一套智能的補貨系統,根據歷史的物流數據,對未來的趨勢做出預測,來給全國每個倉庫補貨。這樣京東就可以做到,你下單買的商品,很大概率在離你家幾公里那個京東倉庫裏就有貨,這樣自然很快就送到了。這個系統的背後,它需要分析每天幾億條物流數據,每條物流數據又細分爲幾段到幾十段,那每天的物流數據就是幾十億的量級。

這份物流數據,它的用途也非常多,比如說,智能補貨系統要用;調度運力的系統也要用;評價每個站點兒、每個快遞小哥的時效達成情況,還要用這個數據;物流規劃人員同樣要用這個數據進行分析,對物流網絡做持續優化。

那用什麼樣的存儲系統保存這些物流數據,才能滿足這些查詢需求呢?顯然,任何一種存儲系統,都滿足不了這麼多種查詢需求。我們需要根據每一種需求,去專門選擇合適的存儲系統,定義適合的數據結構,各自解決各自的問題。而不是用一種數據結構,一個數據庫去解決所有的問題。

對於智能補貨和運力調度這兩個系統,它的區域性很強,那我們可以把數據按照區域(省或者地市)做分片,再彙總一份全國的跨區物流數據,這樣絕大部分查詢都可以落在一個分片上,查詢性能就會很好。

對於站點兒和人的時效達成情況,這種業務的查詢方式以點查詢爲主,那可以考慮事先在計算的時候,按照站點兒和人把數據彙總好,存放到一些分佈式 KV 存儲中,基本上可以做到毫秒級查詢性能。而對於物流規劃的查詢需求,查詢方式是多變的,可以把數據放到 Hive表中,按照時間進行分片。

我們之前也講到過,按照時間分片是對查詢最友好的分片方式。物流規劃人員可以在上面執行一些分析類的查詢任務,一個查詢任務即使是花上幾個小時,用來驗證一個新的規劃算法,也是可以接受的。

三、總結

海量數據的主要用途就是支撐離線分析類業務的查詢,根據數據量規模不同,由小到大可以選擇:關係型數據庫,列式數據庫和一些大數據存儲系統。對於 TB 量級以下的數據,如果可以接受相對比較貴的硬件成本,ES 是一個不錯的選擇。

對於海量數據來說,選擇存儲系統沒有銀彈,重要的是轉變思想,根據業務對數據的查詢方式,反推數據應該使用什麼存儲系統、如何分片,以及如何組織。即使是同樣一份數據,也要根據不同的查詢需求,組織成不同的數據結構,存放在適合的存儲系統中,才能在每一種業務中都達到理想的查詢性能。

前段時間因個人原因停更了,非常抱歉,從今天起每天分享乾貨,敬請期待 ....
覺得還不錯的話,點個紅心吧
→公衆號:慕容千語

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章