歡迎光臨
每天分享高質量文章

Redis作者:近期核心功能的一些思考和澄清

導讀:本文為Redis 作者 Antirez 就重點功能的發展方向做出澄清,並表明“Redis 沒有一個可靠的路線圖,多年來我發現走一步看一步才是優秀的路線圖”,閱讀此文,關註 Redis 功能研發方向。

 

昨天有位Redis 的用戶在Hacker News 上做了以下評論:

 

雖然我喜歡Redis,但我對目前正在開發的一些功能持懷疑態度。 respv3 協議中的一些功能,雖然聽起來很簡潔,但是也可能使客戶端代碼複雜化。 還有細粒度ACL 需要的工作量很大。 我無法理解為什麼這些功能是必要的,或者說比其他功能(如多執行緒支持,更好的持久化模型,資料型別等)的優先級更高。

 

很多用戶將ACL視為Redis Labs 強行添加的功能。 評論中的其他要點也很有趣,我相信這些都值得澄清,以便Redis 社區理解前方的道路。

 

為簡單起見,我將此博客文章分為幾部分,對應原始評論中提到的每個功能。

 

RESP3

 

正如我在文件上所寫的那樣,RESP3 的標的是簡化客戶端環境。我希望每個客戶端都有一個較低層次的抽象,不需要嘗試重新發明更高級別的接口,例如:redis.call(“get”,“foo”)。不再需要進行轉換,因為現有協議在語意上足以告訴客戶端response的結構,不需要事先知道大多數命令的元資料。我認為該用戶指的是 RESP3 對帶外通信的支持,即回覆“屬性”。

 

我認為Redis 未來的“客戶端快取”將是非常重要的功能。這是每個可擴展系統的必經之路。但是如果沒有服務器參與,客戶端快取失效將是一場噩夢。這就是為什麼 RESP3 需要支持回覆屬性。然而Redis 6 不會實現該功能。 Redis 現有不穩定版本將成為Redis 6.該版本已經有一個幾乎完整的RESP3(沒有實現屬性)實現。實現了RESP3 的客戶端可以先不支持屬 性,即使對於將來的Redis版本,也可能根本不發送屬性資料。對於客戶端快取,必須將連接置於特殊樣式。此外,Redis 6 將完全向後兼容RESP2。我認為RESP2 的支持永遠不會被移除,因為它是免費的,一旦我們嘗試在 RESP2 和 RESP3 之間實現一個抽象層,就沒有充分的理由來破壞向後兼容性。

 

通常我不喜歡在沒有充分理由的情況下改變事物,但RESP2 的限制對客戶端生態系統有很大影響。我希望從一個客戶端到遷移另一個客戶端,用戶有賓至如歸的感受。API 都是Redis API,而不是客戶端作者單獨的特殊抽象。除了較低級別的API,我不反對更高級的API,但它們應該有一些共同點,客戶端應該能夠在不知道任何相關命令元資料的情況下發送命令。

 

ACLs

 

四年前我自己修改了ACL 規範。我用了很長時間才說服自己現在是實現該功能的時候了:我們在沒有任何ACL 的情況需要使用命令重命名等方式來達到目的。不能認為實現ACL 的主要動機是因為企業客戶需要安全性。ACL允許出於安全目的對用戶進行身份驗證,但該功能的主要標的是可運維

 

舉例來說,你有一個Redis實體,並且計劃使用該實體來執行新操作:延遲作業處理。你從互聯網上下載了一個庫,它看起來沒啥問題。但是這個庫可以呼叫“FLUSHALL”並清除所有資料。也許只是庫的測試代碼裡面有這樣的命令,然而你意識有問題的時候為時已晚。或者你剛好雇佣了一位喜歡在Redis 實體上呼叫“KEYS ”命令的”高級”開發人員。

 

另一種情況是雲供應商:他們需要小心地重命名管理命令,甚至為了某些原因而屏蔽這些命令。使用ACL,你就能設置Redis,以便在沒有某些身份驗證的情況下,阻止預設用戶執行任何危險的操作。我認為這對運維來說將是一個很大的進步

 

此外,AC L是我為Redis AFAIK 寫的最好的代碼之一。幾乎沒有CPU成本,除非您使用密鑰樣式,然而即便使用密鑰樣式,CPU 消耗依然很低。該實現都在acl.c檔案中,其餘的代碼有一些對ACL API 的呼叫。ACL完全是模塊化的,所以沒有增加系統複雜性。實際上,ACL 代碼圍繞AUTH 命令也做了一些重構。

 

多執行緒

 

Redis 可能通過兩種方式獲得多執行緒支持。我相信用戶希望的是“memcached相似”的多執行緒,即能夠將單個Redis 實體擴展到多個執行緒,以便增加QPS。這種設計將I/O,命令解析等多執行緒化。所以我們稱之為“I/O執行緒”。

 

另一種多執行緒方法是允許在其他執行緒中執行慢速命令,以便不阻塞客戶端。我們將這種執行緒模型稱為“慢速命令執行緒”。

這就是計劃:I/O執行緒方案不會出現在Redis AFAIK中,因為經過深思熟慮之後,我認為該方案太複雜。大部分Redis 的瓶頸實際上是網絡或記憶體。另外,我喜歡share-nothing,所以我想擴展Redis 的方法是改進其對同一主機中執行多個Redis實體的支持,特別是通過Redis Cluster。 因此,2019年主要集中在兩件事:

A)redis cluster多個實體能夠協調使用本地實體的磁盤,即避免AOF同時重寫。

B)我們將把Redis集群代理作為Redis 專案的一部分發佈,這樣用戶就可以在沒有良好實現集群協議客戶端的情況下抽象出集群。

另外需要註意的是Redis不是Memcached,然而像memcached一樣,它是一個記憶體系統。對於非常簡單的資料模型來說多執行緒(如memcached)非常有意義。對於Redis來說,多執行緒磁盤儲存也是必須的。一個多執行緒的複雜記憶體系統將是非常複雜的:Redis 客戶端不是孤立的,資料結構也很複雜。例如,執行LPUSH 的執行緒需要服務於執行 LPOP 的其他執行緒。獲得的收益較少,添加的複雜性也很高。

相比之下,我想要解決的是慢操作問題,並且因為有了Redis 模塊系統,我們已經走上了正確的方向。在將來(不確定是否在Redis 6或7中)我們會在模塊系統中實現key 級鎖定,以便執行緒可以完全獲得對key 的控制以處理慢操作。現在,模塊可以實現命令,並以完全獨立的方式為客戶端創建回覆,但仍然需要訪問共享資料集,這時候需要全域性鎖。

 

更好的儲存

 

最近我們做了多項努力,以改善Redis的基本功能。 最近的最優秀的實現是AOF檔案中的RDB前導碼。 Redis 4和5中還有很多關於複製的工作,與之相比現在的改進完全處另一個級別。 改進這些功能仍然是我的主要工作之一。

 

資料結構

 

從Redis 5 開始,Redis 就支持了Stream 結構。對於Redis 6和7,我們計劃優化一些實現,提高記憶體使用效率。 然而要添加新的資料結構,就需要做很多考慮。 我花了幾年時間才領悟到,如何在時間序列和 stream 的背景下使用stream 來彌合lists, pub/sub以及 sorted sets 的差異。 我希望Redis是一組用戶可以隨意組合的正交資料結構,而不是一組預定義的工具(用戶只能按照設計的方式使用)。 Streams是一個抽象日誌,所以我認為這是一個非常有價值的結構。 然而對於其他結構我不能完全確定它們是否值得加進核心功能。 無論如何,在最近幾年中,添加新資料結構的壓力肯定更大。 HyperLogLogs,更高級的位操作,stream,阻塞的sorted sets操作(ZPOP 和BZPOP )都是很好的例子。

 

結論

 

我相信Redis社區應該知道為什麼要做某事以及為什麼要推遲某些事情。我通過推特進行了大量溝通,但很多人並沒有關註這些內容。博客是一種更好的告知社區的方式,因此我需要花時間寫博客。需要註意的是,Redis沒有一個可靠的路線圖,多年來我發現走一步看一步才是優秀的路線圖。為Redis制定路線圖是愚蠢的,因為OSS核心團隊的規模很小,有時我會在幾個星期內陷入隨機崩潰……任何固定的長期計劃都行不通。此外,由於Redis社區提供反饋,我的想法發生了很大變化,所以我每個月都會重寫路線圖。博客是一個很好的解決方案,至少可以顯示當前版本的優先事項/想法,並說明為什麼其他想法被放棄。

最後一點:我和Redis實驗室在開源專案方面的自由度幾乎是無限的。我認為這在行業中是一個奇跡,或者只是說在Redis Labs中的同事都是很好的人,他們明白我們所做的事情源於開源運動並且明智地保持這種方式。如果Redis路線圖出問題了,那肯定是我的錯誤。

 

原文地址:http://antirez.com/news/126

本文作者 Antirez,由方圓翻譯。轉載本文請註明出處,歡迎更多小伙伴加入翻譯及投稿文章的行列,詳情請戳公眾號選單「聯繫我們」。GIAC全球互聯網架構大會深圳站將於2019年6月舉行,屆時將有Redis相關話題,敬請期待。

    赞(0)

    分享創造快樂