得物熱點(diǎn)探測(cè)技術(shù)架構(gòu)設(shè)計(jì)與實(shí)踐
1、概述
說(shuō)到熱點(diǎn)問(wèn)題,首先我們先理解一下什么是熱點(diǎn)?
熱點(diǎn)通常意義來(lái)說(shuō),是指在一段時(shí)間內(nèi),被廣泛關(guān)注的物品或事件,例如微博熱搜,熱賣商品,熱點(diǎn)新聞,明星直播等等,所以熱點(diǎn)產(chǎn)生主要包含2個(gè)條件:1.有限時(shí)間, 2流量高聚。

而在互聯(lián)網(wǎng)領(lǐng)域,熱點(diǎn)又主要分為2大類:
1. 有預(yù)期的熱點(diǎn):比如在電商活動(dòng)當(dāng)中推出的爆款聯(lián)名限量款的商品,又或者是秒殺的會(huì)場(chǎng)活動(dòng)等
2. 無(wú)預(yù)期的熱點(diǎn):比如受到了,網(wǎng)絡(luò)爬蟲(chóng)頻繁訪問(wèn),又或者突發(fā)新聞帶來(lái)的流量沖擊等
針對(duì)于有預(yù)期的熱點(diǎn)可以通過(guò)熱點(diǎn)數(shù)據(jù)預(yù)熱, 流量限制和異步隊(duì)列進(jìn)行處理。但是對(duì)于突發(fā)性無(wú)感知的熱點(diǎn)數(shù)據(jù)流量,往往由于請(qǐng)求過(guò)于集中,導(dǎo)致訪問(wèn)數(shù)據(jù)流量超出的server的正常負(fù)載水位,從而出現(xiàn)服務(wù)過(guò)載不可用的情況,這種問(wèn)題被稱之為熱點(diǎn)問(wèn)題。
2、熱點(diǎn)場(chǎng)景
看完關(guān)于熱點(diǎn)問(wèn)題的簡(jiǎn)單介紹,我們已經(jīng)理解了熱點(diǎn)產(chǎn)生的條件是短時(shí)間內(nèi)被頻繁訪問(wèn)導(dǎo)致流量高聚,而流量高聚就會(huì)出現(xiàn)一系列的熱點(diǎn)問(wèn)題。那被頻繁訪問(wèn)的Key,就是我們通常所說(shuō)的熱Key。
接下來(lái)我們來(lái)看一下哪些場(chǎng)景會(huì)導(dǎo)致熱點(diǎn)問(wèn)題以及對(duì)應(yīng)的熱Key:
- MySQL中被頻繁訪問(wèn)的數(shù)據(jù) ,如熱門(mén)商品的主鍵Id
 - Redis緩存中被密集訪問(wèn)的Key,如熱門(mén)商品的詳情需要get goods$Id
 - 機(jī)器人爬蟲(chóng)的請(qǐng)求信息,如特定標(biāo)識(shí)的userId、機(jī)器IP
 - 頻繁被訪問(wèn)的接口地址,如獲取用戶信息接口 /userInfo/ + userId
 
3、熱點(diǎn)探測(cè)技術(shù)原理
了解完什么是熱點(diǎn)問(wèn)題和熱Key出現(xiàn)的場(chǎng)景以后,我們會(huì)提出一個(gè)疑問(wèn),如何去提前感知這些熱點(diǎn)數(shù)據(jù)?這里就需要聊到熱點(diǎn)探測(cè)技術(shù)。
3.1 熱點(diǎn)探測(cè)可以帶來(lái)什么好處?
3.1.1 提升性能
解決熱點(diǎn)問(wèn)題通常會(huì)使用分布式緩存,但是在讀取時(shí)還是需要進(jìn)行網(wǎng)絡(luò)通訊,就會(huì)有額外的時(shí)間開(kāi)銷。那如果能對(duì)熱點(diǎn)數(shù)據(jù)提前進(jìn)行本地緩存,即本地預(yù)熱,就能大幅提升機(jī)器讀取數(shù)據(jù)的性能,減輕下層緩存集群的壓力。
- 注意,本地緩存與實(shí)時(shí)數(shù)據(jù)存在不一致的風(fēng)險(xiǎn)。需要根據(jù)具體業(yè)務(wù)場(chǎng)景進(jìn)行評(píng)估,緩存級(jí)數(shù)越多,數(shù)據(jù)不一致的風(fēng)險(xiǎn)就越大!
 
3.1.2 規(guī)避風(fēng)險(xiǎn)
對(duì)于無(wú)預(yù)期的熱數(shù)據(jù)(即突發(fā)場(chǎng)景下形成的熱Key),可能會(huì)對(duì)業(yè)務(wù)系統(tǒng)帶來(lái)極大的風(fēng)險(xiǎn),可將風(fēng)險(xiǎn)分為兩個(gè)層次:
- 對(duì)數(shù)據(jù)層的風(fēng)險(xiǎn)
 
正常情況下,Redis 緩存單機(jī)就可支持十萬(wàn)左右 QPS,并能通過(guò)集群部署提高整體負(fù)載能力。對(duì)于并發(fā)量一般的系統(tǒng),用 Redis 做緩存就足夠了。但是對(duì)于瞬時(shí)過(guò)高并發(fā)的請(qǐng)求,因?yàn)镽edis單線程原因會(huì)導(dǎo)致正常請(qǐng)求排隊(duì),或者因?yàn)闊狳c(diǎn)集中導(dǎo)致分片集群壓力過(guò)載而癱瘓,從而擊穿到DB引起服務(wù)器雪崩。
- 對(duì)應(yīng)用服務(wù)的風(fēng)險(xiǎn)
 
每個(gè)應(yīng)用在單位時(shí)間所能接受和處理的請(qǐng)求量是有限的,如果受到惡意請(qǐng)求,讓惡意用戶獨(dú)自占用了大量請(qǐng)求處理資源,就會(huì)導(dǎo)致其他人畜無(wú)害的正常用戶的請(qǐng)求無(wú)法及時(shí)響應(yīng)。
因此,需要一套動(dòng)態(tài)熱Key 檢測(cè)機(jī)制,通過(guò)對(duì)需要檢測(cè)的熱Key規(guī)則進(jìn)行配置,實(shí)時(shí)監(jiān)聽(tīng)統(tǒng)計(jì)熱Key數(shù)據(jù),當(dāng)無(wú)預(yù)期的熱點(diǎn)數(shù)據(jù)出現(xiàn)時(shí),第一時(shí)間發(fā)現(xiàn)他,并針對(duì)這些數(shù)據(jù)進(jìn)行特殊處理。如本地緩存、拒絕惡意用戶、接口限流 / 降級(jí)等。
3.2 如何進(jìn)行熱點(diǎn)探測(cè)?
首先我們要定義一下如何才能算是一個(gè)熱點(diǎn),我們知道熱點(diǎn)產(chǎn)生的條件是2個(gè):一個(gè)時(shí)間,一個(gè)流量。那么根據(jù)這個(gè)條件我們可以簡(jiǎn)單定義一個(gè)規(guī)則:比如 1 秒內(nèi)訪問(wèn) 1000 次的數(shù)據(jù)算是熱數(shù)據(jù),當(dāng)然這個(gè)數(shù)據(jù)需要根據(jù)具體的業(yè)務(wù)場(chǎng)景和過(guò)往數(shù)據(jù)進(jìn)行具體評(píng)估。
對(duì)于單機(jī)應(yīng)用,檢測(cè)熱數(shù)據(jù)很簡(jiǎn)單,直接在本地為每個(gè)Key創(chuàng)建一個(gè)滑動(dòng)窗口計(jì)數(shù)器,統(tǒng)計(jì)單位時(shí)間內(nèi)的訪問(wèn)總數(shù)(頻率),并通過(guò)一個(gè)集合存放檢測(cè)到的熱 Key。

而對(duì)于分布式應(yīng)用,對(duì)熱 Key 的訪問(wèn)是分散在不同的機(jī)器上的,無(wú)法在本地獨(dú)立地進(jìn)行計(jì)算,因此,需要一個(gè)獨(dú)立的、集中的熱 Key 計(jì)算單元。
我們可以簡(jiǎn)單理解為:分布式應(yīng)用節(jié)點(diǎn)感知熱點(diǎn)規(guī)則配置,將熱點(diǎn)數(shù)據(jù)進(jìn)行上報(bào),工作節(jié)點(diǎn)進(jìn)行熱點(diǎn)數(shù)據(jù)統(tǒng)計(jì),對(duì)于符合閾值的熱點(diǎn)進(jìn)行推送給客戶端,應(yīng)用收到熱點(diǎn)信息進(jìn)行本地緩存等策略這五個(gè)步驟:
1. 熱點(diǎn)規(guī)則:配置熱Key的上報(bào)規(guī)則,圈出需要重點(diǎn)監(jiān)測(cè)的Key
2. 熱點(diǎn)上報(bào):應(yīng)用服務(wù)將自己的熱Key訪問(wèn)情況上報(bào)給集中計(jì)算單元
3. 熱點(diǎn)統(tǒng)計(jì):收集各應(yīng)用實(shí)例上報(bào)的信息,使用滑動(dòng)窗口算法計(jì)算Key的熱度
4. 熱點(diǎn)推送:當(dāng)Key的熱度達(dá)到設(shè)定值時(shí),推送熱Key信息至所有應(yīng)用實(shí)例
5. 熱點(diǎn)緩存:各應(yīng)用實(shí)例收到熱Key信息后,對(duì)Key值進(jìn)行本地緩存(此步驟根據(jù)具體業(yè)務(wù)策略調(diào)整)

4、Burning
理解完熱點(diǎn)探測(cè)原理以后,我們來(lái)聊聊得物的熱點(diǎn)探測(cè)中間件Burning。
作為潮流互聯(lián)網(wǎng)電商平臺(tái),得物的電商業(yè)務(wù)高速發(fā)展,突發(fā)性的熱點(diǎn)數(shù)據(jù)不斷的沖擊著我們的系統(tǒng)服務(wù),比如大促秒殺,熱點(diǎn)商品,等等。針對(duì)于這種突發(fā)性的大流量,單純的機(jī)器擴(kuò)容并不是一個(gè)有效的解決手段,我們需要一個(gè)集熱點(diǎn)探測(cè),熱點(diǎn)感知,熱點(diǎn)數(shù)據(jù)推送,熱點(diǎn)數(shù)據(jù)預(yù)熱,熱點(diǎn)監(jiān)控分析等功能于一體的熱點(diǎn)探測(cè)中間件,因此Burning應(yīng)運(yùn)而生。
4.1 價(jià)值意義
Burning作為得物的熱點(diǎn)探測(cè)中間件,提供可供業(yè)務(wù)方接入的SDK包和管理臺(tái)規(guī)則配置,用于對(duì)熱點(diǎn)數(shù)據(jù)的實(shí)時(shí)性監(jiān)控,探測(cè),操作和本地緩存等。主要解決了以下問(wèn)題:
- 實(shí)時(shí)熱點(diǎn)感知:能實(shí)時(shí)監(jiān)控?zé)狳c(diǎn)數(shù)據(jù),包含熱Key,熱數(shù)據(jù),熱接口等,秒級(jí)上報(bào)集群統(tǒng)一計(jì)算
 - 本地?cái)?shù)據(jù)預(yù)熱:對(duì)于特定場(chǎng)景可以通過(guò)動(dòng)態(tài)本地緩存配置,防止流量突增導(dǎo)致Redis或DB數(shù)據(jù)流量壓力過(guò)大導(dǎo)致系統(tǒng)雪崩
 - 周期熱點(diǎn)統(tǒng)計(jì):對(duì)熱點(diǎn)數(shù)據(jù)進(jìn)行周期性統(tǒng)計(jì)分析,標(biāo)記出熱Key規(guī)則及分布比例等,可以幫助業(yè)務(wù)方進(jìn)行針對(duì)性優(yōu)化治理和營(yíng)銷策略選擇
 - 系統(tǒng)安全治理:可以通過(guò)熱點(diǎn)Key探測(cè)分析,對(duì)于刷子用戶,問(wèn)題IP,機(jī)器人和爬蟲(chóng)進(jìn)行標(biāo)識(shí),可實(shí)時(shí)熔斷存在安全風(fēng)險(xiǎn)的請(qǐng)求,提高系統(tǒng)安全和可用性
 
4.2 關(guān)鍵指標(biāo)
為滿足高并發(fā)場(chǎng)景,熱點(diǎn)探測(cè)中間件Burning在設(shè)計(jì)的時(shí)候,重點(diǎn)關(guān)注了如下指標(biāo):
1.實(shí)時(shí)性:熱點(diǎn)問(wèn)題往往具備突發(fā)性,客戶端必須能夠?qū)崟r(shí)發(fā)現(xiàn)可疑熱Key并推送給計(jì)算單元進(jìn)行探測(cè)
2.高性能:熱點(diǎn)探測(cè)往往需要處理大量的熱點(diǎn)探測(cè)請(qǐng)求和熱點(diǎn)計(jì)算,因此熱點(diǎn)探測(cè)中間件的性能要求較高,才能滿足巨量的并發(fā)并有效降低成本
3.準(zhǔn)確性:熱點(diǎn)探測(cè)需要精準(zhǔn)的探測(cè)符合規(guī)則熱Key,實(shí)時(shí)監(jiān)聽(tīng)規(guī)則的變化,正確的進(jìn)行熱Key上報(bào)和熱Key計(jì)算
4.一致性:熱點(diǎn)探測(cè)需要保證應(yīng)用實(shí)例的本地緩存熱Key一致,當(dāng)熱Key變更導(dǎo)致value失效時(shí),應(yīng)用需要同時(shí)進(jìn)行失效來(lái)保證數(shù)據(jù)一致性,不能出現(xiàn)數(shù)據(jù)錯(cuò)誤
5.可擴(kuò)展:熱點(diǎn)探測(cè)需要統(tǒng)計(jì)和計(jì)算的Key量級(jí)很大,而且存在突發(fā)流量的情況,統(tǒng)一計(jì)算集群需要具備水平擴(kuò)展的能力

4.3 架構(gòu)設(shè)計(jì)
Burning的架構(gòu)設(shè)計(jì)遵循了以上熱點(diǎn)探測(cè)的技術(shù)原理,同時(shí)借鑒了jd-hotKey的設(shè)計(jì)思路,主要分為Burning-Admin、Burning-Worker、Burning-Config、Burning-Client四個(gè)模塊:
- Burning-Admin (熱點(diǎn)探測(cè)管理臺(tái)):與Worker節(jié)點(diǎn)Netty長(zhǎng)鏈接通信,提供不同維度的應(yīng)用管理和熱點(diǎn)規(guī)則配置,提供查詢熱點(diǎn)數(shù)據(jù)統(tǒng)計(jì),規(guī)則和熱點(diǎn)數(shù)據(jù)監(jiān)控大盤(pán),提供工作集群信息查詢及客戶端節(jié)點(diǎn)信息查詢,提供本地緩存動(dòng)態(tài)配置及熱點(diǎn)信息實(shí)時(shí)通知
 - Burning-Worker(熱點(diǎn)集中計(jì)算單元):無(wú)狀態(tài)server端,與管理臺(tái)和客戶端進(jìn)行Netty長(zhǎng)鏈接通信,獲取規(guī)則,滑動(dòng)窗口計(jì)算熱點(diǎn),將熱點(diǎn)記錄推送到管理臺(tái)展示和客戶端處理
 - Burning-Config(熱點(diǎn)配置中心):作為熱點(diǎn)、規(guī)則配置中心和注冊(cè)中心,將規(guī)則配置下發(fā)到Worker節(jié)點(diǎn)和客戶端,通過(guò)Raft算法進(jìn)行系統(tǒng)高可用一致性保證
 - Burning-Client(熱點(diǎn)客戶端SDK):與Worker節(jié)點(diǎn)建立Netty長(zhǎng)鏈接通信,監(jiān)聽(tīng)配置中心配置變化定時(shí)推送熱Key數(shù)據(jù),獲取熱Key推送本地內(nèi)緩存設(shè)置,與Redis-client無(wú)縫集成及其他ORM框架無(wú)縫集成
 

4.4 鏈路流程
熱點(diǎn)探測(cè)主要包含以下幾個(gè)主要流程:
- 用戶在管理后臺(tái)(Burning-Admin)進(jìn)行熱點(diǎn)規(guī)則配置并進(jìn)行熱點(diǎn)數(shù)據(jù)實(shí)時(shí)監(jiān)控
 - 管理后臺(tái)(Burning-Admin)將規(guī)則配置信息上傳給配置中心(Burning-Config)
 - 配置中心(Burning-Config)將熱點(diǎn)規(guī)則下發(fā)給客戶端(Buring-Client)和工作節(jié)點(diǎn)(Burning-Worker)
 - 客戶端(Burning-Client)獲取到規(guī)則, 將指定規(guī)則的熱Key定時(shí)上報(bào)給工作節(jié)點(diǎn)(Burning-Worker)
 - 工作節(jié)點(diǎn)(Burning-Worker)獲取到上報(bào)的熱Key后進(jìn)行滑動(dòng)時(shí)間窗口計(jì)算,對(duì)于滿足閾值的熱點(diǎn)推送給客戶端(Burning-Client)
 - 客戶端(Burning-Client)拿到熱點(diǎn)數(shù)據(jù)后,進(jìn)行對(duì)應(yīng)的本地緩存配置
 

4.5 核心代碼
- 客戶端啟動(dòng)器ClientStarter,啟動(dòng)配置中心和注冊(cè)中心,Worker建連,注冊(cè)事件監(jiān)聽(tīng),設(shè)置app_name、port、caffeine緩存大小、cache配置、監(jiān)控配置等
 
- 客戶端進(jìn)行熱Key判斷,如果符合規(guī)則就上報(bào)給Worker節(jié)點(diǎn)計(jì)算,同時(shí)進(jìn)行統(tǒng)計(jì)計(jì)數(shù)
 
- Worker節(jié)點(diǎn)啟動(dòng)nettyServer,用于各個(gè)業(yè)務(wù)服務(wù)實(shí)例進(jìn)行長(zhǎng)連接,接收客戶端上報(bào)數(shù)據(jù)
 
- Worker節(jié)點(diǎn)通過(guò)監(jiān)聽(tīng)客戶端上報(bào),異步消費(fèi)隊(duì)列Client消息
 
- 如果是新增一個(gè)Key,就生成滑動(dòng)窗口,基于時(shí)間窗口數(shù)據(jù)判斷是否熱Key
 
- 如果是刪除一個(gè)Key,這里刪除包含客戶端發(fā)消息刪除,本地線程掃描過(guò)期Key和管理臺(tái)刪除
 
- Worker計(jì)算完成后將結(jié)果異步推送給Client,通過(guò)app進(jìn)行分組批量推送
 
4.6 最佳實(shí)踐
Burning提供了2種使用方式,一是通過(guò)原生方法調(diào)用,二是通過(guò)聲明式注解@EnableBurning , 以下對(duì)使用注解進(jìn)行熱點(diǎn)探測(cè)的部分場(chǎng)景提供最佳實(shí)踐:
1. 進(jìn)行熱點(diǎn)判斷,用于熱點(diǎn)攔截和自定義處理實(shí)現(xiàn)
2. 命中熱點(diǎn)規(guī)則處理類,可進(jìn)行自定義實(shí)現(xiàn)hitHandler接口(注意cache=false)
3. 用于Redis緩存熱點(diǎn)探測(cè)
4. 用于MySQL熱數(shù)據(jù)緩存
4.7 性能表現(xiàn)
4.7.1 Worker節(jié)點(diǎn)性能壓測(cè)
上游40個(gè)測(cè)試調(diào)用實(shí)例共同調(diào)用的場(chǎng)景下,并發(fā)數(shù)800,遞進(jìn)壓測(cè)

壓測(cè)結(jié)果:1個(gè)4C8G工作節(jié)點(diǎn)每秒可平穩(wěn)處理約15W個(gè)key的熱點(diǎn)探測(cè),成功率大于99.999%,worker節(jié)點(diǎn)CPU平均占用為80%,內(nèi)存占用60%
4.7.2 Client業(yè)務(wù)應(yīng)用性能壓測(cè)
DB場(chǎng)景壓測(cè)
Client配置為4C8G,120個(gè)并發(fā)請(qǐng)求,壓測(cè)時(shí)長(zhǎng)10min?
- 原生未接入Burning的DB操作接口場(chǎng)景
 

壓測(cè)結(jié)果:未接入burning,處理總請(qǐng)求數(shù)約112萬(wàn),平均TPS約1500,平均RT約63MS。CPU在壓測(cè)滿載情況下100%,內(nèi)存平均使用48%
- 接入Burning的DB操作接口場(chǎng)景
 

壓測(cè)結(jié)果:接入burning后,處理總請(qǐng)求數(shù)457萬(wàn)(對(duì)比未接入Burning增加345萬(wàn)),平均TPS約5800(對(duì)比未接入Burning增加4300),平均RT約8MS(對(duì)比未接入Burning下降55MS)。CPU在壓測(cè)滿載情況下100%,內(nèi)存平均使用50%(對(duì)比未接入上升2%,本地緩存消耗)
Redis場(chǎng)景壓測(cè)
Client配置為4C8G,120個(gè)并發(fā)請(qǐng)求,壓測(cè)時(shí)長(zhǎng)10min
- 原生未接入Burning的Redis操作接口場(chǎng)景
 

壓測(cè)結(jié)果:未接入burning,處理總請(qǐng)求數(shù)約298萬(wàn),平均TPS約3800,平均RT約14MS。CPU在壓測(cè)滿載情況下100%,內(nèi)存平均使用48%
- 已接入Burning的Redis操作接口場(chǎng)景
 

壓測(cè)結(jié)果:已接入burning,處理總請(qǐng)求數(shù)約443萬(wàn)(對(duì)比未接入增加145萬(wàn)),平均TPS約5700(對(duì)比未接入上升1900),平均RT約8MS(對(duì)比未接入下降6ms)。CPU在壓測(cè)滿載情況下100%,內(nèi)存平均使用48%,基本持平
4.7.3 壓測(cè)報(bào)告
- Burning工作節(jié)點(diǎn)單機(jī)每秒處理15萬(wàn)個(gè)key的探測(cè)請(qǐng)求,CPU穩(wěn)定在80%左右,基本無(wú)任何異常
 - 客戶端應(yīng)用接入burning后,對(duì)應(yīng)用實(shí)例本身CPU負(fù)載基本無(wú)影響,內(nèi)存占用上升主要取決于指定的本地緩存大小,接入后接口性能提升明顯,QPS明顯上升,RT明顯下降
 
5、總結(jié)
熱點(diǎn)問(wèn)題在互聯(lián)網(wǎng)場(chǎng)景中屢屢出現(xiàn),特別是電商業(yè)務(wù)的需求場(chǎng)景,例如對(duì)于大促期間或者活動(dòng)搶購(gòu)期間的某個(gè)爆品,可能會(huì)出現(xiàn)在幾秒時(shí)間內(nèi)流入大量的流量,由于商品數(shù)據(jù)在Redis cluster場(chǎng)景下會(huì)按照hash規(guī)則被存放在某個(gè)Redis分片上,那么這個(gè)瞬間流量也有可能出現(xiàn)打掛Redis分片,導(dǎo)致系統(tǒng)雪崩。所以我們要善于利用熱點(diǎn)探測(cè)中間件進(jìn)行熱Key探測(cè),通過(guò)預(yù)置本地緩存解決突發(fā)流量導(dǎo)致的系統(tǒng)瓶頸,也能通過(guò)熱點(diǎn)數(shù)據(jù)監(jiān)控分析進(jìn)行針對(duì)性的系統(tǒng)調(diào)優(yōu)。
得物熱點(diǎn)探測(cè)組件Burning上線至今,支持了數(shù)十個(gè)交易核心鏈路服務(wù),在滿足基礎(chǔ)熱點(diǎn)探測(cè)的前提下,Burning還支持本地緩存壓測(cè)標(biāo)/染色標(biāo)識(shí)別能力,客戶端本地Ecache/Caffeine緩存模式選擇,熱點(diǎn)規(guī)則Group聚合統(tǒng)計(jì)等擴(kuò)展能力。應(yīng)用服務(wù)接入Burning后對(duì)于熱點(diǎn)數(shù)據(jù)探測(cè)及數(shù)據(jù)獲取性能顯著提高,通過(guò)預(yù)熱&實(shí)時(shí)本地緩存,極大的降低了下層緩存集群和數(shù)據(jù)庫(kù)的負(fù)載壓力,為業(yè)務(wù)服務(wù)的健康運(yùn)作保駕護(hù)航。?















 
 
 















 
 
 
 