<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] ## 實現一: SETNX實現的分布式鎖 setnx用法參考redis[官方文檔](https://link.zhihu.com/?target=https%3A//redis.io/commands/setnx) ### 語法 ``` SETNX key value ``` >將`key`設置值為`value`,如果`key`不存在,這種情況下等同SET命令。 當`key`存在時,什么也不做。`SETNX`是”**SET**if**N**ot e**X**ists”的簡寫。 ### 返回值 設置成功,返回 1 。 設置失敗,返回 0 。 ### 加鎖步驟 1. `SETNX lock.foo <current Unix time + lock timeout + 1>` 如果客戶端獲得鎖,`SETNX`返回`1`,加鎖成功。 如果`SETNX`返回`0`,那么該鍵已經被其他的客戶端鎖定。 2. 接上一步,`SETNX`返回`0`加鎖失敗,此時,調用`GET lock.foo`獲取時間戳檢查該鎖是否已經過期 * 如果沒有過期,則休眠一會重試。 * 如果已經過期,則可以獲取該鎖。具體的:調用`GETSET lock.foo <current Unix timestamp + lock timeout + 1>`基于當前時間設置新的過期時間。 **注意**: 這里設置的時候因為在`SETNX`與`GETSET`之間有個窗口期,在這期間鎖可能已被其他客戶端搶去,所以這里需要判斷`GETSET`的返回值,他的返回值是SET之前舊的時間戳: * 若舊的時間戳已過期,則表示加鎖成功。 * 若舊的時間戳還未過期(說明被其他客戶端搶去并設置了時間戳),代表加鎖失敗,需要等待重試。 ### 解鎖步驟 解鎖相對簡單,只需`GET lock.foo`時間戳,**判斷是否過期**,過期就調用刪除`DEL lock.foo` ## 實現二:SET實現的分布式鎖 set用法參考[官方文檔](https://link.zhihu.com/?target=https%3A//redis.io/commands/set) ### 語法 `SET key value [EX seconds|PX milliseconds] [NX|XX]` 將鍵`key`設定為指定的“字符串”值。如果`key`已經保存了一個值,那么這個操作會直接覆蓋原來的值,并且忽略原始類型。當`set`命令執行成功之后,之前設置的過期時間都將失效。 從2.6.12版本開始,redis為`SET`命令增加了一系列選項: * `EX`*seconds*– Set the specified expire time, in seconds. * `PX`*milliseconds*– Set the specified expire time, in milliseconds. * `NX`– Only set the key if it does not already exist. * `XX`– Only set the key if it already exist. * `EX`*seconds*– 設置鍵key的過期時間,單位時秒 * `PX`*milliseconds*– 設置鍵key的過期時間,單位是毫秒 * `NX`– 只有鍵key不存在的時候才會設置key的值 * `XX`– 只有鍵key存在的時候才會設置key的值 版本>= 6.0 * `KEEPTTL`\-- 保持 key 之前的有效時間TTL ### 加鎖步驟 一條命令即可加鎖:`SET resource_name my_random_value NX PX 30000` The command will set the key only if it does not already exist (NX option), with an expire of 30000 milliseconds (PX option). The key is set to a value “my*random*value”. This value must be unique across all clients and all lock requests. 這個命令只有當`key`對應的鍵不存在resource\_name時(NX選項的作用)才生效,同時設置30000毫秒的超時,成功設置其值為my\_random\_value,這是個在所有redis客戶端加鎖請求中全局唯一的隨機值。 ### 解鎖步驟 解鎖時需要確保my\_random\_value和加鎖的時候一致。下面的Lua腳本可以完成 ``` if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end ``` 這段Lua腳本在執行的時候要把前面的`my_random_value`作為`ARGV[1]`的值傳進去,把`resource_name`作為`KEYS[1]`的值傳進去。釋放鎖其實包含三步操作:’GET’、判斷和’DEL’,用Lua腳本來實現能保證這三步的原子性。
                  <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>

                              哎呀哎呀视频在线观看