【问题标题】:How many shards in a Google App Engine sharded counter?Google App Engine 分片计数器中有多少个分片?
【发布时间】:2011-03-09 21:37:06
【问题描述】:

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

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

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

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


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

【问题讨论】:

  • 看看 memcache 方法在没有分片的情况下每秒可以处理多少更新会很有趣。 (目前,我似乎无法找到任何关于您可以多快更新给定内存缓存键的数字。)
  • 我只是在学习这方面的知识,但从某种意义上说,memcache 是否不可靠,它可能随时会失效。
  • 是的,memcache 值确实可以随时被驱逐。这通常是由于内存压力而发生的(尽管它可能由于其他原因而发生 - 例如 memcache 服务器出现故障)。这就是为什么基于 memcache 的解决方案可能会被低估的原因之一。
  • 我认为更相关的问题是,如果有的话,选择太多分片有什么缺点?尝试实际获取当前总数时性能变慢?
  • @Peter Recore:我的理解是读快,写慢。此外,计数器值被 memcached 用于检索(但不更新)。

标签: google-app-engine sharding


【解决方案1】:

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

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

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

【讨论】:

  • 但是但是但是..如果有超时,我的计数器就会出错。我承认这不会导致任何生命损失,但它只是让我有点困扰。它只是我们必须忍受的事情之一吗?
  • 面对一些反击失误的可能性可能并没有那么糟糕。只需尝试选择分片数量以适应您的最大预期峰值流量以及一些安全边际。错过的计数越重要,您的安全边际就应该越高。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    基于此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() );             
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-01
      • 2013-12-25
      • 2012-06-21
      • 1970-01-01
      • 2011-04-20
      • 2011-04-16
      • 2012-09-05
      相关资源
      最近更新 更多