Redis 的事務機制和管道技術Pipelining


Redis 的事務機制和管道技術Pipelining


事務的四大特性:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability) 事務的屬性:傳播行為、隔離級別、只讀和事務超時 個人見解:這裡小僧認為事務的特性和屬性不是一個定西,特性側重於說明特點,二屬性則側重於說明本身就有的東西,這裡舉個例子人有鼻子 腿 眼睛 耳朵 這是屬性只要是正常人都有這些東西,但是這個人長得帥 騷氣 這屬於特性,有特點。 關於事務的一些特性和屬性的一些具體解釋小僧這裡就不重複複述了,不懂的自行百度即可。 Redis的事務屬性主要通過5個命令來操作的,分別是 multi、exec、watch、unwatch、discard。下面分別介紹下這屋命令的意思: watch key1 key2 ... : 監視一或多個key,如果在事務執行之前,被監視的key被其他命令改動,則事務被打斷 ( 類似樂觀鎖 )

  multi : 標記一個事務塊的開始( queued )

  exec : 執行所有事務塊的命令 ( 一旦執行exec後,之前加的監控鎖都會被取消掉 ) 

  discard : 取消事務,放棄事務塊中的所有命令

  unwatch : 取消watch對所有key的監控 下面用多種案例實際操作下: (1)正常執行的情況下,multi開啟事務 然後輸入一個或者多個命令這是所有命名沒有執行,當執行exec操作後是開始執行

Redis 的事務機制和管道技術Pipelining

(2)放棄事務,multi開啟事務 然後輸入一個或者多個命令這是所有命名沒有執行,當執行discard操作後怎放棄執行,不作任何操作,在上一步中把name 的值設置為了ergou,所以get的時候獲得ergou

Redis 的事務機制和管道技術Pipelining

(3)若在事務隊列中存在命令性錯誤(類似於java編譯性錯誤),則執行EXEC命令時,所有命令都不會執行

Redis 的事務機制和管道技術Pipelining

(4)若在事務隊列中存在語法性錯誤(類似於java的1/0的運行時異常),則執行EXEC命令時,其他正確命令會被執行,錯誤命令拋出異常。

Redis 的事務機制和管道技術Pipelining

(5)使用watch檢測餘額balance,事務期間balance數據未變動,事務執行成功

Redis 的事務機制和管道技術Pipelining

(6)使用watch檢測balance,在開啟事務後(一窗口),在2窗口執行的操作,更改balance的值,模擬其他客戶端在事務執行期間更改watch監控的數據,然後再執行一窗口後命令,執行EXEC後,事務未成功執行。

Redis 的事務機制和管道技術Pipelining

Redis 的事務機制和管道技術Pipelining

一但執行 EXEC 開啟事務的執行後,無論事務使用執行成功, WARCH 對變量的監控都將被取消。故當事務執行失敗後,需重新執行WATCH命令對變量進行監控,並開啟新的事務進行操作。WARCH 指令類似於樂觀鎖(你有沒有想到java的CAS呢?),在事務提交時,如果watch監控的多個KEY中任何KEY的值已經被其他客戶端更改,則使用EXEC執行事務時,事務隊列將不會被執行,同時返回Nullmulti-bulk應答以通知調用者事務執行失敗。 這裡你應該問Redis為什麼不支持回滾操作呢? 解答:在正常編程中上面案例(3)幾乎是不可能出現的,不過案例(4)怎有可能出現,但是Redis作者認為既然使用Redis他會默認你的操作都是正確的,為了保證高性能就不支持回滾操作了。

  • 管道Pipelining Redis是一種基於客戶端-服務端模型以及請求/響應協議的TCP服務。這意味著通常情況下一個請求會遵循以下步驟: 客戶端向服務端發送一個查詢請求,並監聽Socket返回,通常是以阻塞模式,等待服務端響應。 服務端處理命令,並將結果返回給客戶端。 redis客戶端執行一條命令分4個過程: 發送命令-〉命令排隊-〉命令執行-〉返回結果 這個過程稱為Round trip time(簡稱RTT, 往返時間),Redis提供許多批量操作的命令,如MSET/MGET/HMSET/HMGET等等,這些命令存在的意義是減少維護網絡連接和傳輸數據所消耗的資源和時間。但大部分命令(如hgetall,並沒有mhgetall)不支持批量操作,需要消耗N次RTT(Round trip time往返時間) ,這個時候需要pipeline來解決這個問題。

然而,如果客戶端要連續執行的多次操作無法通過Redis命令組合在一起,例如: SET a "abc" INCR b HSET c name "hi"

此時便可以使用Redis提供的pipelining功能來實現在一次交互中執行多條命令。使用pipelining時,只需要從客戶端一次向Redis發送多條命令(以\\r\\n)分隔,Redis就會依次執行這些命令,並且把每個命令的返回按順序組裝在一起一次返回,比如: $ (printf "PING\\r\\nPING\\r\\nPING\\r\\n"; sleep 1) | nc localhost 6379 +PONG +PONG +PONG 大部分的Redis客戶端都對Pipelining提供支持,所以開發者通常並不需要自己手工拼裝命令列表。 Pipelining的優勢 管道技術最顯著的優勢是提高了 redis 服務的性能。 Pipelining的侷限性 Pipelining只能用於執行連續且無相關性的命令,當某個命令的生成需要依賴於前一個命令的返回時,就無法使用Pipelining了。


分享到:


相關文章: