python – 在put()之后的App Engine Datastore中读取延迟

我写一个博客/新闻网站的代码.主页有10个最新文章,还有一个存档部分,所有文章按修改时间降序排列.在存档部分中,我使用基于游标的分页,并且从第二页开始缓存结果,因为仅当新文章被发布或存在由于某种原因而变为草稿时,页面才被改变.每页有10篇文章.因此,当用户使用一些数字(而不是第一个)访问存档页面时,首先会检查该页面编号的内存缓存.如果页面不在那里,则会为该页面的游标检查memcache,然后使用该游标从数据存储区中获取结果:

class archivePage:
    def GET(self, page):
        if not page:
            articles = memcache.get('archivePage')
            if not articles:
                articles = fetchArticles()
                memcache.set('archivePage', articles)
        else:
            if int(page) == 0 or int(page) == 1:
                raise web.seeother('/archive')
            articles = memcache.get('archivePage'+page)
            if not articles:
                pageCursor = memcache.get('ArchivePageMapping'+page)
                if not pageCursor:
                    pageMapping = ArchivePageMapping.query(ArchivePageMapping.page == int(page)).get()
                    pageCursor = pageMapping.cursor
                    memcache.set('ArchivePageMapping'+page, pageCursor)
                articles = fetchArticles(cursor=Cursor(urlsafe=pageCursor))
                memcache.set('archivePage'+page, articles)

每次创建新文章或更改现有文章的状态(草稿/发布)时,我将刷新缓存以进行归档页面结果和光标.在将文章保存到数据存储区后,我执行此操作:

class addArticlePage:     
    def POST(self):
        formData = web.input()
        if formData.title and formData.content:
            article = Article(title=formData.title,
                              content=formData.content,
                              status=int(formData.status))
            key = article.put()
            if int(formData.status) == 1:
                cacheArchivePages()
            raise web.seeother('/article/%s' % key.id())

def cacheArchivePages():
    articles, cursor, moreArticles = fetchArticlesPage()
    memcache.set('archivePage', articles)
    pageNumber=2
    while moreArticles:
        pageMapping = ArchivePageMapping.query(ArchivePageMapping.page == pageNumber).get()
        if pageMapping:
            pageMapping.cursor = cursor.urlsafe()
        else:
            pageMapping = ArchivePageMapping(page=pageNumber,
                                            cursor=cursor.urlsafe())
        pageMapping.put()
        memcache.set('ArchivePageMapping'+str(pageNumber), cursor.urlsafe())
        articles, cursor, moreArticles = fetchArticlesPage(cursor=cursor)
        memcache.set('archivePage'+str(pageNumber), articles)
        pageNumber+=1

这里有问题.刷新缓存之后,有时候(没有法律,随机发生),我在刷新之前获得与归档页面相同的结果和光标.例如我添加一篇新文章.它保存在数据存储中,它出现在首页和存档的第一页(存档的第一页未缓存).但其他归档页面不会更新.我已经测试了我的cacheArchivePages()函数,它的工作原理.在将()()更新到数据存储区之后,以及在cacheArchivePages()函数中抓取ArticlesPage()之前,是否有过少的时间?也许写入交易还没有完成,所以我得到老的结果?我试图使用time.sleep()并等待几秒钟之前调用cacheArchivePages(),在这种情况下,我无法再现这种行为,但在我看来,time.sleep()不是一个好主意.无论如何,我需要知道这个行为的确切原因以及如何处理它.

你最有可能受到“最终一致查询”的打击.使用人力资源数据存储区时,查询可能会使用稍微旧的数据,而将put()写入的数据需要一段时间才能查询(通过key或id不存在get()的延迟).延迟通常以秒为单位,但我不认为我们保证上限 – 如果您受到不幸的网络分区的攻击,可能是几个小时,我想象.

有各种各样的部分解决方案,当作者最近写入的作者正在查看查询结果以使用祖先查询(有其自己的限制)时,作弊.你可能只是给你的缓存一个有限的生命周期,并更新它读而不是写.

祝你好运!

翻译自:https://stackoverflow.com/questions/11063597/read-delay-in-app-engine-datastore-after-put

转载注明原文:python – 在put()之后的App Engine Datastore中读取延迟