分庫分表技術演進&最佳實踐-修訂篇
https://www.itcodemonkey.com/article/10048.html
每個優秀的程式設計師和架構師都應該掌握分庫分表,這是我的觀點。
移動網際網路時代,海量的使用者每天產生海量的數量,比如:
-
使用者表
-
訂單表
-
交易流水錶
以支付寶使用者為例,8億;微信使用者更是10億。訂單表更誇張,比如美團外賣,每天都是幾千萬的訂單。淘寶的歷史訂單總量應該百億,甚至千億級別,這些海量資料遠不是一張表能Hold住的。事實上MySQL單表可以儲存10億級資料,只是這時候效能比較差,業界公認MySQL單表容量在1KW以下是最佳狀態,因為這時它的BTREE索引樹高在3~5之間。
既然一張表無法搞定,那麼就想辦法將資料放到多個地方,目前比較普遍的方案有3個:
-
分割槽;
-
分庫分表;
-
NoSQL/NewSQL;
說明:只分庫,或者只分表,或者分庫分表融合方案都統一認為是分庫分表方案,因為分庫,或者分表只是一種特殊的分庫分表而已。NoSQL比較具有代表性的是MongoDB,es。NewSQL比較具有代表性的是TiDB。
Why Not NoSQL/NewSQL?
首先,為什麼不選擇第三種方案NoSQL/NewSQL,我認為主要是RDBMS有以下幾個優點:
- RDBMS生態完善;
- RDBMS絕對穩定;
- RDBMS的事務特性;
NoSQL/NewSQL作為新生兒,在我們把可靠性當做首要考察物件時,它是無法與RDBMS相提並論的。RDBMS發展幾十年,只要有軟體的地方,它都是核心儲存的首選。
目前絕大部分公司的核心資料都是:以RDBMS儲存為主,NoSQL/NewSQL儲存為輔!網際網路公司又以MySQL為主,國企&銀行等不差錢的企業以Oracle/DB2為主!NoSQL/NewSQL宣傳的無論多牛逼,就現在各大公司對它的定位,都是RDBMS的補充,而不是取而代之!
Why Not 分割槽?
我們再看分割槽表方案。瞭解這個方案之前,先了解它的原理:
分割槽表是由多個相關的底層表實現,這些底層表也是由控制代碼物件表示,所以我們也可以直接訪問各個分割槽,儲存引擎管理分割槽的各個底層表和管理普通表一樣(所有的底層表都必須使用相同的儲存引擎),分割槽表的索引只是在各個底層表上各自加上一個相同的索引,從儲存引擎的角度來看,底層表和一個普通表沒有任何不同,儲存引擎也無須知道這是一個普通表還是一個分割槽表的一部分。
事實上,這個方案也不錯,它對使用者遮蔽了sharding的細節,即使查詢條件沒有sharding column,它也能正常工作(只是這時候效能一般)。不過它的缺點很明顯:很多的資源都受到單機的限制,例如連線數,網路吞吐等!雖然每個分割槽可以獨立儲存,但是分割槽表的總入口還是一個MySQL示例。從而導致它的併發能力非常一般,遠遠達不到網際網路高併發的要求!
至於網上提到的一些其他缺點比如:無法使用外來鍵,不支援全文索引。我認為這都不算缺點,21世紀的專案如果還是使用外來鍵和資料庫的全文索引,我都懶得吐槽了!
所以,如果使用分割槽表,你的業務應該具備如下兩個特點:
-
資料不是海量(分割槽數有限,儲存能力就有限);
-
併發能力要求不高;
Why 分庫分表?
最後要介紹的就是目前網際網路行業處理海量資料的通用方法:分庫分表。
雖然大家都是採用分庫分表方案來處理海量核心資料,但是還沒有一個一統江湖的中介軟體,筆者這裡列舉一些有一定知名度的分庫分表中介軟體:
-
阿里的TDDL,DRDS和cobar,
-
開源社群的sharding-jdbc(3.x已經更名為sharding-sphere);
-
民間組織的MyCAT;
-
360的Atlas;
-
美團的zebra;
備註:sharding-jdbc的作者張亮大神原來在噹噹,現在在京東金融。但是sharding-jdbc的版權屬於開源社群,不是公司的,也不是張亮個人的!
其他比如網易,58,京東等公司都有自研的中介軟體。總之各自為戰,也可以說是百花齊放。
但是這麼多的分庫分表中介軟體全部可以歸結為兩大型別:
-
CLIENT模式;
-
PROXY模式;
CLIENT模式代表有阿里的TDDL,開源社群的sharding-jdbc(sharding-jdbc的3.x版本即sharding-sphere已經支援了proxy模式)。架構如下:
client arch
PROXY模式代表有阿里的cobar,民間組織的MyCAT。架構如下:
proxy arch
但是,無論是CLIENT模式,還是PROXY模式。幾個核心的步驟是一樣的:SQL解析,重寫,路由,執行,結果歸併。
筆者比較傾向於CLIENT模式,架構簡單,效能損耗較小,運維成本低。
接下來,以幾個常見的大表為案例,說明分庫分表如何落地!
實戰案例
分庫分表第一步也是最重要的一步,即sharding column的選取,sharding column選擇的好壞將直接決定整個分庫分表方案最終是否成功。而sharding column的選取跟業務強相關,筆者認為選擇sharding column的方法最主要分析你的API流量,優先考慮流量大的API,將流量比較大的API對應的SQL提取出來,將這些SQL共同的條件作為sharding column。例如一般的OLTP系統都是對使用者提供服務,這些API對應的SQL都有條件使用者ID,那麼,使用者ID就是非常好的sharding column。
這裡列舉分庫分表的幾種主要處理思路:
-
只選取一個sharding column進行分庫分表 ;
-
多個sharding column多個分庫分表;
-
sharding column分庫分表 + es;
再以幾張實際表為例,說明如何分庫分表。
訂單表
訂單表幾個核心欄位一般如下:
訂單表
以阿里訂單系統為例(參考《企業IT架構轉型之道:阿里巴巴中臺戰略思想與架構實現》),它選擇了三個column作為三個獨立的sharding column,即:order_id,user_id,merchant_code。user_id和merchant_code就是買家ID和賣家ID,因為阿里的訂單系統中買家和賣家的查詢流量都比較大,並且查詢對實時性要求都很高。而根據order_id進行分庫分表,應該是根據order_id的查詢也比較多。
這裡還有一點需要提及,多個sharding-column的分庫分表是冗餘全量還是隻冗餘關係索引表,需要我們自己權衡。
冗餘全量的情況如下--每個sharding列對應的表的資料都是全量的,這樣做的優點是不需要二次查詢,效能更好,缺點是比較浪費儲存空間(淺綠色欄位就是sharding-column):
冗餘全量
冗餘關係索引表的情況如下--只有一個sharding column的分庫分表的資料是全量的,其他分庫分表只是與這個sharding column的關係表,這樣做的優點是節省空間,缺點是除了第一個sharding column的查詢,其他sharding column的查詢都需要二次查詢,這三張表的關係如下圖所示(淺綠色欄位就是sharding column):
表之間的關係圖
冗餘全量表PK.冗餘關係表
-
速度對比:冗餘全量表速度更快,冗餘關係表需要二次查詢,即使有引入快取,還是多一次網路開銷;
-
儲存成本:冗餘全量表需要幾倍於冗餘關係表的儲存成本;
-
維護代價:冗餘全量表維護代價更大,涉及到資料變更時,多張表都要進行修改。
總結:選擇冗餘全量表還是索引關係表,這是一種架構上的trade off,兩者的優缺點明顯,阿里的訂單表是冗餘全量表。
使用者表
使用者表幾個核心欄位一般如下:
使用者表
一般使用者登入場景既可以通過mobile_no,又可以通過email,還可以通過username進行登入。但是一些使用者相關的API,又都包含user_id,那麼可能需要根據這4個column都進行分庫分表,即4個列都是sharding-column。
賬戶表
賬戶表幾個核心欄位一般如下:
賬戶表
與賬戶表相關的API,一般條件都有account_no,所以以account_no作為sharding-column即可。
複雜查詢
上面提到的都是條件中有sharding column的SQL執行。但是,總有一些查詢條件是不包含sharding column的,同時,我們也不可能為了這些請求量並不高的查詢,無限制的冗餘分庫分表。那麼這些條件中沒有sharding column的SQL怎麼處理?以sharding-jdbc為例,有多少個分庫分表,就要併發路由到多少個分庫分表中執行,然後對結果進行合併。具體如何合併,可以看筆者sharding-jdbc系列文章,有分析原始碼講解合併原理。
這種條件查詢相對於有sharding column的條件查詢效能很明顯會下降很多。如果有幾十個,甚至上百個分庫分表,只要某個表的執行由於某些因素變慢,就會導致整個SQL的執行響應變慢,這非常符合木桶理論。
更有甚者,那些運營系統中的模糊條件查詢,或者上十個條件篩選。這種情況下,即使單表都不好建立索引,更不要說分庫分表的情況下。那麼怎麼辦呢?這個時候大名鼎鼎的elasticsearch,即es就派上用場了。將分庫分表所有資料全量冗餘到es中,將那些複雜的查詢交給es處理。
淘寶我的所有訂單頁面如下,篩選條件有多個,且商品標題可以模糊匹配,這即使是單表都解決不了的問題(索引滿足不了這種場景),更不要說分庫分表了:
條件篩選
所以,以訂單表為例,整個架構如下:
archeitecture
具體情況具體分析:多sharding column不到萬不得已的情況下最好不要使用,成本較大,上面提到的使用者表筆者就不太建議使用。因為使用者表有一個很大的特點就是它的上限是肯定的,即使全球70億人全是你的使用者,這點資料量也不大,所以筆者更建議採用單sharding column + es的模式簡化架構。
es+HBase簡要
這裡需要提前說明的是,solr+HBase結合的方案在社群中出現的頻率可能更高,本篇文章為了保持一致性,所有全文索引方案選型都是es。至於es+HBase和solr+HBase孰優孰劣,或者說es和solr孰優孰劣,不是本文需要討論的範疇,事實上也沒有太多討論的意義。es和solr本就是兩個非常優秀且旗鼓相當的中介軟體。最近幾年es更火爆:
es V.S. solr
如果拋開選型過程中所有歷史包袱,單論es+HBase和solr+HBase的優劣,很明顯後者是更好的選擇。solr+HBase高度整合,引入索引服務後我們最關心,也是最重要的索引一致性問題,solr+HBase已經有了非常成熟的解決方案一一Lily HBase Indexer。
延伸閱讀
阿里雲上的雲資料庫HBase版也是藉助solr實現全文索引,有興趣的同學可以戳連結瞭解更多:https://help.aliyun.com/product/49055.html?spm=5176.124785.631202.con1.603452c0cz7bj2。
阿里雲HBase for solr
es+HBase原理
剛剛討論到上面的以MySQL為核心,分庫分表+es的方案,隨著資料量越來越來,雖然分庫分表可以繼續成倍擴容,但是這時候壓力又落到了es這裡,這個架構也會慢慢暴露出問題!
一般訂單表,積分明細表等需要分庫分表的核心表都會有好幾十列,甚至上百列(假設有50列),但是整個表真正需要參與條件索引的可能就不到10個條件(假設有10列)。這時候把50個列所有欄位的資料全量索引到es中,對es叢集有很大的壓力,後面的es分片故障恢復也會需要很長的時間。
這個時候我們可以考慮減少es的壓力,讓es叢集有限的資源儘可能儲存條件檢索時最需要的最有價值的資料,即只把可能參與條件檢索的欄位索引到es中,這樣整個es叢集壓力減少到原來的1/5(核心表50個欄位,只有10個欄位參與條件),而50個欄位的全量資料儲存到HBase中,這就是經典的es+HBase組合方案,即索引與資料儲存隔離的方案。
Hadoop體系下的HBase儲存能力我們都知道是海量的,而且根據它的rowkey查詢效能那叫一個快如閃電。而es的多條件檢索能力非常強大。這個方案把es和HBase的優點發揮的淋漓盡致,同時又規避了它們的缺點,可以說是一個揚長避免的最佳實踐。
它們之間的互動大概是這樣的:先根據使用者輸入的條件去es查詢獲取符合過濾條件的rowkey值,然後用rowkey值去HBase查詢,後面這一查詢步驟的時間幾乎可以忽略,因為這是HBase最擅長的場景,互動圖如下所示:
es+HBase
HBase檢索能力擴充套件
hbase檢索能力
總結
最後,對幾種方案總結如下(sharding column簡稱為sc):
- | 單個sc | 多個sc | sc+es | sc+es+HBase |
---|---|---|---|---|
適用場景 | 單一 | 一般 | 比較廣泛 | 非常廣泛 |
查詢及時性 | 及時 | 及時 | 比較及時 | 比較及時 |
儲存能力 | 一般 | 一般 | 較大 | 海量 |
程式碼成本 | 很小 | 較大 | 一般 | 一般 |
架構複雜度 | 簡單 | 一般 | 較難 | 非常複雜 |
總之,對於海量資料,且有一定的併發量的分庫分表,絕不是引入某一個分庫分表中介軟體就能解決問題,而是一項系統的工程。需要分析整個表相關的業務,讓合適的中介軟體做它最擅長的事情。例如有sharding column的查詢走分庫分表,一些模糊查詢,或者多個不固定條件篩選則走es,海量儲存則交給HBase。
做了這麼多事情後,後面還會有很多的工作要做,比如資料同步的一致性問題,還有執行一段時間後,某些表的資料量慢慢達到單表瓶頸,這時候還需要做冷資料遷移。總之,分庫分表是一項非常複雜的系統工程。任何海量資料的處理,都不是簡單的事情,做好戰鬥的準備吧!
相關推薦
分庫分表技術演進&最佳實踐-修訂篇
https://www.itcodemonkey.com/article/10048.html 每個優秀的程式設計師和架構師都應該掌握分庫分表,這是我的觀點。 移動網際網路時代,海量的使用者每天產生海量的數量,比如: 使用者表 訂單表 交易流水錶 以支付寶使用者為例
分庫分表技術演進&最佳實踐
移動網際網路時代,海量的使用者每天產生海量的數量,比如: 使用者表 訂單表 交易流水錶 以支付寶使用者為例,8億;微信使用者更是10億。訂單表更誇張,比如美團外賣,每天都是幾千萬的訂單。淘寶的歷史訂單總量應該百億,甚至千億級別,這些海量資料遠
分庫分表技術演進&最佳實踐
移動網際網路時代,海量的使用者每天產生海量的數量,比如: 使用者表 訂單表 交易流水錶 以支付寶使用者為例,8億;微信使用者更是10億。訂單表更誇張,比如美團外賣,每天都是幾千萬的訂單。淘寶的歷史訂單總量應該百億,甚至千億級別,這些海量資料
分庫分表技術演進暨最佳實踐
每個優秀的程式設計師和架構師都應該掌握分庫分表,這是我的觀點。 移動網際網路時代,海量的使用者每天產生海量的數量,比如: 使用者表 訂單表 交易流水錶 以支付寶使用者為例,8億;微信使用者更是10億。訂單表更誇張,比如美團外賣,每天都是幾千萬的訂單。淘寶
海量資料的分庫分表技術演進,最佳實踐
每個優秀的程式設計師和架構師都應該掌握分庫分表,移動網際網路時代,海量的使用者每天產生海量的數量 使用者表 訂單表 交易流水錶 以支付寶使用者為例,8億;微信使用者更是10億。訂單表更誇張,比如美團外賣,每天都是幾千萬的訂單。淘寶的歷史訂單總量應該百億,甚至千億級別,
分庫分表技術簡述
今天和大家聊聊分庫分表技術,大家面試的時候肯定都有這樣的經歷,面試官動不動就問分庫分表、高併發、虛擬機器、分散式事務等等這些高大上的技術。所以我們還是有必要要了解一下的。 分表: 分表的意思是在一個庫裡面進行表拆分,很常見的就是日誌表了,分表的規則有按天的、也有按月的。 這種分
mysql分庫分表技術選型時需要注意的點
首先需要明確的一些概念和問題: 原先:一個庫一張表,即db和table。水平拆分之後:多個庫多張表,即 { db1,db2,db3,… } 和 { table1,table2,table3,… },假設現在有物理機器 { server1,server2,server3,… }
【幹貨】數據庫分庫分表基礎和實踐
ima 邏輯關系 部分 平分 range cto database 單個 ron 數據庫架構的演變在業務數據量比較少的時代,我們使用單機數據庫就能滿足業務使用,隨著業務請求量越來越多,數據庫中的數據量快速增加,這時單機數據庫已經不能滿足業務的性能要求,數據庫主從復制架構隨之
訂單系統分庫分表實踐
背景 原大眾點評的訂單單表早就已經突破兩百G,由於查詢維度較多,即使加了兩個從庫,優化索引,仍然存在很多查詢不理想的情況。去年大量搶購活動的開展,使資料庫達到瓶頸,應用只能通過限速、非同步佇列等對其進行保護;業務需求層出不窮,原有的訂單模型很難滿足業務需求,但是基於原訂單表的D
基於代理的資料庫分庫分表框架 Mycat實踐
文章共 1796字,閱讀大約需要 4分鐘 ! 概 述 在如今海量資料充斥的網際網路環境下,分庫分表的意義我想在此處就不用贅述了。而分庫分表目前流行的方案最起碼有兩種: 方案一:基於應用層的分片,即應用層程式碼直接完成分片邏輯 方案二:基於代理層的分片,即在應用程式碼和底層資料庫中
MySql分庫分表實踐
隨著系統業務的發展,資料量的增長,海量資料的儲存和讀取成為系統性能提升的最大瓶頸。通過資料切分水平擴充套件資料庫成為首要方案。 Mysql分庫分表技術層面的文章已經很多,但涉及的如何實施的文章並不多,本人結合剛剛結束的遷移專案經歷整理此文,由於本文為純文字性文章,內容可能比
全量資料同步與資料校驗實踐——應對百億量級分庫分表異構庫遷移
在一家發展中的公司搬磚,正好遇到分庫分表,資料遷移的需求比較多,就入坑了。最近有個系統重構,一直做資料重構、遷移、校驗等工作,基本能覆蓋資料遷移的各個基本點,所以趁機整理一下。 資料同步的場景是:資料庫拆分、資料冗餘、資料表重構。 資料重構服務主要包括:全量
基於代理的資料庫分庫分表框架 Mycat實踐 侵立刪
轉自:http://www.spring4all.com/article/1817 概 述 在如今海量資料充斥的網際網路環境下,分庫分表的意義我想在此處就不用贅述了。而分庫分表目前流行的方案最起碼有兩種: 方案一:基於應用層的分片,即應用層程式碼直接完成分片邏輯
乾貨:資料庫分庫分表基礎和實踐
資料庫架構的演變 在業務資料量比較少的時代,我們使用單機資料庫就能滿足業務使用,隨著業務請求量越來越多,資料庫中的資料量快速增加,這時單機資料庫已經不能滿足業務的效能要求,資料庫主從複製架構隨之應運而生。 主從複製是將資料庫寫操作和讀操作進行分離,使用多個只讀例項(s
Mycat分庫分表的簡單實踐 / 用Mycat,學會資料庫讀寫分離、分表分庫
原創 楊建榮的學習筆記 2017-09-06 10:03 //沒找到原創地址,轉載別人的也沒留地址 。。。 MySQL的使用場景中,讀寫分離只是方案中的一部分,想要擴充套件,勢必會用到分庫分表,可喜的是Mycat裡已經做到了,今天花時間測試了一下,感覺還不錯。
電商系統VIP.com訂單分庫分表的實踐總結以及關鍵步驟
隨著電商系統VIP.com業務的快速發展,訂單量的不斷增長,原有的訂單儲存架構已經不能滿足公司的發展了,特別是在大促高峰期,原訂單庫已經成為搶購瓶頸,已經嚴重製約公司的發展。 唯品會舊訂單庫包含幾十張訂單相關表,舊訂單庫是典型的一主多從架構;主庫容量已接近伺服
Mycat分庫分表的簡單實踐 / 用Mycat,學會資料庫讀寫分離、分表分庫
MySQL的使用場景中,讀寫分離只是方案中的一部分,想要擴充套件,勢必會用到分庫分表,可喜的是Mycat裡已經做到了,今天花時間測試了一下,感覺還不錯。 關於分庫分表 當然自己也理了一下,分庫分表的這些內容,如果分成幾個策略或者階段,大概有下面的幾種。 最上面的第一種是直接拆表,比如資料庫db1下面有te
基於代理的數據庫分庫分表框架 Mycat實踐
行操作 修改 word 參考 接下來 orien ner imageview org 192.168.199.75 MySQL 、 MyCAT master 192.168.199.74 MySQL slave
一次難得的分庫分表實踐
背景 前不久發過兩篇關於分表的文章: 一次分表踩坑實踐的探討 分表後需要注意的二三事 從標題可以看得出來,當時我們只做了分表;還是由於業務發展,截止到現在也做了分庫,目前看來都還比較順利,所以藉著腦子還記得清楚來一次覆盤。 先來回顧下整個分庫分表的流程如下: 整個過程也很好理解,基本符合大部分公
Sharding-JDBC資料分庫分表實踐(水平分表)
摘要 範圍(range)分表也需要確切(precise)分表策略,這點很重要。 確切分表根據分表字段確定資料落在哪一個庫。 範圍分