When an entity wasn't found in the memcache, Objectify later updates the cache with the value from Datastore. This update uses the putIfUntouched method from MemcacheService, so that if there was another request that put that entity to the memcache, we don't overwrite that. In this case, this current request cannot know if that other request had more up-to-date information or not, so here it rather empties the memcache entry for this key.
However, when an entity is accessed at a constantly high rate, this will lead to a continuously occuring race condition. The cache entry will be switching between empty and the actual value, the cache cannot "settle", and we'll end up reading the entity from Datastore at a high rate.
We can avoid this race condition by re-reading the value from memcache before emptying it, and if the value is there and it's matching with our version, then we can skip emptying it.
I'll add a corresponding PR soon, we'll just develop the solution on our fork first and try if it indeed resolves our problem.
I didn't check if Objectify 6 can also have this problem.
When an entity wasn't found in the memcache, Objectify later updates the cache with the value from Datastore. This update uses the
putIfUntouchedmethod from MemcacheService, so that if there was another request that put that entity to the memcache, we don't overwrite that. In this case, this current request cannot know if that other request had more up-to-date information or not, so here it rather empties the memcache entry for this key.However, when an entity is accessed at a constantly high rate, this will lead to a continuously occuring race condition. The cache entry will be switching between empty and the actual value, the cache cannot "settle", and we'll end up reading the entity from Datastore at a high rate.
We can avoid this race condition by re-reading the value from memcache before emptying it, and if the value is there and it's matching with our version, then we can skip emptying it.
I'll add a corresponding PR soon, we'll just develop the solution on our fork first and try if it indeed resolves our problem.
I didn't check if Objectify 6 can also have this problem.