使用memcached進行併發控制(寫的非常好)

2021-06-19 22:10:53 字數 1806 閱讀 3055

原文:

27 february 2011

引子

乙個使用快取進行併發控制的討論,讓我學習到成本與收益間的平衡,以及何為真正的可用性......

防止併發有多種方式,本文只涉及使用快取memcached控制。

併發場景

用例:sns系統中具有高階會員資格的人發起活動。

業務規則:1.乙個人同時只能建立乙個活動。2.具有高階會員資格。

基本流程如下:

這個流程中存在明顯的併發問題,當程序a校驗過會員m有資格,並且為建立過活動,但為開始執行建立操作,此時另乙個程序b也進行了規則判斷,順利通過,並完成建立操作,此時a繼續執行,則會產生兩條m的活動。(這個併發場景很簡單,很普遍)

最初的解決方案:

計畫利用memcached的add操作的原子性來控制併發,具體方式如下:

1.申請鎖:在校驗是否建立過活動前,執行add操作key為memberid,如果add操作失敗,則表示有另外的程序在併發的為該memberid建立活動,返回建立失敗。否則表示無併發

2.執行建立活動

3.釋放鎖:建立活動完成後,執行delete操作,刪除該memberid。

問題:

如此實現存在一些問題:

1.memcached中存放的值有有效期,即過期後自動失效,如add過m1後,m1失效,可以在此add成功

2.即使通過配置,可以使memcached永久有效,即不設有效期,memcached有容量限制,當容量不夠後會進行自動替換,即有可能add過m1後,m1被其他key值置換掉,則再次add可以成功。

3.此外,memcached是基於記憶體的,掉電後資料會全部丟失,導致重啟後所有memberid均可重新add。

應對問題:

針對上述的幾個問題,根本原因是add操作有時效性,過期,被替換,重啟,都會是原來的add操作失效。解決該問題有兩個方法:

1.採用持久化的快取解決方法,如tt(tokyo tyrant:

2.減輕時效性的影響,使用memcached cas(check and set)方式。

第一種不必解釋了,很簡單,原來的所有問題都是時效性惹得禍,時效性源於memcached是基於記憶體的,那麼採用持久話儲存的tt可以徹底**這個問題。

第二種方式需要簡單介紹下:

memcached中除了add操作是原子的,還有另外兩個操作也是原子的:incr和decr,使用cas模式即:

1.預先在memcached中設定乙個key值,假設為creatkey=1

2.每次建立活動時,在規則校驗前先get出createkey=x;

3.進行規則校驗

4.執行incr createkey操作,檢驗返回值是否為所期望的x+1,如果不是,則說明在此期間有另外的程序執行了incr操作,即存在併發,放棄更新。否則

5.執行建立活動

對比這兩種方法,從效果上看可以發現第一種時100%可靠的,不存在問題;第二種,可能存在誤判,即本來不存在併發,卻被判為併發,如快取重啟,或key值失效後,incr值可能不同於期望值,導致誤判。

但是從成本上考慮,tt是持久化的快取解決方案,完美意味著高成本,我們必須維護持久化資料,而使用memcached的cas方式,可以以幾乎0成本的方式解決時效性問題,儘管存在一點小缺陷,但這種缺陷可以通過簡單的重試即可解決。考慮實際的產出比,採用memcached的cas方式更適合實際情況。

成本與收益間的平衡,做科學與做工程的區別~

windows體系使用memcached

1.簡述 memcached官方並不提供原生的donet體系方案,server端需要在linux環境下編譯成windows下的exe包,這裡的server端為1.4.13版本,需要新版本的需要自己編譯,window體系下,使用memcached做快取,建議採用 主從架構 業務快取和配置快取隔離,方便...

memcached使用安裝 問題

使用 1 telnet 127.0.0.1 11211 連線memcached win10開啟telnet需要開始選單 設定 搜尋.windows功能 有個啟用或關閉windows功能 內部有個telnet功能開啟即可 2 使用get或者 gets 獲取key stats 執行狀態安裝 1 memc...

使用Zabbix監控memcached

zabbix server.3.2.11 zabbix agentd centos7.0 1 什麼是memcached?memcached是一套分布式的快取記憶體系統,由livejournal的brad fitzpatrick開發,以bsd license授權發布。它是乙個簡潔的key value儲...