架構思考-業務快速增加時的容量問題

背景mysql

以前作過一個項目,數據庫存儲採用的是mysql。當時面臨着業務指數級的增加,存儲容量不足。當時採用的措施是linux

 

1>短時間解決容量的問題sql

mysql從5.6升級5.7,由於數據核心且重要,數據庫主從同步採用的是全同步, 利用5.7並行複製新特性,減小了主從同步的延遲,提升了吞吐量。數據庫

 

當時業務量高峯是2000TPS,5.6時可承受的最大TPS是3000,升級到5.7壓測可承受的最大TPD是5000.安全

 

2>流量拆分,從根本上解決容量問題數據結構

首先進行容量評估,經過對於業務開展規劃、活動預估,年末的容量會翻5倍。因爲目前指數級增加的特性,數據庫要預留至少4倍的冗餘。併發

 

要對數據庫進行擴容,由於咱們已經使用的是最頂配的SSD物理機了,就算能夠在linux內核層面對numa進行綁核和非綁核等測試調參優化性能,提高容量也頗有限。注意:通常的業務系統numa綁核會提升性能,可是mysql等數據庫系統是相反的。異步

 

因此垂直擴容不成功,就看看是否能夠拆分流量。mysql流量拆分方式有x軸拆分(水平拆分)、y軸拆分(垂直拆分)、z軸拆分。分佈式

 

其中y軸拆分(垂直拆分)就是目前都在說作垂直領域,就是在一個細分領域裏作深刻的意思。由此能夠很容易的記住垂直拆分的意思就是按照業務領域進行拆分,專庫專用。實際上能按領域拆分是最理想的,由於這種拆分業務清晰;拆分規則明確;系統之間整合或擴展容易。可是由於當時的業務已經很簡單,y軸拆分已經沒有什麼空間,這種拆分不能達到擴容20倍的目的。高併發

 

z軸拆分近幾年沒有據說過了,實際上你們也一直在用。這種方式是將一張大表拆分爲子母表,就是分爲概要信息和詳細信息。這種拆分方式對解決容量問題意義不大。

 

比較可行的一個方案是水平拆分。就是常說的分庫分表。按照容量評估,數據庫水平拆分一拆十,根據業務特色找一個標準字段來進行取模。

 

水平拆分一個技術點在於新老切換。

採用的是數據庫雙寫的方式,採用異步確保性的補償型事務,發送實時和延遲兩個MQ,經過開關來控制以老數據爲準仍是新數據庫爲準。開始時以老數據庫爲準,觀察新老數據沒有一致性問題以後,在一個低峯期,關閉了系統入口,等數據庫沒有任何變動以後切換開關,再打開系統入口。

 

問題

對於容量問題,上面採用的是一次性拆分到位的方法。對於一個規模稍大的公司來說,10組物理機(1組包含1主N從)的成本還好。

1>若是量級再次升級,須要每週增長10臺數據庫才能支撐容量呢?

2>而且對系統可用性還有強要求,1s的停機都不能夠接受呢?

 

解決方案分析

垂直流量拆分

首先我要分析的是每週增長10臺數據庫這個容量是否是合理的。是否存在放大效應或者說能夠減小對mysql這種昂貴資源的使用,轉爲增長對HBase、Elasticsearch這種低成本高擴展性資源的使用呢?

 

基於這個思路,咱們須要梳理下是否有可垂直拆分的流量。好比正向流量和負向流量。所謂正向流量是指好比交易下單,負向流量就是取消訂單,包括已付款取消、未付款取消、已到貨取消、未到貨取消等等。實際上負向流量在總訂單裏佔比不多,可是業務要比正向交易業務複雜。將正向和逆向拆分的一個主要優點是分治思想,能夠下降兩部分各自的複雜度。將流量拆分重心轉移到正向流量上。

 

對於正向流量,一個業務比較經常使用的流量拆分思路是CQRS命令查詢分離,也就是常說的讀寫分離。若是讀流量大於寫流量。能夠考慮可否將讀流量進一步拆分。拆分紅實時和離線,將實時性要求不高的查詢走ES。ES的數據能夠經過同步binlog變動得到。

 

另一個思路是將數據庫按照歷史數據來拆分。就是數據庫裏只保存必定時間內的實時數據。超過指定時間則進行數據歸檔。將數據歸檔到HBase等,通常對於歷史的查詢實時性要求也不是很高。

 

垂直流量拆分可能遇到的問題

以上方法都是隻考慮問題1若是量級再次升級,須要每週增長10臺數據庫才能支撐容量的方案。若是再考慮問題2而且對系統可用性還有強要求,1s的停機都不能夠接受。就須要看上述方案可能會遇到的問題。

 

拆分正向流量和負向流量、CQRS都須要改造,改造過程就須要過渡。過渡能夠採用上面說的雙寫方式,觀察運行狀況進行切換。切換過程當中也能夠不關閉流量。

 

麻煩的是數據歸檔。由於數據歸檔後刪除數據庫的數據,變動生效時,針對innodb來講,意味着數據結構重建,頻繁IO。這會影響OLTP在線事務的處理。能夠考慮按表來歸檔,控制操做頻率,控制單位時間內對IO的影響。

 

分佈式關係型數據庫

分佈式關係型數據庫本質上是經過增長代理等方式將分庫分表作的更加隱蔽。

 

阿里巴巴分佈式關係數據庫(DRDS),前身是淘寶分佈式數據層(TDDL),核心就是用於分庫分表管理的代理層,宣稱可實現平滑擴容。

 

 

擴容過程實際是物理數據遷移的過程,引擎層按照分庫遷移後的邏輯先在物理節點上創建新的分庫,而後保留一個時間點進行全量的數據遷移。完成全量遷移後,開始基於先前保留的時間點進行增量的數據追趕。當增量數據追趕到兩邊的數據幾乎一致時,對數據庫進行瞬時停寫,將最後的數據追平,引擎層進行分庫邏輯的路由切換,路由規則切換完成後就完成了核心的擴容邏輯,整個切換過程在毫秒級別完成。

 

由於整個過程是毫秒級,因此能夠作到業務層沒有感知,等多就是看到擴容過程當中請求延時增長了不到1s。從原理上來講是可行的。

 

NOSQL解決方案

像這麼大的數據量一個很好的參考是12306。12306採用的是Geode。它是有數據庫功能的內存數據網格(In-Memory Data Grid,IMDG)。其重要特性是

 

1)集羣內存總容量,如今Geode能夠實現單個節點200-300GB內存,總集羣包含300個節點的大型集羣,所以總容量能夠達到90TB左右的級別。

 

2)Geode集羣功能很是強大,實現了內存中數據Shard分佈,自動管理,集羣故障自動恢復,自動平均分佈等一系列企業級的功能,並且有自帶的集羣間數據同步功能。

 

3)在CAP原理下(不瞭解的話能夠百度一下CAP不可能三角),Geode能夠保證集羣內數據的強一致性,注意是真正的強一致性而不是最終一致性,再加上分區可用性,所以是一個CP型的產品,能夠提供統一的數據視圖,支持高併發下的acid事務。

 

採用新的解決方案最大問題是平滑過渡,平滑過渡方面我仍是以爲上面提到的數據庫雙寫方式安全可靠。

 

系統共建的解決方案

若是達到我所說的量級,基本上在一個行業中是處於壟斷地位的。並非一家純的互聯網公司。這種公司能夠採用和互聯網大廠合做的方式、用已經有這方面經驗的大廠,來根據本身內部系統的特性共建一套合適本身的定製化數據庫。

相關文章
相關標籤/搜索