redis知識整理-進階部分

發佈訂閱

發佈消息

PUBLISH channel message

向c1的channel發佈消息hello

PUBLISH c1 hello

redis知識整理-進階部分

訂閱消息

SUBSCRIBE channel [channel ...]

訂閱c1的channel的消息

SUBSCRIBE c1

訂閱一個channel的消息時只會接收訂閱之後發送到channel的消息,訂閱之前的消息則不會接收,先向c1channel發送一條hello的消息,然後訂閱c1channel,並沒有接收到hello,然後再發送world消息,這是訂閱端接收到world消息

redis知識整理-進階部分

適用場景:

1、聊天室群消息,訂閱一個channel之後實時接收新發送的到這個channel的消息

2、當消息中間件使用等

pipeline

一次請求/響應服務器能實現處理新的請求即使舊的請求還未被響應。這樣就可以將多個命令發送到服務器,而不用等待回覆,最後在一個步驟中讀取該答覆

使用 管道藉助nc一次發送多個redis命令

(printf "set k1 qq\r\nget k1\r\n") | nc localhost 6379

redis知識整理-進階部分

Redis 事務

查看Redis相關命令:help @transactions

MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事務相關的命令。事務可以一次執行多個命令, 並且帶有以下兩個重要的保證:

  • 事務是一個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行。事務在執行的過程中,不會被其他客戶端發送來的命令請求所打斷。
  • 事務是一個原子操作:事務中的命令要麼全部被執行,要麼全部都不執行。

EXEC 命令負責觸發並執行事務中的所有命令:

  • 如果客戶端在使用 MULTI 開啟了一個事務之後,卻因為斷線而沒有成功執行 EXEC ,那麼事務中的所有命令都不會被執行。
  • 另一方面,如果客戶端成功在開啟事務之後執行 EXEC ,那麼事務中的所有命令都會被執行。


redis知識整理-進階部分

MULTI 命令用於開啟一個事務,它總是返回 OK 。 MULTI 執行之後, 客戶端可以繼續向服務器發送任意多條命令, 這些命令不會立即被執行, 而是被放到一個隊列中, 當 EXEC命令被調用時, 所有隊列中的命令才會被執行。

當執行 DISCARD 命令時, 事務會被放棄, 事務隊列會被清空, 並且客戶端會從事務狀態中退出:


redis知識整理-進階部分

WATCH 命令可以為 Redis 事務提供 check-and-set (CAS)行為。

被 WATCH 的鍵會被監視,並會發覺這些鍵是否被改動過了。 如果有至少一個被監視的鍵在 EXEC 執行之前被修改了, 那麼整個事務都會被取消, EXEC 返回nil-reply來表示事務已經失敗。

在一個客戶端中set k1的值為1 ,並用WATCH監聽k1然後執行MULTI命令進入Redis事務,在EXEC之前在另外一個客戶端對k1的值進行修改,然後EXEC命令執行事務會發現返回nil,事務中的命令並未執行。


redis知識整理-進階部分

在事務exec之前另外一個客戶端get 被監聽的key的值不影響事務的正常執行

modules:Redis 布隆過濾器

Redis布隆過濾器的地址
https://github.com/RedisBloom/RedisBloom

安裝及使用:

下載RedisBloom到Redis服務器上然後解壓得到RedisBloom-master文件夾,進去RedisBloom-master文件夾


redis知識整理-進階部分

然後執行make命令得到redisbloom.so文件

重新啟動Redis服務時添加 --loadmodule /path/to/redisbloom.so(redisbloom.so絕對路徑) 參數或者在啟動的配置文件中配置也可以

./redis-server --loadmodule /usr/local/redis5/RedisBloom-master/redisbloom.so

在redis客戶端中輸入BF.並按Tab鍵可循環查看布隆過濾器的相關命令

使用BF.ADD命令向key為bloomfilter的布隆過濾器中添加元素,並查看元素是否可能存在


redis知識整理-進階部分

BF.EXISTS返回0說明是一定不存在,返回1可能存在。用"可能存在"是由於布隆過濾器的概率問題而不是百分百的存在。

布隆過濾器原理簡要介紹:

1、要將元素插入到布隆過濾器中首先使用不同的映射函數獲取該元素在bitmap中的不同位置的下標,如元素"haha"調用三個不同的映射函數返回三個下標值1,3,5,將bitmap中下標位置為1,3,5的位置的值都設置為1,元素"hehe"調用三個不同的映射函數返回三個下標值3,6,7 將bitmap中下標位置為3,6,7的位置的值都設置為1

2、查詢一個元素"hello"是不是布隆過濾器中存在,首先調用三個不同的映射函數獲取三個在bitmap中的下標位置,如果返回的下標位置為1、6、7的話則會被布隆過濾器認為是存在的,因為1、6、7位置的值都是1 ,這就是上面所說的可能存在的問題根源,這是概率問題因為都命中了其他元素返回的下標位置。如果返回的下標位置為1、6、8的話則會被布隆過濾器認為是不存在的,因為8位置的值是0。


redis知識整理-進階部分

提高布隆過濾器的準確率可從兩個維度入手,1是映射函數的個數,2、是bitmap的長度。映射函數的個數越多、bitmap的長度越長髮生碰撞的概率就會越低,誤判的概率就會降低。凡事都用兩面性具體的可查看布隆過濾器的詳細介紹。

Redis緩存/數據庫

redis作為緩存和作為數據庫的區別:

作為數據庫:數據是全量的且持久化不能丟的

作為緩存:數據是可以丟的、不是全量數據,且隨著業務訪問變化的熱數據

Redis裡的數據怎麼隨業務變化只保留熱數據?

1、設置有效期

1)使用 SET key value [expiration EX seconds|PX milliseconds] [NX|XX],在設置值的時候設置過期時間

2)使用 EXPIRE key seconds 給已有的鍵值設置過期時間,

3)使用 EXPIREAT key timestamp 給一個時間戳到達某個時間點後刪除

設置的過期時間不會隨訪問而延長,發生寫操作時會剔除這個key的過期時間,變成不會過期。

redis如何淘汰過期的key?

Redis keys過期有兩種方式:被動和主動方式。

被動方式:當一些客戶端嘗試訪問它時,訪問這個key時發現已過期會被刪除,加入過期的key一直不被訪問則一直不被刪除一直佔用內存空間

主動方式:週期性輪詢,定時隨機測試設置keys的過期時間。所有這些過期的keys將會從密鑰空間刪除。

具體就是Redis每秒10次做的事情:

1、測試隨機的20個keys進行相關過期檢測。

2、刪除所有已經過期的keys。

3、如果有多於25%的keys過期,重複步奏1.

這是一個平凡的概率算法,基本上的假設是,我們的樣本是這個密鑰控件,並且我們不斷重複過期檢測,直到過期的keys的百分百低於25%,這意味著,在任何給定的時刻,最多會清除1/4的過期keys。

2、淘汰掉冷數據

redis配置文件設置最大的內存大小和達到最大內存執行淘汰策略

設置內存最大值(單位是字節):maxmemory

設置達到內存設置的最大值後的淘汰策略:maxmemory-policy noeviction

maxmemory-policy的取值:

allkeys-lru: 嘗試回收最少使用的鍵(LRU),使用時間最老的

allkeys-lfu:嘗試回收使用最少的鍵(LFU),使用次數最少

volatile-random:回收隨機的鍵使得新添加的數據有空間存放,但僅限於在過期集合的鍵。

allkeys-random:回收隨機的鍵使得新添加的數據有空間存放

volatile-ttl:刪除具有最近過期時間的key

noeviction :不刪除任何內容只是在寫操作時報錯


分享到:


相關文章: