KV系統實現并發鎖

jopen 9年前發布 | 11K 次閱讀 并發 NoSQL數據庫

在key-value系統中緩存了網絡服務器上一個重要的ticket,這個ticket用來授權。在一定的時間周期7200s里更新。現需要實現一個CGI提供給前端獲取這個ticket,CGI訪問量為每天百萬pv左右。

假設某一時刻ticket要過期時有A,B兩個請求。A請求過來發現ticket過期,開始從網絡服務器上獲取最新的ticket并寫入KV,同時服務器更新自己存儲的ticket。而B恰好在A寫入前讀出了ticket,此時服務器上的ticket和A同步了。但B的ticket是過期的,這會導致用B獲取的ticket去請求資源時失敗。

因而需要讀寫分離。其實讀寫分離也意味著并發鎖轉移,從可能幾K并發爭鎖減少到幾個并發爭鎖。同時在CGI中降低了加鎖成本。

思路如下:

  • CGI只進行讀KV操作
  • 實現一個daemon程序,只負責每隔固定周期往KV更新ticket。用一個并發鎖去控制寫入時的資源競爭。
  • </ul>


    KV實現并發鎖

    往KV里添加一個字段daemon_mutex,對應的value為pid + timestamp。

    daemon可能會掛掉。掛掉會導致兩方面問題

    • daemon進程占有寫鎖,掛掉后死鎖
    • daemon進程掛掉后KV不會更新
    • </ul>

      因此可以啟動三個daemon進程,相互監督。

      步驟如下:

      1. 3個進程爭寫鎖,爭到的進程為主進程,每隔1s刷新KV中daemon_mutex的timestamp字段,相當于心跳數據。每隔15分鐘更新KV中的ticket。(ticket更新不用太頻繁)
      2. 2個從進程每隔1s讀KV中daemon_mutex的timestamp字段,若time(NULL) - kv.update_time() > 15說明主進程掛掉了,2個從進程開始爭鎖,搶到的進程升級為主進程。重復以上。
      3. </ol>

        分布式系統中心心跳協議的設計可以參見Linux多線程服務端編程


        Chubby技術架構

        如果大家熟悉 ZooKeeper(雅虎公司對Chubby的開源實現) 和 Chubby 就會發現上面的并發鎖設計和 Chubby 一樣。

        一個典型的 Chubby 集群 通常由5臺服務器組成。這些副本服務器采用 Paxos 協議,通過投票的方法來選舉產生一個獲得過半投票的服務器作為 Master。只有 Master 服務器才能對數據庫進行寫操作,而其他的服務器都是使用 Paxos 協議從 Master 服務器上同步數據庫數據的更新。

        在Chubby中,任意一個數據節點都可以充當一個讀寫鎖來使用:一種是單個客戶端以排他(寫)模式持有這個鎖,另一種則是任意數目的客戶端以共享(讀)模式持有這個鎖。


        Memcache實現并發鎖

        memcache也可以利用add去實現并發鎖,主要是通過add的原子性來判斷是否要執行關鍵代碼。

        if (memcache.get(key) == null) {
            // 設置過期時間防止持有寫鎖的進程死鎖
            if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {
                //主進程執行流,當可以增加key_mutex字段,說明獲得鎖
                //業務邏輯操作
                value = db.get(key);
                memcache.set(key, value);
                //刪除key_mutex
                memcache.delete(key_mutex);
            } else {
                //從進程執行流
                sleep(50);
                retry();
            }
        }

        參考

        http://www.cnblogs.com/dluf/p/3849075.html

        http://timyang.net/programming/memcache-mutex/

        Linux多線程服務端編程. Page 356~360.

        從Paxos到ZooKeeper——分布式一致性原理與實踐

        來自:http://fuzhii.com/2015/09/21/concurrentlock/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!