91网首页-91网页版-91网在线观看-91网站免费观看-91网站永久视频-91网站在线播放

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

面試官問(wèn)單表數(shù)據(jù)量大一定要分庫(kù)分表嗎?我們用六個(gè)字和十張圖回答

admin
2023年5月19日 11:30 本文熱度 1770

1 文章概述

在業(yè)務(wù)發(fā)展初期單表完全可以滿足業(yè)務(wù)需求,在阿里巴巴開(kāi)發(fā)手冊(cè)也建議:?jiǎn)伪硇袛?shù)超過(guò)500萬(wàn)行或者單表容量超過(guò)2GB才推薦進(jìn)行分庫(kù)分表,如果預(yù)計(jì)三年后數(shù)據(jù)量根本達(dá)不到這個(gè)級(jí)別,請(qǐng)不要在創(chuàng)建表時(shí)就分庫(kù)分表。

但是隨著業(yè)務(wù)的發(fā)展和深入,單表數(shù)據(jù)量不斷增加,逐漸成為業(yè)務(wù)系統(tǒng)的瓶頸。這是為什么呢?

從宏觀層面分析任何物體都必然有其物理極限。1965年英特爾創(chuàng)始人摩爾預(yù)測(cè):集成電路上可容納的元器件的數(shù)目,約每隔24個(gè)月增加一倍,性能提升一倍,即計(jì)算機(jī)性能每?jī)赡攴环?/p>

但是摩爾定律會(huì)有終點(diǎn)嗎?有些科學(xué)家認(rèn)為摩爾定律是有終點(diǎn)的:半導(dǎo)體芯片單位面積可集成的元件數(shù)量是有極限的,因?yàn)榘雽?dǎo)體芯片制程工藝的物理極限為2到3納米。當(dāng)然也有科學(xué)家不支持這種說(shuō)法,但是我們可以從中看出物理極限是很難突破的,當(dāng)單表數(shù)據(jù)量達(dá)到一定規(guī)模時(shí)必然也達(dá)到極限。

從細(xì)節(jié)層面分析我們將數(shù)據(jù)保存在數(shù)據(jù)庫(kù),實(shí)際上是保存在磁盤(pán)中,一次磁盤(pán)IO操作需要經(jīng)歷尋道、旋轉(zhuǎn)延時(shí)、數(shù)據(jù)傳輸三個(gè)步驟,那么一次磁盤(pán)IO耗時(shí)公式如下:

單次IO時(shí)間 = 尋道時(shí)間 + 旋轉(zhuǎn)延遲 + 傳送時(shí)間

總體來(lái)說(shuō)上述操作都較為耗時(shí),速度和內(nèi)存相比有著數(shù)量級(jí)的差距,當(dāng)數(shù)據(jù)量過(guò)大磁盤(pán)這一瓶頸更加明顯。那么應(yīng)該怎么辦?處理單表數(shù)據(jù)量過(guò)大有以下六字口訣:刪、換、分、拆、異、熱。


刪是指刪除歷史數(shù)據(jù)并進(jìn)行歸檔。換是指不要只使用數(shù)據(jù)庫(kù)資源,有些數(shù)據(jù)可以存儲(chǔ)至其它替代資源。分是指讀寫(xiě)分離,增加多個(gè)讀實(shí)例應(yīng)對(duì)讀多寫(xiě)少的互聯(lián)網(wǎng)場(chǎng)景。拆是指分庫(kù)分表,將數(shù)據(jù)分散至不同的庫(kù)表中減輕壓力。異指數(shù)據(jù)異構(gòu),將一份數(shù)據(jù)根據(jù)不同業(yè)務(wù)需求保存多份。熱是指熱點(diǎn)數(shù)據(jù),這是一個(gè)非常值得注意的問(wèn)題。


2 刪

我們分析這樣一個(gè)場(chǎng)景:消費(fèi)者會(huì)經(jīng)常查詢(xún)一年之前的訂單記錄嗎?答案是一般不會(huì),或者說(shuō)這種查詢(xún)需求量很小。

根據(jù)上述分析那么一年前的數(shù)據(jù)我們就沒(méi)有必要放在單表這張業(yè)務(wù)主表,可以將一年前的數(shù)據(jù)遷移到歷史歸檔表。

在查詢(xún)歷史數(shù)據(jù)表時(shí),可以限制查詢(xún)條件如必須選擇日期范圍,日期范圍不能超過(guò)X個(gè)月等等從而減輕查詢(xún)壓力。

處理歷史存量數(shù)據(jù)比較簡(jiǎn)單,因?yàn)榇媪繑?shù)據(jù)一般是靜態(tài)的,此時(shí)狀態(tài)已經(jīng)不再改變了。數(shù)據(jù)處理一般分為以下兩個(gè)步驟:

(1) 遷移一年前數(shù)據(jù)至歷史歸檔表
(2) 根據(jù)主鍵分批刪除主表數(shù)據(jù)

不能一次性刪除所有數(shù)據(jù),因?yàn)閿?shù)據(jù)量太大可能會(huì)引發(fā)超時(shí),而是應(yīng)該根據(jù)ID分批刪除,例如每次刪除500條數(shù)據(jù)。

第一步查詢(xún)一年前主鍵最大值和最小值,這是我們需要?jiǎng)h除的數(shù)據(jù)范圍:

select
MIN(idAS minId, 
MAX(idAS maxId 
from biz_table 
where create_time < DATE_SUB(now(),INTERVAL 1 YEAR)

第二步刪除數(shù)據(jù)時(shí)不能一次性全部刪掉,因?yàn)楹芸赡軙?huì)超時(shí),我們可以通過(guò)代碼動(dòng)態(tài)更新endId進(jìn)行批量刪除:

delete from biz_table 
where id >= #{minId}
AND id <= #{maxId}
AND id <= #{endId}
LIMIT 500


3 換

換是指換一個(gè)存儲(chǔ)介質(zhì),當(dāng)然并不是說(shuō)完全替換,而是用其它存儲(chǔ)介質(zhì)對(duì)數(shù)據(jù)庫(kù)做一個(gè)補(bǔ)充。例如海量流水記錄,這類(lèi)數(shù)據(jù)量級(jí)是巨量的,根本不適合存儲(chǔ)在MySQL數(shù)據(jù)庫(kù)中,那么這些數(shù)據(jù)可以存在哪里呢?

現(xiàn)在互聯(lián)網(wǎng)公司一般都具備與之規(guī)模相對(duì)應(yīng)的大數(shù)據(jù)服務(wù)或者平臺(tái),那么作為業(yè)務(wù)開(kāi)發(fā)者要善于應(yīng)用公司大數(shù)據(jù)能力,減輕業(yè)務(wù)數(shù)據(jù)庫(kù)壓力。


3.1 消息隊(duì)列

這些海量數(shù)據(jù)可以存儲(chǔ)至Kafka,因?yàn)槠浔举|(zhì)上就是分布式的流數(shù)據(jù)存儲(chǔ)系統(tǒng)。使用Kafka有如下優(yōu)點(diǎn):

第一個(gè)優(yōu)點(diǎn)是Kafka社區(qū)活躍功能強(qiáng)大,已經(jīng)成為了一種事實(shí)上的工業(yè)標(biāo)準(zhǔn)。大數(shù)據(jù)很多組件都提供了Kafka接入組件,經(jīng)過(guò)生產(chǎn)驗(yàn)證并且對(duì)接成本較小,可以為下游業(yè)務(wù)提供更多選擇。

第二個(gè)優(yōu)點(diǎn)是Kafka具有消息隊(duì)列本身的優(yōu)點(diǎn)例如解耦、異步和削峰。



假設(shè)這些海量數(shù)據(jù)都已經(jīng)存儲(chǔ)在Kafka,現(xiàn)在我們希望這些數(shù)據(jù)可以產(chǎn)生業(yè)務(wù)價(jià)值,這涉及到兩種數(shù)據(jù)分析任務(wù):離線任務(wù)和實(shí)時(shí)任務(wù)。

離線任務(wù)對(duì)實(shí)時(shí)性要求不高,例如每天、每周、每月的數(shù)據(jù)報(bào)表統(tǒng)計(jì)分析,我們可以使用基于MapReduce數(shù)據(jù)倉(cāng)庫(kù)工具Hive進(jìn)行報(bào)表統(tǒng)計(jì)。

實(shí)時(shí)任務(wù)對(duì)實(shí)時(shí)性要求高,例如根據(jù)用戶(hù)相關(guān)行為推薦用戶(hù)感興趣的商品,提高用戶(hù)購(gòu)買(mǎi)體驗(yàn)和效率,可以使用Flink進(jìn)行流處理分析。例如運(yùn)營(yíng)后臺(tái)查詢(xún)分析,可以將數(shù)據(jù)同步至ES進(jìn)行檢索。

還有一種分類(lèi)方式是將任務(wù)分為批處理任務(wù)和流處理任務(wù),我們可以這么理解:離線任務(wù)一般使用批處理技術(shù),實(shí)時(shí)任務(wù)一般使用流處理技術(shù)。


3.2 API

上一個(gè)章節(jié)我們使用了Kafka進(jìn)行海量數(shù)據(jù)存儲(chǔ),由于其強(qiáng)大兼容性和集成度,可以作為數(shù)據(jù)中介將數(shù)據(jù)進(jìn)行中轉(zhuǎn)和解耦。

當(dāng)然我們并不是必須使用Kafka進(jìn)行中轉(zhuǎn),例如我們直接可以使用相關(guān)Java API將數(shù)據(jù)存入Hive、ES、HBASE等。

但是我并不推薦這種做法,因?yàn)閷⒈4媪魉@樣操作耦合進(jìn)業(yè)務(wù)代碼并不合適,違反了高內(nèi)聚低耦合的原則,盡量不要使用。


3.3 緩存

從廣義上理解換這個(gè)字,我們還可以引入Redis遠(yuǎn)程緩存,把Redis放在MySQL前面,攔下一些高頻讀請(qǐng)求,但是要注意緩存穿透和擊穿問(wèn)題。

緩存穿透和擊穿從最終結(jié)果上來(lái)說(shuō)都是流量繞過(guò)緩存打到了數(shù)據(jù)庫(kù),可能會(huì)導(dǎo)致數(shù)據(jù)庫(kù)掛掉或者系統(tǒng)雪崩,但是仔細(xì)區(qū)分還是有一些不同,我們分析一張業(yè)務(wù)讀取緩存流程圖。



我們用文字簡(jiǎn)要描述這張圖:

(1) 業(yè)務(wù)查詢(xún)數(shù)據(jù)時(shí)首先查詢(xún)緩存,如果緩存存在數(shù)據(jù)則返回,流程結(jié)束

(2) 如果緩存不存在數(shù)據(jù)則查詢(xún)數(shù)據(jù)庫(kù),如果數(shù)據(jù)庫(kù)不存在數(shù)據(jù)則返回空數(shù)據(jù),流程結(jié)束

(3) 如果數(shù)據(jù)庫(kù)存在數(shù)據(jù)則將數(shù)據(jù)寫(xiě)入緩存并返回?cái)?shù)據(jù)給業(yè)務(wù),流程結(jié)束

假設(shè)業(yè)務(wù)方要查詢(xún)A數(shù)據(jù),緩存穿透是指數(shù)據(jù)庫(kù)根本不存在A數(shù)據(jù),所以根本沒(méi)有數(shù)據(jù)可以寫(xiě)入緩存,導(dǎo)致緩存層失去意義,大量請(qǐng)求會(huì)頻繁訪問(wèn)數(shù)據(jù)庫(kù)。

緩存擊穿是指請(qǐng)求在查詢(xún)數(shù)據(jù)庫(kù)前,首先查緩存看看是否存在,這是沒(méi)有問(wèn)題的。但是并發(fā)量太大,導(dǎo)致第一個(gè)請(qǐng)求還沒(méi)有來(lái)得及將數(shù)據(jù)寫(xiě)入緩存,后續(xù)大量請(qǐng)求已經(jīng)開(kāi)始訪問(wèn)緩存,這是數(shù)據(jù)在緩存中還是不存在的,所以瞬時(shí)大量請(qǐng)求會(huì)打到數(shù)據(jù)庫(kù)。

我們可以使用分布式鎖加上自旋解決這個(gè)問(wèn)題,本文給出一段示例代碼,具體原理請(qǐng)參看我之前的一篇文章:緩存穿透與擊穿問(wèn)題解決方案

/**
 * 業(yè)務(wù)回調(diào)
 *
 * @author 微信公眾號(hào)「JAVA前線」
 *
 */

public interface RedisBizCall {

    /**
     * 業(yè)務(wù)回調(diào)方法
     *
     * @return 序列化后數(shù)據(jù)值
     */

    String call();
}

/**
 * 安全緩存管理器
 *
 * @author 微信公眾號(hào)「JAVA前線」
 *
 */

@Service
public class SafeRedisManager {
    @Resource
    private RedisClient RedisClient;
    @Resource
    private RedisLockManager redisLockManager;

    public String getDataSafe(String key, int lockExpireSeconds, int dataExpireSeconds, RedisBizCall bizCall, boolean alwaysRetry) {
        boolean getLockSuccess = false;
        try {
            while(true) {
                String value = redisClient.get(key);
                if (StringUtils.isNotEmpty(value)) {
                    return value;
                }
                /** 競(jìng)爭(zhēng)分布式鎖 **/
                if (getLockSuccess = redisLockManager.tryLock(key, lockExpireSeconds)) {
                    value = redisClient.get(key);
                    if (StringUtils.isNotEmpty(value)) {
                        return value;
                    }
                    /** 查詢(xún)數(shù)據(jù)庫(kù) **/
                    value = bizCall.call();

                    /** 數(shù)據(jù)庫(kù)無(wú)數(shù)據(jù)則返回**/
                    if (StringUtils.isEmpty(value)) {
                        return null;
                    }

                    /** 數(shù)據(jù)存入緩存 **/
                    redisClient.setex(key, dataExpireSeconds, value);
                    return value;
                } else {
                    if (!alwaysRetry) {
                        logger.warn("競(jìng)爭(zhēng)分布式鎖失敗,key={}", key);
                        return null;
                    }
                    Thread.sleep(100L);
                    logger.warn("嘗試重新獲取數(shù)據(jù),key={}", key);
                }
            }
        } catch (Exception ex) {
            logger.error("getDistributeSafeError", ex);
            return null;
        } finally {
            if (getLockSuccess) {
                redisLockManager.unLock(key);
            }
        }
    }
}


4 分

我們首先看一個(gè)概念:讀寫(xiě)比。互聯(lián)網(wǎng)場(chǎng)景中一般是讀多寫(xiě)少,例如瀏覽20次訂單列表信息才會(huì)進(jìn)行1次確認(rèn)收貨,此時(shí)讀寫(xiě)比例就是20:1。面對(duì)讀多寫(xiě)少這種情況我們可以做什么呢?

我們可以部署多臺(tái)MySQL讀庫(kù)專(zhuān)門(mén)用來(lái)接收讀請(qǐng)求,主庫(kù)接收寫(xiě)請(qǐng)求并通過(guò)binlog實(shí)時(shí)同步的方式將數(shù)據(jù)同步至讀庫(kù)。MySQL官方即提供這種能力,進(jìn)行簡(jiǎn)單配置即可。



那么客戶(hù)端怎么知道訪問(wèn)讀庫(kù)還是寫(xiě)庫(kù)呢?推薦使用ShardingSphere組件,通過(guò)配置將讀寫(xiě)請(qǐng)求分別路由至讀庫(kù)或者寫(xiě)庫(kù)。


5 拆

如果刪除了歷史數(shù)據(jù)并采用了其它存儲(chǔ)介質(zhì),也用了讀寫(xiě)分離,但是單表壓力還是太大怎么辦?這時(shí)我們只能拆分?jǐn)?shù)據(jù)表,即把單庫(kù)單表數(shù)據(jù)遷移到多庫(kù)多張表中。

假設(shè)有一個(gè)電商數(shù)據(jù)庫(kù)存放訂單、商品、支付三張業(yè)務(wù)表。隨著業(yè)務(wù)量越來(lái)越大,這三張業(yè)務(wù)數(shù)據(jù)表也越來(lái)越大,我們就以這個(gè)例子進(jìn)行分析。


5.1 垂直拆分

垂直拆分就是按照業(yè)務(wù)拆分,我們將電商數(shù)據(jù)庫(kù)拆分成三個(gè)庫(kù),訂單庫(kù)、商品庫(kù)。支付庫(kù),訂單表在訂單庫(kù),商品表在商品庫(kù),支付表在支付庫(kù)。這樣每個(gè)庫(kù)只需要存儲(chǔ)本業(yè)務(wù)數(shù)據(jù),物理隔離不會(huì)互相影響。


5.2 水平拆分

按照垂直拆分方案,現(xiàn)在我們已經(jīng)有三個(gè)庫(kù)了,平穩(wěn)運(yùn)行了一段時(shí)間。但是隨著業(yè)務(wù)增長(zhǎng),每個(gè)單庫(kù)單表的數(shù)據(jù)量也越來(lái)越大,逐漸到達(dá)瓶頸。

這時(shí)我們就要對(duì)數(shù)據(jù)表進(jìn)行水平拆分,所謂水平拆分就是根據(jù)某種規(guī)則將單庫(kù)單表數(shù)據(jù)分散到多庫(kù)多表,從而減小單庫(kù)單表的壓力。

水平拆分策略有很多方案,最重要的一點(diǎn)是選好ShardingKey,也就是按照哪一列進(jìn)行拆分,怎么分取決于我們?cè)L問(wèn)數(shù)據(jù)的方式。


5.2.1 范圍分片

現(xiàn)在我們要對(duì)訂單庫(kù)進(jìn)行水平拆分,我們選擇的ShardingKey是訂單創(chuàng)建時(shí)間,拆分策略如下:

(1) 拆分為四個(gè)數(shù)據(jù)庫(kù),分別存儲(chǔ)每個(gè)季度的數(shù)據(jù)
(2) 每個(gè)庫(kù)三張表,分別存儲(chǔ)每個(gè)月的數(shù)據(jù)

上述方法優(yōu)點(diǎn)是對(duì)范圍查詢(xún)比較友好,例如我們需要統(tǒng)計(jì)第一季度的相關(guān)數(shù)據(jù),查詢(xún)條件直接輸入時(shí)間范圍即可。



但是這個(gè)方案問(wèn)題是容易產(chǎn)生熱點(diǎn)數(shù)據(jù)。例如雙11當(dāng)天下單量特別大,就會(huì)導(dǎo)致11月這張表數(shù)據(jù)量特別大從而造成訪問(wèn)壓力。


5.2.2 查表分片

查表法是根據(jù)一張路由表決定ShardingKey路由到哪一張表,每次路由時(shí)首先到路由表里查到分片信息,再到這個(gè)分片去取數(shù)據(jù)。

們分析一個(gè)查表法實(shí)際案例。Redis官方在3.0版本之后提供了集群方案Redis Cluster,其中引入了哈希槽(slot)這個(gè)概念。

一個(gè)集群固定有16384個(gè)槽,在集群初始化時(shí)這些槽會(huì)平均分配到Redis集群節(jié)點(diǎn)上。每個(gè)key請(qǐng)求最終落到哪個(gè)槽計(jì)算公式是固定的:

SLOT = CRC16(key) mod 16384

那么問(wèn)題來(lái)了:一個(gè)key請(qǐng)求過(guò)來(lái)怎么知道去哪臺(tái)Redis節(jié)點(diǎn)獲取數(shù)據(jù)?這就要用到查表法思想。

(1) 客戶(hù)端連接任意一臺(tái)Redis節(jié)點(diǎn),假設(shè)隨機(jī)訪問(wèn)到為節(jié)點(diǎn)A

(2) 節(jié)點(diǎn)A根據(jù)key計(jì)算出slot值

(3) 每個(gè)節(jié)點(diǎn)都維護(hù)著slot和節(jié)點(diǎn)映射關(guān)系表

(4) 如果節(jié)點(diǎn)A查表發(fā)現(xiàn)該slot在本節(jié)點(diǎn)則直接返回?cái)?shù)據(jù)給客戶(hù)端

(5) 如果節(jié)點(diǎn)A查表發(fā)現(xiàn)該slot不在本節(jié)點(diǎn)則返回給客戶(hù)端一個(gè)重定向命令,告訴客戶(hù)端應(yīng)該去哪個(gè)節(jié)點(diǎn)上請(qǐng)求這個(gè)key的數(shù)據(jù)

(6) 客戶(hù)端再向正確節(jié)點(diǎn)發(fā)起連接請(qǐng)求

查表法優(yōu)點(diǎn)是可以靈活制定路由策略,如果我們發(fā)現(xiàn)有的分片已經(jīng)成為熱點(diǎn)則修改路由策略。缺點(diǎn)是多一次查詢(xún)路由表操作增加耗時(shí),而且路由表如果是單點(diǎn)也可能會(huì)有單點(diǎn)問(wèn)題。


5.2.3 哈希分片

現(xiàn)在比較流行的分片方法是哈希分片,相較于范圍分片,哈希分片可以較為均勻?qū)?shù)據(jù)分散在數(shù)據(jù)庫(kù)中。我們現(xiàn)在將訂單庫(kù)拆分為4個(gè)庫(kù)編號(hào)為[0,3],每個(gè)庫(kù)4張表編號(hào)為[0,3],如下圖如所示:



我們現(xiàn)在使用orderId作為ShardingKey,那么orderId=100的訂單會(huì)保存在哪張表?我們來(lái)計(jì)算一下:由于是分庫(kù)分表,首先確定路由到哪一個(gè)庫(kù),取模計(jì)算得到序號(hào)為0表示路由到db[0]

db_index = 100 % 4 = 0

庫(kù)確定了接著在db[0]進(jìn)行取模表路由

table_index = 100 % 4 = 0

最終這條數(shù)據(jù)應(yīng)該路由至下表

db[0]_table[0]

最終計(jì)算結(jié)果如下圖所示:


在實(shí)際開(kāi)發(fā)中最終路由到哪張表,并不需要我們自己算,因?yàn)橛性S多開(kāi)源框架就可以完成路由功能,例如ShardingSphere、TDDL等等。



6 異

現(xiàn)在數(shù)據(jù)已經(jīng)使用哈希分片方法完成了水平拆分,我們選擇的ShardingKey是orderId。這時(shí)客戶(hù)端需要查詢(xún)orderId=111的數(shù)據(jù),查詢(xún)語(yǔ)句很簡(jiǎn)單如下:

select * from order where orderId = 111

這個(gè)語(yǔ)句沒(méi)有問(wèn)題,因?yàn)椴樵?xún)條件包含orderId,可以路由到具體的數(shù)據(jù)表。

現(xiàn)在如果業(yè)務(wù)想要查詢(xún)用戶(hù)維度的數(shù)據(jù),希望查詢(xún)userId=222的數(shù)據(jù),現(xiàn)在問(wèn)題來(lái)了:以下這個(gè)語(yǔ)句可以查出數(shù)據(jù)嗎?

select * from order where userId = 222

答案是可以,但是需要掃描所有庫(kù)的所有表,因?yàn)闊o(wú)法根據(jù)userId路由到具體某一張表,這樣時(shí)間成本會(huì)非常高,這種場(chǎng)景怎么辦呢?

這就要用到數(shù)據(jù)異構(gòu)的思想。數(shù)據(jù)異構(gòu)核心是用空間換時(shí)間,簡(jiǎn)單一句話就是一份數(shù)據(jù)按照不同業(yè)務(wù)需求保存多份,這樣做是因?yàn)榇鎯?chǔ)硬件成本不是很高,而互聯(lián)網(wǎng)場(chǎng)景對(duì)響應(yīng)速度要求很高。

對(duì)于上述需要使用userId進(jìn)行查詢(xún)的場(chǎng)景,我們完全可以新建庫(kù)和表,數(shù)量和結(jié)構(gòu)與訂單庫(kù)表完全一致,唯一不同點(diǎn)是ShardingKey改用userId,這樣就可以使用userId查詢(xún)了。

現(xiàn)在又引出一個(gè)新問(wèn)題,業(yè)務(wù)不可能每次都將數(shù)據(jù)寫(xiě)入多個(gè)數(shù)據(jù)源,這樣會(huì)帶來(lái)性能問(wèn)題和數(shù)據(jù)一致行為。怎么解決老庫(kù)和新庫(kù)數(shù)據(jù)同步問(wèn)題?我們可以使用阿里開(kāi)源的canal組件解決這個(gè)問(wèn)題,看一張官網(wǎng)介紹canal架構(gòu)圖:


canal組件的主要用途是基于MySQL數(shù)據(jù)庫(kù)增量日志解析,提供增量數(shù)據(jù)訂閱和消費(fèi)服務(wù),工作原理如下:

(1) canal偽裝成為MySQL slave模擬交互協(xié)議向master發(fā)送dump協(xié)議

(2) master收到canal發(fā)送的dump請(qǐng)求,開(kāi)始推送binlog給canal

(3) canal解析binlog并發(fā)送到存儲(chǔ)目的地,例如MySQL、Kafka、Elasticsearch

canal組件下游可以對(duì)接很多其它數(shù)據(jù)源,這樣給業(yè)務(wù)提供了更多選擇。我們可以像上述實(shí)例中新建用戶(hù)維度訂單表,也可以將數(shù)據(jù)存在ES中提供運(yùn)營(yíng)檢索能力等等。


7 熱

我們來(lái)分析這樣一個(gè)場(chǎng)景:社交業(yè)務(wù)有一張用戶(hù)關(guān)系表,主要記錄誰(shuí)關(guān)注了誰(shuí)。其中有一個(gè)明星粉絲特別多,如果以u(píng)serId作為分片,那么其所在分片數(shù)據(jù)量就會(huì)特別大。

不僅分片數(shù)據(jù)量特別大,而且可以預(yù)見(jiàn)這個(gè)分片訪問(wèn)頻率也會(huì)非常高。此時(shí)數(shù)據(jù)量大并且訪問(wèn)頻繁,很有可能造成系統(tǒng)壓力。


7.1 熱點(diǎn)概念

我們將訪問(wèn)行為稱(chēng)為熱點(diǎn)行為,將訪問(wèn)對(duì)應(yīng)的數(shù)據(jù)稱(chēng)為熱點(diǎn)數(shù)據(jù)。我們通過(guò)實(shí)例來(lái)分析。

在電商雙11活動(dòng)中百分之八十的訪問(wèn)量會(huì)集中在百分之二十的商品上。用戶(hù)刷新、添加購(gòu)物車(chē)、下單被稱(chēng)為熱點(diǎn)行為,相應(yīng)商品數(shù)據(jù)就被稱(chēng)為熱點(diǎn)數(shù)據(jù)。

在微博場(chǎng)景中大V發(fā)布一條消息會(huì)獲得大量訪問(wèn)。用戶(hù)對(duì)這條消息的瀏覽、點(diǎn)贊、轉(zhuǎn)發(fā)、評(píng)論被稱(chēng)為熱點(diǎn)行為,這條消息數(shù)據(jù)被稱(chēng)為熱點(diǎn)數(shù)據(jù)。

在秒殺場(chǎng)景中參與秒殺的商品會(huì)獲得極大的瞬時(shí)訪問(wèn)量。用戶(hù)對(duì)這個(gè)商品的頻繁刷新、點(diǎn)擊、下單被稱(chēng)為熱點(diǎn)行為,參與秒殺的商品數(shù)據(jù)被稱(chēng)為熱點(diǎn)數(shù)據(jù)。

我們必須將熱點(diǎn)數(shù)據(jù)進(jìn)行一些處理,使得熱點(diǎn)訪問(wèn)更加流暢,更是為了保護(hù)系統(tǒng)免于崩潰。我們從發(fā)現(xiàn)熱點(diǎn)數(shù)據(jù)、處理熱點(diǎn)數(shù)據(jù)來(lái)展開(kāi)分析。


7.2 發(fā)現(xiàn)熱點(diǎn)數(shù)據(jù)

我們把發(fā)現(xiàn)熱點(diǎn)數(shù)據(jù)分為兩種方式:靜態(tài)發(fā)現(xiàn)和動(dòng)態(tài)發(fā)現(xiàn)。

靜態(tài)發(fā)現(xiàn):在開(kāi)始秒殺活動(dòng)之前,參與商家一定知道哪些商品參與秒殺,那么他們可以提前將這些商品報(bào)備告知平臺(tái)。

在微博場(chǎng)景中,具有影響力的大V一般都很知名,網(wǎng)站運(yùn)營(yíng)同學(xué)可以提前知道。技術(shù)同學(xué)還可以通過(guò)分析歷史數(shù)據(jù)找出TOP N數(shù)據(jù)。對(duì)于這些可以提前預(yù)判的數(shù)據(jù),完全可以通過(guò)后臺(tái)系統(tǒng)上報(bào),這樣系統(tǒng)可以提前做出預(yù)處理。

動(dòng)態(tài)發(fā)現(xiàn):有些商品可能并沒(méi)有上報(bào)為熱點(diǎn)商品,但是在實(shí)際銷(xiāo)售中卻非常搶手。在微博場(chǎng)景中,有些話題熱度突然升溫。這些數(shù)據(jù)成為事實(shí)上的熱點(diǎn)數(shù)據(jù)。對(duì)于這些無(wú)法提前預(yù)判的數(shù)據(jù),需要?jiǎng)討B(tài)進(jìn)行判斷。

我們需要一個(gè)熱點(diǎn)發(fā)現(xiàn)系統(tǒng)去主動(dòng)發(fā)現(xiàn)熱點(diǎn)數(shù)據(jù)。大體思路是首先異步收集訪問(wèn)日志,再統(tǒng)計(jì)單位時(shí)間內(nèi)訪問(wèn)頻次,當(dāng)超過(guò)一定閾值時(shí)可以判斷為熱點(diǎn)數(shù)據(jù)。


7.3 處理熱點(diǎn)問(wèn)題

(1) 熱點(diǎn)行為

熱點(diǎn)行為可以采取高頻檢測(cè)方式,如果發(fā)現(xiàn)頻率過(guò)高則進(jìn)行限制。或者采用內(nèi)存隊(duì)列實(shí)現(xiàn)的生產(chǎn)者與消費(fèi)者這種異步化方式,消費(fèi)者根據(jù)能力處理請(qǐng)求。

(2) 熱點(diǎn)數(shù)據(jù)

處理熱點(diǎn)數(shù)據(jù)核心主要是根據(jù)業(yè)務(wù)形態(tài)來(lái)進(jìn)行處理,我一般采用以下方案配合執(zhí)行:

(1) 選擇合適ShardingKey進(jìn)行分庫(kù)分表
 
(2) 異構(gòu)數(shù)據(jù)至其它適合檢索的數(shù)據(jù)源例如ES

(3) 在MySQL之前設(shè)置緩存層

(4) 盡量不在MySQL進(jìn)行耗時(shí)操作(例如聚合)


8 文章總結(jié)

本文我們?cè)敿?xì)介紹處理單表數(shù)據(jù)量過(guò)大的六字口訣:刪、換、分、拆、異、熱。

這并不是意味這每次遇到單表數(shù)據(jù)量過(guò)大情況六種方案全部都要使用,例如拆分?jǐn)?shù)據(jù)表成本確實(shí)比較高,會(huì)帶來(lái)分布式事務(wù)、數(shù)據(jù)難以聚合等問(wèn)題,如果不分表可以解決那么就不要分表,核心還是根據(jù)自身業(yè)務(wù)情況選擇合適的方案。



該文章在 2023/5/19 11:30:05 編輯過(guò)
關(guān)鍵字查詢(xún)
相關(guān)文章
正在查詢(xún)...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專(zhuān)業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車(chē)隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類(lèi)企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷(xiāo)售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶(hù)的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 国产在线拍揄 | 日韩欧美中 | 欧美自拍偷拍 | 欧美日韩成人免费 | 97韩剧网 | 果冻传媒视频电影 | 9I精品福利 | 九九热国产视频精品 | 福利导航视频在线 | 国产亚洲久一区二区 | 国产精品欧美一 | 91精选资源在| 日韩午夜片电影 | 91视频在 | 91香蕉小视频 | 69成人免费视频 | 国产91视频网站 | 国产卡一卡二卡三卡 | 午夜成人免费片 | 人成综合网络 | 99ri| 国产精品综合久成人 | 最新中文字幕第一页 | 日韩二三区 | 日本不卡一 | 欧美性爱二区 | 日本三级免费观看 | 日韩伦理福利免费 | 福利免费视频在线 | 精品国产第一国产 | 国产精品综合社区 | 成人深爱激情综合网 | 成人精品视频大全 | 精品热在线 | 国产在线中文 | 欧美一区二区不卡高 | 最新精品影视播放网站 | 福利小导航 | 日本vs欧| 欧美午夜在线视频 | 国产原创在线播放 |