精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Memcache做頻率限制引發的問題分析

電子工程師 ? 來源:網絡整理 ? 作者:工程師李察 ? 2018-09-08 10:18 ? 次閱讀

線上服務為了限制用戶頻繁訪問敏感資源,通常會引入一種機制來限制這種訪問操作。其中一種常見的方案就是為每個用戶的訪問做一次時間戳,同一個用戶再次訪問對應資源時,檢查當前時間和已經記錄的時間戳的差值 -- 如果此差值小于我們定義的超時時間,此次訪問被判定為頻繁訪問。

我們在某系統的實現中便采用了此種機制,限定用戶在 1s內不能連續訪問2次,配合Memcache,實現起來非常簡單。 核心代碼如下:

publicbooleanisOutOfTime(Stringkey){

returnmemCachedClient.add(key,"abc",newDate(System.currentTimeMillis()+1000));

}

問題

一切看起來很順利,直到有一天線上報錯資源在100ms內被訪問兩次。也就是說,同一個用戶的超時鍵被設置為1s以后,100ms再次去檢查居然鍵過期了。 什么鬼?邏輯上無懈可擊的代碼怎么可能會有漏洞?先不管那些,復現再說。

代碼簡單粗暴,就是啟5個線程,每個線程連續嘗試過濾某個鍵十萬次。

運行上述代碼,每次都有很多鍵被判定為過期。充分分析整個流程,定位可能的問題原因:

后臺業務服務器與Memcache服務器時鐘不同步。Memcache的過期時間是一個時間戳,而不是相對時間偏移量,所以如果Memcache客戶端和服務器有時間差的話,比如客戶端的時間比服務器時間慢1s,那么客戶端設置的過期時間(它當前的時間 + 1000ms)在服務器看來卻已經過期了。

Memcache的鍵清理機制導致。在極端情況下(比如說Memcache被分配的內存不夠用了),Memcache會清理一些鍵值對,即使這些鍵還沒有過期。

但是以上兩個原因中,時鐘不同步的原因很快被排除了。因為從日志分析來看,相當一部分頻繁請求是被攔截下來的,如果時鐘不同步,應該有相當比例的頻繁請求被放過才對。并且跟運維確認,線上的服務器都開啟了時鐘同步功能,兩個服務器的時鐘差不會超過10ms。

現在看來只有內存清理機制這一個原因了。研究了下Memcache的鍵清理機制,總結如下:

當有新數據需要存儲的時候,Memcache會先看數據大小對應的Slab是否有空閑Item,如果有,將數據存入Item,同時更新LRU表。

如果沒有空閑Item,Memcache會嘗試去看對應Slab是否有過期鍵。如果有,清空過期鍵,將數據存入新的Item,同時更新LRU表。

如果沒有過期鍵,Memcache會嘗試申請一個新的Slab,如果申請成功,將數據存入新Slab對應的Item,同時更新LRU表。

如果申請失敗,并且Memcache配置了強制淘汰機制,會將LRU鏈表尾部的Item強制清空,并存入新Item,同時更新LRU表。

總體看下來,強制淘汰的觸發條件還是很苛刻的,并且具體的實現中,LRU鏈表分為Hot,Warm,Cold三個區域,新加入的數據會在Hot區,等Hot區滿了,較早的數據才會被降級到其他區。也就是說,假設存入數據為大小為100B,對應Slab在Memcache服務器上只有一個(一般會有很多),那么此Slab中可用Item數量約為10000個。在這種情況下,如果要觸發剛剛存入100ms的未過期鍵被強制清理的話,需要在100ms內有超過10000條100B左右大小的數據寫入Memcache。在測試環境幾乎不可能。但是這是一個公共的Memcache,誰知道呢?所以需要排除一下這個情況。

診斷

本地起一個虛擬機,裝個Memcache,順便打開日志打印(本來的目的是為了看到鍵淘汰日志)。如果是強制淘汰機制引起,那在只有一個client的本地Memcache上,應該就不會出現這個問題(測試代碼可以控制鍵數量和寫入速度),但是不幸的是,在這個空的Memcache上也出現了同樣的現象 -- 這直接排除了此現象是由強制淘汰機制導致的的可能性。

在本地虛擬機啟動的Memcache打印的日志中,發現了一個現象:所有時間戳都是類似于這樣的格式:1527001620,有點奇怪,比毫秒時間戳短。去查了一下源碼,果然被猜中:

而rel_time_t的定義為:

typedefunsignedintrel_time_t;

毫無疑問,Memcache的時間是用秒計算而不是毫秒。我們使用的客戶端接口方法:

publicbooleanadd(Stringkey,Objectvalue,Dateexpiry);

非常具有誤導性,因為Date是精確到毫秒的,這也使我們一直理所當然地以為Memcache提供毫秒精度的過期時間校驗,然而這是不對的。

原因

至此,問題的原因就很明朗了,Memcache的過期判斷代碼如下:

最重要的一句是:

it->exptime<=?current_time??

即:過期檢測中,當前時間與過期時間相等即被判定為過期。 在這個前提下,當如下情況發生時就會偶現線上的現象。

第一個請求,當前時間××××01900 ,計算出的過期時間是××××02900(+1000ms) → 存入的過期時間是××××02

第二次請求,當前時間××××02000,計算出的過期時間是××××03000(+1000ms) → 請求時,服務器判斷鍵過期(鍵過期時間 ××××02,當前時間××××02) 此次請求add成功。

第一次請求和第二次請求僅隔100ms。

事實上,如果過期時間設置為1000ms,Memcache能幫我們隨機過濾0 ~ 1000ms內的請求。頻繁請求是否被過濾依賴于最后一次成功請求的時間。

總結

使用Memcache的add方法做過期判斷時需要注意以下三點:

Memcache客戶端與服務器時間要同步;

內存被強制淘汰的可能性極低,除非過期時間比較長,Memcache內存吃緊時,需要關注此問題;

過期時間精度為秒。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 服務器
    +關注

    關注

    12

    文章

    9024

    瀏覽量

    85186
  • Memcached
    +關注

    關注

    0

    文章

    12

    瀏覽量

    7007
收藏 人收藏

    評論

    相關推薦

    為什么DCM會限制輸出頻率

    親愛的專家:在我的項目中,我需要使用幾個頻率,例如.2.048M,2.048 * 6M,512k,64k,8k。但我發現DCM限制了輸出頻率。我想知道為什么限制,我該怎么辦。非常感謝
    發表于 05-10 13:43

    memcache源碼實驗步驟

    memcache源碼安裝及測試
    發表于 07-01 16:46

    Mac上memcache的安裝配置方法

    Mac上memcache的安裝配置
    發表于 07-13 15:33

    示波器實現頻率分析的方法

    研究領域和行業的最常用的儀器。  但是示波器能夠頻率分析是近年來才實現的。隨著數字信號處理技術的發展、算法技術改進以及集成電路規模不斷按摩爾定律的指數級增長等相關條件的成熟,研發工程師就把快速傅立葉
    發表于 09-04 17:28

    memcache主線程和工人線程進行通信的設計實現

    1、memcache多線程模型memcache 是采用單進程多線程模型,內部使用 lib 事件庫來處理網絡請求。其工作是主線程負責接受的客戶端請求,然后輪詢模式新任務模式獲取連接工作人員的新線
    發表于 06-23 16:46

    Minitab柏拉圖分析

    Minitab柏拉圖分析:
    發表于 08-17 08:48 ?52次下載
    Minitab<b class='flag-5'>做</b>柏拉圖<b class='flag-5'>分析</b>

    CPU降低頻率或保持最大頻率(不超頻)_如何手動給筆記本CPU限制頻率

    處理器最大頻率不能隨便設置,因為CPU超頻時,產生大量熱量,容易燒壞設備或出現故障,我就是保持CPU的最大頻率,不超率。當CPU滿載運行以至于溫度飆升時怎么手動給筆記本CPU限制
    發表于 01-15 11:34 ?17.4w次閱讀

    redis和mongodb數據庫對比_redis、memcache、mongoDB 對比

    本文是對redis和mongodb數據庫對比分析。以及redis、memcache、mongoDB 區別對比。MongoDB和Redis都是NoSQL,采用結構型數據存儲。二者在使用場景中,存在一定
    發表于 02-07 08:45 ?4234次閱讀
    redis和mongodb數據庫對比_redis、<b class='flag-5'>memcache</b>、mongoDB 對比

    redis、memcache原理對比

    redis、memcache原理對比。Memcached和Redis都能很好的滿足解決我們的問題,它們性能都很高,總的來說,可以把Redis理解為是對Memcached的拓展,是更加重量級的實現,提供了更多更強大的功能。
    的頭像 發表于 02-09 15:31 ?3413次閱讀
    redis、<b class='flag-5'>memcache</b>原理對比

    Memcache系統中有哪些常用的命令?

    Memcache是一個高性能的分布式內存對象緩存系統,用于動態Web應用以減輕數據庫負載。它通過在內存中緩存數據和對象來減少讀取數據庫的次數,從而提高動態、數據庫驅動網站的速度。Memcache
    發表于 04-03 15:09 ?2次下載

    IBM將內存驅動到uDepot!Memcache的問題

    IBM還使用兩個Intel Optane 3D XPoint驅動器(Intel P4800X 375GB)實現了uDepot,并將其與DRAM和閃存Memcache實施進行了比較,再次使用memaslap測試。該公司比較了五種備選的memcache實現
    的頭像 發表于 01-18 14:25 ?3256次閱讀
    IBM將內存驅動到uDepot!<b class='flag-5'>Memcache</b>的問題

    ADV7xx限制MCLK輸出頻率

    ADV7xx限制MCLK輸出頻率
    發表于 05-16 10:53 ?5次下載
    ADV7xx<b class='flag-5'>限制</b>MCLK輸出<b class='flag-5'>頻率</b>

    Memcache系統常用命令講解

    Memcache系統常用命令講解(無線電源技術商業計劃書)-該文檔為Memcache系統常用命令講解文檔,是一份還算不錯的參考文檔,感興趣的可以下載看看,,,,,,,,,,,,,,,,
    發表于 09-28 11:27 ?5次下載
    <b class='flag-5'>Memcache</b>系統常用命令講解

    windows-redis-memcahed redis和memcache集成快速使用包

    ./oschina_soft/gitee-win-redis-memcache.zip
    發表于 06-23 10:09 ?2次下載
    windows-redis-memcahed redis和<b class='flag-5'>memcache</b>集成快速使用包

    信號分析設備可分析頻率低于磁帶頻率

    本文主要介紹了信號分析設備的基本原理、類型和應用。特別關注了信號分析設備在分析低于磁帶頻率的信號時的性能和限制。 引言 信號
    的頭像 發表于 06-03 10:52 ?385次閱讀