0

dbDatastore을 사용하는 GAE 기반 프로젝트가 있습니다. 내 프로젝트에서는 매 15 분마다 작업을 실행하고 데이터를 Datastore으로 업데이트합니다. 그런 다음 Datastore을 쿼리하고 결과를 표시하는 끝점이 있습니다. 하지만, 내가 얻은 결과는 오래되어서 업데이트 된 것이 아닙니다. GAE가 Datastore에 도달하지 못하고 캐시에서 데이터를 반환하는 것으로 보이지만 확실하지 않습니다. 여기 내 코드입니다 : 내가 memcache.flush_all()를 사용하지만, 심지어 문제가 해결되지 않는 캐시를 지우고 시도부실 데이터를 반환하는 Google App Engine Datastore 쿼리

class Contests(db.Model): 
    """Models Contests""" 
    data = db.TextProperty(default="{}") 
    created = db.DateTimeProperty(auto_now_add=True) 
    modified = db.DateTimeProperty(auto_now=True) 

:

class MainHandler(webapp2.RequestHandler): 

    def get(self): 
     query = Contests.all() 
     contests_data = query.fetch(1) # fetch the data from datastore 
     self.response.write(contests_data[0].data) 

class DataBaseHandler(webapp2.RequestHandler): 

    # the job that runs every 15 minutes 
    def get(self): 
     contests_data = get_all_contests() # get the new data 
     query = Contests.all() 
     contests = query.fetch(1) 
     contests[1].data = contests_data # update the data 
     db.put(contests[0]) 
     self.response.write(json.dumps({"message":"updated"})) 

가 여기 내 모델입니다. 왜 GAE는 업데이트 된 데이터를 반환하지 않습니까? 어떻게 문제를 해결할 수 있습니까?

EDIT : 조상 쿼리로 쿼리를 변경했지만 데이터가 여전히 부실합니다 (며칠 전).

main.py

class MainHandler(webapp2.RequestHandler): 

     def get(self): 
      contest_list = ContestList.get_or_insert('contest_list', name='ContestList') 
      query = Contests.all() 
      query.ancestor(contest_list) 
      contests = query.fetch(1) 
      self.response.write(contests[0].data) 

    class DataBaseHandler(webapp2.RequestHandler): 

     def get(self): 
      contests_data = get_all_contests() 
      contest_list = ContestList.get_or_insert('contest_list', name='ContestList') 
      query = Contests.all() 
      query.ancestor(contest_list) 
      contests = query.fetch(1) 
      contests[0].data = contests_data 
      contests[0].put() 
      self.response.write(json.dumps({"message":"updated"})) 

models.py는 :

class MainHandler(webapp2.RequestHandler): 

    def get(self): 
     q = ndb.Key('Contests', 'contest_data').get() 
     if q: 
      self.response.write(q.data) 
     else: 
      self.response.write("error") 

class DataBaseHandler(webapp2.RequestHandler): 

    def get(self): 
     Contests(key=ndb.Key('Contests', "contest_data"), data=get_all_contests()).put() 
     self.response.write(json.dumps({"message":"updated"})) 

가 GAE의 데이터 저장소를 공격하지 않습니다 무엇 :

class ContestList(db.Model): 
    name = db.StringProperty() 

class Contests(db.Model): 
    """Models Contests""" 
    data = db.TextProperty(default="{}") 
    created = db.DateTimeProperty(auto_now_add=True) 
    modified = db.DateTimeProperty(auto_now=True) 

이 난 key를 사용하여 데이터를 가져 오는 시도? 내가 여기서 무엇을 놓치고 있니?

+1

Patrice의 대답은 정확합니다. 오래된 crufty db는 투명하게 캐싱하지 않습니다. (사용자 정의 컨텍스트를 사용하여 제어 할 수있는) 멋진 새 ndb가 필요합니다. 'db'는 캐싱으로 인한 것이 아니고, 결과 일관성과 관련되어야합니다. –

+0

최종 일관성은 자체 해결을 위해 1 ~ 2 초가 소요됩니다. 데이터가 "오래된 것"이상이면 코드 어딘가에 문제가있는 것입니다. –

+1

@AndreiVolgin, 두 번째 또는 종종 더 적은 * typical *이지만 최악의 경우 지연에 대한 보장 된 상한은 없습니다. memcache **가 강력하게 일관성이 있기 때문에 (그러나 휘발성 임에도 불구하고) 엔티티를 투명하게 캐시하는 'ndb'와 같은 현대 서브 시스템 사용자는 거의 관찰하지 않습니다.하지만 오래 된 crufty db로 더 눈에 띄며 언젠가는 거의 없습니다. "never"와 같은 것 : -) ... –

답변

4

데이터 저장소는 쿼리에 대해서만 일관성이 있습니다. 데이터를 복제하는 동안 "부실한"데이터를 기록 할 가능성이 있습니다.

쿼리에서 강력한 일관성을 유지하려면 조상 쿼리 또는 키로 가져 오기를 사용해야합니다.

here

예에 대해 자세히 알아보기 : 조상 쿼리

(documentation) 당신은 분명 당신의 구조를 약간 변경해야하는 것이라고 할 수 있습니다. 모델 "컨테스트"의 조상이 될 수있는 것이 무엇인지 모릅니다. 그러나 이들 모두가 "mainAncestor"엔티티에 속한다고 가정 해 봅시다.

query = Contests.all() 
query.ancestor(mainAncestor) 
contests = query.fetch(1) 

하는 강력한 강제 : 당신이 검색 할 때 그런 다음 코드에서이 추가

newContest = Contest(parent=mainAncestor) 

: 당신이 당신의 엔티티를 만들 때

, 당신은 유사 뭔가를해야합니다 데이터 일관성 유지. 분명히 "mainAncestor"를 만들어야 할 것입니다. 그러면 주소를 확인하는 데 필요한 다른 문제가 발생할 것입니다 (예를 들어 매 초마다 한 엔티티 그룹 (동일한 조상 아래 그룹화 된 엔티티)에만 쓸 수 있습니다.).

+2

좋은 답변이지만 좋은 결과를 얻으려면 2 가지 제안 사항이 있습니다. (A) https://cloud.google.com/developers/articles/balancing-strong-and-eventual-consistency-with-google-로 직접 연결할 수도 있습니다. cloud-datastore/(자바 포커스 된 SO Q :-)를 통해 OP를 보낼 필요가 없음 (B) 이상적으로 OP의 유스 케이스에서 조상 쿼리를 인위적으로 사용하는 방법에 대한 간단한 파이썬 예제를 제공한다. 어쨌든,하지만 당신이 대답을 풍부하게하는 것이 좋습니다! -) –

+0

Fair point. A)는 실제로 사용하려는 링크였습니다. 두 번 확인 했어야 했어. 나는 이것을 바로 잡고 B를 곧 추가 할 것입니다. :) 제안에 감사드립니다. – Patrice

+0

@Patrice @AlexMartelli 도와 주셔서 감사합니다. 그러나 조상 쿼리를 추가하고'key '로 데이터를 얻으려고 시도해도 작동하지 않습니다. 자세한 내용은 질문을 편집했습니다. –

관련 문제