<output id="brrn1"><ruby id="brrn1"></ruby></output>
<sub id="brrn1"></sub>
    <sub id="brrn1"></sub>

      <sub id="brrn1"><ruby id="brrn1"><noframes id="brrn1"><big id="brrn1"><del id="brrn1"></del></big>

      <th id="brrn1"><ruby id="brrn1"></ruby></th>

          <delect id="brrn1"><meter id="brrn1"></meter></delect>
        
        

          <output id="brrn1"></output>

            數據庫

            億級海量數據的實時讀寫和復雜查詢實踐

            廣告
            廣告

            摘要:本文分享了每日億級增量數據的實時讀寫、復雜查詢場景實踐介紹,涉及 MySQL 分表分庫策略、數據異構、TiDB 使用和優化、微服務架構等內容。

              作者:黃哲鏗

              黃哲鏗,中通商業CTO,前1號店技術總監、海爾農業電商 CTO,2015年出版專著《技術管理之巔》,“技術領導力社區”發起人,擅長大型電商系統研發、供應鏈系統研發、大型技術團隊治理,個人擁有多項技術發明和專利。

            本文根據黃哲鏗老師在DTCC數據庫大會分享內容整理而成,將進行每日億級增量數據的實時讀寫、復雜查詢場景實踐介紹,涉及 MySQL 分表分庫策略、數據異構、TiDB 使用和優化、微服務架構等等。

            首先做下自我介紹,我叫黃哲鏗,之前在互聯網的一些企業,像1號店、1藥網,擔任技術開發以及技術管理等職位。同時,我在2015年的時候出版過一本技術治理方面的書《技術管理之巔》。

              本次分享將由以下幾個部分組成:

              多租戶SAAS系統場景簡介

              系統面臨的挑戰

              億級數據實時讀寫的系統架構

              不足及展望

            一、多租戶SAAS系統場景簡介

            首先介紹一下多租戶SaaS系統的應用場景,案例中的系統是給全網的商家、快遞的門店做結算系統。結算每天的派費、收入以及其他費用等等。那這個系統的使用量大概是多少?全國范圍內有大概兩到三萬的網點,同時在線的人數大概有五萬人左右,每天的結算數據時單表的行數增量大概會達到億級別的增量(假設不分表分庫)。

            同時,應用中會有實時讀寫,大量的復雜的SQL分頁查詢。在座很多做金融系統或來自銀行的朋友們應該很清楚,結算系統或者說金融系統對數據的實時性、一致性的要求非常高。用戶的使用習慣是把明細數據導出來,比如說每天可能有幾十萬甚至百萬的數據要去用Excel導出來,這里面其實會有很多工程方面的優化,以及SQL方面的一些優化。

            二、系統面臨的挑戰

            接下來是我們面臨的一些挑戰,大家有做結算系統或財務方面的朋友應該知道,用戶對自己賬戶里的錢是非常敏感的,比如有很多人排隊去把OFO賬戶中的錢兌現,其實沒多少錢,但大家覺得這個是我的錢,我要隨時、馬上看到,拿到。在結算系統中也一樣的道理,這個數據我改了馬上就能夠在系統里面得到反映。一般的小系統很好實現,但是如果每天有上億增量數據的系統,這其實是個比較大的挑戰。

            剛才我們提到應用場景所面臨的一些挑戰和對系統的挑戰,包括億級增量的結算和數據的存儲,單表肯定是放不下的,自然而然會想到去分表、分庫。那按照什么樣的邏輯去分?這又是一個問題,我們接下來會講。

            應用場景剛才也介紹過了,結算系統對一致性、實時性、可用性都有非常高的要求,我們的應用部署的規模大概有幾百個應用實例,部署在系統上。那幾百個實例對數據庫本身就是一個很大的壓力。假設說有兩百個應用,每個應用有三十個數據庫的鏈接,那就是有六千個鏈接,對嗎?所以,這對整個系統的壓力、架構方式都是非常大的挑戰,以及我們的結算系統要求這種高可用,99.9%、99.99%之類的要求。

            我們的數據主要來源于消費,消費的數據需要做實時的處理,雖然他是跑批的,用分布式job來跑。但是在跑批的過程中,單個業務邏輯的處理的業務復雜度其實是非常高的。單個業務邏輯算一條賬單、一條費用時,可能會涉及到十幾、二十個邏輯規則。那這些數據是實時去抽,做一些預處理,放在緩存里面,但是在數據量大的時候,緩存可能又不一定是非常好的一個解決方案。這就是我們遇到的一些問題。

            其實大家可以想想看,以電商系統為例,電商系統其實只是在下訂單的環節才有這樣的一個應用場景。在下訂單的時候要扣積分,扣庫存等等,那個時候需要用實時數據去計算,對系統我壓力比較大。

            那我們的結算場景的復雜度相當于什么?相當于有五萬多個用戶同時在下單。國內可能也沒有幾家電商公司能夠達到這樣的數量。那么這個系統它的難度,它的挑戰在什么地方呢?

            三、億級數據實時讀寫的系統架構

            所以接下來介紹的是我們如何架構一個這樣的系統去應對剛才我們所面臨的這些挑戰。

            1、云原生微服務架構

            首先我們采用的是云原生的微服務架構,微服務架構的好處其實大家應該都很清楚。就是它的解耦性、橫向可擴、團隊之間的獨立性以及沉淀的業務邏輯等等。

            其實微服務也帶來了一些問題,最明顯的一個問題是什么?原本一個團隊開發一個中臺,那我現在按照業務線去拆,比如說你是用戶組,右邊的這張圖就是用戶下單的場景,從左到右注冊、下訂單、結算等等。那豎著來看,按照業務邏輯來垂直去拆分它的微服務,從應用到數據存儲一條線打通。那它帶來的問題就是團隊協作的問題、團隊之間的程序聯調的問題以及服務治理和服務依賴的問題。所以為什么從以前的SOA發展到微服務,再發展到現在所謂的云原生微服務,要用容器化的方式以及DevOps的這些工具,來使微服務的開發能夠快速地、獨立地運行下去。

            我個人認為小的應用及小團隊碰不到微服務的一些架構,因為根本用不上。十幾個人的團隊或者是幾十個人的團隊,你的架構只要解決:加機器就能夠實現橫向可擴,能夠支撐你的業務量,比如一天幾十萬單的規模,所以不要輕易去嘗試這樣的一些架構。這個系統其實也是一樣的,我們一開始在設計的時候它并不是現在的架構。剛開始它就是單體應用,然后通過這個幾千人、上萬人用的時候,我們開始思考,接下來可能就是幾萬人同時在線的這種場景,怎么辦呢?我們也經歷了應用的拆分、分表、分庫,然后怎么去抽取中臺等等,也是這樣演變過來的。

            這里面提到一個業務中臺,包括業務中臺、數據中臺、AI中臺。我個人認為就是說基于公司的一些規模,其實不是所有公司都需要有這么一個中臺。首先你沒那么大的體量,你的業務沒那么復雜,服務化就可以了。剛才也有提到,其實微服務比較難的地方就是它的這種服務之間的調用、依賴等等。那我們就需要有一個服務治理的平臺,去管理每一組服務,不能因為單個服務的故障,使整體系統可用性受到影響,所以要有這種熔斷機制以及限流機制。這個其實是系統架構和工程方面的一些實踐和經驗,就不細講了。

            2、MySQL 分表分庫策略

            那下面我們通過這樣的一個系統,看我們在數據存儲方面做了一些什么樣的調整。首先,剛才介紹過,我們的數據源主要是來自于消息同步,當然消息的量是非常大的。我們會用分布式Job去處理這些數據,所以我們會采用TBSchedule,淘寶的一個開源的分布式job。我們會把這些消費的數據按分配規則進行分片,然后做處理,這是一個比較靈活的框架。

            從這張圖來看,消費數據進了我們的業務庫,當然這不是所有的業務庫,我們是按照這個不一樣的業務場景、業務邏輯去進行了庫的拆分。

            因為這個場景它是一個寫多讀少或者說基本不太讀的這樣一個場景,所以我們就落到主庫,然后有一個從庫用來做備份。同時我們會把這些主庫里計算完成并結算的數據,通過MQ的方式同步到TiTB,把它作為一個只讀庫。把數據同步到TiTB其實是不再進行分表了,這樣能夠降低系統復雜性。

            其實這個數據我們會定期地做刪除,間隔大概是三到四個月,就是會把這些三到四個月之前主庫產生的數據做一些清理,TiTB里面的數據也是一樣。也有一個做法是接下來會把它抽取到hadoop里面,做一些深度的數據挖掘。

            剛才提到了我們對數據庫分表分庫的策略,基于我們的應用場景,我們使用的是sharding-jdbc來做了一些自己的定制化。我們主要的分表規則有三個,一個是按照商家的ID進行分表,還有就是結算單號及時間。剛才也提到說消費完之后,我們會把數據存下來,同時我們會做數據的異構,按照不同規則去拆。比如說按商家來拆,它的應用場景是,商家登錄進來就可以看到自己的賬單,所以我們會把這些SQL都落在單表里面,就按照商家ID進行區分。大概拆成1024張表,后續會再拆的更細一些,因為商家的業務量可能會越來越大。

            另外還有一種場景就是多個商家之間的結算,那這種場景我們會按照結算單號去拆,每一單上面商家A和商家B的所有結算數據。另外,我們也會統計按月或者是按天的、跨商家的數據,要看總報表也是按這樣的維度來分。

            拆分的過程中其實會遇到一個問題。因為商家的業務規模有大有小,有的可能每天幾千單,有的每天幾千萬,所以會使得小商家會受到某些大商家的海量數據的影響。比如,有時候有的商家反映在查詢非常的慢,查下來就會發現原來是大商家在里面占了很大的存儲空間。所以我們會基于sharding-jdbc做一些定制化的一些處理。處理過后,當這個商家的數據達到一定程度的時候,比如說我們有一個閾值,如果每天增量達到十萬條,那我可能就單獨為它去拆分一張表。所以我們大致的方式是通過MySQL主從、讀寫分離來應對目前數據存儲的問題。另外,讀庫方面我們正在逐步轉到TiTB去做。

            其實從剛才說的分表分庫,大家就可以感受到最好的情況其實就是不分表、不分庫,那對應用來說,程序寫得可能就簡單。我們有這種MyCat、sharding-jdbc,雖然你寫得不復雜,但是整個架構就變得復雜了,因為引入了一個中間層。所以我們其實是基于這樣的場景,做了一個適合當前應用的數據量的架構。假設未來數據庫強大到單表幾億的復雜查詢都能夠支持,那應用寫得會非常簡單。所以現在是因為數據存儲技術達不到,導致了應用架構復雜性的增加。

            3、數據異構實踐

            接下來我們介紹數據異構以及數據聚合,其實剛才也有提到一些,比如基于不同的子系統,數據可能要被異構出來變成多份,甚至異構出來的是不存儲在MySQL 里面,也不會存在像ES、Redis。舉個例子,比如說基于每天的賬單數據算出每個商家的余額,可能就扔到Redis里面,它再去讀取的時候就會快很多。ES里面也是一樣,要查賬或者查明細歷史數據,可能一個月范圍內的就不用去數據庫里面撈了,就在ES里面去做。因為這種場景的實時性要求并不是很高的。而且ES里面如果數據量大,分布式搜索引擎創建索引,在合并的時候是有一定的延遲的,而且ES里調優也是非常有技術含量的,需要花很多功夫。

            另外我們還提到了數據聚合,因為現在大多數的應用都采用了前后臺分離,就算是做APP的開發或者說做基于Web端的也是這樣。前面是JS,后面就是調各種微服務的API的一些接口。

            前后端分離會導致一個怎樣的問題呢?當你進到這個頁面的時候,展示一個完整的頁面,但其實前端會向服務端發出,大概十幾、二十個API請求。這種一個是慢,另一個就是網絡耗時、體驗都會受影響,另外復雜性也是一個問題。所以我們才會去做數據聚合,在服務端和應用端都會做一層。舉個例子,比如說剛進到結算系統的首頁,那它展示的可能是今天的出勤率、今天的賬單等等,大概十幾、二十項的數據。這些會在服務端去做一個數據的聚合,會有個job去跑,然后把數據先預存下來,存到比如說Redis或者MySQL里,這樣在客戶端去請求的時候,就能夠做請求合并。這樣就對整個工程或者數據存儲做了一個優化。

            4、TiDB使用與優化

            剛才有提到TiTB,那我們選型的主要思考是MySQL的單機性能和容量無法線性以及靈活擴展。剛才也提到了為什么會用云原生微服務化,其實這個是很復雜的架構。為什么很簡單的一個結算系統會搞的那么復雜?原因就是數據存儲的技術受到一些挑戰。

            我們考慮選型的時候,因為主要的業務場景都是用MySQL來存,我們開始就沒有再用Oracle。所以至少不能讓開發人員去把SQL重寫一套。另外就是強一致性、分布式事務方面的一些要求,這是基本的結算系統的一些要求,所以我們嘗試使用TiTB來解決這樣的問題。

            在使用的過程中,我們首先是將TiTB替代MySQL的從庫,因為TiTB支持海量數據的查詢,所以我們TiDB里對剛才講的各種數據異構、分表分庫等進行了合并。合并的方式遇到也約到了問題,比如說你分了1024張表,那每張表在MySQL里面的自增ID,就是表一表二,其實它可能是有重復主鍵的。那要把它合過來的話,在TiTB里面可能也要重新做一個自增主鍵。

            關于切換場景,我們會從離線業務開始切,然后在非核心業務以及核心業務切。目前我們是做到了第二步即一些非核心業務,大概十幾個節點的規模。其實這也是在做初步的嘗試,因為官方的建議,其實我們可能在硬件、部署各方面還沒有調到最優。

            同時,我們也發現在單表的字段方面,官方的建議是小于一百個字段。因為我們的結算表的字段也是非常多的,大概用了八十幾個字段。所以查下來的話,其實整個的性能還是比較理想。這是我們目前對于非核心業務場景的一個使用情況。這也使得我們會加大對TiTB的嘗試和使用。

            另外,對于延時比較低的場景可能不太適合,比如剛才講的賬單實時編輯的這些場景。我們也想過,在賬單實時編輯,主庫用MySQL,也分表分庫,然后從庫用TiTB。所有的只讀查詢,都到TiTB里面去。這個我們暫時還沒有在核心業務中去嘗試。

            另外還有一個問題,涉及大量刪除的會有GC性能的問題。就是說這種場景在維護的時候肯定不會在業務高峰時間去做。

            四、不足及展望

            上面我們談了SAAS系統多租戶的結算系統以及它所面臨的業務方面的挑戰,還有我們如何使用微服務架構,以及如何使用分表分庫、主從分離等等那些技術。

            總結一下,首先我們這樣的場景,因為業務還是不斷增長的,所以MySQL作為存儲,其實它的容量和性能,對我們的應用場景來說可能已經達到一個極限了。保守來說,如果我們的業務量再翻個兩三倍的話,可能就比較危險了。

            分表分庫的查詢,就像我們剛才講到的在中間層增加了架構的復雜性。所以接下來假設我們做一些嘗試,如果海量分布式數據庫的應用能夠大量去使用的話,可能在架構上就能夠得到極大的簡化。

            另外,其實我們對于業務數據包括熱數據、溫數據以及冷數據,它應該是有一整套完備的數據處理系統,所以我們接下來會做這種工具橋,就是說把MySQL、TiDB等都打通,實現數據的一體化治理。

            最后提一個概念,大型的互聯網系統架構的探索,就是所謂的云原生的微服務,加上云原生數據庫的概念。提到說云原生的微服務,上午其實還在跟嘉賓討論云原生數據庫的問題,可能接下來我們會加強在云原生數據庫這塊的一些應用和探索。

            以上就是我跟大家分享的內容,謝謝大家!

            我還沒有學會寫個人說明!

            事務注解(@Transactional)引起的數據覆蓋故障

            上一篇

            云數據庫反脆弱性運維體系

            下一篇

            你也可能喜歡

            億級海量數據的實時讀寫和復雜查詢實踐

            長按儲存圖像,分享給朋友

            ITPUB 每周精要將以郵件的形式發放至您的郵箱


            微信掃一掃

            微信掃一掃
            亚洲黄色片视频,光棍电影韩国伦理网,女神吧,伊人电影在线观看