MemcacheはGoチームの現在のメンバーである Brad Fitzpatrick 氏によって最初に開発された、 最もよく知られているキャッシュシステムのひとつです!
App EngineはDatastoreを使用する方法と同様に、 Memcacheを使用する非常に簡単な方法を提供します。 あなたは、あなたがビジネス以外のものを気にする必要がないように、 Googleがメンテナンス、拡張、更新する完全に管理されたMemcacheインスタンスにアクセスできます。
Memcacheは指定された時間内にデータを保持し、指定した時間が経過すると値を削除します。 耐久性の保証がないため、Memcacheで回復できないものは保存しないでください。 言い換えれば、Memcacheが動作していなかった場合でも、 おそらく少し遅いながらアプリケーションは完全に動作するはずです。
先ほど紹介したパッケージは、Goランタイムにて google.golang.org/appengine/memcache
という名前でパッケージが提供されています。
memcacheで行える操作は主に2つあります:
memcache.Set
でデータをキャッシュする、そしてmemcache.Get
でデータを取り戻す。
memcache.Set
関数を使用します:
func Set(c appengine.Context, item *Item) error
最初の引数はいつものように appengine.Context
であり、二つ目は保存したいitemです。
ここでは memcache.Item
型の3つのフィールドに注目しましょう:
type Item struct {
Key string
Value []byte
Expiration time.Duration
// わかりやすくするためにいくつかのフィールドを削除しました
}
- Keyは、単純な文字列で、値を識別できます。
- Valueは、最大1Mbサイズのスライスです。
- Expirationフィールドは、値が有効である期間を示します。
キー "name" と値 "gopher" を持つitemを1時間有効にして保存する場合、 次のように書くことができます:
package app
import (
"fmt"
"net/http"
"time"
"google.golang.org/appengine"
"google.golang.org/appengine/memcache"
)
func set(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
// リクエストからパラメーターkとvを取得する
key := r.FormValue("k")
value := r.FormValue("v")
item := &memcache.Item{
Key: key,
Value: []byte(value),
Expiration: 1 * time.Hour,
}
err := memcache.Set(ctx, item)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
Memcacheからitemを取得するには memcache.Get
関数を使用します:
func Get(c appengine.Context, key string) (*Item, error)
キーが与えられた memcache.Get
は Value
フィールドにストア値を含んだ対応するitemがあればそれを返します。
キーがキャッシュに見つからなかった場合、返されるエラーは memcache.ErrCacheMiss
です。
前のコードでキャッシュした値を取得しましょう:
func get(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
key := r.FormValue("k")
item, err := memcache.Get(ctx, key)
switch err {
case nil:
fmt.Fprintf(w, "%s", item.Value)
case memcache.ErrCacheMiss:
fmt.Fprint(w, "key not found")
default:
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
ここ でMemcacheを使用したアプリケーションの完全な例を見ることができます。
curl
や Postman でテストしてみてください。
ご想像のように、Memcacheを使用して構造体データを格納するには、この方法では少し面倒なことがあるため、 このパッケージはJSONでのコーダーとエンコーダー、いわゆるコーデックを使用する方法も提供しています。
memcache.Item
の Value
フィールドを設定するのではなく、コーデックを使うときは Object
フィールドを使うべきです。
例えば、次のようにJSONコーデックを使って Person
をキャッシュして取得することができます:
func set(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
var p Person
if err := json.NewDecoder(r.Body).Decode(&p); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
item := &memcache.Item{
Key: "last_person",
Object: p, // ValueではなくObjectフィールドを設定します
Expiration: 1 * time.Hour,
}
// JSONコーデックを使用します
err := memcache.JSON.Set(ctx, item)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
それを取得するのは、さらに簡単です:
func get(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
var p Person
_, err := memcache.JSON.Get(ctx, "last_person", &p)
if err == nil {
json.NewEncoder(w).Encode(p)
return
}
if err == memcache.ErrCacheMiss {
fmt.Fprint(w, "key not found")
return
}
http.Error(w, err.Error(), http.StatusInternalServerError)
}
ここ でJSONコードを使用したアプリケーションの完全な例を見ることができます。
Datastoreの管理者ページと同様に、 Memcacheビューワーページにアクセスすることでいくつかの統計をチェックしたり、 Memcacheインスタンスに格納されたり使用されたりしているキーを見つけることができます。
アプリケーションをローカルで実行している場合は、 http://localhost:8000/memcache にアクセスできます:
本稼働環境インスタンスの統計を表示する場合は、 ここ で開発者コンソールを使用できます:
イベントアプリを覚えていますか? openweathermap.orgのAPIから天気情報を取得するのにほとんどの時間を費やしたことを覚えていますか? それを ステップ4 で修正しましょう。
Memcacheでデータをキャッシュしたり取得したりできるだけでなく、 JSONのコーデックのおかげで構造化されたデータも扱えるようになりました!
次のセクション にはいくつかの驚きがあります!