Redis進化史:看Redis如何變成緩存
寫在前面:筆者翻閱了很多資料,只能找到Redis2.2及以后的主要版本的發(fā)布日志。所以,讓我們從2.2開始一步一步深入了解Redis。
2.2
- redis-cli命令非常大的改進: Tab補全,支持help(例如help SET、help BITCOUNT),原生輸出,并用新的hiredis C庫對其進行重寫。
- copy-on-write機制對很多讀命令支持更友好,這就意味著,如果大部分是讀操作的話,fork出來的子進程只需要很少的內存即可。
- 新命令WATCH,實現(xiàn)CAS事務。
- 可以對具有EXPIRE失效屬性的KEY進行寫操作。
- 全新的SETBIT、GETBIT、SETRANGE、GETRANGE、STRLEN命令,操作string就像一個數(shù)組一樣,我們可以進行位操作。
- 支持syslog(在配置文件中指定:syslog-enabled yes)。
- List新增了很多命令:LINSERT,LPUSHX,RPUSHX,BRPOPLPUSH 。
- 更強大的INFO命令。
- 啟動時加載RDB或者AOF是無阻塞的,并且在INFO輸出有進度信息。
- hiredis:強大的C語言Redis客戶端庫。
- 支持在配置文件中rename重命名(rename-command KEYS afeikeys)者禁用(rename-command KEYS "")命令。
syslog說明:
在Linux的世界里,有兩種寫日志的方式:
1. 就是把日志寫到文件中,隨著時間的推移,我們會寫到一個新的文件中。這種方式的問題就是,如果有很多的服務產(chǎn)生很多的日志,那么就比較麻煩了。
2.利用syslog服務記錄日志,在幾乎所有可用的Unix和Linux服務器的TCP和UDP端口514上運行一個名為syslog的服務,syslog接受任何向其發(fā)送的日志消息并將這些消息路由到各種消息的磁盤上的日志文件,同時處理舊日志的滾動和刪除。通過配置,它甚至可以將消息轉發(fā)到其他服務器以進行進一步處理,它是遠比直接記錄到文件更方便,因為所有的特殊日志文件的滾動和刪除已經(jīng)幫我們做好了。
2.4
Redis2.4沒有值得大書特書的特性,大部分是一些bug fix或者特性增強,這個版本的新特性一覽:
- VM deprecated,還會支持不過會給出告警,不建議使用。
- 新增CLIENT命令,支持KILL,LIST等操作,從而能夠觀察CLIENT的一些信息;
- 新增OBJECT命令,從而能夠觀察對象的一些內在信息,比如對象是什么編碼;
- 通過直接通過CONFIG SET在不重啟Redis服務的情況下關閉密碼授權;
- 如果沒有設置密碼,而又通過AUTH發(fā)送密碼進行鑒權,那么返回ERROR。
- redis-cli新增實現(xiàn)了--latency模式,以便能監(jiān)控采樣Redis延遲。
- 當fsync刷新策略是everysec的時候,AOF fsync在后臺執(zhí)行。
- SADD, HDEL, SREM, ZREM, ZADD, L/RPUSH命令增強,增加對可變參數(shù)的支持(老版本只支持一個參數(shù))。
2.6
Redis2.6新特性如下:
- 服務側的Lua腳本支持,通過EVAL執(zhí)行,例如:eval "return redis.call('set','foo','bar')" 0。
- 失效時間支持毫秒精度,并且相應的增加了毫秒級失效的命令:PEXPIRE、PSETEX和PTTL等。
- 支持只讀的Slave。
- 支持位操作命令:BITCOUNT和BITOP,還有很多其他新增的命令,例如:DUMP, RESTORE, MIGRATE等。
- RDB文件中新增CRC64校驗值。
- SHUTDOWN支持兩個選項:SAVE和NOSAVE。
- INFO命令輸出按段分割。
- watchdog特性定位延遲問題,只需執(zhí)行config set watchdog-period 100就能開啟該特性,如果值是0就表示關閉該特性。需要說明的是,該特性不能在配置文件中開啟。
- 集成內存測試模式,參考執(zhí)行:redis-server --test-memory 1024。
- 所有redis.conf中的配置都可以通過redis-server的命令行選項指定。
- hash table的seed隨機化,以防止碰撞攻擊。
- 去掉虛擬內存你功能(2.4已經(jīng)deprecated)。
- 去掉對客戶端連接數(shù)硬編碼限制。
watchdog可以參考:https://redis.io/topics/latency,筆者接下來也會單獨撰文進行深入剖析。
2.8
Redis2.8雖然沒有非常重磅的新特性,但是它非常非常穩(wěn)定,除了沒有分布式特性,我挑不出太大的毛病,高可用可以由sentinel保證。筆者當年經(jīng)歷過的一個項目,用Redis2.8.23這個版本,單機模式,10G+的數(shù)據(jù)量,居然穩(wěn)定的運行了500天左右。
即使到現(xiàn)在,如果你的項目不需要幾十個G的緩存,我依然認為Redis2.8.x這個版本是不錯的選擇,結合sentinel模式保證高可用,而且相比Redis3.x的分布式集群模式,它的架構更簡單,而且不需要妥協(xié)任何功能和命令(Redis cluster模式下,很多命令功能閹割,或者受到限制。當然,Redis3.x以后的高版本,也可以只用sentinel,可以不用redis cluster架構)。
OK,還是來看一下2.8新特性吧:
- slave支持從master部分同步,這樣就能避免主從斷開一會兒時間(例如網(wǎng)絡抖動)后需要通過RDB全量同步。
- 支持IPv6。
- 支持config set maxclients 1024。
- 支持綁定多個IP地址。
- CONFIG REWRITE能夠將通過CONFIG SET操作的配置輸出在redis.conf配置文件中。
- 新增PUBSUB命令,即為了實現(xiàn)Pub/Sub的自省能力。
- 通過Pub/Sub實現(xiàn)keyspaces的變化通知,例如實現(xiàn)過期KEY的通知功能。
- 如果在最大延遲下沒有足夠數(shù)量從,主可以停止寫請求。配置參考如下:
- # 例如,至少3個延遲在10秒以內的slave,master才會正常寫入:
- # min-slaves-to-write 3
- # min-slaves-max-lag 10
3.0
Redis3.0絕對是一個里程碑版本,耗時4年才開發(fā)完成。在Redis3.0之前,Redis是沒有分布式模式的(sentinel模式只能保證高可用)。正因為這樣,導致民間出現(xiàn)了很多Redis分布式方案,比較有名氣的3種是:1. Redis客戶端分片,2. twemproxy,3. codis(豌豆莢)。
Redis3.0的重磅功能有:
- Redis Cluster,即Redis分布式模式,Redis3.0最重磅的特性;
- WAIT命令阻塞,直到寫命令被同步到指定數(shù)量的slave上,命令始終返回寫命令發(fā)送的slaves的數(shù)量。用法:WAIT numslaves timeout。例如:WAIT 2 5000,即等待2個slave同步所有寫命令并設置超時5秒鐘。
- 新增CLIENT PAUSE命令,例如:CLIENT PAUSE 10000,即停止處理客戶端命令10秒鐘,這時候如果有新的命令執(zhí)行,會一直阻塞。
- CONFIG SET命令增強,支持不同的單位,例如CONFIG SET maxmemory 1gb、CONFIG SET maxmemory 1024mb;
- MIGRATE命令增強,增加了COPY和REPLACE操作。
- Redis日志做了小小的調整,日志中會反應當前實例的角色,很明顯是為了Redis Cluster。
3.2
Redis3.2版本的一些重要特性如下:
- Lua debugger,官方給出了參考視頻,不過是在Youtube上:https://www.youtube.com/watch?v=IMvRfStaoyM,能不能看的了就靠自己了。
- CONFIG SET/GET實現(xiàn)重寫,支持更多的操作項。
- 新增HSTRLEN命令,返回hash結構指定field的value的字符串長度,如果hash或者field不存在,那么返回0。
- 通過RESIZEDB避免不必要的hash擴容,實現(xiàn)更快的RDB加載速度。
- 新增對GEO的支持,并提供若干個操作GEO的命令,例如:GEOADD, GEORADIUS,GEOHASH,GEOPOS等。
- 實現(xiàn)CLIENT REPLY,并支持三種操作:ON、OFF、SKIP。ON就是正常模式,服務端會回復請求。OFF模式下,服務端不會對任意命令回復。這種情況一般用于發(fā)送-忘記的場景下,例如:大量緩存數(shù)據(jù)加載,利用OFF模式可以關閉響應,節(jié)省帶寬等資源。
- SPOP命令支持count參數(shù),使用參考:SPOP key [count]。即刪除并返回count個元素。
- List類型新的編碼方式:Quicklists。在RDB文件中能節(jié)省很多內存和存儲空間。
4.0
Redis官方給出沒有命名為3.4而是4.0的原因是:這個版本添加了很多重要的特性,而且很多核心功能被重寫了。讓我們看一下Redis4.0主要的功能有哪些:
- Redis模塊系統(tǒng),這個功能的實現(xiàn),開發(fā)者可以為Redis自定義擴展,實現(xiàn)新的數(shù)據(jù)結構等任意特性。
- PSYNC版本升級到v2版本,優(yōu)化了之前版本中,主從節(jié)點切換必然引起全量復制的問題。
- 緩存驅逐策略增強,新增了LFU策略,即Least Frequently Used。
- 異步刪除(延遲回收)。Redis4.0可以在后臺異步刪除KEY,而不需要同步阻塞服務端,通過新增的命令UNLINK實現(xiàn),用法:UNLINK key [key …]。
- 混合RDB-AOF格式,這種格式被用在重寫AOF文件的時候,重寫用更緊湊更快速的方式生成RDB文件,AOF流追加到這個文件上,這樣的話,AOF持久化重寫和重新加載的速度更快,參考配置:aof-use-rdb-preamble yes。
- 增加一個MEMORY命令,能否做很多不同的內存分析工作,例如內存問題排查、查看一個KEY用了多少內存、提供與INFO命令內容相比更加深入地報告Redis內存使用情況;
- Redis可以整理內存碎片化了,能在運行的過程中回收內存空間,參考配置:activedefrag yes,還有很多對應的配置參數(shù),可以在Redis4.0以后的版本的redis.conf中查看。
- Redis集群支持NAT/Docker。
memory命令使用參考--查看一個KEY用了多少內存(單位是字節(jié)),相信很多同學不知道這個神奇的命令吧,那么,現(xiàn)在就GET它吧:
- > SET foo bar
- OK
- > MEMORY USAGE foo
- (integer) 54
5.0
這是Redis最新的一個主要版本,筆者之前有篇文章對Redis5.0有深入分析,感興趣的朋友請戳:。5.0的重要特性主要有:
- Streams數(shù)據(jù)結構,Redis一個全新的數(shù)據(jù)結構,借鑒了很多kafka的設計(這個數(shù)據(jù)結構筆者之前也有文章介紹,詳情請戳:)。
- Redis集群管理腳本從Ruby(redis-trib.rb)遷移到存C,且集成到redis-cli中(redis-cli --cluster)。
- Sorted Set新增兩個重要的命令:ZPOPMIN和ZPOPMAX。
- 支持HZ動態(tài)化;
- 不再使用slave這個詞,除非為了API向后兼容(種族歧視問題)。
- Lua腳本可以設置超時。
- CLIENT支持兩個新命令:CLIENT ID和CLIENT UNBLOCK。