将 GAE 实体缓存到 Memcache

Cache GAE Entity to Memcache

这是我用来 实体放入 GAE 数据存储区的代码:

public Key put(Object object) {
    Key result = null;
    Iterable<Entity> entities = marshall(object);
    List<Key> keys = _ds.put(entities);
    if(isCached(object)){ // check if class is annotated with @Cached
        // TODO: How should I cache the Entity before put or after put?
    }
    assert list(entities).size() == keys.size();
    result = Iterables.getLast(keys);
    return result;
}

这里是我的 get 数据存储实体的代码:

public <T> T get(Class<T> clazz, String key) {
    T result = null;
    try {
        String kind = getKind(clazz);
        if(isCached(clazz)){ // check if class is annotated with @Cached
              // TODO: How should I get cache?
        }
        Entity e = _ds.get(KeyStructure.createKey(kind, key));
        result = createInstance(clazz);
        unmarshaller().unmarshall(result, e);
    } catch (EntityNotFoundException e1) {
        e1.printStackTrace();
    }
    return result;
}

I want to know in what ways I can do caching for this?

缓存是一个复杂的话题,所以请不要把它当作绝对真理。对于这个简单的 put / get 对,您可能希望在 put 期间设置缓存并在 get 期间检查缓存(应用 the memcache pattern)。

这个方法被称为write-through cache,意思是在确认操作之前缓存和持久存储都被更新。

Should the whole Entity be cached or just fields?

通常一个实体只包含它的可序列化字段,所以我通常缓存整个东西。

Should it be cached before or after the Datastore put?

通常在之后,因为您不希望缓存 return 未成功提交到数据存储的内容。这样,如果对数据存储或内存缓存的调用失败,get 操作仍将 return 数据存储的正确状态。

Is there a default cache expiration, or it should be explicitly defined?

不指定生存时间 (TTL) 或将 TTL 指定为 0 意味着内存缓存不会丢弃密钥,除非它处于内存压力之下(这种情况经常发生)。设置 TTL 意味着 memcache 最多会将数据保留那么多秒。没有什么能保证数据会在那里 - 您应该始终将内存缓存视为不可靠的存储。

P.S.: Objectify 可以自动为您执行这个简单的缓存。这是一个很棒的库,我强烈推荐它而不是使用原始数据存储。