简体   繁体   中英

Force immediate availability of item in Memcache

Using Google App Engine NDB, most aspects of memcache are handled automatically. However, an item does not become available in Memcache until it is read at least once. So first the item must be read using get, and then memcache stores it. Put() removes it from memcache.

However, I need something to be available in memcache immediately on put. I'm new to memcache, so I'm not entirely sure how everything works behind the scenes, but there are two ways I can do this:

  1. Immediately after a put() of an entity, do a get(), just so that it becomes available in memcache.
  2. Immediately after a put(), manually set the item in memcache. This would make sense, but I'm not sure if there are any gotachas with this approach. If I manually set something in memcache, will this interfere with the rest of NDB's automatic memcache handling? Also , what key should I use when setting something in memcache manually so that upon a get, the automatic memcache handler knows what to look for?

I suspect you are referring to this:

Memcache does not support transactions. Thus, an update meant to be applied to both the Datastore and memcache might be made to only one of the two. To maintain consistency in such cases (possibly at the expense of performance), the updated entity is deleted from memcache and then written to the Datastore. A subsequent read operation will find the entity missing from memcache, retrieve it from the Datastore, and then update it in memcache as a side effect of the read. Also, NDB reads inside transactions ignore the Memcache.

So if you need something to be available on put then you'll have to cache it in memcache yourself.

Which brings us to 2)

If you manually set something in memcache AFAIK it won't interact with NDB's automatic caching in any way. Also AFAIK you can't set a manual memcache entry with a key that the automatic version will then be able to automatically work with.

You simply have to build a layer of memcache around your content that you explicitly control. Every time you to do a put you use a function that puts to the datastore then into memcache, invalidating existing entries if required. Likewise for get, you try memcache first then fall back to the datastore. Which sounds almost exactly like what NDB is doing already for you!

Perhaps look at the Policy functions options for finer control: https://developers.google.com/appengine/docs/python/ndb/cache#policy_functions

Don't forget however that the in context cache might well be doing what you want already:

The in-context cache persists only for the duration of a single incoming HTTP request and is "visible" only to the code that handles that request. It's fast; this cache lives in memory. When an NDB function writes to the Datastore, it also writes to the in-context cache. When an NDB function reads an entity, it checks the in-context cache first. If the entity is found there, no Datastore interaction takes place.

Queries do not look up values in any cache. However, query results are written back to the in-context cache if the cache policy says so (but never to Memcache).

So if your put and subsequent get is happening in the same request it's coming out of the in-context cache in any case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM