当前位置: 首页 > 知识库问答 >
问题:

GAE Python LXML-超过软私有内存限制

乐正浩博
2023-03-14

我正在获取一个GZip LXML文件,并试图将产品条目写入数据库模型。以前,我有本地内存问题,这是通过SO(问题)的帮助解决的。现在我得到了一切工作和部署它,然而在服务器上我得到以下错误:

Exceeded soft private memory limit with 158.164 MB after servicing 0 requests total

现在我尝试了所有我知道的方法来减少内存使用,目前正在使用下面的代码。gzip文件约为7MB,而解压缩文件约为80MB。本地代码运行良好。我试着将其作为HTTP请求和Cron作业运行,但没有什么不同。现在我想知道是否有任何方法可以提高效率。

关于SO的一些类似问题涉及前端和后端规范,我不熟悉。我正在运行GAE的免费版本,这个任务必须每周运行一次。如能就前进的最佳方式提出任何建议,将不胜感激。

from google.appengine.api.urlfetch import fetch
import gzip, base64, StringIO, datetime, webapp2
from lxml import etree
from google.appengine.ext import db

class GetProductCatalog(webapp2.RequestHandler):
  def get(self):
    user = XXX
    password = YYY
    url = 'URL'

    # fetch gziped file
    catalogResponse = fetch(url, headers={
        "Authorization": "Basic %s" % base64.b64encode(user + ':' + password)
    }, deadline=10000000)

    # the response content is in catalogResponse.content
    # un gzip the file
    f = StringIO.StringIO(catalogResponse.content)
    c = gzip.GzipFile(fileobj=f)
    content = c.read()

    # create something readable by lxml
    xml = StringIO.StringIO(content)

    # delete unnecesary variables
    del f
    del c
    del content

    # parse the file
    tree = etree.iterparse(xml, tag='product')

    for event, element in tree:
        if element.findtext('manufacturer') == 'New York':
            if Product.get_by_key_name(element.findtext('sku')):
                    coupon = Product.get_by_key_name(element.findtext('sku'))
                    if coupon.last_update_prov != datetime.datetime.strptime(element.findtext('lastupdated'), "%d/%m/%Y"):
                        coupon.restaurant_name = element.findtext('name')
                        coupon.restaurant_id = ''
                        coupon.address_street = element.findtext('keywords').split(',')[0]
                        coupon.address_city = element.findtext('manufacturer')
                        coupon.address_state = element.findtext('publisher')
                        coupon.address_zip = element.findtext('manufacturerid')
                        coupon.value = '$' + element.findtext('price') + ' for $' + element.findtext('retailprice')
                        coupon.restrictions = element.findtext('warranty')
                        coupon.url = element.findtext('buyurl')
                        if element.findtext('instock') == 'YES':
                            coupon.active = True
                        else:
                            coupon.active = False
                        coupon.last_update_prov = datetime.datetime.strptime(element.findtext('lastupdated'), "%d/%m/%Y")
                        coupon.put()
                    else:
                        pass
            else:
                    coupon = Product(key_name = element.findtext('sku'))
                    coupon.restaurant_name = element.findtext('name')
                    coupon.restaurant_id = ''
                    coupon.address_street = element.findtext('keywords').split(',')[0]
                    coupon.address_city = element.findtext('manufacturer')
                    coupon.address_state = element.findtext('publisher')
                    coupon.address_zip = element.findtext('manufacturerid')
                    coupon.value = '$' + element.findtext('price') + ' for $' + element.findtext('retailprice')
                    coupon.restrictions = element.findtext('warranty')
                    coupon.url = element.findtext('buyurl')
                    if element.findtext('instock') == 'YES':
                        coupon.active = True
                    else:
                        coupon.active = False

                    coupon.last_update_prov = datetime.datetime.strptime(element.findtext('lastupdated'), "%d/%m/%Y")
                    coupon.put()
        else:
            pass

        element.clear()

乌德帕特

根据保罗的建议,我实现了后端。经过一些麻烦,它像一个魅力-找到我在下面使用的代码。

我的屁股。yaml如下所示:

backends:
- name: mybackend
  instances: 10
  start: mybackend.app
  options: dynamic

我的app.yaml如下:

handlers:
- url: /update/mybackend
  script: mybackend.app
  login: admin

共有2个答案

骆照
2023-03-14

关于后端:看看你提供的例子——看起来你的请求只是由前端实例处理的。

要使其由后端处理,请尝试调用以下任务:http://mybackend.my_app_app_id.appspot.com/update/mybackend

另外,我认为您可以删除:start:mybackend。从后端下载应用程序。yaml

湛嘉歆
2023-03-14

后端与前端实例类似,但它们不可扩展,您必须根据需要停止并启动它们(或者将它们设置为动态,这可能是您的最佳选择)。

您可以在后端拥有高达1024MB的内存,因此它可能对您的任务运行良好。

https://developers.google.com/appengine/docs/python/backends/overview

App Engine后端是应用程序的实例,它不受请求截止日期的限制,并且比普通实例可以访问更多的内存(高达1GB)和CPU(高达4.8GHz)。它们专为需要更快性能、大量可寻址内存和连续或长时间运行的后台进程的应用程序而设计。后端有多种尺寸和配置,按正常运行时间计费,而不是按CPU使用率计费。

后端可以配置为常驻或动态。常驻后端持续运行,允许您随时间依赖其内存状态并执行复杂的初始化。动态后端在接收到请求时出现,在空闲时被拒绝;它们非常适合间歇工作或由用户活动驱动的工作。有关常驻后端和动态后端之间差异的更多信息,请参阅后端类型以及启动和关闭的讨论。

听起来正是你需要的。免费使用级别也可以用于您的任务。

 类似资料:
  • 我们有一个可怕的经验与gae围棋。当我们的应用程序是一个免费的,我们从来没有超过软私有内存限制的问题。我们抢了定额,因此决定付款。我们每天的预算定为3美元。付费服务激活后,我们可以再次使用该网站,超额配额消失了。几个小时后,我们得到了这个超软私有内存限制,除了这个,再也看不到任何东西了。我试图清除数据存储中的一些大数据,禁用内置插件,但仍然没有运气。 我在代码中做了一些测试,以确定故障来自何处。删

  • 我目前有一个在Google App Engine标准环境中运行的应用程序,其中包括一个大型天气数据数据库和一个生成数据图的前端endpoint。该数据库位于Google云数据存储中,Python Flask应用程序通过NDB库访问它。 我的问题如下:当我试图为跨越一周以上的天气数据生成图表(数据每5分钟存储一次)时,我的应用程序超出了GAE的软私有内存限制并崩溃。然而,在我的每个WeatherDa

  • 我遇到偶尔错误在各种各样的请求处理程序中的应用程序引擎。我明白这个错误意味着实例使用的内存超过了分配的数量,以及这是如何导致实例关闭的。 我想了解错误的可能原因,首先,我想了解应用引擎Python实例如何管理内存。我的基本假设是: 一个F2实例以256 MB开始 当它启动时,它加载我的应用程序代码-比方说30 MB 当它处理请求时,它有226 MB可用 只要该请求不超过226 MB(误差幅度),该

  • 问题内容: 我的应用程序的用户尝试使用我的应用程序将文件作为电子邮件附件发送。但是,这样做会引发以下异常,我无法解读 什么是“软私有内存限制”?有什么可能导致此异常? 问题答案: “软专用内存限制”是App Engine将停止实例接收任何更多请求,等待任何未完成的请求并终止该实例的内存限制。当您使用过多内存时,可以将其视为正常关机。 偶尔达到软限制是可以的,因为您的所有请求均已完成。但是,每次发生

  • 我的一个GAE任务队列请求超过了软内存限制(下面的日志)。我对软内存限制的理解是,它让请求完成,然后在完成后关闭实例。 然而,从日志来看,当我达到软内存限制时,执行似乎停止了。在内存限制消息之后,我没有看到更多的日志代码,我已经检查了我的状态,看起来请求没有完成。我不确定它是否重要,但此请求正在延迟库TaskQueue中执行。 因此,如果TaskQueue达到软私有内存限制,执行是继续直到请求完成

  • 我们在谷歌应用引擎(GAE)上有一个长期运行的服务。然而,过了一会儿,我们开始得到图像中的错误。代码没有变化。我不明白为什么我们会有以前没有的问题。 2020-01-05 08:31:32.704UTC-8在总共服务0个请求后,超过了2048 MB的软内存限制(2068 MB)。考虑在app.yaml.中设置一个更大的实例类 2020-01-05 08:31:32.705UTC-8此请求导致为应用