Ключ Engine Memcache префикс ключа во всех версиях - PullRequest
1 голос
/ 21 февраля 2011

Привет!

У меня есть программа установки Google App Engine, в которой ключам memcached предшествует os.environ['CURRENT_VERSION_ID'] для создания нового кэша при развертывании без необходимости его очистки вручную.

Это работало очень хорошо, пока для разработки не стало необходимым запускать две версии приложения одновременно. Это, конечно, приводит к несоответствиям в кэшировании.

Я ищу предложения о том, как префикс клавиш сейчас. По сути, должна существовать переменная, которая изменяется между версиями при развертывании любой версии. (Ну, это не совсем идеально, так как кэш полностью разрушен.)

Я думал о следующих возможностях:

  • Создание объекта RuntimeEnvironment, в котором хранится последний префикс кэша. Недостатки: даже если кешируется, тормозит каждый запрос. Не может быть кэширован в памяти, только в memcached, так как развертывание другой версии может изменить его.

  • Использовать номер версии для каждой сущности. Это дает очень хорошую детализацию в том, что кэш может оставаться теплым для неизмененных объектов. Недостатком является то, что нам нужно нажимать на все версии при смене моделей, чего я хочу избежать, чтобы протестировать изменения модели перед развертыванием в производство.

  • Забудьте префикс ключа. Глобальное пространство имен для ключей. Напишите скрипт для очистки кэша при каждом развертывании. На самом деле это выглядит так же хорошо, как если бы не лучше, чем первая идея: кеш полностью разрушается в обоих сценариях, и это позволяет избежать накладных расходов на объект времени выполнения.

Любые мысли, разные идеи высоко ценятся!

Ответы [ 2 ]

1 голос
/ 02 марта 2011

Значение os.environ ['CURRENT_VERSION_ID'] будет отличаться для двух ваших версий, поэтому у вас будет отдельный кэш для каждой (живой и тестовой),

, Я полагаю, ваша проблема в том, что когда вы "развертываете" версию, вы не хотите, чтобы кэш из разработки / тестирования использовался?(в противном случае, как Ник и systempuntoout, я в замешательстве).

Одним из способов достижения этого было бы использование заголовка домена / хоста в кэше - поскольку это отличается для ваших версий dev / live.Вы можете извлечь хост, выполнив что-то вроде этого:

scheme, netloc, path, query, fragment = urlparse.urlsplit(self.request.url)

# Discard any port number from the hostname
domain = netloc.split(':', 1)[0]

Это не даст особенно приятных ключей, но, вероятно, будет делать то, что вы хотите (если я правильно понял).

0 голосов
/ 03 марта 2011

Был некоторый беспорядок с тем, как я сформулировал вопрос.

Я закончил хэшем атрибутов для каждого класса. Возьмите этот класс, например:

class CachedModel(db.Model):

  @classmethod
  def cacheVersion(cls):
    if not hasattr(cls, '__cacheVersion'):
      props = cls.properties()
      prop_keys = sorted(props.keys())
      fn = lambda p: '%s:%s' % (p, str(props[p].model_class))
      string = ','.join(map(fn, prop_keys))
      cls.__cacheVersion = hashlib.md5(string).hexdigest()[0:10]
    return cls.__cacheVersion

  @classmethod
  def cacheKey(cls, key):
    return '%s-%s' % (cls.cacheVersion(), str(key))

Таким образом, когда сущности сохраняются в memcached, используя их cacheKey(...), они будут совместно использовать кеш, только если фактический класс такой же.

Это также имеет дополнительное преимущество, заключающееся в том, что отправка обновления, которое не изменяет модель, оставляет все записи в кэше для этой модели без изменений. Другими словами, отправка обновления больше не действует как очистка кэша.

Недостатком этого метода является хеширование класса один раз для каждого экземпляра веб-приложения.

ОБНОВЛЕНИЕ 2011-3-9: Я перешел на более сложный, но более точный способ получения версии. Оказывается, использование __dict__ дало неверные результаты, поскольку его представление str включает адреса указателей. Этот новый подход учитывает только свойства хранилища данных.

ОБНОВЛЕНИЕ 2011-3-14: Таким образом, хэш python (...), очевидно, не гарантируется равным между запусками интерпретатора. Были странные случаи, когда другой экземпляр ядра приложения видел разные хэши. используя md5 (который быстрее чем sha1 быстрее чем sha256) сейчас. нет реальной необходимости быть криптобезопасным. просто нужен хороший hashfn. Вероятно, переключится на что-то более быстрое, но сейчас я скорее буду без ошибок. Также гарантируется сортировка ключей, а не объектов свойств.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...