為什麼 Redis 6 只支援 RESP3 ?

2022-08-25 09:39:11 字數 2381 閱讀 4700

redis 5 發布幾周後,我開始著手實現 resp3,經過幾天的工作,可以實現這一目標了。 resp3 是 redis 將從 redis 6 開始使用的新的客戶端-伺服器協議, 上的規範清楚地說明我們舊協議 resp2 的這種演進可以如何改進 redis 生態系統,其中最重要的是,resp3 比 resp2 更加「語義化」。例如,它具有對映,集合(元素的無序列表),返回資料的屬性(可以使用輔助資訊來增強回覆)等概念。最終目標是使新的 redis 客戶端為我們減少工作量,也就是說,只需確定一組固定規則,即可將每種回覆型別從 resp3 轉換為給定型別的客戶端庫程式語言。

在 redis 的未來中,我看到了一些更智慧型的客戶端,更好的處理連線、流水線和狀態,並且顯然在面向使用者方面要簡單得多,以至於理想 redis 客戶端就像:

result= redis.call(」get」,keyname);

當然最重要的是,你可以構建更高階的抽象,但是最底層應該看起來像這樣,並且返回的回覆不應要求對特定命令進行臨時過濾:resp3 返回型別應包含足夠的資訊以返回適當的資料型別,因此 hgetall 將返回 resp3「對映」,而 lrange 將返回「陣列」,而 exists 將返回 resp3「布林」。

即使客戶端庫不是專門為處理它而設計的,新命令也能夠按預期工作。在 resp2 中,該命令可能返回「缺少方法」之類的錯誤,但後來在客戶端庫中確實實現了該命令時,返回的型別發生了變化,從而引入了輕微的不相容性。

但是,儘管新協議是對舊協議的增量改進,它還是會在客戶端庫側和在應用層中引入不相容性。例如,由於 zscore 現在將返回 double 型別,而不是 string 型別,因此應更新應用程式**,或者客戶端庫可以實現相容性選項,該選項將把 resp3 回覆變回其原始 resp2 型別。

如果不對新協議進行適配,lua 指令碼也將不能正常工作,因為 lua 還將看到 redis.call()命令返回的更多語義型別,同樣 lua 將能夠返回在 resp3 中實現的所有新資料型別。

因此,人們對我的決定感到恐懼:我將在 redis 6 發行時僅支援 resp3,沒有將 redis 6 伺服器切換到 resp2 的相容模式,因此您要麼公升級客戶端庫並公升級應用程式(或使用客戶端庫向後相容模式),要麼無法切換到 redis 6。

我這樣做是有充分的理由的,我想解釋為什麼我要做出這個決定,以及如何減輕使用者和客戶端庫作者的問題,讓我們從緩解措施開始:

* redis 6 發行後的 2 年內將完全支援 redis5,所有關鍵內容都將移植到 redis 5,並且補丁程式級別的發行版將一直可用。

* redis 6 預計將在大約 1 年或一年半內發布,但是 redis 6 將在大約 1 個月內切換到 resp3,因此,人們將使用、嘗試和處理不穩定的 redis 版本,該版本長時間使用新協議。與許多其他軟體不同,redis stable 具有大量的臨時使用者,這既是因為它是 github 上的預設分支,又因為傳統上 redis stable 從未真正如此不穩定,所以這會帶來很多先前的風險。

*我仍然不能 100%確定, 但是 lua 指令碼引擎可能具有相容模式,以便返回與 redis 5 相同的型別。但是,預設情況下不會啟用相容性,並且會在呼叫 redis 命令之前通過呼叫特殊的 redis.resp2_compat()函式,選擇啟用每個執行的指令碼。因此,無論其配置如何,每台 redis 6 伺服器都將表現出相同的行為,就像 redis 在過去 10 年中一樣。

這些是緩解措施,這就是為什麼我決定 redis 6 不同時支援兩個版本的原因:

1)也許是完全無用的。如果人們將 redis 6 切換到 resp2 模式,他們就會一直停留在過去,在沒有 resp2 支援的情況下等待 redis 7 推出並打破一切。同時當您使用乙個 redis 6 時,根據配置的方式,你永遠不會知道它會回覆什麼,相同的客戶端庫可能會為相同的命令返回雜湊或陣列。

2)沒有充分的理由,這需要更多的工作和更多的複雜性(請參閱「1」),許多命令將需要檢查舊協議,以檢視以哪種格式答覆。

3)通過將 redis 6 的新功能與協議的變更繫結在一起,我們為使用者提供了充分的理由進行切換並移植其客戶端和應用程式。總有一天一切都會結束,我們可以專注於新事物。否則,我們將擁有一些這樣的 redis 6 使用者,這些使用者已切換到新伺服器以使用新功能,但仍使用舊協議,而且使用 redis 7 時也會重蹈覆轍。

4)如果有人告訴你改寫客戶端庫是一件很糟糕的事情,那麼我可不敢苟同。是需要做一些更改,但是既然我正在實現伺服器端,我發現它並不那麼糟糕,其實可怕的是,大多數客戶端的工作根本沒有報酬,而僅僅是因為熱情和與他人分享的意願。我敢打賭,我們很快就會看到 resp3 的許多實現。

5)resp3 的設計使客戶端可以自動檢測它是 resp2 還是 resp3,並進行切換,因此新客戶端可以同時使用 redis 6 和 redis 5 以及之前版本。

我希望它可以闡明我的觀點及其背後的原因,同時希望在協議切換期間啟用的緩解措施可以使使用者相信這不會造成很「嚴重」的破壞。

為什麼jsonp只支援get請求

jsonp 是一種 請求一段 js 指令碼,把執行這段指令碼的結果當做資料 的玩法。所以,你能 post 一段通過 script 標籤引入的指令碼嗎?如果看過 jsonp 庫的原始碼就知道,常見的實現 其實就是 document.createelement script 生成乙個 script 標籤...

為什麼 Redis 不支援回滾 roll back

以下是這種做法的優點 redis 命令只會因為錯誤的語法而失敗 並且這些問題不能在入隊時發現 或是命令用在了錯誤型別的鍵上面 這也就是說,從實用性的角度來說,失敗的命令是由程式設計錯誤造成的,而這些錯誤應該在開發的過程中被發現,而不應該出現在生產環境中。因為不需要對回滾進行支援,所以 redis 的...

為什麼Redis事務不支援回滾

redis命令在事務中可能會執行失敗,但是redis事務不會回滾,而是繼續會執行餘下的命令。如果您有乙個關係型資料庫的知識,這對您來說可能會感到奇怪,因為關係型資料在這種情況下都是會回滾的。redis這樣做,主要是因為 只有當發生語法錯誤 這個問題在命令佇列時無法檢測到 了,redis命令才會執行失...