前面已經學習了redis的基本的命令行操做和數據類型,下面開始redis一些有趣的功能。redis
定義:發佈者至關於電臺,訂閱者至關於客戶端,客戶端發到頻道的消息,將會被推送到全部訂閱此頻道的客戶端;客戶端不須要主動去獲取消息,只須要訂閱頻道,這個頻道的內容就會被推送過來;數據庫
做用:發佈者和訂閱者的解耦合能夠帶來更大的擴展性和更加動態的網絡拓撲;緩存
# 訂閱消息 subscribe 頻道1 頻道2 # 此時redis客戶端會一直處於監聽頻道的狀態,一有消息就處理; # 取消訂閱 unsubcribe 頻道1 ... # 若是不寫頻道名稱,則取消全部的訂閱; # 推送消息 publish 頻道1 消息內容
發佈訂閱機制通常使用在對同一個redis實例來講,實現相似於生產者消費者模式;服務器
在主從集羣中,master發佈的消息能夠推送到slave中,但slave中的消息不能推送到master中;網絡
訂閱發佈機制的不足:併發
若是消息接收方不能及時處理推送的消息,消息會在緩存隊列中,會致使緩存佔用的空間愈來愈大,最終致使redis崩潰;高併發
發佈的消息推送存在即時性,但網絡通常是不穩定的,對於客戶端來講,若是出現了斷網的現象,那麼接收的消息就會丟失,因此發佈訂閱模式不能用在對數據完整性要求高的場合;性能
方式一:修改配置文件學習
# 設置主服務器的配置,綁定固定的ip sudo vi redis.conf bind 服務器的ip # 設置從服務器的ip sudo vi redis.conf bind 服務器的ip slaveof 主服務器的ip 主服務器redis端口 # 注意,ip與端口之間使用空格分割 # 分別啓動主從redis,主服務器redis負責寫,也能夠讀;從服務器只能讀,不能寫;
方式二:使用命令行的方式動態設置spa
# 從服務器鏈接主服務器 slaveof host port # 從服務器斷開主服務器 slaveof no one
重要說明
從服務器與主服務器進行初始鏈接時,從服務器會丟棄全部的舊數據,而後載入主服務器的數據;
redis不支持主主複製,也就是說不能夠兩個redis相互設置對方爲主服務器,雖然不會報錯,但性能方面,以及對客戶端的請求均可能出現問題;
等待從服務器的命令進入-->執行bgsave,建立快照文件;使用緩存區記錄bgsave命令執行後全部的寫命令-->快照文件建立完畢後,向服務器發送快照文件-->發送快照文件完畢後向從服務器發送緩存區的寫命令-->完畢後每收到一個寫命令就向從服務器發送
鏈接主服務器,發送sync命令-->等待響應-->丟棄全部的舊數據,載入主服務器的快照文件-->完成快照文件的解釋,開始接受命令請求-->執行從主服務器發送的全部的寫命令;
注意:redis支持主從鏈,即從服務器還能夠有從服務器,可是從服務器A複製從服務器B的過程和從服務器B複製主服務器是有區別的;從服務器B向從服務器A發送完畢快照文件後,會先斷開與從服務器A的鏈接,從服務器A須要從新鏈接而且請求同步;
redis有像關係型數據庫同樣的事務機制來保證多條命令做爲原子操做;事務中的命令要麼全執行,要麼全不執行;
事務的完整過程:開始事務-->命令進入緩存-->執行事務;
# 開啓一個事務 multi # 提交命令後,redis會將後面的操做保存起來 # 提交事務 exec # 提交命令後,redis會執行前面保存的全部的命令 # 取消事務 discard # 若是書寫命令隊列的過程當中須要取消事務時使用
> lpush list a b c (integer) 3 > multi OK > lpush list d QUEUED > lpuxh list f (error) ERR unknown command 'lpuxh' > lrange list 0 10 QUEUED > exec (error) EXECABORT Transaction discarded because of previous errors. > lrange list 0 10 1) "c" 2) "b" 3) "a" # 全部的命令都沒有執行
> lpush li blue red green (integer) 3 > multi OK > get li QUEUED > lpush li white QUEUED > exec 1) (error) WRONGTYPE Operation against a key holding the wrong kind of value 2) (integer) 4 > lrange li 0 10 1) "white" 2) "green" 3) "red" 4) "blue" # 全部的命令都執行了,只不過有的命令執行失敗
注意點
redis的開啓事務是將命令暫時保存在一個隊列裏,執行時依次操做;若是命令隊列有一條出現語法錯誤,整個事務建立會失敗;
redis沒有提供事務的回滾功能,客戶端必須本身處理失敗的命令;
# 基本命令 watch key key .. # 監控鍵值 # 取消對全部鍵的監控 unwatch
因爲redis的事務中的命令實際上是緩存隊列,而且redis能夠防止在事務的執行過程當中有其餘的命令插入,即具備隔離性;可是在多個客戶端進行併發操做時存在數據沒法同步的問題;如客戶端A、B同時操做鍵key的值加一,預期結果爲增長2,實際可能只有1.
爲了解決這個問題,redis引入了watch監控鍵;
> watch num OK > set num 7 OK > multi OK > set num 5 QUEUED > exec (nil) > get num "7"
注意:不管監控多少個鍵或事務中有沒有與該鍵相關的命令,在最近的一個執行了exec,不管事務執行有沒有成功,watch監控的全部鍵都將會取消,後面的事務再也不受影響。
說明:使用watch監控實現併發修改鍵值,若是事務被取消,須要手動從新執行事務;
問題