2009-04-01 2 views
1

Ich schreibe eine Twitter-App in Google App Engine. Er akzeptiert Befehle als direkte Nachrichten, also habe ich einen Cronjob-Dienst von Drittanbietern eingerichtet, um einen Handler aufzurufen, der DMs in regelmäßigen Intervallen verarbeitet. Ich habe ein Model 'Info', das nur einen Eintrag hat, es speichert einige allgemeine Daten, die an vielen Stellen in der App verwendet werden (in diesem Fall die Zeit, als die Nachrichten kürzlich verarbeitet wurden). Das allgemeine Muster meiner Handler ist wie folgt:Google App Engine-Datenbankinkonsistenz

class Info(db.Model): 
    msg_polled = db.DateTimeProperty(auto_now_add = True) 
    .... More Properties .... 

    @classmethod 
    def get_info(cls): 
     info = cls.all().get() 
     if not info: 
      info = cls() 
      info.put() 
     return info 
--------------------------------------------------------- 
info = Info.get_info() 
msgs = api.GetDirectMessages(since = info.msg_polled) 
if not msgs: 
    return 
logging.info('Processing Messages since %s ' % str(info.msg_polled)) 
for msg in msgs: 

    ...process commands... 

    logging.info('Processed Message :- @%s : %s' % (msg.sender_screen_name, msg.text)) 

info.msg_polled = datetime.datetime.now() 
info.put() 

Aber manchmal bekomme ich Protokolle wie folgt aus:

I 03-30 07:50AM 10.973 
Processing Messages since Sun, 29 Mar 2009 11:41:59 GMT 
I 03-30 07:50AM 11.122 
Processed Message :- @foo : Foo_Bar 
------------------------------------------------------- 
I 03-30 07:46AM 08.014 
Processing Messages since Sun, 29 Mar 2009 11:41:59 GMT 
I 03-30 07:46AM 08.130 
Processed Message :- @foo : Foo_Bar 

Hier scheint es, dass Informationen nicht in der Datenbank verpflichtet zu werden. Die Nachricht wird mehrmals verarbeitet, manchmal bis zu 10 Mal, bevor sich der Wert von msg_polled ändert. Ich erhalte jedoch keine Datastore-Ausnahmen. Dies passiert nur ab und zu.

Jede Hilfe wird geschätzt.

+0

Sie zeigen in Ihrer Beispiel nicht, wie Sie ursprünglich Informationen abrufen. Kannst du das mit einbeziehen? –

+0

Auch der zweite Satz von Protokolleinträgen ist vor dem ersten Satz datiert - war das absichtlich? –

+0

Entschuldigung, ich werde das auch aufnehmen .. und ja, die Logs sind in umgekehrter chronologischer Reihenfolge. – z33m

Antwort

0

Der Google AppEngine-Datenspeicher verwendet BigTable unter dem Deckblatt, einem verteilten Datenbanksystem. Aus diesem Grund sind Aktualisierungen möglicherweise nicht sofort sichtbar, da die neuen Daten noch nicht alle verteilte Tabellen erreicht haben (Amazon nennt diese "mögliche Konsistenz" in ihrer SimpleDB). Nach ein paar Minuten sollte es Ihnen gut gehen. Hier

+0

Aber die Docs haben keine Erwähnung einer solchen Latenz .. Also, reduziert die Häufigkeit der Cronjob das Problem zu lösen? – z33m

+0

Ich weiß, ich suchte nach einigen Links, um meine Geschichte zu unterstützen, konnte aber keine finden. Ich bin mir sicher, dass ich es irgendwo gelesen habe. Die Reduzierung der Frequenz könnte in der Tat helfen. Ich schlage vor, Sie versuchen es und sehen, was passiert. Gib mir Bescheid! – Rik

+0

Der Cronjob läuft gerade einmal alle 4 Minuten .. Sie können dies in den Log-Zeitstempeln sehen. Denken Sie nicht, 4min ist für diese Art von Verzögerung ein bisschen zu lang, selbst die Verzögerungen bei der SimpleDB-Konsistenz liegen in der Größenordnung von Sekunden richtig? – z33m

0

ist eine gute Dokumentation über die Konsistenz in GAE Datenspeicher:

https://cloud.google.com/developers/articles/balancing-strong-and-eventual-consistency-with-google-cloud-datastore

Fazit:

Eventual Consistency ist ein wesentliches Element der nicht-relationale Datenbanken, die es Entwicklern ermöglicht eine optimale zu finden Balance zwischen Skalierbarkeit, Leistung und Konsistenz. Es ist wichtig zu verstehen, wie Sie mit der Balance zwischen eventueller und starker Konsistenz umgehen, um ein optimales Datenmodell für Ihre Anwendung zu entwickeln. In Google Cloud Datastore ist die Verwendung von Entitätsgruppen und Ancestor-Abfragen der beste Weg, um eine starke Konsistenz über einen Bereich von Entitäten hinweg zu gewährleisten. Wenn Ihre Anwendung aufgrund der oben beschriebenen Einschränkungen keine Entitätsgruppen enthalten kann, können Sie andere Optionen in Betracht ziehen, z. B. die Verwendung von Nur-Schlüssel-Abfragen oder Memcache. Wenden Sie bei großen Anwendungen bewährte Methoden an, z. B. die Verwendung von verstreuten IDs und eine reduzierte Indexierung, um die Konsistenz zu verringern. Es kann auch wichtig sein, Google Cloud Datastore mit BigQuery zu kombinieren, um die Geschäftsanforderungen für komplexe Abfragen zu erfüllen und die Verwendung von Google Cloud Datastore-Indizes so weit wie möglich zu reduzieren.