發布訂閱
·服務器狀態在pubsub_channels字典保存了所有頻道的訂閱關系:SUBSCRIBE命令負責將客戶端和被訂閱的頻道關聯到這個字典里面,而UNSUBSCRIBE命令則負責解除客戶端和被退訂頻道之間的關聯。
·服務器狀態在pubsub_patterns鏈表保存了所有模式的訂閱關系:PSUBSCRIBE命令負責將客戶端和被訂閱的模式記錄到這個鏈表中,而PUNSUBSCRIBE命令則負責移除客戶端和被退訂模式在鏈表中的記錄。
·PUBLISH命令通過訪問pubsub_channels字典來向頻道的所有訂閱者發送消息,通過訪問pubsub_patterns鏈表來向所有匹配頻道的模式的訂閱者發送消息。
·PUBSUB命令的三個子命令都是通過讀取pubsub_channels字典和pubsub_patterns鏈表中的信息來實現的。
更多命令
http://www.runoob.com/redis/redis-pub-sub.html
事務
Redis通過MULTI、EXEC、WATCH等命令來實現事務(transaction)功能。事務提供了一種將多個命令請求打包,然后一次性、按順序地執行多個命令的機制,並且在事務執行期間,服務器不會中斷事務而改去執行其他客戶端的命令請求,它會將事務中的所有命令都執行完畢,然后才去處理其他客戶端的命令請求。‘
’
·事務提供了一種將多個命令打包,然后一次性、有序地執行的機制。
·多個命令會被入隊到事務隊列中,然后按先進先出(FIFO)的順序執行。
·事務在執行過程中不會被中斷,當事務隊列中的所有命令都被執行完畢之后,事務才會結束。
·帶有WATCH命令的事務會將客戶端和被監視的鍵在數據庫的watched_keys字典中進行關聯,當鍵被修改時,程序會將所有監視被修改鍵的客戶端的REDIS_DIRTY_CAS標志打開。
·只有在客戶端的REDIS_DIRTY_CAS標志未被打開時,服務器才會執行客戶端提交的事務,否則的話,服務器將拒絕執行客戶端提交的事務。
·Redis的事務總是具有ACID中的原子性、一致性和隔離性,當服務器運行在AOF持久化模式下,並且appendfsync選項的值為always時,事務也具有耐久性。
排序
Redis的SORT命令可以對列表鍵、集合鍵或者有序集合鍵的值進行排序。
SORT<key>命令的實現
這個命令可以對一個包含數字值的鍵key進行排序。
redis> RPUSH numbers 3 1 2 (integer) 3 redis> SORT numbers 1) "1" 2) "2" 3) "3"
1)創建一個和numbers列表長度相同的數組,該數組的每個項都是一個redis.h/redisSortObject結構
2)遍歷數組,將各個數組項的obj指針分別指向numbers列表的各個項,構成obj指針和列表項之間的一對一關系
3)遍歷數組,將各個obj指針所指向的列表項轉換成一個double類型的浮點數,並將這個浮點數保存在相應數組項的u.score屬性里面
4)根據數組項u.score屬性的值,對數組進行數字值排序,排序后的數組項按u.score屬性的值從小到大排列
5)遍歷數組,將各個數組項的obj指針所指向的列表項作為排序結果返回給客戶端,程序首先訪問數組的索引0,返回u.score值為1.0的列表項"1";然后訪問數組的索引1,返回u.score值為2.0的列表項"2";最后訪問數組的索引2,返回u.score值為3.0的列表項"3"
BY選項的實現
redis> SADD fruits "apple" "banana" "cherry" (integer) 3 redis> SORT fruits ALPHA 1) "apple" 2) "banana" 3) "cherry" redis> MSET apple-price 8 banana-price 5.5 cherry-price 7 OK redis> SORT fruits BY *-price 1) "banana" 2) "cherry" 3) "apple"
1)創建一個redisSortObject結構數組,數組的長度等於fruits集合的大小。
2)遍歷數組,將各個數組項的obj指針分別指向fruits集合的各個元素。
3)遍歷數組,根據各個數組項的obj指針所指向的集合元素,以及BY選項所給定的模式*-price,查找相應的權重鍵:
·對於"apple"元素,查找程序返回權重鍵"apple-price"。
·對於"banana"元素,查找程序返回權重鍵"banana-price"。
·對於"cherry"元素,查找程序返回權重鍵"cherry-price"。
4)將各個權重鍵的值轉換成一個double類型的浮點數,然后保存在相應數組項的u.score屬性里面:
·"apple"元素的權重鍵"apple-price"的值轉換之后為8.0。
·"banana"元素的權重鍵"banana-price"的值轉換之后為5.5。
·"cherry"元素的權重鍵"cherry-price"的值轉換之后為7.0。
5)以數組項u.score屬性的值為權重,對數組進行排序,得到一個按u.score屬性的值從小到大排序的數組:
·權重為5.5的"banana"元素位於數組的索引0位置上。
·權重為7.0的"cherry"元素位於數組的索引1位置上。
·權重為8.0的"apple"元素位於數組的索引2位置上。
6)遍歷數組,依次將數組項的obj指針所指向的集合元素返回給客戶端。
GET選項
通過使用GET選項,我們可以讓SORT命令在對鍵進行排序之后,根據被排序的元素,以及GET選項所指定的模式,查找並返回某些鍵的值。
STORE選項
通過使用STORE選項,我們可以將排序結果保存在指定的鍵里面,並在有需要時重用這個排序結果。
多個選項執行順序
1)排序:在這一步,命令會使用ALPHA、ASC或DESC、BY這幾個選項,對輸入鍵進行排序,並得到一個排序結果集。
2)限制排序結果集的長度:在這一步,命令會使用LIMIT選項,對排序結果集的長度進行限制,只有LIMIT選項指定的那部分元素會被保留在排序結果集中。
3)獲取外部鍵:在這一步,命令會使用GET選項,根據排序結果集中的元素,以及GET選項指定的模式,查找並獲取指定鍵的值,並用這些值來作為新的排序結果集。
4)保存排序結果集:在這一步,命令會使用STORE選項,將排序結果集保存到指定的鍵上面去。
5)向客戶端返回排序結果集:在最后這一步,命令遍歷排序結果集,並依次向客戶端返回排序結果集中的元素。
SORT <key> ALPHA DESC BY <by-pattern> LIMIT <offset> <count> GET <get-pattern> STORE <store_key>
如果命令包含了多個GET選項,那么在調整選項的位置時,我們必須保證多個GET選項的擺放順序不變,這才可以讓排序結果集保持不變。
SORT <key> GET <pattern-a> GET <pattern-b> STORE <store_key>
重點
·SORT命令通過將被排序鍵包含的元素載入到數組里面,然后對數組進行排序來完成對鍵進行排序的工作。
·在默認情況下,SORT命令假設被排序鍵包含的都是數字值,並且以數字值的方式來進行排序。
·如果SORT命令使用了ALPHA選項,那么SORT命令假設被排序鍵包含的都是字符串值,並且以字符串的方式來進行排序。
·SORT命令的排序操作由快速排序算法實現。
·SORT命令會根據用戶是否使用了DESC選項來決定是使用升序對比還是降序對比來比較被排序的元素,升序對比會產生升序排序結果,被排序的元素按值的大小從小到大排列,降序對比會產生降序排序結果,被排序的元素按值的大小從大到小排列。
·當SORT命令使用了BY選項時,命令使用其他鍵的值作為權重來進行排序操作。
·當SORT命令使用了LIMIT選項時,命令只保留排序結果集中LIMIT選項指定的元素。
·當SORT命令使用了GET選項時,命令會根據排序結果集中的元素,以及GET選項給定的模式,查找並返回其他鍵的值,而不是返回被排序的元素。
·當SORT命令使用了STORE選項時,命令會將排序結果集保存在指定的鍵里面。
·當SORT命令同時使用多個選項時,命令先執行排序操作(可用的選項為ALPHA、ASC或DESC、BY),然后執行LIMIT選項,之后執行GET選項,再之后執行STORE選項,最后才將排序結果集返回給客戶端。
·除了GET選項之外,調整選項的擺放位置不會影響SORT命令的排序結果。
二進制位數組
Redis提供了SETBIT、GETBIT、BITCOUNT、BITOP四個命令用於處理二進制位數組(bit array,又稱“位數組”)。
SETBIT命令用於為位數組指定偏移量上的二進制位設置值,位數組的偏移量從0開始計數,而二進制位的值則可以是0或者1。
redis> SETBIT bit 0 1 # 0000 0001 (integer) 0 redis> SETBIT bit 3 1 # 0000 1001 (integer) 0 redis> SETBIT bit 0 0 # 0000 1000 (integer) 1
redis> GETBIT bit 0 # 0000 1000 (integer) 0 redis> GETBIT bit 3 # 0000 1000 (integer) 1
BITCOUNT命令用於統計位數組里面,值為1的二進制位的數量。
redis> BITCOUNT bit # 0000 1000 (integer) 1 redis> SETBIT bit 0 1 # 0000 1001 (integer) 0 redis> BITCOUNT bit (integer) 2 redis> SETBIT bit 1 1 # 0000 1011 (integer) 0 redis> BITCOUNT bit (integer) 3
BITOP命令既可以對多個位數組進行按位與(and)、按位或(or)、按位異或(xor)運算。
redis> SETBIT x 3 1 # x = 0000 1011 (integer) 0 redis> SETBIT x 1 1 (integer) 0 redis> SETBIT x 0 1 (integer) 0 redis> SETBIT y 2 1 # y = 0000 0110 (integer) 0 redis> SETBIT y 1 1 (integer) 0 redis> SETBIT z 2 1 # z = 0000 0101 (integer) 0 redis> SETBIT z 0 1 (integer) 0 redis> BITOP AND and-result x y z # 0000 0000 (integer) 1 redis> BITOP OR or-result x y z # 0000 1111 (integer) 1 redis> BITOP XOR xor-result x y z # 0000 1000 (integer) 1
慢查詢日志
·Redis的慢查詢日志功能用於記錄執行時間超過指定時長的命令。
·Redis服務器將所有的慢查詢日志保存在服務器狀態的slowlog鏈表中,每個鏈表節點都包含一個slowlogEntry結構,每個slowlogEntry結構代表一條慢查詢日志。
·打印和刪除慢查詢日志可以通過遍歷slowlog鏈表來完成。
·slowlog鏈表的長度就是服務器所保存慢查詢日志的數量。
·新的慢查詢日志會被添加到slowlog鏈表的表頭,如果日志的數量超過slowlog-max-len選項的值,那么多出來的日志會被刪除。
引用
《Redis 設計與實現》