日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

基于TairString實現(xiàn)高性能樂觀鎖

在大量請求并發(fā)訪問和更新實例中儲存的共享資源時,必須有一種精準高效的并發(fā)控制機制來防止邏輯異常和數(shù)據(jù)錯誤,樂觀鎖就是這樣一種機制。比起原生Redis,Tair(企業(yè)版)的TairString模塊能幫助您實現(xiàn)性能更高、成本更低的樂觀鎖。

并發(fā)與Last-Writer-Win

下圖展示了一個典型的并發(fā)導(dǎo)致資源競爭的場景:

  1. 初始狀態(tài),string類型數(shù)據(jù)key_1的值為hello。

  2. t1時刻,App1讀取到key_1的值hello

  3. t2時刻,App2讀取到key_1的值hello

  4. t3時刻,App1將key_1的值修改為world。

  5. t4時刻,App2將key_1的值修改為universe

key_1的值是由最后一次寫入決定的,到了t4時刻,App1對key_1的認知已經(jīng)出現(xiàn)了明顯的誤差,后續(xù)操作很可能出現(xiàn)問題,這就是所謂的Last-Writer-Win。要解決Last-Writer-Win問題,就需要保證訪問并更新String數(shù)據(jù)這個操作的原子性,或者說,將作為共享資源的String數(shù)據(jù)轉(zhuǎn)變?yōu)榫哂性有缘淖兞?。您可以使?a href="http://bestwisewords.com/zh/redis/developer-reference/tairsting-command" id="09334255a1tri" title="" class="xref">exString數(shù)據(jù)結(jié)構(gòu),構(gòu)建高性能的樂觀鎖來達成這個效果。

使用TairString實現(xiàn)樂觀鎖

TairString,又稱為exString(extended string),是一種帶版本號的String類型數(shù)據(jù)結(jié)構(gòu)。原生Redis String僅由Key和Value組成,而TairString不僅包含Key和Value,還攜帶了版本(Version),非常適合樂觀鎖等場景。更多介紹及命令詳情信息請參見exString。

說明

TairString與Redis原生String是兩種不同的數(shù)據(jù)結(jié)構(gòu),相關(guān)命令不可混用。

TairString有以下特性:

  • 每個Key都帶有Version,用于說明當前Value的版本。使用EXSET命令新建Key時,默認Version為1。

  • 使用EXGET命令查詢Key時,可以獲取到Value和Version兩個字段。

  • 更新Value時,需要校驗Version,如果校驗失敗會返回異常信息ERR update version is stale;校驗成功則更新Value,且自動將Version加1。

  • 除了比特位(bit)相關(guān)操作外,TairString可以覆蓋原生Redis String的所有其它功能。

因為這些特性,使得TairString類型數(shù)據(jù)具有了鎖的機制,使用TairString實現(xiàn)樂觀鎖就非常方便了,示例如下:

while(true){
    {value, version} = EXGET(key);      // 獲取Key的Value和Version
    value2 = update(...);               // 先將新Value保存到Value2
    ret = EXSET(key, value2, version);  // 嘗試更新Key并將返回值賦予變量ret
    if(ret == OK)
       break;                           // 如果返回值為OK則更新成功,跳出循環(huán)
    else if (ret.contains("version is stale"))     
       continue;                        // 如果返回值包含"version is stale"則更新失敗,重復(fù)循環(huán)
}
說明
  • 刪除TairString后,即便以相同的key重新設(shè)置一條TairString,其Version也會是1,而不會繼承原TairString的Version。

  • 使用ABS選項可以跳過Version校驗強行覆蓋Version并更新TairString,詳情參見EXSET。

降低樂觀鎖的性能消耗

前文的示例代碼中,如果在執(zhí)行EXGET后該共享資源被其它客戶端更新了,當前客戶端會獲取到更新失敗的異常信息,然后重復(fù)循環(huán),再次執(zhí)行EXGET獲取共享資源的當前Value和Version,直到更新成功,這樣每次循環(huán)都有兩次訪問Redis的IO操作。如果使用TairString的EXCAS命令,可以將兩次訪問減少為一次,極大地節(jié)約系統(tǒng)資源消耗,提升高并發(fā)場景下的服務(wù)性能。

EXCAS命令可以在調(diào)用時攜帶一個用于校驗的Version值,如果校驗成功則直接更新TairString的Value,如果校驗失敗則返回三個字段:

  • "ERR update version is stale"

  • Value

  • Version

更新失敗后可以直接得到TairString當前的版本,無需再次查詢,將原本每個循環(huán)需要進行兩次的訪問減少到一次。示例如下:

while(true){
    {ret, value, version} = excas(key, new_value, old_version)    // 直接嘗試用CAS命令置換Value
    if(ret == OK)
       break;                                                     // 如果返回值為OK則更新成功,跳出循環(huán)
    else (if ret.contains("update version is stale"))             // 如果返回值包含"update version is stale"則更新失敗,更新兩個變量
       update(value);
       old_version = version;
 }