【问题标题】:Google App Engine and Google Sheets exceeding soft memory limit超过软内存限制的 Google App Engine 和 Google 表格
【发布时间】:2017-02-11 21:35:23
【问题描述】:

我正在编写一个简单的服务来从多个来源获取数据,将它们组合在一起,然后使用 Google API 客户端将其发送到 Google 表格。 Easy peasy 效果不错,数据没那么大。

问题是在构建 api 服务(即build('sheets', 'v4', http=auth).spreadsheets())后调用 .spreadsheets() 会导致大约 30 兆字节的内存跳跃(我做了一些分析以分离出分配内存的位置)。当部署到 GAE 时,这些峰值会持续很长一段时间(有时一次数小时),然后逐渐上升,并在多次请求后触发 GAE 的“超出软私有内存限制”错误。

我将 memcache 用于发现文档并使用 urlfetch 获取数据,但这些是我使用的唯一其他服务。

我尝试过手动垃圾回收,更改 app.yaml 中的线程安全,甚至更改调用 .spreadsheets() 的点,都无法解决这个问题。也有可能我只是误解了 GAE 的架构,但我知道峰值是由对 .spreadsheets() 的调用引起的,并且我没有在本地缓存中存储任何内容。

有没有办法 1) 通过调用 .spreadsheets() 减少内存峰值的大小或 2) 防止峰值留在内存中(或者最好两者都做)。下面是一个非常简化的要点,以提供 API 调用和请求处理程序的概念,如果需要,我可以提供更完整的代码。我知道以前有人问过类似的问题,但我无法解决。

https://gist.github.com/chill17/18f1caa897e6a20201232165aca05239

【问题讨论】:

  • 其实我在googleappengine的issues tracker中找到了Issue#7973Issue#12220,与遇到的问题“Exceeded soft private memory limit”相关。根据给定的线程,此问题尚未完全解决,其中一个线程中给出的解决方法似乎也与您的担忧无关。

标签: python google-app-engine google-sheets-api


【解决方案1】:

我在只有 20MB 可用 RAM 的小型处理器上使用电子表格 API 时遇到了这个问题。问题是 google API 客户端以字符串格式提取整个 API 并将其作为资源对象存储在内存中。

如果空闲内存是个问题,您应该构建自己的 http 对象并手动发出所需的请求。请参阅我的 Spreadsheet() 类作为如何使用此方法创建新电子表格的示例。

SCOPES = 'https://www.googleapis.com/auth/spreadsheets'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Google Sheets API Python Quickstart'

class Spreadsheet:

    def __init__(self, title):

        #Get credentials from locally stored JSON file
        #If file does not exist, create it
        self.credentials = self.getCredentials()

        #HTTP service that will be used to push/pull data

        self.service = httplib2.Http()
        self.service = self.credentials.authorize(self.service)
        self.headers = {'content-type': 'application/json', 'accept-encoding': 'gzip, deflate', 'accept': 'application/json', 'user-agent': 'google-api-python-client/1.6.2 (gzip)'}        


        print("CREDENTIALS: "+str(self.credentials))


        self.baseUrl = "https://sheets.googleapis.com/v4/spreadsheets"
        self.spreadsheetInfo = self.create(title)   
        self.spreadsheetId = self.spreadsheetInfo['spreadsheetId']    



    def getCredentials(self):
        """Gets valid user credentials from storage.

        If nothing has been stored, or if the stored credentials are invalid,
        the OAuth2 flow is completed to obtain the new credentials.

        Returns:
            Credentials, the obtained credential.
        """
        home_dir = os.path.expanduser('~')
        credential_dir = os.path.join(home_dir, '.credentials')
        if not os.path.exists(credential_dir):
            os.makedirs(credential_dir)
        credential_path = os.path.join(credential_dir,
                                       'sheets.googleapis.com-python-quickstart.json')

        store = Storage(credential_path)
        credentials = store.get()
        if not credentials or credentials.invalid:
            flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
            flow.user_agent = APPLICATION_NAME
            if flags:
                credentials = tools.run_flow(flow, store, flags)
            else: # Needed only for compatibility with Python 2.6
                credentials = tools.run(flow, store)
            print('Storing credentials to ' + credential_path)
        return credentials

    def create(self, title):

        #Only put title in request body... We don't need anything else for now
        requestBody = {
            "properties":{
                "title":title
            },
        }


        print("BODY: "+str(requestBody))
        url = self.baseUrl

        response, content = self.service.request(url, 
                                        method="POST", 
                                        headers=self.headers,
                                        body=str(requestBody))
        print("\n\nRESPONSE\n"+str(response))
        print("\n\nCONTENT\n"+str(content))

        return json.loads(content)

【讨论】:

    猜你喜欢
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-28
    相关资源
    最近更新 更多