Redis 的作者 antirez 在三天之前通過部落格文章《 The first release candidate of Redis 4.0 is out 》發布了 Redis 4.0 的第一個 RC 版本, 在博文中他說, 因為這個新版本的 Redis 出現了多項改變, 所以他決定從原來的 3.x 版本直接跳到 4.0 版本, 以此來強調這次更新的變化之大。
本文將對 Redis 4.0 的各項主要新功能做一個簡單的介紹, 方便大家第一時間瞭解到這次更新的主要內容。
Redis 4.0 發生的最大變化就是加入了模組系統, 這個系統可以讓使用者通過自己編寫的代碼來擴充和實現 Redis 本身並不具備的功能, 具體使用方法可以參考 antirez 的博文《Redis Loadable Module System》: http://antirez.com/news/106
因為模組系統是通過高層次 API 實現的, 它與 Redis 核心本身完全分離、互不干擾, 所以使用者可以在有需要的情況下才啟用這個功能, 以下是 redis.conf 中記載的模組載入方法:
################################## MODULES ###################################### Load modules at startup. If the server is not able to load modules# it will abort. It is possible to use multiple loadmodule directives.## loadmodule /path/to/my_module.so# loadmodule /path/to/other_module.so
目前已經有人使用這個功能開發了各種各樣的模組, 比如 Redis Labs 開發的一些模組就可以在 http://redismodules.com 看到, 此外 antirez 自己也使用這個功能開發了一個神經網路模組: https://github.com/antirez/neural-redis
模組功能使得使用者可以將 Redis 用作基礎設施, 並在上面構建更多功能, 這給 Redis 帶來了無數新的可能性。
新版本的 PSYNC 命令解決了舊版本的 Redis 在複製時的一些不夠最佳化的地方: 在舊版本 Redis 中, 如果一個從伺服器在 FAILOVER 之後成為了新的主節點, 那麼其他從節點在複製這個新主的時候就必須進行全量複製。 在 Redis 4.0 中, 新主和從伺服器在處理這種情況時, 將在條件允許的情況下使用部分複製。 在舊版本 Redis 中, 一個從伺服器如果重啟了, 那麼它就必須與主伺服器重新進行全量複製, 在 Redis 4.0 重, 只要條件允許, 主從在處理這種情況時將使用部分複製。
新添加了 Last Frequently Used 緩衝驅逐策略, 具體資訊見 antirez 的博文《Random notes on improving the Redis LRU algorithm》: http://antirez.com/news/109
另外 Redis 4.0 還對已有的緩衝驅逐策略進行了最佳化, 使得它們能夠更健壯、高效、快速和精確。 非阻塞 DEL 、 FLUSHDB 和 FLUSHALL
在 Redis 4.0 之前, 使用者在使用 DEL 命令刪除體積較大的鍵, 又或者在使用 FLUSHDB 和 FLUSHALL 刪除包含大量鍵的資料庫時, 都可能會造成伺服器阻塞。
為瞭解決以上問題, Redis 4.0 新添加了 UNLINK 命令, 這個命令是 DEL 命令的非同步版本, 它可以將刪除指定鍵的操作放在後台線程裡面執行, 從而儘可能地避免伺服器阻塞:
redis> UNLINK fruits(integer) 1
因為一些曆史原因, 執行同步刪除操作的 DEL 命令將會繼續保留。
此外, Redis 4.0 中的 FLUSHDB 和 FLUSHALL 這兩個命令都新添加了 ASYNC 選項, 帶有這個選項的資料庫刪除操作將在後台線程進行:
redis> FLUSHDB ASYNCOKredis> FLUSHALL ASYNCOK
Redis 4.0 對資料庫命令的另外一個修改是新增了 SWAPDB 命令, 這個命令可以對指定的兩個資料庫進行互換: 比如說, 通過執行命令 SWAPDB 0 1 , 我們可以將原來的資料庫 0 變成資料庫 1 , 而原來的資料庫 1 則變成資料庫 0 。
以下是一個使用 SWAPDB 的例子:
redis> SET your_name "huangz" -- 在資料庫 0 中設定一個鍵OKredis> GET your_name"huangz"redis> SWAPDB 0 1 -- 互換資料庫 0 和資料庫 1OKredis> GET your_name -- 現在的資料庫 0 已經沒有之前設定的鍵了(nil)redis> SELECT 1 -- 切換到資料庫 1OKredis[1]> GET your_name -- 之前在資料庫 0 設定的鍵現在可以在資料庫 1 找到"huangz" -- 證明兩個資料庫已經互換
混合 RDB-AOF 持久化格式
Redis 4.0 新增了 RDB-AOF 混合持久化格式, 這是一個可選的功能, 在開啟了這個功能之後, AOF 重寫產生的檔案將同時包含 RDB 格式的內容和 AOF 格式的內容, 其中 RDB 格式的內容用於記錄已有的資料, 而 AOF 格式的記憶體則用於記錄最近發生了變化的資料, 這樣 Redis 就可以同時兼有 RDB 持久化和 AOF 持久化的優點 —— 既能夠快速地產生重寫檔案, 也能夠在出現問題時, 快速地載入資料。
這個功能可以通過 aof-use-rdb-preamble 選項進行開啟, redis.conf 檔案中記錄了這個選項的使用方法:
# When rewriting the AOF file, Redis is able to use an RDB preamble in the# AOF file for faster rewrites and recoveries. When this option is turned# on the rewritten AOF file is composed of two different stanzas:## [RDB file][AOF tail]## When loading Redis recognizes that the AOF file starts with the "REDIS"# string and loads the prefixed RDB file, and continues loading the AOF# tail.## This is currently turned off by default in order to avoid the surprise# of a format change, but will at some point be used as the default.aof-use-rdb-preamble no
新添加了一個 MEMORY 命令, 這個命令可以用於視察記憶體使用量情況, 並進行相應的記憶體管理操作:
redis> MEMORY HELP1) "MEMORY USAGE <key> [SAMPLES <count>] - Estimate memory usage of key"2) "MEMORY STATS - Show memory usage details"3) "MEMORY PURGE - Ask the allocator to release memory"4) "MEMORY MALLOC-STATS - Show allocator internal stats"
其中, 使用 MEMORY USAGE 子命令可以估算儲存給定鍵所需的記憶體:
redis> SET msg "hello world"OKredis> SADD fruits apple banana cherry(integer) 3redis> MEMORY USAGE msg(integer) 62redis> MEMORY USAGE fruits(integer) 375
使用 MEMORY STATS 子命令可以查看 Redis 當前的記憶體使用量情況:
redis> MEMORY STATS1) "peak.allocated"2) (integer) 10144803) "total.allocated"4) (integer) 10145125) "startup.allocated"6) (integer) 9630407) "replication.backlog"8) (integer) 09) "clients.slaves"10) (integer) 011) "clients.normal"12) (integer) 4961413) "aof.buffer"14) (integer) 015) "db.0"16) 1) "overhead.hashtable.main" 2) (integer) 264 3) "overhead.hashtable.expires" 4) (integer) 3217) "overhead.total"18) (integer) 101295019) "keys.count"20) (integer) 521) "keys.bytes-per-key"22) (integer) 1029423) "dataset.bytes"24) (integer) 156225) "dataset.percentage"26) "3.0346596240997314"27) "peak.percentage"28) "100.00315093994141"29) "fragmentation"30) "2.1193723678588867"
使用 MEMORY PURGE 子命令可以要求分配器釋放更多記憶體:
redis> MEMORY PURGEOK
使用 MEMORY MALLOC-STATS 子命令可以展示分配器內部狀態:
redis> MEMORY MALLOC-STATSStats not supported for the current allocator
相容 NAT 和 Docker
Redis 4.0 將相容 NAT 和 Docker , 具體的使用方法在 redis.conf 中有記載:
########################## CLUSTER DOCKER/NAT support ######################### In certain deployments, Redis Cluster nodes address discovery fails, because# addresses are NAT-ted or because ports are forwarded (the typical case is# Docker and other containers).## In order to make Redis Cluster working in such environments, a static# configuration where each node known its public address is needed. The# following two options are used for this scope, and are:## * cluster-announce-ip# * cluster-announce-port# * cluster-announce-bus-port## Each instruct the node about its address, client port, and cluster message# bus port. The information is then published in the header of the bus packets# so that other nodes will be able to correctly map the address of the node# publishing the information.## If the above options are not used, the normal Redis Cluster auto-detection# will be used instead.## Note that when remapped, the bus port may not be at the fixed offset of# clients port + 10000, so you can specify any port and bus-port depending# on how they get remapped. If the bus-port is not set, a fixed offset of# 10000 will be used as usually.## Example:## cluster-announce-ip 10.1.1.5# cluster-announce-port 6379# cluster-announce-bus-port 6380