我今天读到sharded counters in Google App Engine。文章说,您应该期望在数据存储中每个实体最多大约5 /每秒更新。但在我看来,这个解决方案并没有“扩展”,除非你有办法知道你每秒有多少更新。例如,您可以分配10个分片,但随后会以每秒50次更新开始阻塞。
那么您如何知道更新的速度有多快,以及如何将该数字反馈到分片数量?
我的猜测是,除了计数器,你可以保留一些最近活动的记录,如果你发现了尖峰,你可以增加分片的数量。这一般是怎么做的?如果是这样,为什么不在示例代码中完成? (最后一个问题可能无法解决。)在流量上升时监控网站活动和更新分片计数是否更为常见?与在代码中自动执行相比,这是不是很常见?
更新:分片和窒息太少会带来什么实际后果?它只是意味着网站没有响应,或者是否因超时而丢失计数器更新?
<小时/> 顺便说一句,this question讨论了在没有分片的情况下实现计数器,但其中一个答案暗示即使流量很高,甚至需要对memcache进行分片。所以这个分片和调优问题似乎很重要。
答案 0 :(得分:4)
手动监控网站的受欢迎程度并根据需要增加分片数量显然更为简单。我猜大多数网站都采用这种方法。以编程方式执行此操作不仅困难,而且听起来会增加一些不可接受的开销来记录所有最近的活动并尝试分析它以动态调整您正在使用的分片数。
我更倾向于采用更简单的方法,只是在你选择的碎片数量偏高的方面犯错。
你对碎片太少的实际后果是正确的。更频繁地更新数据存储区实体,这最初会导致某些请求花费很长时间(写入重试时)。如果你有足够的堆积,那么当请求超时时它们将开始失败。这肯定会导致错过柜台。从好的方面来说,您的页面速度太慢,用户应该开始离开,这样可以减轻数据存储的压力:)。
答案 1 :(得分:3)
要解决问题的最后部分:您的memcache值不需要分片。单个内存缓存服务器可以处理数万个QPS的提取和更新,因此没有合理的大型应用程序需要对其内存密钥进行分片。
答案 2 :(得分:2)
为什么不在异常开始时添加分片数?
基于此GAE Example:
try{
Transaction tx = ds.beginTransaction();
// increment shard
tx.commit();
} catch(DatastoreFailureException e){
// Datastore is struggling to handle the current load, increase it / double it
addShards( getShardCount() );
} catch(DatastoreTimeoutException to){
// Datastore is struggling to handle the current load, increase it / double it
addShards( getShardCount() );
} catch (ConcurrentModificationException cm){
// Datastore is struggling to handle the current load, increase it / double it
addShards( getShardCount() );
}