The first release candidate of Redis 4.0 is out

Salvatore Sanfilippo

Redis 4.0 首個候選版釋出

原文由 Salvatore Sanfilippo 發布,訂閱此部落格

它還不是穩定版,但很快就會是了,而且帶來了一長串會讓 Redis 對我們這些使用者更實用的東西:終於,Redis 4.0 Release Candidate 1 來了,而且還大膽地直接叫自己 4.0,而不是 3.4。對我來說,語意化版本控制根本不是重點,我更喜歡的是試著用版號和版號的跳躍來傳達新版本到底是怎麼回事,而在這個例子裡,4.0 的意思就是「這東西屌炸了」。

只是 Redis 4.0 有太多 Redis 早就該有的東西,在另一個世界裡,一個開發者可以像《北斗神拳》一樣,分身成十個然後同時開始寫程式。但不管我多努力去學新的 vim 快捷鍵,分身術還是不在我的技能組裡。

不過呢,總算在 4.0 裡我們把很多這類東西都完成了……以下是幾個重點項目的清單,附上一點細節和延伸閱讀的線索。

1. 模組

你大概已經知道 Redis 4.0 有了模組系統,而且是那種能玩出不少花樣的系統,像是實作可透過 RDB/AOF 持久化的全新資料型別、建立非阻塞指令等等。重點在於,這一切都是透過一套更高階、完全與核心分離的抽象 API 來完成的,所以你寫的模組在未來的新版 Redis 上也能繼續運作。透過模組,我寫了 Neural Redis,一個可以在 Redis 內部直接訓練的類神經網路資料型別,也有很多人正在做非常有趣的東西:有新的限流指令(用 Rust 實作的!)、建在 Redis 之上的圖資料庫、次級索引、時間序列模組、全文索引,以及其他一大堆東西,而我的感覺是,這還只是開始。

這不僅讓 Redis 能夠成長、涵蓋更多新領域,同時又能讓核心保持精簡——就算稱不上極簡,至少也只保留對大多數使用者有用的、相當通用的功能。但它也有潛力讓許多任務免去重寫一個網路伺服器的麻煩,即使你的目標是要做一個跟 Redis、資料庫、快取或任何 Redis 所代表的東西無關的東西。也就是說,你完全可以只靠寫一個模組,就借用 Redis 的「基礎設施」:協定、大家已經寫好的客戶端等等。所以我對此抱持樂觀,核心沒有壓力,想玩更瘋狂東西的使用者也能享有自由。

2. 複寫機制第二版

從維運的角度來看,這在正式環境中會非常實用。過去某個時間點,我們引入了所謂的「PSYNC」。那是一個新的主從協定,讓 master 與 slave 在兩者之間的連線中斷後,還能從中斷的地方繼續同步。在那之前,主從之間複寫連線的每一次中斷,都會導致一次完整同步:在 master 端產生 RDB 檔、傳輸過去、在 slave 端載入,好,你知道這是怎麼運作的。所以 PSYNC 算是一大進步。但還不夠……

PSYNC 在發生容錯移轉時還不夠好。如果一個 slave 被提升為 master,原本跟舊 master 同步的那些 slave 就沒辦法連上這個新晉升的 slave 並與它進行 PSYNC:必須做一次完整重新同步。這不太妙,對 Redis Cluster 來說也不好。然而要修掉這個問題,就必須改動複寫協定,因為我真的想確保,只要實例之間還保有共同的複寫歷史,無論拓撲怎麼變化,部分重新同步都能正常運作。

所以第一個需要的改動,是關於「鏈式複寫」如何運作,也就是 slave 的 slave 的 slave……它們是怎麼運作的?像是,A 是 master,而我們有這樣的結構:

A —> B —> C —> D

所以 A 是 B 的 master,而 B 是 C 的 master,依此類推。在 Redis 4.0 之前,情況是 B 從 A 接收複寫協定。複寫協定通常就是一串寫入指令的串流。B 作為 C 的 master,內部只是重做 A 在做的事:每寫入一次,就重新產生一份合適的複寫協定傳給 C,依此類推。

現在則不同,B 只是原封不動地把從 A 收到的東西代理轉發給 C,C 也會對 D 做同樣的事:既然所有的下層 slave 現在收到的都是一模一樣的位元組串流,它們就能替某段歷史打上「標籤」,並利用這個標籤和偏移量,只要彼此有共同的部分,就嘗試接續下去。

master 本身在被轉為 slave 時,現在也能夠與新的 master 進行 PSYNC。而 slave 即使在「乾淨」重啟後,通常也能與 master 進行 PSYNC,因為 RDB 檔案現在會儲存複寫標籤與偏移量等資訊。

要讓它運作得好,細節其實比這樣複雜得多,不過重點就在於,盡量別再被完整重新同步搞得心煩。而 PSYNC v2 顯然在這方面做得不錯。如果你對這個功能感興趣,請試試看並讓我知道感想。

3. 快取淘汰機制的改進

關於這個,我幾個月前寫過一篇完整的文章:http://antirez.com/news/109。所以這裡只給你 TLDR。我們現在有了 LFU(Last Frequently Used),而且所有其他策略也都換成了更穩健、更快、更精準的實作。所以對快取使用情境來說是個大消息。如果你關心這方面的東西,去讀完整文章吧,裡面有大量資訊。

4. 非阻塞的 DEL 與 FLUSHALL/FLUSHDB

代號叫「lazy freeing of objects」,不過對這麼棒的功能來說是個有點遜的名字。有一個新指令叫 UNLINK,它只會刪除資料庫中的鍵參照,並在另一個執行緒中實際清理所配置的記憶體,所以如果你對一個巨大的鍵改用 UNLINK 而不是 DEL,伺服器就不會被卡住。更棒的是,透過 FLUSHALL 和 FLUSHDB 的 ASYNC 選項,你甚至可以對整個 DB 或執行個體內的所有資料做同樣的事。搭配新的 SWAPDB 指令——它會互換兩個 Redis 資料庫的內容——FLUSHDB ASYNC 就變得相當有趣。舉例來說,一旦你把新版的資料填進 DB 1,就可以執行 SWAPDB 0 1,然後用 FLUSHDB ASYNC 清掉放著舊資料的資料庫,再建立更新的版本並反覆操作。這之所以現在才可行,是因為清空整個 DB 不再會造成阻塞。

UNLINK 沒有成為 DEL 預設行為是有原因的。我知道一些內情……我不能說 (**)。

5. 混合式 RDB-AOF 持久化格式

可選地,如果你啟用它,現在 AOF 重寫會透過在 AOF 檔案開頭加上一個 RDB 檔案來完成,這樣產生和載入都更快。這在某些環境下會非常有用,但也讓 AOF 檔案變得比較不那麼直觀透明,所以目前還是個可選項目。這個功能已經被討論了很久,總算「進來了」。

6. 全新的 MEMORY 指令

我超愛它,就像我當初超愛 LATENCY DOCTOR 一樣,那個指令一推出,就把郵件論壇上「我的 Redis 好慢」這類抱怨的比例砍到只剩一小部分。現在,我們對記憶體問題也有同樣的東西了。

127.0.0.1:6379> MEMORY DOCTOR
Hi Sam, this instance is empty or is using very little memory, my issues detector can't be used in these conditions. Please, leave for your mission on Earth and fill it with some data. The new Sam and I will be back to our programming as soon as I finished rebooting.

電影版權方大概會因為我借用了科幻片台詞而告我,不過沒關係。到時來探監記得帶顆橘子給我。

MEMORY 能做的還不只這些。

127.0.0.1:6379> MEMORY HELP
1) "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"

USAGE 子指令的記憶體用量報告會非常實用,不過「STATS」提供的深入資訊也同樣有幫助。

目前這些都還完全沒有文件,所以好好享受摸索它到底在幹嘛的樂趣吧。

7. Redis Cluster 現在相容於 NAT / Docker

但這其實也是個壞消息,因為節點之間用來溝通的「Cluster bus」二進位協定改了,所以要升級到 4.0,你就得把整個 Redis Cluster 全部重啟。很抱歉我被拐去做了這些 NAT / Docker 的修正,請原諒我。我也試過要做到向下相容,但無論是簡單還是困難的方法,都沒辦法輕鬆達成,除非去搞一些非常彆扭的東西。

這個功能在範例的 redis.conf 檔案裡有說明。你看得出來我對這個功能比起其他功能稍微不那麼興奮吧,對吧?

好吧……我想大概就是這樣,這些就是主要的東西。如果你想,也可以到這裡閱讀發行說明:https://raw.githubusercontent.com/antirez/redis/4.0/00-RELEASENOTES

至於何時會變成穩定版,一如往常還是未知數:我計畫大約每 2 到 4 週釋出一個新的 RC。當錯誤回報無論在嚴重程度還是頻率上都明顯放緩時,就是 Redis 4.0 正式版的時候了。不過還有大量文件要更新,所以我還有很多事要做。

非常感謝所有為這個版本做出貢獻的人:很多人都以重要的方式參與了。在上面的發行說明中,有所有 commit 的清單,你可以瀏覽看看提交者的名字。

感謝 Redis 社群與 Redis Labs 讓這一切成真,但更要特別感謝所有使用 Redis、並在日常問題中好好運用它來把事情搞定的開發者,因為這才是重點所在,除了寫程式時的樂趣之外。

P.s. 要最快拿到新程式碼的方式,就是從 GitHub 上抓取 '4.0' 分支。儲存庫一如往常是 antirez/redis。

** 關於 UNLINK 沒有成為 DEL 預設行為的更多資訊,請參考 https://news.ycombinator.com/item?id=13091370

本文章由 muse-spark-1.2-contributor 進行翻譯

留言