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

          緩存熱點,緩存穿透,終極解決方案看過來

          共 3669字,需瀏覽 8分鐘

           ·

          2021-08-30 09:38

          作者:鉑賽東
          來源:SegmentFault 思否社區(qū)

          背景

          前不久,因為公司業(yè)務需要,需要解決在大促場景下后端業(yè)務的熱點緩存問題,所以研究了下緩存熱點解決方案。
          很多公司的緩存都是基于redis來做的,redis的性能其實已經(jīng)足以能應付大部分的場景,但是對于大促期間或者活動搶購期間的某個爆品,可能會出現(xiàn)在幾秒時間內(nèi)流入大量的流量,由于某個爆品的數(shù)據(jù)在redis cluster場景下會按照hash規(guī)則被存放在某個redis分片上,那么這幾秒的流量都會壓到這個redis分片,從而在瞬間會導致這個redis分片的癱瘓,也會影響后續(xù)的redis請求的阻塞。
          還有個場景,就是公司并不是所有的服務端邏輯都有緩存。在流量起來的時候,這些熱key還是會壓到數(shù)據(jù)庫層面。導致壓力。

          解決方案

          一般常見的解決方案就是增加二級緩存,對于熱點數(shù)據(jù)寫到jvm里一份。設置過期時間。但是什么時候設置,熱點如何探測,規(guī)則如何設置,過期時間設置多少。甚至于如何快速落地,這都是需要研究的問題。
          我們希望有一個統(tǒng)一的方案來解決這些問題。
          我們發(fā)現(xiàn)了Hotkey這款開源框架。
          Hotkey源于京東,hotkey能自動地對任意突發(fā)性的無法預知的熱點數(shù)據(jù),按照配置的規(guī)則進行毫秒級別的探測,探測到的熱數(shù)據(jù)會推送到所有的服務端JVM中,大幅減輕對后端數(shù)據(jù)層的沖擊。這些熱數(shù)據(jù)在整個微服務集群會保持一致性,當熱點消失的時候,自動從jvm中進行移除。
          Hotkey的特性能很好的實現(xiàn)我們的目標。并且京東內(nèi)部也用Hotkey實戰(zhàn)了618大促,穩(wěn)定性有所保障。
          Hotkey的架構(gòu)圖(以下圖引用自Hotkey在Gitee的主頁)


          Hotkey整個架構(gòu)共分為以下幾個部分:
          worker:負責采集上報信息,根據(jù)規(guī)則計算出熱點信息,規(guī)則來自于etcd。熱點信息推送到client里
          client:每個client連接etcd,獲取每個worker的ip和端口,和worker保持長鏈接,接受worker的熱點信息推送
          etcd:分布式的協(xié)調(diào)者,接受每個worker的心跳上報,并把worker的連接信息推送給client。監(jiān)聽規(guī)則的改變,推送給worker
          dashboard:ui界面,查看實例以及worker的狀態(tài),查看以及修改規(guī)則數(shù)據(jù)。規(guī)則存到mysql,同時由etcd推送給worker
          下面給出hotkey的項目地址
          hotkey: 京東App后臺中間件,毫秒級探測熱點數(shù)據(jù),毫秒級推送至服務器集群內(nèi)存,大幅降低熱key對數(shù)據(jù)層查詢壓力 (gitee.com)
          關于Hotkey的介紹和如何搭建,大家可以看這篇文章來了解,這里就不多贅述。
          京東毫秒級熱key探測框架設計與實踐,已實戰(zhàn)于618大促 (qq.com)

          碰到的問題

          我們在搭建hotkey環(huán)境和落地實施中,碰到2個問題:
          • Hotkey雖然開源,但是相關client jar包并未上傳中央倉庫,dashboard和worker啟動包也并未提供下載。需要下載源碼進行編譯,編譯過程中也碰到一些包依賴的問題。

          • Hotkey的client jar只提供了api級別的方法供程序使用,如果要落地到業(yè)務項目中,需要大規(guī)模的修改代碼才能實施。


          我們更希望提供一種侵入更少的方式,在RPC以及接口的層面進行代理包裝。使用者無論使用什么RPC框架,只是在相關接口上打上標注,而無需動業(yè)務的任何代碼。就可以在這個接口層面進行檢測熱點。如果該接口的某個參數(shù)為熱點的話,就自動進行代理,走jvm的熱點數(shù)據(jù),等熱點消除后,依舊走原來的調(diào)用。
          如果你覺得上述的描述過于難以理解的話,那么直白點說就是:
          比如某個活動大促期間有個商品S001進行搶購,有大量的流量進入了商品詳情頁面。這個商品詳情RPC方式調(diào)用了商品服務的以下接口方法獲取商品信息:
          public interface ProductService{
            SkuInfo getSkuInfo(String skuCode);
          }

          那么我們希望只在這個接口上打上標注。就可以適配Hotkey框架進行探測熱點,當商品S001被大量請求時,S001這個商品就可以成為熱點,這時getSkuInfo這個接口就會被自動代理,從而只從Jvm中獲取數(shù)據(jù),而不會真正走RPC調(diào)用。等熱點消除后,這個接口依舊調(diào)用RPC獲取數(shù)據(jù)。
          這樣的方式無疑侵入性更小,更容易使Hotkey框架落地。

          Hotlink客戶端

          為此我們基于Hotkey client研發(fā)了Hotlink客戶端框架,該客戶端框架能讓Hotkey更完美的落地,增強了Hotkey客戶端的能力。
          Hotlink的項目地址:hotlink: Hotlink框架是一個基于Hotkey框架的客戶端增強版實現(xiàn),該客戶端框架能讓Hotkey更完美的落地,增強了Hotkey客戶端的能力。(gitee.com)
          該客戶端框架有以下特點:
          • 業(yè)務接入簡單,只需要一個標注,1分鐘就能使你的RPC接口接入熱點探測框架

          • 啟動時動態(tài)掃描所有Hotlink標注的接口,創(chuàng)建動態(tài)代理

          • 基于動態(tài)代理去對接口做增強,理論上只要有接口,就支持任何RPC框架

          • 本地方法只要有接口,也能使用熱點探測






          結(jié)合Hotkey的架構(gòu)圖,Hotlink在整個架構(gòu)圖中的位置如下圖:

          Hotlink如何使用

          第一步
          按照Hotkey的部署要求,搭建好worker和dashboard。具體方式請參照:
          hotkey: 京東App后臺中間件,毫秒級探測熱點數(shù)據(jù),毫秒級推送至服務器集群內(nèi)存,大幅降低熱key對數(shù)據(jù)層查詢壓力 (gitee.com)
          第二步
          本地業(yè)務項目依賴jar包(此jar包并未上傳到中央倉庫,需要大家自己deploy到自己公司的私庫)
          <dependency>
            <groupId>com.thebeastshop</groupId>
            <artifactId>hotlink-spring-boot-starter</artifactId>
            <version>1.0.12</version>
          </dependency>

          hotlink需要的fastjson和groovy版本有點要求,如果你項目中的這2個包版本過低又同時覆蓋了hotlink的傳遞依賴包時,需要額外指定版本:
          <fastjson.version>1.2.70</fastjson.version>
          <guava.version>29.0-jre</guava.version>

          第三步
          本地springboot配置文件里加入?yún)?shù)
          #此app-name不配置的話,會優(yōu)先讀取spring.application.name屬性
          hotlink.app-name=test
          #etcd地址和端口
          hotlink.etcd-url=http://xxx.xxx.xxx.xxx:2379

          第四步
          在你的接口里加入標簽@Hotlink
          在接口上加:接口里所有的方法都會自動探測熱點
          在方法上加:只有這個方法會自動探測熱點
          比如:
          public interface ProductService{
            @Hotlink
            SkuInfo getSkuInfo(String skuCode);
          }

          那么當某一個SKU001成為熱點時,那么傳入?yún)?shù)SKU001會自動代理從JVM里取到數(shù)據(jù),而SKU002則繼續(xù)走RPC調(diào)用。
          這樣就完成了所有的配置。啟動皆可。

          使用Hotlink需要注意的事項

          由于Hotlink的實現(xiàn)是用動態(tài)代理來實現(xiàn),只要滿足這兩個條件,即可在啟動時會掃描器掃到:
          • 接口層面上標注@Hotlink

          • 相關實現(xiàn)會被注入Spring上下文中




          在標注接口的時候,盡量標注在一定時間范圍內(nèi)是冪等的接口。比如會員查詢,sku信息查詢,相關活動信息的查詢,這些信息在一定時間范圍內(nèi)不會頻繁變動,那么就適合做熱點探測。
          非冪等性的接口,即便是相同參數(shù),每次返回也會不一樣。那就不建議做熱點探測。比如下單,庫存的查詢,余額的查詢。這樣的接口如果一旦被升級成熱點。那會影響業(yè)務界面的正確性和后續(xù)邏輯的判斷錯誤。


          點擊左下角閱讀原文,到 SegmentFault 思否社區(qū) 和文章作者展開更多互動和交流,掃描下方”二維碼“或在“公眾號后臺回復“ 入群 ”即可加入我們的技術(shù)交流群,收獲更多的技術(shù)文章~

          - END -


          瀏覽 18
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  高潮流水视频 | 大香中文字幕在线观看 | 无码人妻一区 | 青娱乐自拍 | 成人尤物网站 |