2016-06-05 28 views
1

Gibt es eine bekannte Architekturlösung für hochverteilte OLTP-Situationen, in denen Vorbedingungen gelten? Nehmen wir zum Beispiel ein Banking-Beispiel. Person A möchte $ N an Person B übertragen. Voraussetzung dafür ist, dass Person A mehr als $ N auf ihrem Konto haben muss.Hochverteilte OLTP-Architektur

Aus Sicht von Person A melden sie sich in einer Webanwendung an. Sie erstellen einen Transfer von sich selbst zu Person B für $ N. Denken Sie daran, dass im Hintergrund Geld abgehoben und in Echtzeit auf dem Konto von Person A hinterlegt wird, während diese Übertragung angewendet wird und während die Übertragung erstellt wird. Das Geld kann vor der Erstellung existieren, aber sobald die Übertragung angewendet wird, kann es nicht. Mit anderen Worten, dies könnte keine clientseitige Validierung sein. Person A möchte wissen, dass diese Übertragung synchron erfolgreich war oder fehlgeschlagen ist. Person A möchte die Übertragung nicht asynchron übermitteln und später zu einer Warteschlange oder einer Benachrichtigung zurückkehren, dass die Übertragung fehlgeschlagen ist.

Gibt es eine bekannte Architektur, die dieses Problem im großen Maßstab löst? Wenn sich alle Konten in einem einzelnen RDBMS befinden, können Sie über integrierte Transaktionsfunktionen so etwas tun. Aber wenn Sie einen möglicherweise konsistenten NoSQL-Datenspeicher oder eine Log/Message-basierte Infrastruktur wie Kafka verwenden, gibt es eine bekannte Lösung für solche Probleme?

+0

Ich bin Ich bin mir nicht sicher, ob Sie einen Ansatz oder ein Tool benötigen, aber Sie können sich das einmal ansehen: http://blog.cask.co/2014/11/how-we-built-it-designing-a-globally- konsistente Transaktions-Engine / – guillaume31

Antwort

0

Grundsätzlich benötigen Sie einen verteilten Sperrmechanismus. Viele der verteilten Serveranwendungen bieten eine solche Funktion.

Grundsätzlich, wenn wir Ihre Frage in Code umwandeln wird es so aussehen

// BANK WITHDRAWAL APPLICATION 

// Fetch BankAccount object from NCache 
BankAccount account = cache.Get("Key") as BankAccount; // balance = 30,000 
Money withdrawAmount = 15000; 

if (account != null && account.IsActive) 
{ 
    // Withdraw money and reduce the balance 
    account.Balance -= withdrawAmount; 

    // Update cache with new balance = 15,000 
    cache.Insert("Key", account); 
} 

=========================

// BANK DEPOSIT APPLICATION 

// Fetch BankAccount object from NCache 
BankAccount account = cache.Get("Key") as BankAccount; // balance = 30,000 
Money depositAmount = 5000; 

if (account != null && account.IsActive) 
{ 
    // Deposit money and increment the balance 
    account.Balance += depositAmount; 

    // Update cache with new balance = 35,000 
    cache.Insert("Key", account); 
} 

Dies ist im Grunde ein Beispiel für Renn Zustand

Eine race-Bedingung ist, wenn zwei oder mehr Benutzer versuchen, die gleichen gemeinsamen Daten zur gleichen Zeit zugreifen und diese ändern, aber es am Ende tun in der falschen Reihenfolge.

Die Antwort auf den obigen Code würde in verteilten Verriegelungs

LockHandle lockHandle = new LockHandle(); 

// Specify time span of 10 sec for which the item remains locked 
// NCache will auto release the lock after 10 seconds. 
TimeSpan lockSpan = new TimeSpan(0, 0, 10); 

try 
{ 
    // If item fetch is successful, lockHandle object will be populated 
    // The lockHandle object will be used to unlock the cache item 
    // acquireLock should be true if you want to acquire to the lock. 
    // If item does not exists, account will be null 
    BankAccount account = cache.Get(key, lockSpan, 
    ref lockHandle, acquireLock) as BankAccount; 
    // Lock acquired otherwise it will throw LockingException exception 

    if(account != null && account.IsActive) 
    { 
     // Withdraw money or Deposit 
     account.Balance += withdrawAmount; 
     // account.Balance -= depositAmount; 

     // Insert the data in the cache and release the lock simultaneously 
     // LockHandle initially used to lock the item must be provided 
     // releaseLock should be true to release the lock, otherwise false 
     cache.Insert("Key", account, lockHandle, releaseLock); 
    } 
    else 
    { 
     // Either does not exist or unable to cast 
     // Explicitly release the lock in case of errors 
     cache.Unlock("Key", lockHandle); 
    } 
} 
catch(LockingException lockException) 
{ 
    // Lock couldn't be acquired 
    // Wait and try again 
} 

sein, diese Antwort sehr spezifisch für NCache (A Distributed Cache). Ich bin sicher, dass Sie mehr Lösungen unter dem Stichwort `Distributed Locking“

Source

0

Haben Sie einen Blick auf Splice-Maschine genommen finden? Es ist ein RDBMS ist, die vollständig ACID-konform ist, die oben auf der läuft Hadoop-Stack (hbase, spark, hdfs, zookeeper). Sie haben eine Dual-Architektur, die hbase für schnelle OLTP-Abfragen und Funken für OLAP-Abfragen verwendet und es verfügt über integrierte Funktionen, die keine Sperre erfordern.