Redis的速度不夠用?為什麼你應該考慮使用 KeyDB,一個更快、更強大、更靈活的開源資料庫

2023-10-20 15:00:58

你是否正在使用 Redis 作為您的資料結構儲存,享受它的高效能、高可用的特性?如果是這樣,那麼你可能會對 KeyDB 感興趣。

什麼是 KeyDB?

KeyDB 一個由 Snap 提供支援、專為擴充套件而構建的開源資料庫。它是 Redis 的高效能分支,專注於多執行緒、記憶體效率和高吞吐量。KeyDB 採用 MVCC 體系結構,允許您執行 KEYS 和 SCAN 等查詢,而不會阻塞資料庫並降低效能。KeyDB 保持與 Redis 協定、模組和指令碼的完全相容性,這包括指令碼和事務的原子性保證。由於 KeyDB 與 Redis 開發保持同步,KeyDB 是 Redis 功能的超集,這使得 KeyDB 成為現有 Redis 理想的替代品。

專案地址:https://docs.keydb.dev/
原始碼地址:https://github.com/Snapchat/KeyDB

KeyDB 獨有特性

除了與 Redis 相同的功能外,KeyDB 還提供了一些獨有的特性,例如:

  • 無阻塞架構:採用一種 MVCC 體系結構,允許你可以查詢資料庫的單個快照,從而避免阻塞 SCAN 和 KEYS 等呼叫。這樣可以大規模並行呼叫此類查詢,而不會降低現有工作負載的整體效能。
  • 跨區域主動複製:這是一種新的複製模式,允許你在多個主節點之間進行雙向非同步複製。這樣可以實現跨區域的多主站支援,提高資料可用性和一致性,無需哨兵監視節點進行故障轉移。
  • 子項過期:這是一種新的過期機制,允許你對集合中的成員設定過期時間。這樣可以實現更細粒度的資料管理和清理。
  • TLS加密:這是一種新的安全機制,為你的資料提供 TLS(傳輸層安全)支援。KeyDB 的 TLS 效能是 Redis + TLS 的 7 倍,並且不需要任何額外的設定或證書。
  • JavaScript 模組:這是一種新的擴充套件機制,讓你可以使用 JavaScript 來編寫自定義的命令和邏輯。JavaScript 模組基於 V8 引擎構建,比 Lua 更快,並且支援許多 Node.js 模組。

KeyDB 效能測試

在同一硬體上,KeyDB 可以實現比 Redis 高得多的吞吐量。主動複製簡化了熱備盤故障切換,使你能夠輕鬆地跨副本分佈寫入操作,並使用簡單的基於 TCP 的負載平衡/故障轉移。KeyDB 的更高效能允許你在更少的硬體上做更多的事情,從而降低運營成本和複雜性。

下圖為Redis、TLS 和多執行緒 KeyDB 基準測試比較:

圖表, 條形圖

描述已自動生成

測試顯示,在 Redis 6(單執行緒)上啟用 TLS 的情況下,測量值下降了 36%。但是,如果你以前使用過 I/O 執行緒功能,則可能會看到效能下降 61%,因為使用 TLS 不支援 I/O 執行緒。

下圖為Redis、TLS 和多執行緒 KeyDB 延遲基準測試比較(數值越低越好):

圖表, 條形圖

描述已自動生成

可以看到,使用 TLS 時,這些負載下的延遲明顯更高。KeyDB 不僅在非常高的容量下提供服務,而且延遲也比使用 TLS 的 Redis 低 7 倍。

下圖為使用 YCSB 對 Redis 6 多執行緒 I/O 與 Elasticache 和 KeyDB 進行吞吐量測試比較:

圖表, 條形圖

描述已自動生成

很明顯,KeyDB 在每個測試的工作負載下都實現了最高的吞吐量。Elasticache 排在第二位,其次是 Redis 6。可以注意到,在沒有 I/O 執行緒的情況下,Redis 6 仍然比版本5快。

下圖為使用 YCSB 對 Redis 6 多執行緒 I/O 與 Elasticache 和 KeyDB 進行延遲測試比較(以微秒為單位,值越低越好):

上面顯示的趨勢表明,當範例接近其容量吞吐量時,延遲會顯著增加。KeyDB 可以處理比 Redis 6 高得多的吞吐量,並且略高於 Elasticache,因此能夠在更高的負載下保持較低的延遲。

KeyDB、Elasticache 和 Redis 6 在輕度到中等流量下都有類似的延遲。直到容量開始達到更高的負載,才能看到差異。

更多測試內容請移步這裡檢視:https://docs.keydb.dev/blog

如何使用 KeyDB?

由於 KeyDB 與 Redis完全相容,使得它非常容易使用,我們可以像 Redis 一樣來使用它。來做一個簡單的範例,演示如何連線到 KeyDB,設定和獲取一個字串值,以及使用 EXPIREMEMBER 命令來設定子項過期。

KeyDB命令檔案:https://docs.keydb.dev/docs/commands/#expiremember

首先,從 Docker Hub 拉取 KeyDB 的映象並執行:

# 拉取 KeyDB 的映象
docker pull eqalpha/keydb

# 執行 KeyDB 的容器
docker run -p 6379:6379 -d eqalpha/keydb

然後,建立一個控制檯應用程式,安裝 StackExchange.Redis 庫:

# 建立一個控制檯應用程式
dotnet new console -o KeyDBDemo

# 安裝 StackExchange.Redis 庫
nuget install StackExchange.Redis

然後,編輯 Program.cs 檔案,新增以下程式碼:

using StackExchange.Redis;
public class KeyDBDemo
{
    private static void Main(string[] args)
    {
        // 建立一個連線到本地Redis範例的聯結器
        ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
        // 獲取一個資料庫物件
        IDatabase db = redis.GetDatabase();

        // 設定一個字串值,鍵為 "name",值為 "Bing"
        db.StringSet("name", "Bing");

        // 獲取鍵為 "name" 的字串值
        var name = db.StringGet("name");

        // 列印結果
        Console.WriteLine($"The name is {name}");

        // 設定一個集合值,鍵為 "fruits",值為 ["apple", "banana", "orange"]
        db.SetAdd("fruits", new RedisValue[] { "apple", "banana", "orange" });

        // 為集合中的成員 "apple" 設定過期時間為 5 秒
        db.Execute("EXPIREMEMBER", "fruits", "apple", 5);

        // 獲取鍵為 "fruits" 的集合值
        var fruits = db.SetMembers("fruits");

        // 列印結果
        Console.WriteLine($"The fruits are {string.Join(", ", fruits)}");

        // 等待 5 秒後,再次獲取鍵為 "fruits" 的集合值
        Thread.Sleep(5100);
        fruits = db.SetMembers("fruits");

        // 列印結果
        Console.WriteLine($"The fruits are {string.Join(", ", fruits)}");

        // 關閉連線
        redis.Close();
    }
}

最後,執行程式,可以得到以下結果:

The name is Bing
The fruits are banana, apple, orange
The fruits are banana, orange

 寫作不易,轉載請註明文章出處,否則禁轉!!!