Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.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
Python 如何将数据导入/同步到App Engine数据存储区,而无需过度读取数据存储区或超时_Python_Google App Engine_Optimization_Google Cloud Datastore_App Engine Ndb - Fatal编程技术网

Python 如何将数据导入/同步到App Engine数据存储区,而无需过度读取数据存储区或超时

Python 如何将数据导入/同步到App Engine数据存储区,而无需过度读取数据存储区或超时,python,google-app-engine,optimization,google-cloud-datastore,app-engine-ndb,Python,Google App Engine,Optimization,Google Cloud Datastore,App Engine Ndb,我正在编写一个应用程序,它使用远程API提供相当静态的数据(但仍然可以一天更新几次)。问题是API非常慢,我更愿意将数据导入到我自己的数据存储中,这样我就可以在我的终端上查询数据 问题是,结果包含约700条记录,需要每5小时左右同步一次。这包括添加新记录、更新旧记录和删除过时记录 我有一个简单的解决方案可以工作——但速度很慢,在超时之前(大约500条记录之后)使用30000个数据存储读取操作 最糟糕的是,这700条记录只针对一个客户机,而我只是做了一个测试。事实上,我想为数百或数千个记录数量相似

我正在编写一个应用程序,它使用远程API提供相当静态的数据(但仍然可以一天更新几次)。问题是API非常慢,我更愿意将数据导入到我自己的数据存储中,这样我就可以在我的终端上查询数据

问题是,结果包含约700条记录,需要每5小时左右同步一次。这包括添加新记录、更新旧记录和删除过时记录

我有一个简单的解决方案可以工作——但速度很慢,在超时之前(大约500条记录之后)使用30000个数据存储读取操作

最糟糕的是,这700条记录只针对一个客户机,而我只是做了一个测试。事实上,我想为数百或数千个记录数量相似的客户做同样的事情。。。你可以看到这是如何不扩大的

以下是我的实体类定义:

class Group(ndb.Model):
    groupid = ndb.StringProperty(required=True)
    name = ndb.StringProperty(required=True)
    date_created = ndb.DateTimeProperty(required=True, auto_now_add=True)
    last_updated = ndb.DateTimeProperty(required=True, auto_now=True)
以下是我的同步代码(Python):

currentTime=datetime.now()
groups=get_list_of_groups_from_api(clientid)#[{'groupname':'groupname','id':'12341235'},]
对于组中的组:
groupid=组[“id”]
groupObj=Group.get_或_insert(groupid,groupid=Group[“id”],name=Group[“name”])
groupObj.put()
staleGroups=Group.query(Group.last\u更新
我无法告诉您为什么要进行30000次读取操作

您应该首先运行appstats并分析此代码,以查看在何处执行数据存储操作

尽管如此,我可以看到您的代码中存在一些真正的低效之处

例如,您的delete-stale-groups代码效率极低

您应该先执行一个只包含密钥的查询,然后执行批量删除。 您所做的非常慢,循环中的每个delete()都有很多延迟

另外,get\u或\u insert使用一个事务(同样,如果组不存在,put已经完成,然后您执行第二个put()),如果您不需要事务,您会发现运行速度会更快。您没有存储任何附加数据这一事实意味着您可以盲写组(因此初始get/read),除非您想保留
date\u created

其他加快速度的方法是对键列表执行批处理get/put。 然后对所有不存在的实体执行批处理put()

同样,这比迭代每个键要快得多

此外,您应该使用TaskQueue来运行这组代码,然后您将有一个10分钟的处理窗口

之后,可以通过将流程拆分为两个任务来实现进一步的扩展。第一个创建/更新组实体。完成后,启动删除过时组的任务—将datetime作为参数传递给下一个任务

如果您拥有的实体比这个简单模型中可以处理的还要多,那么请开始查看MapReduce


但对于初学者来说,只需将精力集中在提高当前运行的工作效率上。

您能否详细说明一下,为什么每个客户机需要大约30000次阅读?当它只有大约700个实体需要处理时,我不知道为什么它使用30000个读取操作。。这是我问题的一部分。我更希望它尽可能少。我不是故意做30000次读取操作——这是我的实现的结果:/你能提供来自\u api()代码的\u组的get\u list\u吗?我怀疑您想修改它以返回较少的组…它所做的只是返回一个列表中约700个组项的列表(看起来像我在该行末尾的注释)。该函数对数据存储没有任何作用——只是对json端点的简单web请求。该函数只需5秒钟即可返回。。因此,在超时之前剩下的55秒完全是由于函数调用下面的代码中的内容。你说的远程api是什么意思?针对远程api运行的代码`/\u ah/remote\u api'可以运行数天,因此不会超时。
    currentTime = datetime.now()
    groups = get_list_of_groups_from_api(clientid) #[{'groupname':'Group Name','id':'12341235'}, ...]

    for group in groups:
        groupid = group["id"]

        groupObj = Group.get_or_insert(groupid, groupid=group["id"], name=group["name"])
        groupObj.put()

    staleGroups = Group.query(Group.last_updated < currentTime)
    for staleGroup in staleGroups:
        staleGroup.delete()