(尊重勞動成果,轉載請註明出處:https://yangwenqiang.blog.csdn.net/article/details/90414751冷血之心的博客)
關注微信公衆號(文強的技術小屋),學習更多技術知識,一起遨遊知識海洋~
快速導航:
Redis入門總結(一):redis配置文件,五種數據結構,線程模型和持久化方式
這篇文章主要總結了:redis的主從複製,redis的事務以及redis實現發佈訂閱。
-
主從複製:
-
背景:
-
隨着項目訪問量的增加,對Redis服務器的操作也越加頻繁,雖然Redis讀寫速度都很快,但是一定程度上也會造成一定的延時,那麼爲了解決訪問量大的問題,通常會採取的一種方式是主從架構Master/Slave,Master 以寫爲主,Slave 以讀爲主,Master 主節點更新後根據配置,自動同步到從機Slave 節點。
-
-
通過 info replication 命令查看節點角色
-
哨兵模式:
-
解決了主節點掛掉之後,從節點還是從節點,無法自動轉爲主節點,導致系統無法正常工作的問題
-
哨兵模式監控redis是否按照預期良好地運行(至少是保證主節點是存在的),若一臺主機出現問題時,哨兵會自動將該主機下的某一個從機設置爲新的主機,並讓其他從機和新主機建立主從關係。
-
哨兵模式也可以設置爲集羣模式,解決哨兵的單節點故障
-
-
主從複製原理:
-
舊版同步:
-
當從節點發出 SLAVEOF 命令,要求從服務器複製主服務器時,從服務器通過向主服務器發送 SYNC 命令來完成。該命令執行步驟:
-
從服務器向主服務器發送 SYNC 命令
-
收到 SYNC 命令的主服務器執行 BGSAVE 命令,在後臺生成一個 RDB 文件,並使用一個緩衝區記錄從開始執行的所有寫命令
-
當主服務器的 BGSAVE 命令執行完畢時,主服務器會將 BGSAVE 命令生成的 RDB 文件發送給從服務器,從服務器接收此 RDB 文件,並將服務器狀態更新爲RDB文件記錄的狀態。
-
主服務器將緩衝區的所有寫命令也發送給從服務器,從服務器執行相應命令。
-
-
-
命令傳播:
-
當同步操作完成之後,主服務器會進行相應的修改命令,這時候從服務器和主服務器狀態就會不一致。
-
爲了讓主服務器和從服務器保持狀態一致,主服務器需要對從服務器執行命令傳播操作,主服務器會將自己的寫命令發送給從服務器執行。從服務器執行相應的命令之後,主從服務器狀態繼續保持一致。
-
問題:
-
如果從服務器正在同步,但是斷開了連接,在其恢復之前,主服務器又進行了一系列的寫操作,那麼我們需要重新生成RDB文件來進行同步操作,這樣會導致效率降低。
-
這樣雖然能夠保證一致性,但是其實斷開連接之前主從服務器狀態是保持一致的,不一致的是從服務器斷開連接,而主服務器執行了一些寫命令,那麼從服務器恢復連接後能不能只要斷開連接的哪些寫命令,而不是整個RDB快照呢?
-
-
解決辦法:
-
Redis從2.8版本之後,使用了新的同步命令 PSYNC 來代替 SYNC 命令。該命令的部分重同步功能用於處理斷線後重複製的效率問題。也就是說當從服務器在斷線後重新連接主服務器時,主服務器只將斷開連接後執行的寫命令發送給從服務器,從服務器只需要接收並執行這些寫命令即可保持主從一致。
-
-
-
主從複製的缺點:
-
當系統繁忙的時候,主從延遲會比較大。
-
-
-
-
redis對事務的支持:
-
redis 是單進程程序,並且它保證在執行事務時,不會對事務進行中斷,事務可以運行直到執行完所有事務隊列中的命令爲止。因此,Redis的事務支持隔離性。
-
redis會將一個事務中的所有命令序列化,然後按順序執行。Redis不可能在一個Redis事務的執行過程中插入執行另一個客戶端發出的請求。這樣便能保證Redis將這些命令作爲一個單獨的隔離操作執行。
-
操作事務的相關命令:
-
MULTI :標記一個事務塊的開始。
-
EXEC :執行所有事務塊內的命令。
-
DISCARD :取消事務,放棄執行事務塊內的所有命令。
-
UNWATCH :取消 WATCH 命令對所有 key 的監視。
-
WATCH key [key ...] :監視一個(或多個) key ,如果在事務執行之前這個(或這些) key 被其他命令所改動,那麼事務將被打斷。
-
-
redis事務不支持回滾:
-
只有當被調用的Redis命令有語法錯誤時,這條命令纔會執行失敗(在將這個命令放入事務隊列期間,Redis能夠發現此類問題),或者對某個鍵執行不符合其數據類型的操作:實際上,這就意味着只有程序錯誤纔會導致Redis命令執行失敗,這種錯誤很有可能在程序開發期間發現,一般很少在生產環境發現。
-
Redis已經在系統內部進行功能簡化,這樣可以確保更快的運行速度,因爲Redis不需要事務回滾的能力。
-
-
redis以 MULTI 開始一個事務,然後將多個命令入隊到事務中,最後由 EXEC 命令觸發事務, 一併執行事務中的所有命令:
-
單個 Redis 命令的執行是原子性的,但 Redis 沒有在事務上增加任何維持原子性的機制,所以 Redis 事務的執行並不是原子性的。
-
當EXEC調用之後,開始從隊列裏邊取出命令執行,一條命令執行失敗,並不會影響到其餘命令的繼續執行。
-
redis事務爲什麼不支持原子性?
-
當我們開啓事務時,將一系列的命令都封裝塞進了一個隊列,當EXEC開始執行的時候,只有錯誤的命令纔會導致執行失敗,而這通常在將該命令塞進隊列的時候已經報錯,我們應該可以提前發現該錯誤纔對。
-
-
-
事務內部錯誤如何處理?
-
錯誤分類:
-
一個命令可能會在被放入隊列時失敗。因此,事務有可能在調用EXEC命令之前就發生錯誤。例如,這個命令可能會有語法錯誤(參數的數量錯誤、命令名稱錯誤,等等),或者可能會有某些臨界條件(例如:如果使用maxmemory指令,爲Redis服務器配置內存限制,那麼就可能會有內存溢出條件)。
-
在調用EXEC命令之後,事務中的某個命令可能會執行失敗。例如,我們對某個鍵執行了錯誤類型的操作(例如,對一個字符串(String)類型的鍵執行列表(List)類型的操作)。
-
-
解決辦法:
-
可以使用Redis客戶端檢測第一種類型的錯誤,在調用EXEC命令之前,這些客戶端可以檢查被放入隊列的命令的返回值:
-
如果命令的返回值是QUEUE字符串,那麼就表示已經正確地將這個命令放入隊列;
-
否則,Redis將返回一個錯誤。如果將某個命令放入隊列時發生錯誤,那麼大多數客戶端將會中止事務,並且丟棄這個事務。
-
-
在Redis 2.6.5版本之前,如果發生了上述的錯誤,那麼在客戶端調用了EXEC命令之後,Redis還是會運行這個出錯的事務,執行已經成功放入事務隊列的命令,而不會關心先前發生的錯誤。從2.6.5版本開始,Redis在遭遇上述錯誤時,服務器會記住事務積累命令期間發生的錯誤。然後,Redis會拒絕執行這個事務,在運行EXEC命令之後,便會返回一個錯誤消息。最後,Redis會自動丟棄這個事務。這樣便能輕鬆地混合使用事務和管道。在這種情況下,客戶端可以一次性地將整個事務發送至Redis服務器,稍後再一次性地讀取所有的返回值。
-
相反,在調用EXEC命令之後發生的事務錯誤,Redis不會進行任何特殊處理:在事務運行期間,即使某個命令運行失敗,所有其他的命令也將會繼續執行。
-
-
-
redis通過WATCH監視命令實現樂觀鎖:
-
redis使用 check-and-set 操作實現樂觀鎖。WATCH 命令可以爲 Redis 事務提供 check-and-set (CAS)行爲。
-
類似Java中的CompareAndSet機制,被 WATCH 的鍵會被監視,並會發覺這些鍵是否被改動過了。
-
如果有至少一個被監視的鍵在 EXEC 執行之前被修改了, 那麼整個事務都會被取消, EXEC 返回空多條批量回復(null multi-bulk reply)來表示事務已經失敗。
-
-
redis事務總結:
-
單獨的隔離操作:事務中的所有命令會被序列化、按順序執行,在執行的過程中不會被其他客戶端發送來的命令打斷
-
沒有隔離級別的概念:隊列中的命令在事務沒有被提交之前不會被實際執行
-
不保證原子性:redis中的一個事務中如果存在命令執行失敗,那麼其他命令依然會被執行,沒有回滾機制
-
-
-
redis信息通知(發佈/訂閱模式):
-
優點:
-
松耦合。生產者和消費者無需知道彼此的實現細節,只需要約定好任務的描述格式。這使得生產者和消費者可以由不同的團隊使用不同的編程語言編寫
-
易於擴展。消費者可以有多個,而且可以分佈在不同的服務器中, 藉此可以輕易地降低單臺服務器的負載
-
-
使用LPUSH和RPOP命令實現隊列
-
利用BRPOP命令可以檢測多個key的功能。如果多個鍵都有元素,則按照從左到右順序取第一個鍵中的一個元素。因此,要實現優先級隊列,把優先級高的key放到前面就ok了。
-
發佈訂閱模式:
-
"發佈/訂閱"模式中包含兩種角色,分別是發佈者和訂閱者。
-
訂閱者可以訂閱一個或若干個頻道(channel)
-
發佈者可以向指定的頻道發送消息,所有訂閱此頻道的訂閱者都會收到此消息。
-
-
以上內容摘抄總結與網絡,感謝各位前輩的總結與鋪墊。接下來我會繼續更新Redis相關文章,全部會以這種筆記形式給出,大家對筆記中不太懂的地方,可以發表評論,我們一起研究學習,此處權當給大家列個學習提綱了。
如果對你有幫助,記得點贊哦~歡迎大家關注我的博客,可以進羣366533258一起交流學習哦~
本羣給大家提供一個學習交流的平臺,內設菜鳥Java管理員一枚、精通算法的金牌講師一枚、Android管理員一枚、藍牙BlueTooth管理員一枚、Web前端管理一枚以及C#管理一枚。歡迎大家進來交流技術。
關注微信公衆號(文強的技術小屋),學習更多技術知識,一起遨遊知識海洋~