in-memoryなcache libraryをさっと調べた
要件
GRPC endpointへの負荷を減らすために、結果をキャッシュしたい。
複数の関数からは参照されないので、Cache objectを適切なStruct内に持っていてSet/Getを呼べれば充分。
必須な要件
- TTLを設定できて自動的にExpireしたEntryを削除してくれる
- Thread safe
あったらいいなの要件
- 充分メンテナンスされている
- Starが多い
- Codeがシンプルで無駄な機能がない
- 簡単に使いたいのでEntryにDeSerialize掛けくて直にSet/Getできる
- 簡単に使いたいのでDefault TTLを設定できる
- Valueの型をGenerics的に指定できて、GetしたValueの型Castしなくていい
- Entryの最大数を設定できて、もし予想外にEntryを追加されてメモリを圧迫しないようにできる
- Cache hitしなかったときにCallback関数の結果を格納する
- 自前でLockしなくても同じタイミングでCache missしたときに複数プロセスが重い処理をしないことが保証できるのがいいな
なくてもいい機能
- KeyごとにTTL変える必要はない
- 多数のEntryを管理できなくていい
- Entry数は充分小さいので凝ったReplacement policy (LRUなど)はなくてもいい
- KeyはString型なので任意の型をKeyに使えなくても良い
選んだLibrary
要件がかなりシンプルなので、充分なシンプルなLibraryでコードを読んで理解できるものを選んだ。
GitHub - patrickmn/go-cache: An in-memory key:value store/cache (similar to Memcached) library for Go, suitable for single-machine applications.github.com
コードがかなりシンプルでどこでLockかけているかとか、いつExpireした結果が消されるかが理解しやすい。
探したときのメモ
GitHub - eko/gocache: ☔️ A complete Go cache library that brings you multiple ways of managing your cachesのMemory Storeでサポートされているライブラリとかも良さそう
- GitHub - allegro/bigcache: Efficient cache for gigabytes of data written in Go.
- (de)serialization必要
- 別にそこまで大量のデータを入れないので無駄な複雑さが足されている
- GitHub - dgraph-io/ristretto: A high performance memory-bound Go cache
- 機能多すぎるけど、別の機会に深堀りしてみたい
- GitHub - patrickmn/go-cache: An in-memory key:value store/cache (similar to Memcached) library for Go, suitable for single-machine applications.
- 必要な機能を満たしていて、充分シンプル、充分枯れているので有力候補
GitHub - avelino/awesome-go: A curated list of awesome Go frameworks, libraries and softwareでcacheとついているものを調べた(Starが少なすぎるものは除外)
-
the TTL will be reset on each cache hit and you need to explicitly configure the cache to use a TTL that will not get extended
- このデフォルトの挙動が今回の要件には合わない(TTLはMasterデータを定期的にFetchするために設定しているので)
- 設定すればこの挙動を替えられそうだけど、単純に使えないのはマイナスポイント
- ライブラリが複雑になっていそう
Loader function to retrieve missing keys can be provided. Additional Get calls on the same key block while fetching is in progress (groupcache style).
- この機能いいね
-
It will expire after not being accessed via Value(key) for more than 5 seconds.
- ttlcacheと同様にこの挙動が要件と違う。また変更もできなさそう
-
Keys and values must be byte slices. Other types must be marshaled before storing them in the cache.
- 自前でDeSerializeしないといけない
There is no cache expiration
- TTL設定できない
-
- Distributedなので機能過多
- Memcacheみたいになってるので取り出した値の型が設定できる?
- 機会があったら深堀りしたい
GitHub - hashicorp/golang-lru: Golang LRU cache
- TTL設定できない