将 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;
}
- 我想知道我可以通过哪些方式对此进行缓存?
- 应该缓存整个实体还是只缓存字段?
- 应该在 Datastore put 之前还是之后缓存?
- 是否有默认的缓存过期时间,或者应该明确定义?
这里是我的 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;
}
- 顺便问一句,捕获 Datastore get() 请求好还是让使用此代码的应用程序处理异常好,最佳做法是什么?
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 可以自动为您执行这个简单的缓存。这是一个很棒的库,我强烈推荐它而不是使用原始数据存储。
这是我用来将 实体放入 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;
}
- 我想知道我可以通过哪些方式对此进行缓存?
- 应该缓存整个实体还是只缓存字段?
- 应该在 Datastore put 之前还是之后缓存?
- 是否有默认的缓存过期时间,或者应该明确定义?
这里是我的 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;
}
- 顺便问一句,捕获 Datastore get() 请求好还是让使用此代码的应用程序处理异常好,最佳做法是什么?
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 可以自动为您执行这个简单的缓存。这是一个很棒的库,我强烈推荐它而不是使用原始数据存储。