日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一文读懂分库分表的技术演进(最佳实践)

發(fā)布時(shí)間:2025/3/21 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一文读懂分库分表的技术演进(最佳实践) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

每個(gè)優(yōu)秀的程序員和架構(gòu)師都應(yīng)該掌握分庫分表,這是我的觀點(diǎn)。

移動互聯(lián)網(wǎng)時(shí)代,海量的用戶每天產(chǎn)生海量的數(shù)據(jù),比如:

  • 用戶表

  • 訂單表

  • 交易流水表

以支付寶用戶為例,8億;微信用戶更是10億。訂單表更夸張,比如美團(tuán)外賣,每天都是幾千萬的訂單。淘寶的歷史訂單總量應(yīng)該百億,甚至千億級別,這些海量數(shù)據(jù)遠(yuǎn)不是一張表能Hold住的。事實(shí)上MySQL單表可以存儲10億級數(shù)據(jù),只是這時(shí)候性能比較差,業(yè)界公認(rèn)MySQL單表容量在1KW以下是最佳狀態(tài),因?yàn)檫@時(shí)它的BTREE索引樹高在3~5之間。

既然一張表無法搞定,那么就想辦法將數(shù)據(jù)放到多個(gè)地方,目前比較普遍的方案有3個(gè):

  • 分區(qū);

  • 分庫分表;

  • NoSQL/NewSQL;

  • 說明:只分庫,或者只分表,或者分庫分表融合方案都統(tǒng)一認(rèn)為是分庫分表方案,因?yàn)榉謳?#xff0c;或者分表只是一種特殊的分庫分表而已。NoSQL比較具有代表性的是MongoDB,es。NewSQL比較具有代表性的是TiDB。

    Why Not NoSQL/NewSQL?

    首先,為什么不選擇第三種方案NoSQL/NewSQL,我認(rèn)為主要是RDBMS有以下幾個(gè)優(yōu)點(diǎn):

    • ?RDBMS生態(tài)完善;
    • ?RDBMS絕對穩(wěn)定;
    • ?RDBMS的事務(wù)特性;

    NoSQL/NewSQL作為新生兒,在我們把可靠性當(dāng)做首要考察對象時(shí),它是無法與RDBMS相提并論的。RDBMS發(fā)展幾十年,只要有軟件的地方,它都是核心存儲的首選。

    目前絕大部分公司的核心數(shù)據(jù)都是:以RDBMS存儲為主,NoSQL/NewSQL存儲為輔!互聯(lián)網(wǎng)公司又以MySQL為主,國企&銀行等不差錢的企業(yè)以O(shè)racle/DB2為主!NoSQL/NewSQL宣傳的無論多牛逼,就現(xiàn)在各大公司對它的定位,都是RDBMS的補(bǔ)充,而不是取而代之!

    Why Not 分區(qū)?

    我們再看分區(qū)表方案。了解這個(gè)方案之前,先了解它的原理:

    分區(qū)表是由多個(gè)相關(guān)的底層表實(shí)現(xiàn),這些底層表也是由句柄對象表示,所以我們也可以直接訪問各個(gè)分區(qū),存儲引擎管理分區(qū)的各個(gè)底層表和管理普通表一樣(所有的底層表都必須使用相同的存儲引擎),分區(qū)表的索引只是在各個(gè)底層表上各自加上一個(gè)相同的索引,從存儲引擎的角度來看,底層表和一個(gè)普通表沒有任何不同,存儲引擎也無須知道這是一個(gè)普通表還是一個(gè)分區(qū)表的一部分。

    事實(shí)上,這個(gè)方案也不錯(cuò),它對用戶屏蔽了sharding的細(xì)節(jié),即使查詢條件沒有sharding column,它也能正常工作(只是這時(shí)候性能一般)。不過它的缺點(diǎn)很明顯:很多的資源都受到單機(jī)的限制,例如連接數(shù),網(wǎng)絡(luò)吞吐等!雖然每個(gè)分區(qū)可以獨(dú)立存儲,但是分區(qū)表的總?cè)肟谶€是一個(gè)MySQL實(shí)例。從而導(dǎo)致它的并發(fā)能力非常一般,遠(yuǎn)遠(yuǎn)達(dá)不到互聯(lián)網(wǎng)高并發(fā)的要求!

    至于網(wǎng)上提到的一些其他缺點(diǎn)比如:無法使用外鍵,不支持全文索引。我認(rèn)為這都不算缺點(diǎn),21世紀(jì)的項(xiàng)目如果還使用外鍵和數(shù)據(jù)庫的全文索引,我都懶得吐槽了!

    所以,如果使用分區(qū)表,你的業(yè)務(wù)應(yīng)該具備如下兩個(gè)特點(diǎn):

  • 數(shù)據(jù)不是海量(分區(qū)數(shù)有限,存儲能力就有限);

  • 并發(fā)能力要求不高;

  • Why 分庫分表?

    最后要介紹的就是目前互聯(lián)網(wǎng)行業(yè)處理海量數(shù)據(jù)的通用方法:分庫分表。

    雖然大家都是采用分庫分表方案來處理海量核心數(shù)據(jù),但是還沒有一個(gè)一統(tǒng)江湖的中間件,筆者這里列舉一些有一定知名度的分庫分表中間件:

    • 阿里的TDDL,DRDS和cobar,

    • 開源社區(qū)的sharding-jdbc(3.x已經(jīng)更名為sharding-sphere);

    • 民間組織的MyCAT;

    • 360的Atlas;

    • 美團(tuán)的zebra;

    備注:sharding-jdbc的作者張亮大神原來在當(dāng)當(dāng),現(xiàn)在在京東金融。但是sharding-jdbc的版權(quán)屬于開源社區(qū),不是公司的,也不是張亮個(gè)人的!

    其他比如網(wǎng)易,58,京東等公司都有自研的中間件??傊髯詾閼?zhàn),也可以說是百花齊放。

    但是這么多的分庫分表中間件全部可以歸結(jié)為兩大類型:

    • CLIENT模式

    • PROXY模式

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

    client arch

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

    proxy arch

    但是,無論是CLIENT模式,還是PROXY模式。幾個(gè)核心的步驟是一樣的:SQL解析,重寫,路由,執(zhí)行,結(jié)果歸并。

    筆者比較傾向于CLIENT模式,架構(gòu)簡單,性能損耗較小,運(yùn)維成本低。

    接下來,以幾個(gè)常見的大表為案例,說明分庫分表如何落地!

    實(shí)戰(zhàn)案例

    分庫分表第一步也是最重要的一步,即sharding column的選取,sharding column選擇的好壞將直接決定整個(gè)分庫分表方案最終是否成功。而sharding column的選取跟業(yè)務(wù)強(qiáng)相關(guān),筆者認(rèn)為選擇sharding column的方法最主要分析你的API流量,優(yōu)先考慮流量大的API,將流量比較大的API對應(yīng)的SQL提取出來,將這些SQL共同的條件作為sharding column。例如一般的OLTP系統(tǒng)都是對用戶提供服務(wù),這些API對應(yīng)的SQL都有條件用戶ID,那么,用戶ID就是非常好的sharding column。

    這里列舉分庫分表的幾種主要處理思路:

  • 只選取一個(gè)sharding column進(jìn)行分庫分表 ;

  • 多個(gè)sharding column多個(gè)分庫分表;

  • sharding column分庫分表 + es;


  • 再以幾張實(shí)際表為例,說明如何分庫分表。

    訂單表

    訂單表幾個(gè)核心字段一般如下:

    訂單表

    以阿里訂單系統(tǒng)為例(參考《企業(yè)IT架構(gòu)轉(zhuǎn)型之道:阿里巴巴中臺戰(zhàn)略思想與架構(gòu)實(shí)現(xiàn)》),它選擇了三個(gè)column作為三個(gè)獨(dú)立的sharding column,即:order_id,user_id,merchant_code。user_id和merchant_code就是買家ID和賣家ID,因?yàn)榘⒗锏挠唵蜗到y(tǒng)中買家和賣家的查詢流量都比較大,并且查詢對實(shí)時(shí)性要求都很高。而根據(jù)order_id進(jìn)行分庫分表,應(yīng)該是根據(jù)order_id的查詢也比較多。

    這里還有一點(diǎn)需要提及,多個(gè)sharding-column的分庫分表是冗余全量還是只冗余關(guān)系索引表,需要我們自己權(quán)衡。

    冗余全量的情況如下--每個(gè)sharding列對應(yīng)的表的數(shù)據(jù)都是全量的,這樣做的優(yōu)點(diǎn)是不需要二次查詢,性能更好,缺點(diǎn)是比較浪費(fèi)存儲空間(淺綠色字段就是sharding-column):

    冗余全量

    冗余關(guān)系索引表的情況如下--只有一個(gè)sharding column的分庫分表的數(shù)據(jù)是全量的,其他分庫分表只是與這個(gè)sharding column的關(guān)系表,這樣做的優(yōu)點(diǎn)是節(jié)省空間,缺點(diǎn)是除了第一個(gè)sharding column的查詢,其他sharding column的查詢都需要二次查詢,這三張表的關(guān)系如下圖所示(淺綠色字段就是sharding column):

    表之間的關(guān)系圖

    冗余全量表PK.冗余關(guān)系表

  • 速度對比:冗余全量表速度更快,冗余關(guān)系表需要二次查詢,即使有引入緩存,還是多一次網(wǎng)絡(luò)開銷;

  • 存儲成本:冗余全量表需要幾倍于冗余關(guān)系表的存儲成本;

  • 維護(hù)代價(jià):冗余全量表維護(hù)代價(jià)更大,涉及到數(shù)據(jù)變更時(shí),多張表都要進(jìn)行修改。

  • 總結(jié):選擇冗余全量表還是索引關(guān)系表,這是一種架構(gòu)上的trade off,兩者的優(yōu)缺點(diǎn)明顯,阿里的訂單表是冗余全量表。

    用戶表

    用戶表幾個(gè)核心字段一般如下:

    用戶表

    一般用戶登錄場景既可以通過mobile_no,又可以通過email,還可以通過username進(jìn)行登錄。但是一些用戶相關(guān)的API,又都包含user_id,那么可能需要根據(jù)這4個(gè)column都進(jìn)行分庫分表,即4個(gè)列都是sharding-column。

    賬戶表

    賬戶表幾個(gè)核心字段一般如下:

    賬戶表

    與賬戶表相關(guān)的API,一般條件都有account_no,所以以account_no作為sharding-column即可。

    復(fù)雜查詢

    上面提到的都是條件中有sharding column的SQL執(zhí)行。但是,總有一些查詢條件是不包含sharding column的,同時(shí),我們也不可能為了這些請求量并不高的查詢,無限制的冗余分庫分表。那么這些條件中沒有sharding column的SQL怎么處理?以sharding-jdbc為例,有多少個(gè)分庫分表,就要并發(fā)路由到多少個(gè)分庫分表中執(zhí)行,然后對結(jié)果進(jìn)行合并。具體如何合并,可以看筆者sharding-jdbc系列文章,有分析源碼講解合并原理。

    這種條件查詢相對于有sharding column的條件查詢性能很明顯會下降很多。如果有幾十個(gè),甚至上百個(gè)分庫分表,只要某個(gè)表的執(zhí)行由于某些因素變慢,就會導(dǎo)致整個(gè)SQL的執(zhí)行響應(yīng)變慢,這非常符合木桶理論。

    更有甚者,那些運(yùn)營系統(tǒng)中的模糊條件查詢,或者上十個(gè)條件篩選。這種情況下,即使單表都不好創(chuàng)建索引,更不要說分庫分表的情況下。那么怎么辦呢?這個(gè)時(shí)候大名鼎鼎的elasticsearch,即es就派上用場了。將分庫分表所有數(shù)據(jù)全量冗余到es中,將那些復(fù)雜的查詢交給es處理。

    淘寶我的所有訂單頁面如下,篩選條件有多個(gè),且商品標(biāo)題可以模糊匹配,這即使是單表都解決不了的問題(索引滿足不了這種場景),更不要說分庫分表了:

    條件篩選

    所以,以訂單表為例,整個(gè)架構(gòu)如下:

    archeitecture

    具體情況具體分析:多sharding column不到萬不得已的情況下最好不要使用,成本較大,上面提到的用戶表筆者就不太建議使用。因?yàn)橛脩舯碛幸粋€(gè)很大的特點(diǎn)就是它的上限是肯定的,即使全球70億人全是你的用戶,這點(diǎn)數(shù)據(jù)量也不大,所以筆者更建議采用單sharding column + es的模式簡化架構(gòu)。

    es+HBase簡要

    這里需要提前說明的是,solr+HBase結(jié)合的方案在社區(qū)中出現(xiàn)的頻率可能更高,本篇文章為了保持一致性,所有全文索引方案選型都是es。至于es+HBase和solr+HBase孰優(yōu)孰劣,或者說es和solr孰優(yōu)孰劣,不是本文需要討論的范疇,事實(shí)上也沒有太多討論的意義。es和solr本就是兩個(gè)非常優(yōu)秀且旗鼓相當(dāng)?shù)闹虚g件。最近幾年es更火爆:

    es V.S. solr

    如果拋開選型過程中所有歷史包袱,單論es+HBase和solr+HBase的優(yōu)劣,很明顯后者是更好的選擇。solr+HBase高度集成,引入索引服務(wù)后我們最關(guān)心,也是最重要的索引一致性問題,solr+HBase已經(jīng)有了非常成熟的解決方案一一Lily HBase Indexer。

    延伸閱讀

    阿里云上的云數(shù)據(jù)庫HBase版也是借助solr實(shí)現(xiàn)全文索引,有興趣的同學(xué)可以戳鏈接了解更多:https://help.aliyun.com/product/49055.html?spm=5176.124785.631202.con1.603452c0cz7bj2。

    阿里云HBase for solr

    es+HBase原理

    剛剛討論到上面的以MySQL為核心,分庫分表+es的方案,隨著數(shù)據(jù)量越來越大,雖然分庫分表可以繼續(xù)成倍擴(kuò)容,但是這時(shí)候壓力又落到了es這里,這個(gè)架構(gòu)也會慢慢暴露出問題!

    一般訂單表,積分明細(xì)表等需要分庫分表的核心表都會有好幾十列,甚至上百列(假設(shè)有50列),但是整個(gè)表真正需要參與條件索引的可能就不到10個(gè)條件(假設(shè)有10列)。這時(shí)候把50個(gè)列所有字段的數(shù)據(jù)全量索引到es中,對es集群有很大的壓力,后面的es分片故障恢復(fù)也會需要很長的時(shí)間。

    這個(gè)時(shí)候我們可以考慮減少es的壓力,讓es集群有限的資源盡可能保存條件檢索時(shí)最需要的最有價(jià)值的數(shù)據(jù),即只把可能參與條件檢索的字段索引到es中,這樣整個(gè)es集群壓力減少到原來的1/5(核心表50個(gè)字段,只有10個(gè)字段參與條件),而50個(gè)字段的全量數(shù)據(jù)保存到HBase中,這就是經(jīng)典的es+HBase組合方案,即索引與數(shù)據(jù)存儲隔離的方案

    Hadoop體系下的HBase存儲能力我們都知道是海量的,而且根據(jù)它的rowkey查詢性能那叫一個(gè)快如閃電。而es的多條件檢索能力非常強(qiáng)大。這個(gè)方案把es和HBase的優(yōu)點(diǎn)發(fā)揮的淋漓盡致,同時(shí)又規(guī)避了它們的缺點(diǎn),可以說是一個(gè)揚(yáng)長避免的最佳實(shí)踐。

    它們之間的交互大概是這樣的:先根據(jù)用戶輸入的條件去es查詢獲取符合過濾條件的rowkey值,然后用rowkey值去HBase查詢,后面這一查詢步驟的時(shí)間幾乎可以忽略,因?yàn)檫@是HBase最擅長的場景,交互圖如下所示:

    es+HBase

    HBase檢索能力擴(kuò)展

    hbase檢索能力

    圖片來源于HBase技術(shù)社區(qū)-HBase應(yīng)用實(shí)踐專場-HBase for Solr

    總結(jié)

    最后,對幾種方案總結(jié)如下(sharding column簡稱為sc):

    -單個(gè)sc多個(gè)scsc+essc+es+HBase
    適用場景單一一般比較廣泛非常廣泛
    查詢及時(shí)性及時(shí)及時(shí)比較及時(shí)比較及時(shí)
    存儲能力一般一般較大海量
    代碼成本很小較大一般一般
    架構(gòu)復(fù)雜度簡單一般較難非常復(fù)雜

    總之,對于海量數(shù)據(jù),且有一定的并發(fā)量的分庫分表,絕不是引入某一個(gè)分庫分表中間件就能解決問題,而是一項(xiàng)系統(tǒng)的工程。需要分析整個(gè)表相關(guān)的業(yè)務(wù),讓合適的中間件做它最擅長的事情。例如有sharding column的查詢走分庫分表,一些模糊查詢,或者多個(gè)不固定條件篩選則走es,海量存儲則交給HBase。

    做了這么多事情后,后面還會有很多的工作要做,比如數(shù)據(jù)同步的一致性問題,還有運(yùn)行一段時(shí)間后,某些表的數(shù)據(jù)量慢慢達(dá)到單表瓶頸,這時(shí)候還需要做冷數(shù)據(jù)遷移??傊?#xff0c;分庫分表是一項(xiàng)非常復(fù)雜的系統(tǒng)工程。任何海量數(shù)據(jù)的處理,都不是簡單的事情,做好戰(zhàn)斗的準(zhǔn)備吧!

    鳴謝

    最后感謝為這篇文章提出寶貴意見的阿里大佬右軍[公眾號:?技術(shù)瑣話]和陸金所HBase扛把子峰神[公眾號:?HBase技術(shù)社區(qū)]。

    筆者寫完這篇文章在第一時(shí)間將初稿發(fā)給了右軍,大佬很有耐心的看完,和我交流,并于當(dāng)天下午給我提出了非常寶貴的一些改進(jìn)意見,這才有了這篇修訂版。

    峰神對HBase造詣很深,并且維護(hù)著HBase技術(shù)社區(qū),為無數(shù)HBase學(xué)者提供了很好的學(xué)習(xí)平臺。在修訂這篇文章的時(shí)候,與峰神討論了很多。另外,曾經(jīng)另一位在*1信用卡待過的朋友,他們的HBase出了問題,運(yùn)維折騰了半天沒有搞定。最后咨詢峰神,只簡單的點(diǎn)撥就搞定了!對HBase感興趣的同學(xué),都可以去社區(qū)學(xué)習(xí)和交流,一定不會讓你失望!

    《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的一文读懂分库分表的技术演进(最佳实践)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。