<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>

          圖數(shù)據(jù)庫(kù)系統(tǒng)重構(gòu)之路:從OrientDB遷移到NebulaGraph 真實(shí)案例分享

          共 7787字,需瀏覽 16分鐘

           ·

          2023-08-17 02:42

          一、寫(xiě)在前面

          讀過(guò)我公眾號(hào)文章的同學(xué)都知道,我做過(guò)很多次重構(gòu),可以說(shuō)是“重構(gòu)釘子戶”,但是這次,重構(gòu)圖數(shù)據(jù)庫(kù)OrientDB為Nebula Graph(https://www.nebula-graph.io/),可以說(shuō)是我做過(guò)最艱難的一次重構(gòu),那這篇文章就來(lái)聊聊,圖數(shù)據(jù)庫(kù)重構(gòu)之路。

          二、難點(diǎn)在哪里

          1、歷史包袱重,原來(lái)使用OrientDB系統(tǒng)是2016年開(kāi)始開(kāi)發(fā)的,邏輯很復(fù)雜,歷史背景完全不清楚。

          2、業(yè)務(wù)不了解,我們是臨時(shí)接的大數(shù)據(jù)需求,之前沒(méi)有參與過(guò)這塊業(yè)務(wù),完全不了解。

          3、技術(shù)棧不了解,圖數(shù)據(jù)庫(kù)是第一次接觸(團(tuán)隊(duì)中也沒(méi)有人了解),OrientDB和Nebula之前都沒(méi)有接觸過(guò),原來(lái)老系統(tǒng)大部分代碼是Scala語(yǔ)言寫(xiě)的,系統(tǒng)中使用的Hbase,Spark,Kafka對(duì)于我們也比較陌生。

          4、時(shí)間緊迫

          總結(jié)來(lái)說(shuō): 業(yè)務(wù)不了解,技術(shù)棧不熟悉!

          tips: 大家思考一個(gè)問(wèn)題,在業(yè)務(wù)和技術(shù)棧都不熟的情況下,如何做重構(gòu)呢?

          三、技術(shù)方案

          下面介紹一下本次重構(gòu)技術(shù)方案

          1、背景

          獵戶座的圖數(shù)據(jù)庫(kù)OrientDB存在性能瓶頸和單點(diǎn)問(wèn)題,需升級(jí)為Nebula。

          老系統(tǒng)使用技術(shù)棧無(wú)法支持彈性伸縮,監(jiān)控報(bào)警設(shè)施也不夠完善。

          2、調(diào)研事項(xiàng)

          注: 既然業(yè)務(wù)都不熟悉,那我們都調(diào)研了哪些東西呢?

          1)、對(duì)外接口梳理: 梳理系統(tǒng)所有對(duì)外接口,包括接口名,接口用途,請(qǐng)求量(QPS),平均耗時(shí),調(diào)用方(服務(wù)和IP)

          2)、老系統(tǒng)核心流程梳理: 輸出老系統(tǒng)整理架構(gòu)圖,重要的接口(大概10個(gè))輸出流程圖

          3)、環(huán)境梳理: 涉及到的需要改造的項(xiàng)目有哪些 , 應(yīng)用部署、Mysql,Redis,Hbase集群IP,及目前線上部署分支整理

          4)、觸發(fā)場(chǎng)景: 接口都是如何觸發(fā)的,從業(yè)務(wù)使用場(chǎng)景出發(fā),每個(gè)接口至少一個(gè)場(chǎng)景覆蓋到,方便后期功能驗(yàn)證

          5)、改造方案: 可行性分析,針對(duì)每一個(gè)接口,如何改造(OrientDB語(yǔ)句改為Nebula查詢語(yǔ)句),入圖(寫(xiě)流程)如何改造

          6)、新系統(tǒng)設(shè)計(jì)方案: 輸出整理架構(gòu)圖,核心流程圖

          3、項(xiàng)目目標(biāo)

          完成圖數(shù)據(jù)庫(kù)數(shù)據(jù)源 OrientDB改造為Nebula,重構(gòu)老系統(tǒng)統(tǒng)一技術(shù)棧為Java,支持服務(wù)水平擴(kuò)展。

          4、整體方案

          我們采用了比較激進(jìn)的方案:

          1、從調(diào)用接口入口出發(fā),直接重寫(xiě)底層老系統(tǒng),影響面可控

          2、一勞永逸,方便后期維護(hù)

          3、統(tǒng)一Java技術(shù)棧、接入公司統(tǒng)一服務(wù)框架,更利于監(jiān)控及維護(hù)

          4、基礎(chǔ)圖數(shù)據(jù)庫(kù)應(yīng)用邊界清晰,后續(xù)上層應(yīng)用接入圖數(shù)據(jù)庫(kù)更簡(jiǎn)單

          注:這里就貼調(diào)研階段畫(huà)的圖,圖涉及業(yè)務(wù),我這里就不列舉了。

          5、灰度方案

          747be7c936142a7f7055eeeee9d5154d.webp

          ** 1) 灰度方案**

          寫(xiě)請(qǐng)求:采用同步雙寫(xiě)

          讀請(qǐng)求:按流量從小到大陸續(xù)遷移、平滑過(guò)渡

          ** 2) 灰度計(jì)劃**

          階段一 階段二 階段三 階段四 階段五 階段六 階段七
          0% 1‰ 1% 10% 20% 50% 100%
          同步雙寫(xiě), 流量回放采樣對(duì)比,100%通過(guò)、預(yù)計(jì)灰度2天 灰度2天 灰度2天 灰度5天、此階段要壓測(cè) 灰度2天 灰度2天 -

          注:

          1. 1. 配置中心開(kāi)關(guān)控制,有問(wèn)題隨時(shí)切換,秒級(jí)恢復(fù)。

          2. 2. 讀接口遺漏無(wú)影響, 只有改到的才會(huì)影響。

          3. 3. 使用參數(shù) hash值作為key,確保同一參數(shù)多次請(qǐng)求結(jié)果一致、滿足 abs(key) % 1000 < X ( 0< X < 1000, X為動(dòng)態(tài)配置 ) 即為命中灰度。

          題外話: 其實(shí)重構(gòu),最重要的就是灰度方案,這個(gè)我在之前文章也提到過(guò),本次灰度方案設(shè)計(jì)比較完善,大家重點(diǎn)看階段一、在灰度放量之前,我們用線上真實(shí)的流量去異步做數(shù)據(jù)對(duì)比,對(duì)比完全通過(guò)之后,再放量,本次數(shù)據(jù)對(duì)比階段比預(yù)期長(zhǎng)了一些(實(shí)際上用了2周時(shí)間,發(fā)現(xiàn)了很多隱藏問(wèn)題)。

          6、數(shù)據(jù)對(duì)比方案

          1) 未命中灰度流程如下:

          先調(diào)用老系統(tǒng),再根據(jù)是否命中采樣(采樣比例配置 0% ~ 100% ),命中采樣會(huì)發(fā)送MQ,再在新系統(tǒng)消費(fèi)MQ,請(qǐng)求新系統(tǒng)接口,于老系統(tǒng)接口返回?cái)?shù)據(jù)進(jìn)行json對(duì)比,對(duì)比不一致發(fā)送企業(yè)微信通知,實(shí)時(shí)感知數(shù)據(jù)不一致,發(fā)現(xiàn)并解決問(wèn)題。

          c06ddf82e4e482a76a0191fddbbf0b72.webpimg

          反之亦然!!

          7、數(shù)據(jù)遷移方案

          1)、 全量(歷史數(shù)據(jù)):腳本全量遷移,上線期間產(chǎn)生不一致從MQ消費(fèi)近3天數(shù)據(jù)

          2)、增量:同步雙寫(xiě)(寫(xiě)的接口很少,寫(xiě)請(qǐng)求QPS不高)

          8、改造案例 - 以子圖查詢?yōu)槔?/h3>

          1)改造前

              
              @Override
              public MSubGraphReceive getSubGraph(MSubGraphSend subGraphSend) {
                  logger.info("-----start getSubGraph------(" + subGraphSend.toString() + ")");
                  MSubGraphReceive r = (MSubGraphReceive) akkaClient.sendMessage(subGraphSend, 30);
                  logger.info("-----end getSubGraph:");
                  return r;
              }

          2)改造后

          定義灰度模塊接口

              
              
          public interface IGrayService {
              /**
               * 是否命中灰度 配置值 0 ~ 1000  true: 命中  false:未命中
               *
               * @param hashCode
               * @return
               */

              public boolean hit(Integer hashCode);

              /**
               * 是否取樣 配置值 0 ~ 100
               *
               * @return
               */

              public boolean hitSample();

              /**
               * 發(fā)送請(qǐng)求-響應(yīng)數(shù)據(jù)
               * @param requestDTO
               */

              public void sendReqMsg(MessageRequestDTO requestDTO);

              /**
               * 根據(jù)
               * @param methodKeyEnum
               * @return
               */

              public boolean hitSample(MethodKeyEnum methodKeyEnum);
          }

          接口改造如下, newCoreService請(qǐng)求到new-core新服務(wù),接口業(yè)務(wù)邏輯和老系統(tǒng)接口保持一致、底層圖數(shù)據(jù)庫(kù)改為查詢Nebula

              
              @Override
              public MSubGraphReceive getSubGraph(MSubGraphSend subGraphSend) {
                  logger.info("-----start getSubGraph------(" + subGraphSend.toString() + ")");
                  long start = System.currentTimeMillis();
                  //1. 請(qǐng)求灰度
                  boolean hit = grayService.hit(HashUtils.getHashCode(subGraphSend));
                  MSubGraphReceive r;
                  if (hit) {
                      //2、命中灰度 走新流程
                      r = newCoreService.getSubGraph(subGraphSend); // 使用Dubbo調(diào)用新服務(wù)
                  } else {
                      //這里是原來(lái)的流程 使用的akka通信
                      r = (MSubGraphReceive) akkaClient.sendMessage(subGraphSend, 30);
                  }
                  long requestTime = System.currentTimeMillis() - start;

                  //3.采樣命中了發(fā)送數(shù)據(jù)對(duì)比MQ 
                  if (grayService.hitSample(MethodKeyEnum.getSubGraph_subGraphSend)) {
                      MessageRequestDTO requestDTO = new MessageRequestDTO.Builder()
                              .req(JSON.toJSONString(subGraphSend))
                              .res(JSON.toJSONString(r))
                              .requestTime(requestTime)
                              .methodKey(MethodKeyEnum.getSubGraph_subGraphSend)
                              .isGray(hit).build();
                      grayService.sendReqMsg(requestDTO);
                  }
                  logger.info("-----end getSubGraph: {} ms", requestTime);
                  return r;
              }

          9、項(xiàng)目排期計(jì)劃

          投入人力: 開(kāi)發(fā)4人,測(cè)試1人

          主要事項(xiàng)及耗時(shí)如下:

          方案設(shè)計(jì)階段 開(kāi)發(fā)階段 測(cè)試階段 灰度階段
          1、流程梳理
          2、畫(huà)流程圖、整理架構(gòu)圖
          3、方案設(shè)計(jì)
          1、新服務(wù)項(xiàng)目搭建,Nebula操作類ORM框架封裝
          2、接口改造(10多個(gè)接口改造)
          3、MQ消費(fèi)改造
          4、數(shù)據(jù)對(duì)比工具開(kāi)發(fā)(含企微通知)
          5、數(shù)據(jù)遷移腳本開(kāi)發(fā)
          6、接口聯(lián)調(diào)
          7、代碼組內(nèi)CR
          1、功能測(cè)試
          2、數(shù)據(jù)對(duì)比
          3、100%流量老系統(tǒng)回歸測(cè)試
          4、100%流量新系統(tǒng)回歸測(cè)試
          5、生產(chǎn)數(shù)據(jù)遷移

          1、分7個(gè)階段灰度,平滑過(guò)渡
          2、生產(chǎn)數(shù)據(jù)實(shí)時(shí)對(duì)比
          3、監(jiān)控&報(bào)警設(shè)施完善(這個(gè)在壓測(cè)之前完成,方案壓測(cè)的時(shí)候觀測(cè)指標(biāo))
          4、壓測(cè)(10%流量壓測(cè))
          5、數(shù)據(jù)備份與恢復(fù)演練(采用nebula快照備份)、擴(kuò)容演練
          耗時(shí)1周 耗時(shí)3周 耗時(shí)2周

          10、所需資源

          3臺(tái)Nebula機(jī)器 ,配置: 8核64G,2T SSD硬盤(pán)

          6臺(tái)docker服務(wù),配置: 2核4G

          四、重構(gòu)收益

          經(jīng)過(guò)團(tuán)隊(duì)2個(gè)月奮斗,目前已完成灰度階段,收益如下

          1、Nebula本身支持分布式擴(kuò)展,新系統(tǒng)服務(wù)支持彈性伸縮,整體支持性能水平擴(kuò)展

          2、從壓測(cè)結(jié)果看,接口性能提升很明顯,可支撐請(qǐng)求遠(yuǎn)超預(yù)期

          3、接入公司統(tǒng)一監(jiān)控、告警,更利于后期維護(hù)

          五、總結(jié)

          本次重構(gòu)順利完成,感謝本次一起重構(gòu)的小伙伴,以及大數(shù)據(jù)、風(fēng)控同學(xué)支持,同時(shí)也感謝Nebula社區(qū)(https://discuss.nebula-graph.com.cn/) ,我們遇到一些問(wèn)題提問(wèn),也很快幫忙解答。

          歡迎關(guān)注微信公眾號(hào)“淺談架構(gòu)”,不定期分享原創(chuàng)技術(shù)文章。

          9579a483c5c0af7a3b6c2065b53348c4.webp


          瀏覽 59
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  欧美午夜在线观看 | 人人操人人干超碰 | 国际精品久久 | 丝袜脚交一区二区三区 | 逼特逼视频网址大全免费观看 |