摘要: 社區最新GA版本Redis 4.0推出已近一年,阿里雲數據庫Redis 4.0版也上線近半年,以前關於Redis 4.0的系列文章從源碼實現來分析這些新功能,本文旨在從用戶角度出發,讓Redis的用戶可以快速瞭解並使用Redis 4.0帶來的福利。git
Redis做爲時下最火爆的NoSQL數據庫以性能強悍、數據結構豐富著稱,同時其成長的腳步也從未中止,自誕生伊始已經歷屢次蛻變不斷推出新功能。github
社區最新GA版本Redis 4.0推出已近一年,阿里雲數據庫Redis 4.0版也上線近半年,以前關於Redis 4.0的系列文章從源碼實現來分析這些新功能,本文旨在從用戶角度出發,讓Redis的用戶可以快速瞭解並使用Redis 4.0帶來的福利。redis
大key刪除的問題想必不少用戶都遇到過,Redis除string外還支持list、set、hash和sorted set等複雜數據結構,這些數據結構豐富了Redis的用法,可是若是使用不當形成單key體積過大的話就會引發一些問題。算法
舉個簡單的例子,假如某社交網站有一個大V,有上百萬的粉絲,咱們能夠用set集合類型的數據結構來存儲他的粉絲ID,存儲粉絲集合的key叫作funs好了,咱們來看下粉絲數:數據庫
127.0.0.1:6379> SCARD funs
數據結構
(integer) 6320505
異步
的確是大V,有600多萬的粉絲,可是很不幸的有一天這個大V註銷了,這時就要刪除他的信息,咱們用DEL命令來刪除這個key:函數
能夠看到刪除這個動做竟然耗時3秒多,也就意味着這3秒內Redis沒法執行其餘命令,這對於線上業務來說是有傷害的,那麼如何避免刪除大key時的阻塞問題呢?Redis 4.0推出了Lazyfree這一功能,使用UNLINK命令來刪除大key,主線程只負責把key從數據庫中"摘除",真正的釋放動做放在了BIO後臺線程去作,咱們來看下效果:性能
能夠看到UNLINK執行很快沒有產生slowlog。優化
Lazyfree一共有3個命令:
以及4個配置項:
對於源碼實現有興趣的讀者能夠閱讀《Redis 4.0之Lazyfree》。
Redis內嵌了Lua環境來支持用戶擴展功能,可是出於數據一致性考慮,要求腳本必須是純函數的形式,也就是說對於一段Lua腳本給定相同的參數,重複執行其結果都是相同的。
爲何要有這個限制呢?緣由是Redis不只僅是單機版的內存數據庫,它還支持主從複製和持久化,執行過的Lua腳本會複製給slave以及持久化到磁盤,若是重複執行獲得結果不一樣,那麼就會出現內存、磁盤、slave之間的數據不一致,在failover或者重啓以後形成數據錯亂影響業務。
仍是以具體例子來看,假設有這麼一段Lua腳本,目的很簡單就是想記錄下當前時間:
這裏使用了Redis的TIME命令來獲取時間戳,而後存儲到名爲now的key中,可是其執行時會報錯:
錯誤提示也很明顯,若是執行過非肯定性命令(也就是TIME,由於時間是隨機的),Redis就不容許執行寫命令,以此來保證數據一致性。那如何才能實現隨機寫入呢?剛纔的錯誤提示也給出了答案,使用redis.replicate_commands(),在執行redis.replicate_commands()以後,Redis就再也不是把整個Lua腳本同步給slave和持久化,而是把腳本中調用Redis的寫命令直接去作複製,那麼slave和持久化也能夠獲得肯定的結果。
腳本修改以下:
再執行就能夠實現隨機寫入了:
LFU是Redis 4.0新增的一類內存逐出策略,提供了更精確的內存淘汰算法,其本質是記錄了一段時間內key的訪問頻率,同時也帶來了額外的福利就是熱點key的發現。
LFU簡單來說就是用0-255來表示key的訪問頻率,值越大說明訪問頻率越高,而且這裏對頻率的計數採用的是基於對數的機率增加,LFU爲255能夠表明100W次的訪問,關於LFU的實現有興趣的讀者能夠參考《Redis 4.0之基於LFU的熱點key發現機制》。
使用OBJECT FREQ命令便可獲取指定key的訪問頻率,不過須要首先把內存逐出策略設置爲allkeys-lfu或者volatile-lfu:
使用scan命令遍歷全部key,再經過OBJECT FREQ獲取訪問頻率並排序,便可獲得熱點key。爲了方便用戶使用,Redis自帶的客戶端redis-cli也提供了熱點key發現功能,執行redis-cli時加上--hotkeys選項便可,示例以下:
分析內存能夠優化Redis的使用方式,全新的MEMORY命令能夠幫助用戶來實現這一操做。
MEMORY命令一共有5個子命令,能夠經過MEMORY HELP來查看:
關於各個子命令的詳細使用方式能夠參考《Redis 4.0之MEMORY命令詳解》。