1

ご挨拶!

キャッシュを手動でフラッシュすることなく、デプロイ時に新しいキャッシュを生成するために、memcachedキーのプレフィックスが付けられた Google App Engine セットアップを用意しました。os.environ['CURRENT_VERSION_ID']

開発でアプリケーションの 2 つのバージョンを同時に実行する必要が生じるまで、これは問題なく機能していました。もちろん、これはキャッシュに矛盾をもたらします。

キーのプレフィックスを付ける方法についての提案を探しています。基本的に、任意のバージョンがデプロイされたときにバージョン間で変化する変数が必要です。(まあ、キャッシュが完全に吹き飛ばされるので、これはあまり理想的ではありません。)

以下の可能性を考えていました。

  • RuntimeEnvironment最新のキャッシュ プレフィックスを格納するエンティティを作成します。欠点: たとえキャッシュされていても、すべてのリクエストが遅くなります。他のバージョンをデプロイすると変更される可能性があるため、memcached にのみキャッシュできません。

  • エンティティごとのバージョン番号を使用します。これにより、変更されていないエンティティに対してキャッシュをウォームに保つことができるという点で、非常に優れた粒度が得られます。欠点は、モデルが変更されたときにすべてのバージョンにプッシュする必要があることです。これは、本番環境にデプロイする前にモデルの変更をテストするために避けたいと考えています。

  • キープレフィックスを忘れてください。キーのグローバル名前空間。デプロイごとにキャッシュをフラッシュするスクリプトを作成します。これは実際には最初のアイデアと同じくらい良いように思えます: キャッシュは両方のシナリオで完全に吹き飛ばされ、これはランタイム エンティティのオーバーヘッドを回避します。

任意の考え、さまざまなアイデアを大歓迎します!

4

2 に答える 2

1

os.environ['CURRENT_VERSION_ID'] の値は 2 つのバージョンで異なるため、それぞれに個別のキャッシュ (ライブのものと開発/テスト用のもの) があります。

だから、あなたの問題は、バージョンを「デプロイ」するときに、開発/テストからのキャッシュを使用したくないということだと思いますか? (そうでなければ、Nick や systempuntoout のように、私は混乱します)。

これを実現する 1 つの方法は、キャッシュ内のドメイン/ホスト ヘッダーを使用することです。これは、dev/live バージョンでは異なるためです。次のようにしてホストを抽出できます。

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

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

これは特に良いキーを与えるわけではありませんが、おそらくあなたが望むことをするでしょう (私が正しく理解していると仮定して)。

于 2011-03-02T20:56:09.227 に答える
0

質問の言い方に少し混乱がありました。

最終的に、属性のクラスごとのハッシュに行き着きました。たとえば、次のクラスを見てください。

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(...)と、実際のクラスが同じ場合にのみキャッシュが共有されます。

これには、モデルを変更しない更新をプッシュしても、そのモデルのすべてのキャッシュ エントリがそのまま残るという追加の利点もあります。つまり、更新のプッシュは、キャッシュのフラッシュとして機能しなくなりました。

これには、webapp のインスタンスごとに 1 回クラスをハッシュするという欠点があります。

2011 年 3 月 9 日の更新: バージョンを取得するための、より複雑ではあるがより正確な方法に変更しました。その表現にはポインターアドレスが含ま__dict__れているため、得られた誤った結果を使用することが判明しました。strこの新しいアプローチでは、データストアのプロパティのみが考慮されます。

2011 年 3 月 14 日の更新: したがって、python の hash(...) は、インタープリターの実行間で等しいことが保証されていないようです。別のアプリ エンジン インスタンスで別のハッシュが表示されるという奇妙なケースが発生していました。今のところ md5 を使用しています (これは sha256 よりも sha1 よりも高速です)。暗号化で安全である必要はありません。ok hashfn が必要です。おそらくより速いものを使用するように切り替えるでしょうが、今のところ私はバグフリーです。また、プロパティ オブジェクトではなく、キーが確実にソートされるようにしました。

于 2011-03-03T06:23:56.883 に答える