Redis 4.0 首個候選發行版釋出
它還不算穩定,但很快就會穩定下來,而且帶來了一長串會讓 Redis 對我們使用者更有用的東西:Redis 4.0 Release Candidate 1 終於來了,還大膽地自稱為 4.0,而不是 3.4。對我來說,語意化版本控制根本不是重點,我更喜歡的是試著透過版號與版號的跳躍,來傳達新版本到底是怎麼回事,而在這個特例中,4.0 的意思就是「這就是超屌的東西」。
Redis 4.0 其實包含了許多 Redis 早就該有的東西,如果是在另一個世界裡,一位開發者可以像 Ken The Warrior 一樣,分身成十個自己同時開始寫程式。但不管我多努力學習新的 vim 快捷鍵,那個分身術終究不在我的絕招裡。
不過呢,透過 4.0 我們總算把其中很多東西都完成了……以下是幾個重點項目的清單,附上一些細節與延伸閱讀的線索。
1. Modules(模組)
如你可能已經知道的,Redis 4.0 擁有了一套 modules 系統,而且是一套能做出相當炫目功能的系統,例如實作可透過 RDB/AOF 持久化的新資料型別、建立非阻塞指令等等。重點在於,這一切都是透過一套與核心完全分離、更高層級的抽象 API 來完成,所以你撰寫的 modules 在新版的 Redis 上依然能運作。透過 modules,我寫了 Neural Redis,一種可以在 Redis 內部直接訓練的神經網路資料型別,也有許多人正在做非常有趣的事:有在 Rust 中實作的全新限流指令、在 Redis 之上打造的 Graph DBs、次要索引、時間序列 modules、全文索引,以及其他許許多多的東西,而我的感覺是,這僅僅是開始。
這不僅讓 Redis 能在保持核心——若非極簡,至少也是僅保留對多數使用者有用、相當通用的功能——的同時,持續成長並涵蓋新領域。也有潛力讓許多任務免去重寫一整個網路伺服器的麻煩,即使目標是要打造某個與 Redis、資料庫、快取或 Redis 所代表的任何事物無關的東西。也就是說,你大可只寫一個 module,來利用 Redis 的「基礎設施」:協定、大家已經寫好的客戶端等等。所以我對此感覺相當樂觀,核心沒有壓力,想做更瘋狂嘗試的使用者則擁有自由。
2. 複寫版本 2
所以,從維運的角度來看,這在正式環境中將會非常有用。過去某個時間點,我們引入了所謂的「PSYNC」。那是一種全新的主從協定,讓主節點與從節點在兩者之間的連線中斷後,能從中斷處繼續同步。在那之前,主節點與從節點之間複寫連線的每一次中斷,都會導致一次完整同步:在主節點產生 RDB 檔案、傳輸它、在從節點載入它,好吧你知道這是怎麼運作的。所以 PSYNC 可說是一大改進。但還不夠……
PSYNC 在發生容錯移轉時還不夠好。如果一個從節點被提升為主節點,原本與舊主節點進行複寫的從節點就無法連接到這個新晉升的從節點並與之 PSYNC:必須進行一次完整重新同步。這可不理想,對 Redis Cluster 來說也不好。然而,要修正這個問題,就必須對複寫協定做更動,因為我真的想確保,只要執行個體之間存在共同的複寫歷史,無論發生任何可能的拓撲變動,部分重新同步都能正常運作。
因此,第一個需要的改動是關於「chained replication(鏈式複寫)」如何運作,也就是從節點的從節點的從節點……它們是如何運作的?像是,A 是主節點,而我們有像這樣的結構:
A —> B —> C —> D
所以 A 是 B 的主節點,但 B 是 C 的主節點,依此類推。在 Redis 4.0 之前,實際發生的情況是 B 從 A 接收複寫協定。複寫協定通常是一串寫入指令的串流。B 作為 C 的主節點,僅僅是在內部重做 A 所做的事:在每次寫入時,它都會再次產生一套合適的複寫協定來傳遞給 C,依此類推。
現在,B 則是逐字原樣地將它從 A 接收到的內容代理轉發給 C,而 C 也會對 D 做同樣的事:既然所有下層從節點現在都收到完全相同的位元組串流,它們就能為一段給定的歷史「打上標籤」,並利用該標籤與位移量,只要彼此有共同的部分,就嘗試接續下去。
主節點本身在被轉為從節點後,現在也能夠與新的主節點 PSYNC。而從節點通常即使在「乾淨」重啟後,也能與主節點 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-final 的時候了。不過還有大量文件需要更新,所以我還有很多事要做。
非常感謝所有為這個版本做出貢獻的人:許多人都以重要的方式付出了。在上面的發行說明中有所有 commit 的清單,你可以瀏覽以查看提交者的名字。
感謝 Redis 社群與 Redis Labs 讓這一切得以實現,但尤其要感謝所有使用 Redis 並在日常問題中善加運用、把事情搞定的開發者們,因為這才是全部的重點,當然,除了寫程式時的樂趣之外。
P.S. 取得新程式碼最快的方式是從 Github 上抓取 '4.0' 分支。儲存庫一如往常是 antirez/redis。
** 關於 UNLINK 為何不是 DEL 預設行為的更多資訊,請查看 https://news.ycombinator.com/item?id=13091370。
隨機一篇部落格