0

少しの間、アプリで memcache を動作させるのに苦労しています。データベースから読み取ることのない場所 (もちろん、memcache データが失われない限り) でようやく機能するようになったと思いましたが、データストアの読み取り数がクォータを超えたため、サイトがシャットダウンされました! 私は現在無料のアプリスポットを使用していますが、できるだけ長く使い続けたいと思っています。とにかく、これが私のコードです。誰かがその穴を見つけるのを手伝ってくれるかもしれません。

私は現在、db.Model.all()、delete()、および put() メソッドをオーバーライドして memcache を最初にクエリすることにより、memcache を実装しようとしています。データストア内の各オブジェクトが独自の memcache 値を持ち、その ID がキーになるように memcache を設定しました。次に、モデル クラスごとに、クエリ方法を知っているキーの下に ID のリストがあります。これを十分に明確に説明したことを願っています。

""" models.py """
         @classmethod
         def all(cls, order="sent"):
                 result = get_all("messages", Message)
                 if not result or memcache.get("updatemessages"):
                         result = list(super(Message, cls).all())
                         set_all("messages", result)
                         memcache.set("updatemessages", False)
                         logging.info("DB Query for messages")

                 result.sort(key=lambda x: getattr(x, order), reverse=True)
                 return result

         @classmethod
         def delete(cls, message):
                 del_from("messages", message)
                 super(Message, cls).delete(message)

         def put(self):
                 super(Message, self).put()

                 add_to_all("messages", self)



""" helpers.py """

 def get_all(type, Class):
         all = []
         ids = memcache.get(type+"allid")
         query_amount = 0
         if ids:
                 for id in ids:
                         ob = memcache.get(str(id))
                         if ob is None:
                                 ob = Class.get_by_id(int(id))
                                 if ob is None:
                                         continue
                                 memcache.set(str(id), ob)
                                 query_amount += 1
                         all.append(ob)
                 if query_amount: logging.info(str(query_amount) + " ob queries")
                 return all
         return None

 def add_to_all(type, object):
         memcache.set(str(object.key().id()), object)
         all = memcache.get(type+"allid")
         if not all:
                 all = [str(ob.key().id()) for ob in object.__class__.all()]
                 logging.info("DB query for %s" % type)
         assert all is not None, "query returned None.  Send this error code to ____: 2 3-193A"
         if not str(object.key().id()) in all:
                 all.append(str(object.key().id()))
         memcache.set(type+"allid", all)

 @log_on_fail
 def set_all(type, objects):
         assert type in ["users", "messages", "items"], "set_all was not passed a valid type.  Send this error code to ____: 33-205"
         assert not objects is None, "set_all was passed None as the list of objects.    Send this error code to _________: 33-206"
         all = []
         for ob in objects:
                 error = not memcache.set(str(ob.key().id()), ob)
                 if error:
                         logging.warning("keys not setting properly. Object must not be pickleable")
                 all.append(str(ob.key().id()))
         memcache.set(type+"allid", all)

 @log_on_fail
 def del_from(type, object):
         all = memcache.get(type+"allid")
         if not all:
                 all = object.__class__.all()
                 logging.info("DB query %s" % type)
         assert all, "Could not find any objects.  Send this error code to _____: 13-    219"
         assert str(object.key().id()) in all, "item not found in cache.  Send this error code to ________: 33-220"
         del all[ all.index(str(object.key().id())) ]
         memcache.set(type+"allid", all)
         memcache.delete(str(object.key().id()))

ごちゃごちゃしていて優雅さが欠けていることをお詫びします。うまくいけば、誰かが助けてくれるでしょう。ndb に切り替えることも考えましたが、今のところはカスタム キャッシュに固執しています。に気付くでしょうlogging.info("some-number of ob queries")。このログは頻繁に取得します。30分ごとに1回か2回かもしれません。memcache は本当に頻繁にデータを失うのでしょうか、それともコードに何か問題があるのでしょうか?

4

2 に答える 2

5

簡単な解決策: NDBに切り替えます。

NDB モデルは memcache とインスタンス キャッシュ (100% 無料) に値を保存し、これらのモデルはオブジェクトを更新/削除するときにキャッシュを無効にします。取得は、最初にインスタンス キャッシュからの取得を試み、失敗した場合は memcache から取得を試み、最後にデータストアから取得を試みます。途中で取得できなかったキャッシュのいずれかに値を設定します。

于 2012-11-01T05:19:18.867 に答える
0

App Engine の memcache は、最適化されたエビクション アルゴリズムによってオブジェクトを削除するため、このログ メッセージを指定した頻度で表示すると、2 つの理由が考えられます。

これらのデータはあまり頻繁にアクセスされないか、memcache にあるデータの量がかなり大きいため、その一部が時々削除されます。

また、memcache とインスタンス キャッシュの使用を非常に効率的に処理する ndb に移行することも提案します。

お役に立てれば!

于 2012-11-01T08:11:54.957 に答える