为什么我的每秒实体组写入的数据存储远远超过规定的限制?

时间:2015-01-16 00:09:09

标签: google-app-engine google-cloud-datastore objectify

我在交易中更新了具有客体化的实体。我的猜测是我每秒只能写入1到5次相同的实体组。这符合围绕写入数据存储区的文档和建议。但是在对以下代码运行一些简单的负载测试之后,我看到了

  • 单个实体每秒约90次写入
  • 对同一实体组中的随机实体每秒约50次写入。

为什么这可能?我的错误在哪里?

// text => a random text, different for each request
public void update(final Key<SomeEntity> toLoad, String text) {
    final AtomicInteger attempts = new AtomicInteger(0);

    SomeEntity modified = ofy().transact(new Work<SomeEntity>() {
        public SomeEntity run() {
            // count every attempt
            attempts.incrementAndGet();

            SomeEntity toModify = ofy().load().key(toLoad).now();
            if (toModify != null) {

                // modifies the entity
                toModify.setText(text);

                ofy().save().entity(toModify).now();
            }

            return toModify;
        }
    });

    if (attempts.get() > 1) {
        logger.warning(attempts.get() + " attempts for update on " + modified);
    }
}

在云控制台日志查看器中报告了大量重试,大多数警告有2次尝试,一些事务有5次尝试,但是已执行并更新了实体。对GAE进行负载测试是否有特殊策略?或者关于这个主题的任何一般性建议?

更新

实体组结构和测试设置的简短描述。为了便于选择实体,密钥名称反映了实体在其实体组中的位置。 “001-001-100”是实体组中的第二级实体,其根实体为“100”并且具有父“001-100”。所以实体组看起来像这样:

- 100
  - 001-100
    - 001-001-100
    - 002-001-100
    - 003-001-100
    - ...
  - 002-100
  - 003-100
  - 004-100
  - 005-100
  - ...
- 101
- ...

我尝试了三种不同的版本。每个人都在JMeter中使用另一个值来更新请求。所有更新完全相同的实体“001-001-100”。

// Version A: text does not change during load test
vars.put("text", "Foo Bar");

// Version B: text changes every second during load test
var d = new Date();
vars.put("text", [d.getHours(), d.getMinutes(), d.getSeconds()].join("-")));

// Version B: text changes every request
vars.put("text", Math.random());
  • 版本A:~110个请求/秒
  • 版本B:约70个请求/秒
  • 版本C:~24个请求/秒

但是:每秒在一个实体上写入24次真的很高。所以我稍微重新设计了测试。

然后我稍微修改了测试。我现在只在一个实体的第二层上分发请求,而不是仅在一个实体上触发请求。因此JMeter随机使用“001-001-100”,“002-001-100”,“003-001-100”,“004-001-100”或“005-001-100”。或多或少的结果就像我只选择一个实体一样。

  • 版本A:~110个请求/秒
  • 版本B:约100个请求/秒
  • 版本C:~20个请求/秒

更新2: 如果仅使用一个线程执行负载测试,则吞吐量大约为每秒2.5次更新。这更接近拟议的限制。如果我使用80个线程运行测试,吞吐量会上升到我之前发布的数字。样本的响应时间不是最好的,但吞吐量保持很高:avg = 2100ms,中值= 1350ms,90%= 5400ms,max = 18000ms。也许吞吐量可能不是数据存储限制的直接衡量标准?

1 个答案:

答案 0 :(得分:1)

  1. 您可以获得实体缓存的好处(版本A和B)。它可能位于Objectify级别,也可能位于Datastore的基础架构内。

  2. 每秒5个请求不是硬限制。这是一个警告:

  3.   

    App Engine会将写入单个实体组的序列化   数据存储,因此对更新数据存储的速度有限制   实体组。一般来说,这可以在1到5之间   每秒更新;一个好的指导方针是你应该考虑的   重新架构,如果您希望实体组必须维持更多   超过每秒一次更新。

    请注意:

    (a)简单的文本字符串几乎没有序列化开销。对于复杂的实体,情况并非如此。

    (b)警告包括&#34;延长期&#34;。