【问题标题】:Objectify - many writes to same entity in short period of time with and without transactionObjectify - 在有和没有事务的情况下,在短时间内对同一实体进行多次写入
【发布时间】:2016-07-05 03:51:54
【问题描述】:

我正在做的是创建一个交易

1) 实体 A 的计数器更新为 +1
2) 将新实体 B 写入数据存储区。

看起来像这样:

WrappedBoolean result = ofy().transact(new Work<WrappedBoolean>() {
    @Override
    public WrappedBoolean run() {

        // Increment count of EntityA.numEntityBs by 1 and save it
        entityA.numEntityBs = entityA.numEntityBs +1;
        ofy().save().entity(entityA).now();

        // Create a new EntityB and save it
        EntityB entityB = new EntityB();
        ofy().save().entity(entityB).now();

        // Return that everything is ok
        return new WrappedBoolean("True");

    }
});

我正在做的是计算 EntityB 的 entityA 有多少。这两个操作需要在一个事务中,所以要么保存要么都发生,要么都不发生。

但是,很多用户可能会执行包含上述事务的 api 方法。我担心我可能会遇到太多人试图更新 entityA 的问题。这是因为如果多个事务尝试更新同一个实体,第一个提交的事务将获胜,而其他所有事务都失败。

这引出了两个问题:

1) 如果对 API 方法进行大量调用,我编写的事务是否是一个坏主意并注定会导致无法写入?有没有更好的方法来实现我想要做的事情?

2) 如果对不在事务中的实体进行大量更新(例如更新实体拥有的计数器)怎么办?如果在事务中进行大量更新,您最终会遇到扩展问题吗?短时间内?数据存储如何处理这个问题?

很抱歉这个冗长的问题,但我希望有人能通过上述问题阐明这个系统如何为我工作。谢谢。

编辑:当我的意思是在短时间内对实体进行大量更新时,请考虑像 Instagram 之类的东西,您想在其中跟踪一张图片有多少“喜欢”。一些用户拥有数百万的关注者,当他们发布一张新图片时,他们每秒可以获得 10-50 个赞。

【问题讨论】:

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


    【解决方案1】:

    数据存储允许每个实体组大约 1 次写入/秒。可能看起来不明显的是独立实体(即没有父级和没有子级的实体)仍然属于一个实体组 - 他们自己的。因此,对同一独立实体的重复写入受到相同的速率限制。

    超过写入限制最终会导致写入操作失败,出现类似TransactionFailedError(Concurrency exception.)

    在事务之外对同一实体进行的重复写入可能会相互覆盖。事务可以帮助解决这个问题——冲突的写入会自动重试几次。从这个角度来看,你的方法看起来不错。但它只有在平均写入速率保持在限制以下时才有效。

    您可能想阅读Avoiding datastore contention。您需要shard your counter 才能以超过 1/秒的速率对事件进行计数。

    【讨论】:

    • 如果我在事务内的实体中增加一个计数器,该事务不能由应用程序执行多次(由于重试)并增加计数器超过需要?我在某处读到事务需要是幂等的,并且事务中的 myEntity.count = myEntity.count + 1; 之类的东西可以多次执行。还是我错了(假设我们没有超过写入限制)?
    • 在最终失败的事务中执行的任何数据存储更改都将被回滚。但是在失败的事务中完成的非数据存储操作(例如内存缓存操作、正在发送的消息等)不能回滚——这些是幂等注释所指的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    • 1970-01-01
    相关资源
    最近更新 更多