Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在google应用程序引擎python上与memcache抗争_Python_Google App Engine_Memcached - Fatal编程技术网

在google应用程序引擎python上与memcache抗争

在google应用程序引擎python上与memcache抗争,python,google-app-engine,memcached,Python,Google App Engine,Memcached,我一直在努力让memcache在我的应用程序上运行一段时间。我以为我终于让它在从不从数据库读取数据的地方工作了(当然,除非memcache数据丢失),结果我的网站因为读取数据超过qota而关闭了!我目前正在使用一个免费的appspot,并希望尽可能长时间保持这种状态。不管怎样,这是我的密码,也许有人能帮我找到它的漏洞 我目前正试图通过重写db.Model.all()、delete()和put()方法来实现memcache,以首先查询memcache。我设置了memcache,其中数据存储中的每个

我一直在努力让memcache在我的应用程序上运行一段时间。我以为我终于让它在从不从数据库读取数据的地方工作了(当然,除非memcache数据丢失),结果我的网站因为读取数据超过qota而关闭了!我目前正在使用一个免费的appspot,并希望尽可能长时间保持这种状态。不管怎样,这是我的密码,也许有人能帮我找到它的漏洞

我目前正试图通过重写db.Model.all()、delete()和put()方法来实现memcache,以首先查询memcache。我设置了memcache,其中数据存储中的每个对象都有自己的memcache值,其id作为键。然后,对于每个模型类,我都有一个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(“一些ob查询”)
。我经常收到这个日志。也许每半小时一到两次。memcache真的经常丢失数据吗?还是我的代码有问题?

简单的解决方案:切换到


NDB模型将在memcache和实例缓存(100%免费)中存储值,并且当您更新/删除对象时,这些模型还将使缓存失效。检索将首先尝试从实例缓存中获取,然后如果从memcache中获取失败,最后从数据存储中获取,它将在向上的过程中设置丢失的任何缓存中的值。

简单解决方案:切换到


NDB模型将在memcache和实例缓存(100%免费)中存储值,并且当您更新/删除对象时,这些模型还将使缓存失效。检索将首先尝试从实例缓存中获取,然后如果从memcache中获取失败,最后从数据存储中获取,它将在向上移动过程中丢失的任何缓存中设置值。

App Engine memcache通过优化的逐出算法移除对象,因此,以您描述的频率显示此日志消息会导致两种可能的解释

要么这些数据不常被访问,要么memcache中的数据量相当大,因此会不时删除其中的一些数据

我还建议转向ndb,它可以非常有效地处理memcache和实例缓存的使用


希望这有帮助

App Engine memcache通过优化的逐出算法删除对象,因此,按照您描述的频率显示此日志消息会导致两种可能的解释

要么这些数据不常被访问,要么memcache中的数据量相当大,因此会不时删除其中的一些数据

我还建议转向ndb,它可以非常有效地处理memcache和实例缓存的使用


希望这有帮助

是否可以显示不带行号的代码?是否可以显示不带行号的代码?如果我希望缓存本身进行更新和删除,而不是使其失效并读取数据库,该怎么办?您是指仅使用memcache/实例缓存的实现吗?“从自身更新”这句话在其他方面没有意义。对不起,我的意思是:NDB是否每次我
delete()
put()
时都会从数据存储中“重新填充”或更新其实体缓存?这就是你所说的模型使“更新/删除对象时为你缓存”无效的意思吗?如果是这样的话,看到某人经常“
put()
s”一个实体,并且每次必须从数据库中重新加载大约1.5k个实例,似乎不会有太大帮助。它不会重新加载,它在将数据放入数据存储的同一过程中设置缓存。如果我希望缓存本身进行更新和删除,而不是使其失效并读取数据库,该怎么办?你是说只使用memcache/实例缓存实现吗?“从自身更新”这句话在其他方面没有意义。对不起,我的意思是:NDB是否每次我
delete()
put()
时都会从数据存储中“重新填充”或更新其实体缓存?这就是你所说的模型使“更新/删除对象时为你缓存”无效的意思吗?如果是这样的话,看到某人经常“
put()
s”一个实体并每次从数据库中重新加载大约1.5k个实例似乎不会有太大帮助。它不会重新加载,而是在将数据放入数据存储的同一过程中设置缓存。