小さなプロジェクトで作業するプロセスでは、データのキャッシュが必要になることが多く、RedisやMemcacheを使用できない場合があります。 このような状況では、追加のツールを使用しないシンプルでかなり効果的な方法が適切です-RAMにキャッシュします。
この記事では、Go自分でメモリ内のキャッシュマネージャを書き始める場所を説明します。
注意! この記事は、アカデミック目的のみの初心者デベロッパーを対象としており、Redis、Memcacheなどのツールは対象としていません。
また、メモリの割り当ての問題については掘り下げません。
簡単にするために、 Set
Get
およびDelete
3つの主要な方法に限定しています。
データはキー/値の形式で保存されます。
構造
最初に行うことは、ストレージコンテナーを記述する構造を作成することです。
type Cache struct { sync.RWMutex defaultExpiration time.Duration cleanupInterval time.Duration items map[string]Item }
sync.RWMutex
読み取り/書き込み中にデータに安全にアクセスするため(ミューテックスhttps://gobyexample.com/mutexesの詳細 )、defaultExpiration
デフォルトのキャッシュ有効期間(このパラメーターは各項目に対して再定義できます)cleanupInterval
キャッシュクリーニングメカニズムが開始される間隔(ガベージコレクタ、以降GC)items
キャッシュ要素(キー/値の形式)
次に、要素の構造について説明します。
type Item struct { Value interface{} Created time.Time Expiration int64 }
Value
-値。 任意(数値/文字列/配列など)にできるため、 interface{}
のタイプとしてinterface{}
を指定する必要があります。Created
-キャッシュ作成時間、Expiration
-有効期限(UnixNanoで)-それに応じて、キャッシュの関連性をチェックします
ボールトの初期化
新しいストレージコンテナを初期化することから始めましょう。
func New(defaultExpiration, cleanupInterval time.Duration) *Cache {
新しいキャッシュインスタンスの初期化には、 defaultExpiration
とcleanupInterval
2つの引数が必要cleanupInterval
defaultExpiration
デフォルトのキャッシュ有効期間、0以下に設定されている場合-キャッシュ有効期間は無制限です。cleanupInterval
期限切れのキャッシュを削除する間隔。 値が0以下に設定されている場合、期限切れのキャッシュのクリアと削除は行われません。
出力では、 Cache
構造を持つコンテナを取得します
これらのパラメーターを設定するときは、値が小さすぎるか大きすぎると、たとえばcleanupInterval = 1 * time.Second
を設定した場合に、望ましくない結果につながる可能性があることに注意してください。 逆に、 cleanupInterval = 168 * time.Hour
設定すると、未使用の要素がメモリに蓄積されます。
設定値
コンテナが作成されたら、それにデータを書き込むことができると便利です。このため、 Set
メソッドの実装を記述します
func (c *Cache) Set(key string, value interface{}, duration time.Duration) { var expiration int64
Set
は、新しいアイテムをキャッシュに追加するか、既存のアイテムを置き換えます。 ただし、キーの存在の確認は行われません。 引数として、文字列key
、value value
およびキャッシュ寿命の形式のキー識別子を受け入れます。
値を取得する
Set
の助けを借りて、リポジトリにデータを記録し、今度はそれらを受信するメソッドを実装します。
func (c *Cache) Get(key string) (interface{}, bool) { c.RLock() defer c.RUnlock() item, found := c.items[key]
Get
は値(またはnil
)を返し、キーが見つかった場合は2番目のbool
パラメーターはtrue
、キーが見つからないかキャッシュが古い場合はfalse
になります。
キャッシュの削除
インストールとレシートができたので、キャッシュを削除できるようにする必要があります(不要になった場合)。このためにDelete
メソッドを記述します。
func (c *Cache) Delete(key string) error { c.Lock() defer c.Unlock() if _, found := c.items[key]; !found { return errors.New("Key not found") } delete(c.items, key) return nil }
Delete
キーを使用してアイテムDelete
削除します;キーが存在しない場合はエラーを返します。
ガベージコレクション
追加、受信、削除します。 有効期限が切れたキーの検索とその後のクリーニング(GC)の実装は引き続き行われます
これを行うために、 StartGC
の新しいインスタンスの初期化が開始され、プログラムが完了するまで機能するStartGC
メソッドを作成します。
func (c *Cache) StartGC() { go c.GC() } func (c *Cache) GC() { for {
使用例
import ( memorycache "github.com/maxchagin/go-memorycache-example" )
次は?
これで、最小限の機能を備えたキャッシュマネージャーができました。これは、最も単純なタスクには十分です。 これで十分でない場合(そして95%の場合)、次のステップとして、メソッドを個別に実装できます。
カウント-キャッシュ内のアイテムの数を取得する
GetItem-キャッシュアイテムの取得
名前の変更-キーの名前を変更
コピー-アイテムをコピーします
増分-増分
デクリメント-デクリメント
存在-要素の存在を確認
有効期限-有効期限のキャッシュを確認
FlushAll-すべてのデータを消去します
SaveFile-データをファイルに保存します
LoadFile-ファイルからデータをロードする
これは完全なリストではありませんが、基本的な機能については十分である可能性があります。
GitHubの例を含むソース
メモリに既製のキャッシュマネージャーが必要な場合は、次のプロジェクトに注意することをお勧めします。
Patrickmn go-cacheの実装
beegoによるMemoryCache