go-cache
GitHub概要
patrickmn/go-cache
An in-memory key:value store/cache (similar to Memcached) library for Go, suitable for single-machine applications.
スター8,675
ウォッチ117
フォーク900
作成日:2012年1月2日
言語:Go
ライセンス:MIT License
トピックス
cachegolibrary
スター履歴
データ取得日時: 2025/10/22 08:07
キャッシュライブラリ
go-cache
概要
go-cache(patrickmn/go-cache)は、memcachedに似たGo用のインメモリkey:valueストア/キャッシュライブラリです。単一マシンで動作するアプリケーションに適しており、本質的にthread-safe map[string]interface{}に有効期限を追加した実装です。
詳細
go-cacheは、ネットワーク越しにコンテンツをシリアライズ/送信する必要がないため、非常にシンプルで高速です。任意のオブジェクトを指定した期間または永続的に保存でき、複数のgoroutineから安全に使用できます。キャッシュ全体をファイルに保存したり、ファイルから読み込んだりすることで、ダウンタイムから迅速に復旧できます。
内部的にはデフォルトの有効期限時間(例:5分)とクリーンアップ間隔(例:10分)を設定でき、期限切れアイテムを定期的に削除します。シンプルながら実用的な機能を提供し、Go開発者にとって非常に使いやすいキャッシュソリューションです。
メリット・デメリット
メリット
- シンプルで直感的なAPI設計
- thread-safeで複数goroutineから安全にアクセス可能
- memcachedライクな使い心地
- ネットワークシリアライゼーション不要で高速
- 任意のGoオブジェクトを保存可能
- 自動的な期限切れアイテム削除
- ファイル保存/読み込み機能によるダウンタイム対応
- 単一マシンアプリケーションに最適
デメリット
- 単一マシン限定(分散キャッシュ非対応)
- 他のキャッシュシステム(Redis、Memcached等)と比べて機能が限定的
- 大規模データや複雑なキャッシュ戦略には不向き
- メモリ使用量の詳細制御機能が少ない
- ネットワーク経由でのアクセスは不可
参考ページ
書き方の例
基本的なセットアップ
package main
import (
"fmt"
"time"
"github.com/patrickmn/go-cache"
)
func main() {
// デフォルト有効期限5分、クリーンアップ間隔10分でキャッシュを作成
c := cache.New(5*time.Minute, 10*time.Minute)
}
基本的なSet/Get操作
// 文字列の保存
c.Set("username", "john_doe", cache.DefaultExpiration)
// 任意のオブジェクトの保存
user := map[string]interface{}{
"id": 123,
"name": "John Doe",
"email": "[email protected]",
}
c.Set("user:123", user, cache.DefaultExpiration)
// 値の取得
username, found := c.Get("username")
if found {
fmt.Printf("Username: %s\n", username.(string))
}
// 型アサーション付きの取得
if userData, found := c.Get("user:123"); found {
if userMap, ok := userData.(map[string]interface{}); ok {
fmt.Printf("User: %v\n", userMap)
}
}
有効期限の指定
// 1時間後に有効期限切れ
c.Set("temp_data", "temporary", 1*time.Hour)
// 永続的に保存(有効期限なし)
c.Set("config", "permanent_value", cache.NoExpiration)
// デフォルト有効期限を使用
c.Set("default_ttl", "uses_default", cache.DefaultExpiration)
// 10秒後に有効期限切れ
c.Set("short_lived", "quick_access", 10*time.Second)
追加とインクリメント操作
// AddはキーがまだAbsorption場合のみ追加
err := c.Add("counter", 1, cache.DefaultExpiration)
if err != nil {
fmt.Printf("Key already exists: %v\n", err)
}
// 数値のインクリメント
c.Set("views", 100, cache.DefaultExpiration)
newValue, err := c.Increment("views", 1)
if err == nil {
fmt.Printf("New view count: %d\n", newValue)
}
// デクリメント
newValue, err = c.Decrement("views", 5)
if err == nil {
fmt.Printf("Decremented view count: %d\n", newValue)
}
// float64でのインクリメント
c.Set("score", 10.5, cache.DefaultExpiration)
newScore, err := c.IncrementFloat("score", 2.3)
if err == nil {
fmt.Printf("New score: %.2f\n", newScore)
}
キャッシュの管理操作
// アイテムの削除
c.Delete("username")
// キーの存在確認(期限切れチェック込み)
_, found := c.Get("user:123")
fmt.Printf("User exists: %t\n", found)
// 全アイテムの取得
items := c.Items()
fmt.Printf("Total items: %d\n", len(items))
// 期限切れアイテムの手動削除
c.DeleteExpired()
// 全キャッシュのクリア
c.Flush()
有効期限の確認と更新
// アイテムの有効期限確認
if item, found := c.get("user:123"); found {
fmt.Printf("Expires at: %v\n", item.Expiration)
}
// 有効期限の更新(既存値を維持して期限のみ変更)
if currentValue, found := c.Get("user:123"); found {
c.Set("user:123", currentValue, 2*time.Hour) // 2時間に延長
}
// TTLの実装(Goの標準ライブラリを使用)
func getTTL(c *cache.Cache, key string) time.Duration {
if item, found := c.get(key); found {
if item.Expiration > 0 {
return time.Until(time.Unix(0, item.Expiration))
}
return -1 // NoExpiration
}
return 0 // Not found
}
ファイル保存と復元
// キャッシュをファイルに保存
items := c.Items()
err := saveToFile("cache_backup.gob", items)
if err != nil {
fmt.Printf("Save error: %v\n", err)
}
// ファイルからキャッシュを復元
items, err := loadFromFile("cache_backup.gob")
if err != nil {
fmt.Printf("Load error: %v\n", err)
} else {
// 復元されたアイテムで新しいキャッシュを作成
restoredCache := cache.NewFrom(cache.DefaultExpiration, 10*time.Minute, items)
}
// ファイル保存のヘルパー関数例
func saveToFile(filename string, items map[string]cache.Item) error {
// encoding/gobやjsonを使用してシリアライズ
// 実装は具体的な要件に応じて行う
return nil
}
設定とカスタマイズ
// カスタムクリーンアップ間隔
c := cache.New(30*time.Minute, 1*time.Minute) // 1分毎にクリーンアップ
// クリーンアップの無効化(手動管理)
c := cache.New(30*time.Minute, -1)
// カスタムコールバック機能(疑似実装)
c.OnEvicted(func(key string, value interface{}) {
fmt.Printf("Evicted: %s = %v\n", key, value)
})
// 使用統計の追跡(独自実装が必要)
type StatsCache struct {
*cache.Cache
hits int64
misses int64
}
func (s *StatsCache) Get(key string) (interface{}, bool) {
value, found := s.Cache.Get(key)
if found {
s.hits++
} else {
s.misses++
}
return value, found
}