我正在使用appengine服务器。我希望得到很多请求(几十个),这会使我的一些数据处于不一致的状态。清理这些数据可以有效地进行批处理 - 例如,最好在几十个请求全部完成后运行我的清理代码一次。我不确切地知道将会有多少请求,或者它们将会有多近。如果清理代码多次运行,则可以,但必须在最后一次请求之后运行。
最小化清理次数的最佳方法是什么?
这是我的想法:
public void handleRequest() {
manipulateData();
if (memCacheHasCleanupToken()) {
return; //yay, a cleanup is already scheduled
} else {
scheduleDeferredCleanup(5 seconds from now);
addCleanupTokenToMemCache();
}
}
...
public void deferredCleanupMethod() {
removeCleanupTokenFromMemcache();
cleanupData();
}
我认为这会崩溃,因为即使在某些请求发现memcache中存在清理令牌(HRD延迟等)后,cleanupData
也可能会收到过时的数据,因此清理时可能会遗漏某些数据
所以,我的问题:
答案 0 :(得分:1)
您建议的一般策略将起作用,提供需要清理的数据不会存储在每个实例上(例如,它存储在数据存储区或内存缓存中),并且只要您的schduleDeferredCleanup
方法使用任务队列。优化将是使用基于它们运行的时间间隔的任务名称,以避免在memcache密钥到期时安排重复清理。
但是,上面描述的程序要注意的一个问题是竞争条件。如上所述,与清理任务同时处理的请求可以检查内存缓存,观察令牌是否存在,并且忽略排队清理任务,同时清理任务已经完成,但尚未删除内存缓存密钥。避免这种情况的最简单方法是使memcache密钥自行过期,但在相关任务执行之前。这样,您可以安排重复的清理任务,但是您永远不应该省略所需的任务。