1

Я начал использовать Google App Engine 3 месяца назад, и у меня есть вопрос относительно Python на memcaching. Я стараюсь описать свою проблему как можно лучше.Результаты кэширования запросов на GAE

Я использую ndb (App Engine Datastore) и у меня есть «стол» сущности, как это:

class Event(ndb.Model): 
    dateInsert = ndb.DateTimeProperty(auto_now_add=True)    # Inserting date 
    notes = ndb.StringProperty(indexed=False)       # event notes 
    geohash = ndb.StringProperty(required=True)      # Coordinates geohash 
    eventLatitude = ndb.FloatProperty(indexed=True, required=True) # self explanatory 
    eventLongitude = ndb.FloatProperty(indexed=True, required=True) # self explanatory 

сторона клиента (с помощью мобильного приложения, например) пользователь может хранить в хранилище данных события в указанных координатах. Те вставленные события видны, конечно, мобильным приложением (на карте) и на веб-сайте. Прямо сейчас, чтобы получить сохраненные события, клиент вызывает веб-метод, поиск события вблизи данного места:

class getEvents(webapp.RequestHandler): 
    def get(self): 
     #blablabla get passed parameters 
     #[...] 

     # hMinPos and hMaxPos are hashed coordinates passed by client + X meters. 
     # In this way I can filter stored events in a precise bounding box. 
     # For example, I can get events near my location in a box of 5000 meters 
     qryEvent = Event.query(ndb.AND(Event.geohash >= hMinPos, Event.geohash <= hMaxPos)) 
     events = qryEvent.fetch(1000) 

Тогда я должен принести каждый результат с циклом петли для создания JSON для хранения в списке и возврате это клиенту. Так что

for event in events: 
    #do my stuff 

Все работает отлично, но большая проблема бесполезные операции чтения каждый раз, когда я называю этот метод. Я имею в виду, что каждый раз, когда метод вызывается, он выбирает те же события, что и другие запросы клиентов или худшие, те же события, что и предыдущий запрос того же клиента (если я перемещаюсь на 50 метров, и я делаю клиентский запрос, события аналогичны предыдущему запросу ad 99 %). Это очень скоро приведет к использованию квот и чтению операций. Я думаю, что я должен использовать memcache, чтобы хранить извлеченные события и читать их в memcache, прежде чем читать их из хранилища данных, но я не имею идеи реализовать его с моей структурой.

Моя идея состояла в том, чтобы использовать geohash в качестве ключа memcache, но я не могу выполнять итерацию через кешированные элементы, я могу только сделать точный доступ к заданному ключу, чтобы мое решение не применимо (я не могу сделать прямой доступ к memcache с ключом, мне нужно выполнить итерацию в элементах memcache, чтобы найти событие, которое соответствует моему запросу диапазона координат). У кого-то есть намек или предложение?

+0

Знаете ли вы, что ndb уже выполняет [два уровня кэширования] (https://cloud.google.com/appengine/docs/python/ndb/cache)? Вас больше беспокоит запрос или выборка сущностей? Я бы рекомендовал взглянуть на [Cloud Trace] (https://cloud.google.com/cloud-trace/), чтобы узнать, какие RPC будут поражать вас больше всего. – tx802

+0

Спасибо за ответ. Сейчас моя самая большая проблема заключается в том, чтобы ограничить чтение из хранилища данных, поэтому я беспокоюсь о том, что сущности, получающие ..., я смотрю на предоставленные ссылки! – Zeladyon

+2

Кэширование с ndb не происходит с запросами. Только с get's. Вы могли бы принять несколько стратегий.Кэшируйте результаты запроса, однажды преобразованные в json your self или выполняющие только запрос ключей, и сделайте get_multi, и пусть ndb кэширует элементы для вас. –

ответ

1

я могу думать 2 растворов:

1) Хранить в Memcached информации меньшего размера коробки (например, длинной 100 метров), с идентификатором широты-долготы. Вы можете запросить у ndb большую коробку, например. Длиной 5500 метров, и сохраните информацию обо всех содержащихся в нем небольших ящиках в memcached. Когда пользователь перемещается на 50, 100 или 400 метров, вы сможете дать ей ответ с memcached данными, и если кто-то рядом с этим местом (в радиусе 500 метров), произойдет то же самое.

2) Вы можете использовать ElasticSearch, в частности, Geo Distance Filter. С его помощью вы можете фильтровать "documents that include only hits that exists within a specific distance from a geo point".

Примечание: если getEvents события возврата в коробке 5000 метров, возможно, вы не должны запускать новый запрос при перемещении 50 метров, но на большее расстояние.

Смежные вопросы