0
votes

I am experimenting with Google App Engine (High Replication Datastore) I understand that frequent writes to a single entity group can cause contention. Precisely to avoid that happening, my entities are all root entities ie each entity is a seperate entity group.

I begin a transaction

get the entity

if it already exists rollback the transaction

else put the entity and commit the transaction

So I thought I was leveraging app engines's claimed strength of high throughput for non-related entities (ie entities not in the same entity group)

However sometimes on the put, I am getting the dreaded exception 'too much contention on these entities'. Why should there be contention on entities not in the same group?

We are told that for a single entity group we can expect no more than 1 to 10 writes per second.

But I have not seen a figure for what we can expect app engine to handle for writes to seperate entity groups The contention seems to happen for what I consider to be quite low demands (around 100 writes per second)

Am I missing something? As well as having seperate entity groups, are there other rules to conform to in order to get high throughput?

Or are my expectations of at least several hundred writes per second simply too high?

3

3 Answers

1
votes

your pseduo code looks correct if you are inserting a single entity per txn.

you are also correct that non related root entities insert should prevent contention.

I am updating multiple root entities in a single request, so there is no chance of another request concurrently modifiying the same data as my request

However there is 5 entity group limit within a txn. what can be done in txn

to solve your solution

  1. use a txn for a single entity update
  2. OR limit the txn to <5 entities.

-lp

0
votes

Your first mistake is using entity groups. They are not at all intended for avoiding contention. Its the exact opossite. You cant update an item on an entity group too often, see the docs. Entity groups are useful for consistent reads not contention or speed.

0
votes

Not sure how to delete an answer so I am editing this one.

The getMessage for the exception returns the 'too much contention' message. But the class of the exception is ConcurrentModification.

I am updating multiple root entities in a single request, so there is no chance of another request concurrently modifiying the same data as my request

So I don't understand where this 'contention' is coming from.

It seems that the single request is 'contending' with itself!

One idea is that because of the asynchronous nature of put then the first operations are not fully complete before later ones come along?

Since these are seperate entity groups I think the problems must be caused by things like 'tablet splitting' etc. If that is the case I think it is a shame that all of these failures are presented to the caller as ConcurrentModification exceptions. I think it would be useful to be able to differentiate between a failed operation because of internal processes in the datastore and more normal issues such as another user has modified the data before you