11

我今天读到了 Google App Engine 中的分片计数器。文章说,您应该期望数据存储中每个实体每秒最多更新约 5 次。但在我看来,除非您有某种方式知道您每秒进行了多少更新,否则该解决方案不会“扩展”。例如,您可以分配 10 个分片,但随后会以每秒 50 次更新开始阻塞。

那么,您如何知道更新的速度有多快,以及如何将该数字反馈到分片数量中?

我的猜测是,与计数器一起,您可以保留一些最近活动的记录,如果您检测到峰值,您可以增加分片的数量。一般是这样处理的吗?如果是这样,为什么不在示例代码中完成?(最后一个问题可能无法回答。)是否更常见的做法是监控网站活动并在流量增加时更新分片计数,而不是在代码中自动执行?

更新:碎片太少和窒息的实际后果是什么?这是否仅仅意味着网站变得无响应,或者是否有可能因为超时而丢失计数器更新?


顺便说一句,这个问题谈到了在没有分片的情况下实现计数器,但其中一个答案暗示,如果流量很高,即使 memcache 也需要分片。所以这个分片分配和调整问题似乎很重要。

4

3 回答 3

4

手动监控网站的受欢迎程度并根据需要增加分片数量显然更简单。我猜大多数网站都采用这种方法。以编程方式进行不仅很困难,而且听起来会增加不可接受的开销来记录所有最近的活动并尝试对其进行分析以动态调整您正在使用的分片数量。

我更喜欢更简单的方法,即在您选择的分片数量上稍微偏高一点。

您对分片太少的实际后果是正确的。比可能更频繁地更新数据存储实体,这最初会导致某些请求需要很长时间(而写入重试)。如果你有足够多的它们堆积起来,那么它们将随着请求超时而开始失败。这肯定会导致错过计数器。从好的方面来说,您的页面会很慢,以至于用户应该开始离开,这应该可以减轻数据存储区的压力:)。

于 2010-06-29T23:36:57.300 回答
3

要解决您问题的最后一部分:您的 memcache 值不需要分片。单个 memcache 服务器可以处理数万 QPS 的获取和更新,因此没有一个看似合理的大型应用程序需要对它的 memcache 键进行分片。

于 2010-06-30T09:15:05.710 回答
2

当异常开始发生时,为什么不增加分片的数量?

基于此GAE 示例

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() );             

}
于 2012-01-24T20:18:01.520 回答