分庫分表後跨分片查詢與Elastic Search

攜程酒店訂單Elastic Search實戰:http://www.lvesu.com/blog/main/cms-610.html

爲什麼分庫分表後不建議跨分片查詢:https://www.jianshu.com/p/1a0c6eda6f63

分庫分表技術演進(阿里怎麼分):https://mp.weixin.qq.com/s/3ZxGq9ZpgdjQFeD2BIJ1MA

 

1.需求背景

移動互聯網時代,海量的用戶每天產生海量的數量,這些海量數據遠不是一張表能Hold住的。比如

  • 用戶表:支付寶8億,微信10億。CITIC對公140萬,對私8700萬。
  • 訂單表:美團每天幾千萬,淘寶曆史訂單百億、千億。
  • 交易流水錶

2.選擇方案

(1)NoSQL/NewSQL(不選擇

     選擇RDBMS,不選擇NoSQL/NewSQL,主要是因爲NoSQL/NewSQL可靠性無法與RDBMS相提並論。RDBMS有以下幾個優點:

  • RDBMS生態完善;
  • RDBMS絕對穩定;
  • RDBMS的事務特性;

     目前絕大部分公司的核心數據都是:以RDBMS存儲爲主,NoSQL/NewSQL存儲爲輔!互聯網公司又以MySQL爲主,國企&銀行等不差錢的企業以Oracle/DB2爲主!NoSQL比較具有代表性的是MongoDB,es。NewSQL比較具有代表性的是TiDB。

(2)分區(不選擇

  • 分區原理:分區表是由多個相關的底層表實現,存儲引擎管理分區的各個底層表和管理普通表一樣,只是分區表在各個底層表上各自加上一個相同的索引(分區表要求所有的底層表都必須使用相同的存儲引擎)。
  • 分區優點:它對用戶屏蔽了sharding的細節,即使查詢條件沒有sharding column,它也能正常工作(只是這時候性能一般)。
  • 分區缺點:連接數、網絡吞吐量等資源都受到單機的限制;併發能力遠遠達不到互聯網高併發的要求。(主要因爲雖然每個分區可以獨立存儲,但是分區表的總入口還是一個MySQL示例)。
  • 適用場景:併發能力要求不高;數據不是海量(分區數有限,存儲能力就有限)。

(3)分庫分表(選擇

 互聯網行業處理海量數據的通用方法:分庫分表。 分庫分表中間件全部可以歸結爲兩大類型:

  • CLIENT模式;

  • PROXY模式;

 CLIENT模式代表有阿里的TDDL,開源社區的sharding-jdbc(sharding-jdbc的3.x版本即sharding-sphere已經支持了proxy模式)。架構如下:

PROXY模式代表有阿里的cobar,民間組織的MyCAT。架構如下:

 

 無論是CLIENT模式,還是PROXY模式。幾個核心的步驟是一樣的:SQL解析重寫路由執行結果歸併

 3.分庫分表思路(MYSQL)

  • 單個sharding column分庫分表 
  • 多個sharding column分庫分表;
  • sharding column分庫分表 + ES檢索

阿里:選用orderid分表,那我用userid來查詢的很多,那不是所有的分表都要查?怎麼處理

以阿里訂單系統爲例(參考《企業IT架構轉型之道:阿里巴巴中臺戰略思想與架構實現》),它選擇了三個column作爲三個獨立的sharding column,即:order_id,user_id,merchant_code。user_id和merchant_code就是買家ID和賣家ID,因爲阿里的訂單系統中買家和賣家的查詢流量都比較大,並且查詢對實時性要求都很高。而根據order_id進行分庫分表,應該是根據order_id的查詢也比較多。

4.分庫分表落地(MYSQL)

(1)選擇合適的sharding column

   分庫分表第一步也是最重要的一步,即sharding column的選取,sharding column選擇的好壞將直接決定整個分庫分表方案最終是否成功。sharding column的選取跟業務強相關。

  • 選擇方法:分析你的API流量,將流量比較大的API對應的SQL提取出來,將這些SQL共同的條件作爲sharding column。
  • 選擇示例:例如一般的OLTP系統都是對用戶提供服務,這些API對應的SQL都有條件用戶ID,那麼,用戶ID就是非常好的sharding column。

(2)冗餘全量表和冗餘關係表選擇(訂單表)

例如將一張訂單表t_order拆分成三張表t_order、t_user_order、t_merchant_order。分別使用三個獨立的sharding column,即order_id(訂單號),user_id(用戶ID),merchant_code(商家ID)。

冗餘全量表:每個sharding列對應的表的數據都是全量的

 

 冗餘關係表:只有一個sharding column的分庫分表的數據是全量的,其他分庫分表只是與這個sharding column的關係表。實際使用中可能會冗餘更多常用字段,如用戶名稱、商戶名稱等。

冗餘全量表 VS 冗餘關係表

  • 速度對比:冗餘全量表速度更快,冗餘關係表需要二次查詢,即使有引入緩存,還是多一次網絡開銷;
  • 存儲成本:冗餘全量表需要幾倍於冗餘關係表的存儲成本;
  • 維護代價:冗餘全量表維護代價更大,涉及到數據變更時,多張表都要進行修改。

總結:選擇冗餘全量表還是索引關係表,這是一種架構上的trade off(權衡),兩者的優缺點明顯,阿里的訂單表是冗餘全量表。

 (3)單個sharding column分庫分表示例(賬戶表)

一般賬戶相關API使用account_no爲sharding column

(4)多個sharding column分庫分表示例(用戶表)

用戶可以通過mobile_no,email和username進行登錄,一些用戶相關API又常使用user_id,所以sharding column選這4個字段。

 (5)sharding column分庫分表 + ES檢索(模糊查詢)

上面提到的都是條件中有sharding column的SQL執行。但是,總有一些查詢條件是不包含sharding column的,同時,我們也不可能爲了這些請求量並不高的查詢,無限制的冗餘分庫分表。那麼這些查詢條件中沒有sharding column的SQL怎麼處理?以sharding-jdbc爲例,有多少個分庫分表,就要併發路由到多少個分庫分表中執行,然後對結果進行合併。這種條件查詢相對於有sharding column的條件查詢性能很明顯會下降很多。

更有甚者,尤其是有些運營系統中的模糊條件查詢,或者上十個條件篩選。例如淘寶我的所有訂單頁面,篩選條件有多個,且商品標題可以模糊匹配,這即使是單表都解決不了的問題,更不用談分庫分表了。

sharding column + es的模式,將分庫分表所有數據全量冗餘到es中,將那些複雜的查詢交給es處理。(ElasticSearch,搜索引擎)以訂單表爲例:

 PS:多sharding column不到萬不得已的情況下最好不要使用,建議採用單sharding column + es的模式簡化架構。

5.全文索引思路(HBase)

  • Solr+HBase
  • ES+HBase

可能參與條件檢索的字段索引到ES中,所有字段的全量數據保存到HBase中,這就是經典的ES+HBase組合方案,即索引與數據存儲隔離的方案。Hadoop體系下的HBase存儲能力我們都知道是海量的,而且根據它的rowkey查詢性能那叫一個快如閃電。而es的多條件檢索能力非常強大。這個方案把es和HBase的優點發揮的淋漓盡致,同時又規避了它們的缺點,可以說是一個揚長避免的最佳實踐。

它們之間的交互大概是這樣的:先根據用戶輸入的條件去es查詢獲取符合過濾條件的rowkey值,然後用rowkey值去HBase查詢,後面這一查詢步驟的時間幾乎可以忽略,因爲這是HBase最擅長的場景,交互圖如下所示: 

 

6.總結

最後,對幾種方案總結如下(sharding column簡稱爲sc):

對於海量數據,且有一定的併發量的分庫分表,絕不是引入某一個分庫分表中間件就能解決問題,而是一項系統的工程。需要分析整個表相關的業務,讓合適的中間件做它最擅長的事情。例如有sharding column的查詢走分庫分表,一些模糊查詢,或者多個不固定條件篩選則走es,海量存儲則交給HBase。

做了這麼多事情後,後面還會有很多的工作要做,比如數據同步的一致性問題,還有運行一段時間後,某些表的數據量慢慢達到單表瓶頸,這時候還需要做冷數據遷移。

 

MySQL單表可以存儲10億級數據,只是這時候性能比較差,業界公認MySQL單表容量在1KW以下是最佳狀態,因爲這時它的BTREE索引樹高在3~5之間。

 

參考文檔:

分庫分表技術演進&最佳實踐-修訂篇

HBase應用實踐專場-HBase for Solr

分庫分表思路

基於Solr的HBase多條件查詢測試

 

轉自:https://www.cnblogs.com/badboy200800/p/9790395.html

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