自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

真實(shí)線上DB存儲(chǔ)架構(gòu)升級(jí)實(shí)戰(zhàn)!

開發(fā) 架構(gòu)
本文介紹了一個(gè)線上交易系統(tǒng)從單庫單表架構(gòu)升級(jí)為多庫多表過程中,如何實(shí)現(xiàn)不停服平滑遷移的方案,同時(shí)在整個(gè)遷移過程中實(shí)現(xiàn)了可觀測(cè)、可回滾。

前言

交易系統(tǒng)1.0的存儲(chǔ)架構(gòu)采用了單庫單表,隨著業(yè)務(wù)快速發(fā)展,訂單量從日單量十萬級(jí)別快速增長到日單量百萬級(jí)別,預(yù)計(jì)在未來兩三個(gè)月就存儲(chǔ)就會(huì)出現(xiàn)瓶頸,DB存儲(chǔ)架構(gòu)升級(jí)迫在眉睫。

交易系統(tǒng)如何做到平滑遷移?

由于面對(duì)業(yè)務(wù)場景是交易系統(tǒng),即使是業(yè)務(wù)低峰期,業(yè)務(wù)也無法接受臨時(shí)停服,基于此背景下,設(shè)計(jì)了如下一套不停服下的數(shù)據(jù)平滑遷移工具。

平滑遷移流程設(shè)計(jì)

由于面對(duì)的業(yè)務(wù)場景是交易系統(tǒng),即使是業(yè)務(wù)低峰期,依舊有交易在不斷產(chǎn)生,所以對(duì)于線上DB停寫從業(yè)務(wù)角度是不能接受的,同時(shí)如何實(shí)現(xiàn)新舊數(shù)據(jù)源的靈活切換、切換前的充分驗(yàn)證及觀測(cè),以及切換后如果出現(xiàn)問題如何快速回滾,基于這些問題設(shè)計(jì)了一套雙寫雙讀流程。

切換前充分驗(yàn)證和可觀測(cè)性: 在整個(gè)切換過程中的關(guān)鍵環(huán)節(jié)都增加監(jiān)控?cái)?shù)據(jù)埋點(diǎn)上報(bào),從而實(shí)現(xiàn)整個(gè)操作過程的可觀測(cè),也保證了在每一個(gè)環(huán)境切換前的充分驗(yàn)證。

動(dòng)態(tài)配置下發(fā): 將切換過程中需要調(diào)整的參數(shù)全部寫入動(dòng)態(tài)配置中心(比如Nacos),并為每個(gè)動(dòng)態(tài)下發(fā)參數(shù)設(shè)計(jì)灰度放量的過程,比如基于用戶尾號(hào)放量、基于租戶維度放量等,保證在切換過程中的影響范圍做到可控。

具體操作流程如下:

a). 對(duì)業(yè)務(wù)代碼進(jìn)行改造上線,使得具備雙寫讀舊數(shù)據(jù)源的能力,通過Grafana監(jiān)控讀寫曲線及異常監(jiān)控等指標(biāo)。

b). 通過離線任務(wù)或者DBA提供的數(shù)據(jù)同步組件,將舊數(shù)據(jù)源的數(shù)據(jù)開始全量同步。

c). 待全量數(shù)據(jù)同步完成后,通過動(dòng)態(tài)配置中心開始逐步放量,將雙寫讀舊數(shù)據(jù)源切換到雙寫讀新數(shù)據(jù)源,同時(shí)通過Grafana監(jiān)控讀寫曲線及異常監(jiān)控等指標(biāo).

d). 灰度一段時(shí)間后,若未發(fā)現(xiàn)異常時(shí),在通過動(dòng)態(tài)配置中心逐步灰度切換到單寫讀新數(shù)據(jù)源,最后下線舊數(shù)據(jù)源。在第3、4步驟切換過程中一旦發(fā)現(xiàn)問題立刻對(duì)動(dòng)態(tài)配置進(jìn)行回滾。

圖片圖片

切流組件實(shí)現(xiàn)

平滑切流組件的執(zhí)行流程圖如下圖所示:

圖片圖片

對(duì)應(yīng)的核心執(zhí)行代碼如下:

public T call() {
    try {
        // 1. 灰度開關(guān)關(guān)閉,走老邏輯
        if (Objects.isNull(shardConfig)) {
            return oldCall.call();
        }
        
        Callable<T> mainCall = oldCall;
        Callable<T> subCall = newCall;
        // 2. 業(yè)務(wù)是否使用新數(shù)據(jù)源數(shù)據(jù)返回的結(jié)果
        if (shardConfig.isUseNewResult()) {
            mainCall = newCall;
            subCall = oldCall;
        }
        
        // 未命中灰度,則直接返回主邏輯結(jié)果
        if (!isGray()) {
            return result;
        }

        // 是否開啟異步數(shù)據(jù)對(duì)比旁路邏輯
        if (shardConfig.isAsync()) {
            Callable<T> finalSubCall = subCall;
            Thread thread = new Thread(() -> {
                process(finalSubCall, result);
            });
            EXECUTOR_SERVICE.submit(thread);
        } else {
            // 同步鏈路數(shù)據(jù)對(duì)比
            process(subCall, result);
        }

        return result;
    } catch (Exception e) {
        throw new RuntimeException("call error");
    }  
}

/**
 * 對(duì)新邏輯返回的結(jié)果和舊邏輯返回的數(shù)據(jù)進(jìn)行對(duì)比
 * @param subCall 子邏輯結(jié)果
 * @param result 主邏輯結(jié)果
 */
private void process(Callable<T> subCall, T result){
    // TODO 對(duì)新邏輯返回的結(jié)果和舊邏輯返回的數(shù)據(jù)進(jìn)行對(duì)比
    try {
        T subReuslt = subCall.call();
        boolean isSame = shardComparator.compare(result, subReuslt);
        if (!isSame) {
            // TODO 上報(bào)對(duì)比異常監(jiān)控
            PerfHelper.report("methodName", methodName);
        }
    } catch (Exception e) {
        LOGGER.error("compare exception");
    }
}

private boolean isGray() {
    // TODO 業(yè)務(wù)灰度規(guī)則
    return true;
}

交易系統(tǒng)平滑遷移過程中的數(shù)據(jù)一致性如何保證?

圖片圖片

用戶下單后需要冗余三個(gè)視角維度的數(shù)據(jù),對(duì)于C端用戶視角的數(shù)據(jù)一致性,采用雙寫+binlog補(bǔ)償+定時(shí)任務(wù)兜底;對(duì)于B端商家視角的數(shù)據(jù)一致性,使用雙寫+binlog補(bǔ)償+定時(shí)任務(wù)兜底+數(shù)據(jù)回源四種手段保證數(shù)據(jù)一致性。最后通過數(shù)據(jù)流對(duì)賬+可視化監(jiān)控來實(shí)時(shí)觀測(cè)數(shù)據(jù)不一致的情況,并對(duì)異常數(shù)據(jù)進(jìn)行手動(dòng)修復(fù)。

遇到的一些坑

下單鏈路代碼不合理

從單庫單表切換到分庫分表后,通過監(jiān)控發(fā)現(xiàn)讀新數(shù)據(jù)源數(shù)據(jù)對(duì)比錯(cuò)誤量放大,原因是原來的下單鏈路存在:更新完DB后立馬查詢,由于主從數(shù)據(jù)同步還未完成導(dǎo)致無法查詢到最新數(shù)據(jù)。

解決思路: 調(diào)整業(yè)務(wù)邏輯

數(shù)據(jù)對(duì)比采用線程池進(jìn)行異步對(duì)比導(dǎo)致監(jiān)控異常

起初使用線程池進(jìn)行異步對(duì)比,是為了盡量不影響主鏈路耗時(shí),但由于線程池使用姿勢(shì)不太合理,導(dǎo)致實(shí)際發(fā)生比對(duì)時(shí)新舊數(shù)據(jù)源已經(jīng)不一致,其根本原因是由于異步延遲執(zhí)行導(dǎo)致。

解決思路: 1. 數(shù)據(jù)對(duì)比改為同步執(zhí)行,主鏈路耗時(shí)無明顯劣化,業(yè)務(wù)可接受;2. 動(dòng)態(tài)調(diào)整線程池參數(shù),使得異步任務(wù)執(zhí)行更快處理(該方法嘗試后,發(fā)現(xiàn)錯(cuò)誤量有所下降,但未完全消除。

后續(xù)

本文介紹了一個(gè)線上交易系統(tǒng)從單庫單表架構(gòu)升級(jí)為多庫多表過程中,如何實(shí)現(xiàn)不停服平滑遷移的方案,同時(shí)在整個(gè)遷移過程中實(shí)現(xiàn)了可觀測(cè)、可回滾。

隨著訂單量持續(xù)增長,后續(xù)B端商家側(cè)的數(shù)據(jù)逐漸出現(xiàn)了數(shù)據(jù)傾斜、大賬單等問題,后續(xù)有機(jī)會(huì)再介紹這些問題的解決思路和治理方案。

責(zé)任編輯:武曉燕 來源: 程序反思錄
相關(guān)推薦

2024-06-21 09:37:57

2012-11-09 10:48:49

VDIvSphere

2018-02-23 14:24:15

集群

2022-06-13 14:58:19

系統(tǒng)案例

2017-08-18 22:40:33

線上線程備份

2023-12-11 06:27:39

MySQL線上業(yè)務(wù)優(yōu)化后臺(tái)上傳文件

2021-07-04 22:29:12

MySQL死鎖云日志

2018-05-09 10:59:55

軟件定義存儲(chǔ)

2010-06-18 15:43:21

Exchange 20

2025-03-10 00:45:00

2018-08-21 09:22:46

58速運(yùn)架構(gòu)DB

2014-07-26 16:37:20

WOT2014

2023-02-18 18:26:11

隨著信息大爆炸,企業(yè)

2023-07-26 15:46:52

Docker管理容器

2010-11-03 10:35:45

DB2存儲(chǔ)過程

2009-02-12 10:06:14

XIV集群存儲(chǔ)IBM DS 8000SVC

2017-08-19 23:21:14

線上CPU定位

2023-12-08 13:23:00

大數(shù)據(jù)MySQL存儲(chǔ)

2018-02-10 09:59:51

Java網(wǎng)絡(luò)IO模型

2018-06-22 09:00:29

軟件定義存儲(chǔ)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)