<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          客戶端分片到Proxy分片,如絲般順滑的平穩(wěn)遷移

          共 3226字,需瀏覽 7分鐘

           ·

          2021-08-25 12:11

          點擊上方藍色字體,選擇“設為星標”

          回復”學習資料“獲取學習寶典


          背景

          隨著訂單數(shù)量的增多,以及大促時需要扛住比平時多N倍的流量,單庫單表的瓶頸日益顯現(xiàn)。

          需要對數(shù)據(jù)庫進行水平拆分,目前訂單使用的是客戶端分片的方式進行拆分,采用Sharding-Jdbc框架實現(xiàn)。

          Sharding-Jdbc后改名為ShardingSphere,提供client和proxy方式進行數(shù)據(jù)庫的拆分,目前訂單使用的是client方式。

          client方式的優(yōu)勢是實現(xiàn)簡單,只需要通過簡單的配置即可完成拆分操作。在本地通過分片進行計算,得到真實的庫和表進行路由,性能相對較高。不依賴于三方,沒有單點故障。

          client方式的劣勢是每個項目都要去管理分片,讀寫分離等信息,沒辦法統(tǒng)一進行管理。

          當需要升級的時候只能所有項目都進行升級,沒辦法統(tǒng)一升級。最難的點在于需要推動各個業(yè)務域進行升級,升級的周期較長,對業(yè)務方的壓力也比較大。

          相對于proxy方式,client方式連接數(shù)占用的比較多,一個數(shù)據(jù)源10個連接,部署10個實例就是100個連接。

          proxy方式指的是部署一個獨立的服務,這個服務會實現(xiàn)Mysql協(xié)議,應用中只需要連接這個獨立的proxy服務,把它當做一個完整的獨立的數(shù)據(jù)庫使用即可。

          分庫分表等規(guī)則全部由這個proxy去管理,對應用透明。

          彩虹橋DAL是得物基礎架構組研發(fā)的proxy方式的代理服務,有了彩虹橋就可以統(tǒng)一管理所有數(shù)據(jù)庫,可以對數(shù)據(jù)庫操作做限流保護,可以做壓測時的數(shù)據(jù)自動進入影子庫,可以監(jiān)控慢SQL等等。

          接入方案

          直接修改老數(shù)據(jù)源-改成連接彩虹橋

          最簡單,最快速的方式就是直接將所有老的數(shù)據(jù)源改成新的代理數(shù)據(jù)源,然后重新發(fā)布就可以了。這個方案確實快,但是不夠好,不夠完美,不夠穩(wěn)定,為啥?

          這其實跟改接口是一樣的道理,當某天加了個新的需求,你會發(fā)現(xiàn)直接在老接口的基礎上改一下就完成了。改完后測試發(fā)現(xiàn)當前沒問題,但是老版本的產(chǎn)品還在用,然后兼容出問題了。這種場景下如果你是對接口進行升級,之前是v1,現(xiàn)在改成v2,老的邏輯完全不動,就完美了呀。

          如果我們直接改成最新的方式,那么如何平滑的發(fā)布上線呢?

          全部發(fā)布,萬一彩虹橋那邊配置有問題,或者有其他的問題導致不可用,你這不就尷尬了么,當然也可以回滾歷史版本。

          另一種方式就是灰度發(fā)布一臺機器,進行測試,沒問題后全部發(fā)布,有問題就不發(fā),其實也不錯。就怕過了一段時間,萬一彩虹橋有Bug, 我們還是得回滾到接入彩虹橋之前的版本。

          新增一套數(shù)據(jù)源 - 支持開關切換到新數(shù)據(jù)源,下線老數(shù)據(jù)源

          新增數(shù)據(jù)源,支持開關切換就跟升級API版本是一樣的邏輯。保持老邏輯不變,上線時還是走老的數(shù)據(jù)源,然后通過開關動態(tài)切換到新的數(shù)據(jù)源,完成上線動作。

          當然這邊也會出現(xiàn)上面提到的問題,比如彩虹橋不可用之類的情況,也可以通過灰度配置的方式來測試。將開關配置灰度到某個節(jié)點上,只切這個節(jié)點的數(shù)據(jù)源,進行測試,沒問題后可以擴大范圍。有問題開關一關就還原到之前的邏輯了,無影響。

          如果用了一段時間,彩虹橋有Bug的話同樣改下開關的配置即可回滾,也不用重新發(fā)布項目。

          此方案不足的點就是會占用一分部數(shù)據(jù)庫的連接,因為老的數(shù)據(jù)源還存在。此時需要改代碼去掉老的數(shù)據(jù)源,就能釋放了。如果后面還要去改代碼,那還能叫完美的方案么?

          這點我也考慮到了,還是通過配置開關來關閉老的數(shù)據(jù)源,但是這個操作得重啟服務,重啟后就只有一套數(shù)據(jù)源了。(請確保以后只用彩虹橋的方式才用此開關)

          實現(xiàn)步驟

          • 配置2套新數(shù)據(jù)源,連接彩虹橋的地址,訂單的庫分為老訂單庫和新的分庫分表庫。

          • 新增2個動態(tài)數(shù)據(jù)源,用于開關動態(tài)切換,使用AbstractRoutingDataSource管理。

          • 老數(shù)據(jù)源通過@ConditionalOnProperty來控制是否加載,默認加載,用于后期下線老數(shù)據(jù)源。

          • 讀寫分離兼容client和proxy方式。

          • 分片算法重寫,之前用的Sharding-Jdbc3.X版本,新的彩虹橋基于5.X版本深度定制開發(fā),在自定義算法這塊有變化,目前彩虹橋的分片算法全部在彩虹橋的擴展包中,不在訂單里面。

          注意事項

          select last_insert_id()不支持

          在insert中通過select last_insert_id()實時返回當前插入的自增ID場景需要修改,目前訂單中就一個地方用到了,而且上層其實沒消費這個ID, 如果后面有其他場景需要獲取剛插入的ID可以手動提前獲取分布式ID,然后再用這個ID存到表中。

          強制走從節(jié)點查詢

          老的讀寫分離用的Sharding-Jdbc做的,正常情況下默認查詢走從節(jié)點,其他走主節(jié)點。而現(xiàn)在訂單里面默認都是走主節(jié)點,如果需要強制走從節(jié)點需要使用HintManagerHolder.clear() 清空Hint信息來實現(xiàn)。

          猜測最開始沒有從節(jié)點,業(yè)務都走主節(jié)點。后面加了從節(jié)點,如果用默認的方式查詢都會走從節(jié)點,但是在某些業(yè)務場景中一致性比較高,必須走主節(jié)點查詢,相對于標記出哪些查詢走從節(jié)點來說,默認全部走主節(jié)點更穩(wěn)。然后根據(jù)業(yè)務場景再標記是否要走從節(jié)點,這樣幾乎不會影響老的邏輯。

          接入彩虹橋后,默認是彩虹橋和Sharding-Jdbc兩套數(shù)據(jù)源共存的,所以在HintManagerHolder.clear() 這塊也需要做兼容,同時支持彩虹橋和Sharding-Jdbc方式的強制走從節(jié)點。

          第一步:兼容老代碼

          將所有使用HintManagerHolder.clear()改成SqlHintUtils.clear()。

          public class SqlHintUtils {
             public static void clear() {        
               // ShardingJdbc        
               HintManagerHolder.clear();        
               // 彩虹橋DAL        
               BifrostContext.clearNotAutoClearPrimary();    
             }
          }

          第二步:新增注解強制走從節(jié)點,比代碼更優(yōu)雅

          以后有新的查詢需要走從節(jié)點就在Dao方法上增加@ForceSlave注解即可,此注解只能作用于Dao方法上,加在其它層無效。如果Dao方法上加了注解,那么方法內(nèi)所有的查詢操作都將走從節(jié)點。

          老的clear相關的代碼其實可以用注解代替,但為了保險起見還是不改變原有的方式,新的可以用注解的方式。

          參考文檔 shardingsphere:https://shardingsphere.apache.org/document/current/cn/overview/

          后臺回復 學習資料 領取學習視頻


          如有收獲,點個在看,誠摯感謝


          瀏覽 69
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  色老汉在线视频 | 91.天堂网 | 亚洲女人天堂AV | 日韩一二区 | 免费的A级毛片 |