<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## 背景 在分布式K-V存儲系統中,對某個key進行讀寫時,會根據該key的hash計算出一臺固定的server來存取該K-V,如果集群不發生服務器數量變化,那么這一映射關系就不會變化。 云數據庫 memcached 就是這樣一種K-V緩存系統。在實際應用中的某些高峰時段,有的云數據庫 memcached 用戶會大量請求同一個Key(可能對應應用的熱賣商品、熱點新聞、熱點評論等),所有的請求(且這類請求讀寫比例非常高)都會落到同一個server上,該機器的負載就會嚴重加劇,此時整個系統增加新server也沒有任何用處,因為根據hash算法,同一個key的請求還是會落到同一臺新機器上,該機器依然會成為系統瓶頸。這個問題稱為“熱點key”問題。 ![](https://box.kancloud.cn/2016-04-22_5719d9fe4def4.png) ## 現狀 用戶使用云數據庫 memcached 就是為了提升業務性能,難免會觸發“熱點key問題”。但云數據庫memcached做為公有云服務,在發現有熱點的情況下,如果繼續放任該熱點無限激增,就會帶來整個系統雪崩。所以當前的做法是對每個用戶在每臺服務器上分配一定的QPS或帶寬,當用戶在某臺服務器上的請求超過該用戶的配額,我們就會對用戶進行流控,服務端返回TEMPORARY_FAILURE,該限制會影響用戶正常請求,持續時間分鐘級。 ## 思考 用戶觸發熱點問題是業務需要,是理所當然;云數據庫 memcached 對熱點 key 進行流控是保障系統穩定性,也在情理之中。但有沒有一種既能提供用戶熱點 key 訪問的需求,又能保護云數據庫memcached服務器的方法呢,這正是本文所要闡述的。 解決熱點問題有很多辦法,比如用戶如果提前知道某些key可能成為熱點,那么客戶端可以提前拆分熱點key;也可以搭建一個備用集群,寫的時候雙寫,然后隨機雙讀。這些方案的實現前提和難度可想而知,下面給出的是對應用透明,且動態發現熱點的解決方案。 ## 解決方案 ### 整體思路 本方案解決的是用戶讀熱點問題,不解決寫熱點問題。 首先,云數據庫memcached簡單架構圖如下: ![](https://box.kancloud.cn/2016-04-22_5719d9fe7996a.png) 我們的proxy是無狀態層,上面做了些訪問控制功能,用戶客戶端到proxy是隨機的,不受固定算法(如hash)控制。而proxy到DataServer的鏈路是根據key決定的,當用戶訪問熱點key時,所有proxy上關于該key的請求都會落到同一臺DataServer。 所以解決熱點問題,其核心思路是:每臺DataServer對所有key進行采樣、定位,實時計算出當前熱點key,將其反饋給proxy層,由proxy緩存備份。即負載壓力由DataServer轉向proxy。理由是:Proxy可以無狀態擴容,而DataServer不可以。 ### DataServer如何發現熱點 每臺服務器有個HotKey邏輯,讓每個到達服務器的目標請求(可配置不同類型請求)經歷三個流水階段: 1. 采樣階段(根據配置設定采樣次數sample_max) 本階段輸出:是否有熱點現象,如果有熱點,輸出熱點的桶號供下階段使用。 2. 定位階段(根據配置設定采樣次數reap_max) 本階段輸出:熱點key(如果滿足閾值),并添加到服務端的LRU鏈表。 3. 反饋階段 對到達服務器的目標請求,取出key,然后查詢LRU鏈表判斷該key是否為熱點key。如果是熱點,就會在請求結束后,向proxy發送一個feedback包,通知proxy。 至此,服務器hot-key邏輯結束。流程圖如下: ![](https://box.kancloud.cn/2016-04-22_5719d9feb8d9e.png) ### 發現熱點后proxy怎么處理 當Proxy收到DataServer的熱點反饋之后,會將該key寫入到自己的LRU-cache里面,該cache的過期時間和容量大小都交由用戶通過控制臺設置,默認分別是100ms和30。這樣熱點的key就已經存在于與proxy中了,下次用戶請求就可以直接返回了。 ### 如何保證數據一致性呢? 下面討論都是用戶client已經觸發了熱點key問題,假設用戶client跟每個proxy都建立了鏈接,并且每個proxy上都有對熱點key的請求,那么理論上每個proxy的LRU-cache都有一份數據。 我們保證單條連接上的一致性。 當用戶client和proxy1建立連接,用戶修改了一個key(任何寫操作),proxy1上會在LRU-cache中同步刪除該key,新key就會寫到DataServer上,然后在讀數據的時候,由于LRU-cache不命中,就會從DataServer上拿到最新數據。 不同鏈接上只能提供弱一致性。 如果這個時候用戶從proxy2上讀熱點數據呢?理論上就會讀到老數據,該數據將于100ms之后從proxy-cache中過期淘汰掉,之后就會更新會最新數據,即不同連接間可能有100ms不一致。 怎樣看待弱一致性。 事實上,不開啟熱點key功能,在不同鏈接上也會存在弱一致。假設用戶client建立了兩條鏈接到云數據庫memcached,在鏈接1上寫入key-value1,在鏈接1、2上分別讀該key。當鏈接1上用戶update了key-value2,這個請求需要一定的網絡延遲才能寫入到服務端,如果這個時候鏈接2上同時發起對key的讀取操作,如果讀請求先到服務端,它將讀到的是value1的老值。 所以開啟熱點key功能,只是增加了不一致時間,且該功能為可選,控制權由用戶掌握。 ### 適用場景 由以上分析可以看到,開啟熱點key功能之后,只會對用戶的讀請求產生影響,該影響增加了不同鏈接上的弱一致性的時間。因此,該功能適合讀多寫少,且對強一致性要求不高的應用。 ### 收益 整個方案核心是負載壓力由DataServer轉移到Proxy。好處如下: 1. 因為DataServer擴容也解決不了熱點問題,而Proxy可以無狀態擴容,對用戶來講就極大提升了熱點key訪問的能力,不受單點制約; 2. 縮短了服務端處理鏈路,對用戶平均RT也所降低; 3. 免除服務端熱點流控的分鐘級別影響。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看