2016-12-02 106 views
1

我目前有一个应用程序在appengine上运行,我使用延迟库执行一些作业,其中一些任务每天运行一次,而其中一些任务每月执行一次。这些任务中的大多数都会查询Datastore以检索文档,然后将实体存储在索引(Search API)中。其中一些表格每月更换一次,我必须在所有实体(4〜5M)上运行这些任务。这样的任务的Google appengine:任务队列性能

一为例是:

def addCompaniesToIndex(cursor=None, n_entities=0, mindate=None): 
    #get index 
    BATCH_SIZE = 200 
    cps, next_cursor, more = Company.query().\ 
            fetch_page(BATCH_SIZE, 
               start_cursor=cursor) 

    doc_list = [] 

    for i in range(0, len(cps)): 
     cp = cps[i] 
     #create a Index Document using the Datastore entity 
     #this document has only about 5 text fields and one date field 
     cp_doc = getCompanyDocument(cp) 
     doc_list.append(cp_doc) 

    index = search.Index(name='Company') 
    index.put(doc_list) 

    n_entities += len(doc_list) 

    if more: 
     logging.debug('Company: %d added to index', n_entities) 
     #to_put[:] = [] 
     doc_list[:] = [] 
     deferred.defer(addCompaniesToIndex, 
         cursor=next_cursor, 
         n_entities=n_entities, 
         mindate=mindate) 
    else: 
     logging.debug('Finished Company index creation (%d processed)', n_entities) 

当我只运行一个任务,执行需要大约每推迟任务4-5s,所以索引我5M实体将需要大约35小时。

另一件事是,当我运行的另一指标的更新(例如,每天更新一)使用在同一个队列不同的递延任务,都被执行速度慢了很多。并开始每个延迟的呼叫约10-15秒,这是无法忍受的。

我的问题是:有没有办法更快地做到这一点,缩放推队列每次运行一个以上的工作吗?或者我应该使用不同的方法解决这个问题?

由于提前,

回答

2

通过将if more声明在addCompaniesToIndex()函数结束时你几乎序列化任务执行:不创建下一个任务延期,直到当前递延任务完成索引其份额文档。

您可以做的是在Company.query().fetch_page()调用之后立即移动if more语句,您可以在其中获取(大部分)下一个延迟任务执行所需的变量。

这样下一个任务延迟将被创建并添加到队列中(长)的当前一个完成之前,所以其处理可以潜在地重叠/交错。您还需要其他一些修改,例如处理n_entities变量,这会在更新后的场景中失去其当前含义 - 但这或多或少是表面化/信息化的,对于实际的文档索引操作不是必需的。

如果延期任务的数量是非常高的有排队的同时太多的风险,这可能导致在GAE情况会催生处理它们的数量“爆炸”。在这种情况下不需要,可以通过延迟执行一些操作来“调节”延迟任务产生的速率,请参见https://stackoverflow.com/a/38958475/4495081

+0

嗨丹,我申请你的想法,我的代码,但我的印象中,从数据存储读取实际上是很多比插入索引这些实体,因此,我期待的吞吐量增益不是很大比较贵,我想尽量减少读取操作的大小可能会有帮助,会做更多的测试并回复给您。 – Clds

+0

在这种情况下,最好是使用keys_only查询,然后在排队完成下一个任务之后,为页面组装键列表并为其执行批量读取以获取文档并更新索引。 –

+0

顺便说一句 - 您实际上可以检查您对数据存储区读取成本的怀疑:在开发控制台中检查应用程序的日志 - 某些日志条目在请求持续时间列中有蓝色链接 - 单击链接,然后单击“查看跟踪”在弹出菜单中,您将看到StackDriver中的appstats-like跟踪,以便您更好地了解该特定请求花费的时间。 –