【问题标题】:Python - GAE - Script loop consuming much memoryPython - GAE - 脚本循环消耗大量内存
【发布时间】:2013-01-21 13:23:05
【问题描述】:

我正在使用以下脚本创建一些 rss 快照(只是说)。

脚本在后端运行,我的内存消耗越来越大。

class StartHandler(webapp2.RequestHandler):

    @ndb.toplevel
    def get(self):
        user_keys = User.query().fetch(1000, keys_only=True)
        if not user_keys:
            return
        logging.info("Starting Process of Users")
        successful_count = 0
        start_time = time.time()
        for user_key in user_keys:
            try:
                this_start_time = time.time()
                statssnapshot = StatsSnapShot(parent=user_key,
                                        property=get_rss(user_key.id())
                                        )
                #makes a urlfetch
                statssnapshot.put_async()
                successful_count += 1               
            except:
                pass
        logging.info("".join(("Processed: [",
                            str(successful_count),
                            "] users after [",
                            str(int(time.time()-start_time)),
                            "] secs")))
        return

编辑

这里还有 rss 函数可以说:

def get_rss(self, url):
        try:
            result = urlfetch.fetch(url)
            if not result.status_code == 200:
                logging.warning("Invalid URLfetch")
                return
        except urlfetch.Error, e:
            logging.warning("".join("Fetch Failed to get ",url," with",e))
            return
        content = result.content #Around 500 - 200KB
        reobj = re.compile(r'(?<=")[0-9]{21}(?=")')
        user_ids = reobj.findall(content)
        user_ids = set(user_ids)#set to fail if something is not unique
        return user_ids

脚本运行正常,但是随着用户的增多,脚本消耗的内存越来越多。 来自 C 我不知道如何在 Python 中高效地操作内存和变量。

例如,我知道如果没有再次引用 python 中的变量,垃圾收集器会释放用于该变量的内存,但我的情况似乎是什么,我在哪里做错了?

我怎样才能优化这个脚本有一个不断增加内存使用,但只消耗每个需要的内存 用户进程?

【问题讨论】:

  • 我没有在您的代码 sn-p 中发现任何 明显 内存泄漏,但是 1/ 我没有使用 GAE 的经验,并且 2/ 您的部分代码没有提交(特别是“StatsSnapShot”)。只是一些提示wrt /更pythonic: - logging.warning("".join("Fetch Failed to get ",url," with",e)) => logging.exception("Fetch Failed to get %s with %s", url, e) - set(someseq) 不会“如果某些东西不是唯一的则失败” - 从不曾经使用裸的 except 子句(在最少使用 logging.exception 来获得一些反馈)
  • @brunodesthuilliers 意思是会失败是错字,意思是不重复。
  • use_cache=False 是否按预期工作?
  • @tesdal 是的,一切都好。给我一些时间,我会在一些测试后验证答案。还禁用了内存缓存。
  • 太好了,很高兴听到它! get_rss 也是 ndb async 的一个很好的候选对象,可以作为 query.map 的回调,也可以作为屏障进行批处理。如果后端现在主要等待 urlfetches,您可以同时进行 100 个 API 调用,这使您可以显着加快速度。

标签: python google-app-engine memory urlfetch


【解决方案1】:

NDB 增加了自动缓存,这通常很方便。你有内存缓存和memcached,你可以为它们设置策略。

进行看跌时,您可以提供context options,我怀疑以下内容对您有用:

statssnapshot.put_async(use_cache=False)

【讨论】:

  • 非常感谢。这解决了我的问题并节省了大量资源。我还禁用了内存缓存,这也大大改善了情况。要说的一件小事是,在开发服务器上它仍然会获得大量内存,但在生产环境中工作正常。
  • 开发服务器具有 memcached 仿真并使用 sqllite,而不是外部服务,因此您可以获得更多内存使用。关于异步,developers.google.com/appengine/docs/python/ndb/async 值得一读。
猜你喜欢
  • 2018-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
  • 1970-01-01
  • 2022-01-16
  • 2014-01-04
  • 2012-07-03
相关资源
最近更新 更多