Otter:探索 Go 語言中高效無鎖緩存庫的實現與應用

在當今軟件開發的背景下,性能優化已經成爲了一個不可或缺的部分。尤其是在緩存技術這一塊,優秀的緩存機制不僅能大幅提高應用的響應速度,更能夠有效減輕後端系統的壓力。今天,我們要深入探究的是 Otter——這是一個針對 Go 語言設計的高性能無鎖緩存庫。接下來,我們將詳細介紹 Otter 的設計原理、特性與使用方法,並通過實例演示如何在 Go 項目中集成 Otter。

Otter 緩存庫概述

Otter 是一個高性能的無鎖緩存庫,它爲 Go 語言提供了一個具有出色性能的緩存解決方案,聲稱其速度遠超同類產品 Ristretto 等。Otter 憑藉自身的設計,實現了更高的吞吐率和更優的命中率,在處理併發緩存操作時表現尤爲突出。

動機與挑戰

Otter 的萌生起於現有 Go 緩存庫普遍存在內容衝突(contention)的問題。許多緩存庫只不過是在 map 結構的基礎上加了一個互斥鎖(mutex)和一個驅逐策略(eviction policy)。然而,開發者對更高性能的追求促使 Otter 誕生,目標是創建一個既快速又易於使用的緩存庫。

相關工作

Otter 的設計基於以下論文研究成果:

特性

如何使用 Otter

在介紹如何使用 Otter 之前,我們需要確保環境滿足使用要求。

環境要求

安裝 Otter

使用下列 Go 命令進行安裝:

go get -u github.com/maypok86/otter

實例講解

創建具有恆定 TTL 的緩存實例

以下是一個創建和使用帶有恆定 TTL(1 小時)的緩存實例的例子。

package main

import (
    "fmt"
    "time"

    "github.com/maypok86/otter"
)

func main() {
    cache, err := otter.MustBuilder[string, string](10_000).
        CollectStats().
        Cost(func(key string, value string) uint32 {
            return 1
        }).
        WithTTL(time.Hour).
        Build()
    if err != nil {
        panic(err)
    }

    cache.Set("key""value") // 將值存入緩存,並設置TTL爲1小時
    value, ok := cache.Get("key") // 從緩存中獲取值
    if !ok {
        panic("未找到對應的鍵")
    }
    fmt.Println(value) // 輸出獲取到的值
    cache.Close() // 關閉緩存實例
}

創建具有可變 TTL 的緩存實例

這是一個創建帶有可變 TTL 的緩存實例並進行操作的代碼示例。

package main

import (
    "fmt"
    "time"

    "github.com/maypok86/otter"
)

func main() {
    cache, err := otter.MustBuilder[string, string](10_000).
        CollectStats().
        Cost(func(key string, value string) uint32 {
            return 1
        }).
        WithVariableTTL().
        Build()
    if err != nil {
        panic(err)
    }

    // 設置不同TTL的值
    cache.Set("key1""value1", time.Hour)   // 1小時
    cache.Set("key2""value2", time.Minute) // 1分鐘

    value, ok := cache.Get("key1") // 從緩存中獲取值
    if !ok {
        panic("未找到對應的鍵")
    }
    fmt.Println(value) // 輸出獲取到的值
    cache.Close() // 關閉緩存實例
}

Otter 的性能及命中率

Otter 在性能方面經過了嚴格的測試,無論在讀取密集還是寫入密集的情況下,吞吐率表現都非常出色。除極端的寫入密集工作負載之外,在所有工作負載中都表現得非常好。

關於命中率,通過 Zipf、S3 等不同的追蹤數據集進行了測試,結果表明 S3-FIFO(Otter)的命中率在一些對 LFU 友好的追蹤(如數據庫、搜索、分析)中略遜於 W-TinyLFU(theine),但在 web 追蹤中有更高或相等的命中率。

總結

Otter 是一個出色的高性能無鎖緩存庫,它在 Go 語言的環境中提供了非同凡響的速度和靈活性。在深入瞭解 Otter 的設計理念、特性以及使用方法後,我們認識到它是現代 Go 應用不可缺少的組件之一。無論是簡潔的 API 設計還是卓越的性能指標,Otter 都將成爲 Go 開發者鍾愛的緩存解決方案。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/y2LI7XGZldBNbu0CtLrC6g