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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

海量数据的分库分表技术演进,最佳实践

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

每個(gè)優(yōu)秀的程序員和架構(gòu)師都應(yīng)該掌握分庫(kù)分表,移動(dòng)互聯(lián)網(wǎng)時(shí)代,海量的用戶每天產(chǎn)生海量的數(shù)量

  • 用戶表
  • 訂單表
  • 交易流水表

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

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

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

    ?

    Why Not NoSQL/NewSQL?

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

    - RDBMS生態(tài)完善; ? ?

    - RDBMS絕對(duì)穩(wěn)定; ? ?

    - RDBMS的事務(wù)特性;

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

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

    ?

    Why Not 分區(qū)?

    我們?cè)倏捶謪^(qū)表方案。了解這個(gè)方案之前,先了解它的原理:

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

    事實(shí)上,這個(gè)方案也不錯(cuò),它對(duì)用戶屏蔽了sharding的細(xì)節(jié),即使查詢條件沒有sharding column,它也能正常工作(只是這時(shí)候性能一般)。不過它的缺點(diǎn)很明顯:很多的資源都受到單機(jī)的限制,例如連接數(shù),網(wǎng)絡(luò)吞吐等!雖然每個(gè)分區(qū)可以獨(dú)立存儲(chǔ),但是分區(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ù)庫(kù)的全文索引,我都懶得吐槽了!

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

  • 數(shù)據(jù)不是海量(分區(qū)數(shù)有限,存儲(chǔ)能力就有限);
  • 并發(fā)能力要求不高;
  • ?

    Why 分庫(kù)分表?

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

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

    • 阿里的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),也可以說是百花齊放。

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

    • CLIENT模式
    • PROXY模式

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

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

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

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

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

    ?

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

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

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

  • 只選取一個(gè)sharding column進(jìn)行分庫(kù)分表 ;?
  • 多個(gè)sharding column多個(gè)分庫(kù)分表;
  • sharding column分庫(kù)分表 + es;

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

    訂單表

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

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

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

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

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


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

  • 速度對(duì)比:冗余全量表速度更快,冗余關(guān)系表需要二次查詢,即使有引入緩存,還是多一次網(wǎng)絡(luò)開銷;
  • 存儲(chǔ)成本:冗余全量表需要幾倍于冗余關(guān)系表的存儲(chǔ)成本;
  • 維護(hù)代價(jià):冗余全量表維護(hù)代價(jià)更大,涉及到數(shù)據(jù)變更時(shí),多張表都要進(jìn)行修改。
  • 總結(jié):選擇冗余全量表還是索引關(guān)系表,這是一種架構(gòu)上的trade off,兩者的優(yōu)缺點(diǎn)明顯,阿里的訂單表是冗余全量表。

    用戶表

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

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

    賬戶表

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

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

    復(fù)雜查詢

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

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

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

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

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

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

    es+HBase簡(jiǎn)要

    這里需要提前說明的是,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+HBase和solr+HBase的優(yōu)劣,很明顯后者是更好的選擇。solr+HBase高度集成,引入索引服務(wù)后我們最關(guān)心,也是最重要的索引一致性問題,solr+HBase已經(jīng)有了非常成熟的解決方案一一Lily HBase Indexer

    延伸閱讀

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

    es+HBase原理

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

    一般訂單表,積分明細(xì)表等需要分庫(kù)分表的核心表都會(huì)有好幾十列,甚至上百列(假設(shè)有50列),但是整個(gè)表真正需要參與條件索引的可能就不到10個(gè)條件(假設(shè)有10列)。這時(shí)候把50個(gè)列所有字段的數(shù)據(jù)全量索引到es中,對(duì)es集群有很大的壓力,后面的es分片故障恢復(fù)也會(huì)需要很長(zhǎng)的時(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ù)存儲(chǔ)隔離的方案

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

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

    HBase檢索能力擴(kuò)展

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

    ?

    總結(jié)

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

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

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

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

    總結(jié)

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

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