2009-07-01 13 views
1

Haftungsausschluss: Ich fragte schon this question, aber ohne die Einsatz Anforderung. Ich bekam eine Antwort, die 3 upvotes bekam, und als ich die Frage redigierte, um die Bereitstellungsbedingung einzuschließen, wurde die Antwort dann irrelevant. Der Grund, warum ich bin Wiedervorlage ist, weil SO die ursprüngliche Frage "beantwortet", auch , obwohl ich keine sinnvolle upvoted Antwort. Ich habe ein uservoice submission über dieses Problem geöffnet. Der Grund, warum ich neu poste, ist, dass StackOverflow die ursprüngliche Frage als beantwortet betrachtet und nicht auf der Registerkarte "unbeantwortete Fragen" angezeigt wird.Distributed Lock-Service über MySql/GigaSpaces/Netapp

Welcher Distributed Lock Service würden Sie verwenden?

Anforderungen sind:

  1. A gegenseitiger Ausschluß (Sperre), die aus verschiedenen Prozessen/Maschinen
  2. Schlösser ... Release Semantik
  3. Automatische Entriegelung nach einer gewissen Zeit gesehen werden können - wenn Schloss holder dies, es Willens automatically seist freed nachdem X Sekunden
  4. Java implementation
  5. Easy deployment - must nicht require compl Bereitstellung über Netapp, MySql oder GigaSpaces hinaus. Muss gut mit diesen Produkten spielen (besonders GigaSpaces - deshalb war TerraCotta ausgeschlossen).
  6. Nice to have: .NET-Implementierung
  7. Wenn es kostenlos ist:

in Antworten, wie ich bin nicht daran interessiert, Deadlock Detection/Milderung oder „es sein kann,„kann es über eine Datenbank erfolgen“ über JavaSpaces erledigt "- Ich weiß. Relevante Antworten sollten nur eine fertige, bewährte und bewährte Implementierung enthalten.

+0

Ich verstehe nicht, warum Sie die andere Frage nicht bearbeiten, und wenn eine Antwort hinzugefügt wird, die Ihre überarbeiteten Anforderungen erfüllt, akzeptieren Sie es; Es ist nicht wirklich wichtig, dass eine andere Antwort mehr Upvotes hat. Es ist sehr üblich (und akzeptiert), dass einige Antworten durch die Bearbeitung der Frage irrelevant werden. – erickson

+0

Da es als "beantwortet" (upvoted antwort) gilt, wird es auf der Registerkarte "unbeantwortete Fragen" nicht angezeigt. – ripper234

Antwort

1

Hier ist der Umriss einer Antwort GigaSpaces basiert, die Ihren Kriterien erfüllt, je nach genau das, was Sie in Kriterien bedeuten 3. Ich mit GigaSpaces von .NET arbeiten, nicht Java:

mit einem SpaceID eine Sperrklasse erstellen + SpaceRouting Eigenschaft Iding was gesperrt ist und ein Datamember Bool Eigenschaft freigeschaltet:

sealed public class IdLockTrans 
{ 
    [SpaceID] 
    [SpaceRouting] 
    public string ID 
    { 
     get; 
     set; 
    } 

    [DataMember] 
    public bool Unlocked 
    { 
     get; 
     set; 
    } 

    public IdLockTrans(Id id) 
    { 
     ID = id.ID; 
    } 

    public IdLockTrans() 
    { 
    } 
} 

Sie Lease-Zeit GigaSpaces verwenden für Entriegelung nach einer gewissen Timeout. Dies veranlasst GigaSpaces, die IdLockTrans-Objekte automatisch aus dem Speicherbereich zu entfernen, nachdem sie für den Zeitraum inaktiv waren. Das Fehlen eines IdLockTrans für eine ID bedeutet, dass die ID entsperrt ist.

Dein Spind Klasse definieren und diese Klassenmitglieder

private readonly ISpaceProxy _proxy; 
    private readonly long _leaseTime; 

    public override bool Lock(Id id, long timeout) 
    { 
     bool locked; 
     IdLockTrans lockTransTemplate = new IdLockTrans(id); 
     // Assume that this is a new id. 
     try 
     { 
      _proxy.Write(lockTransTemplate, null, _leaseTime, 0, UpdateModifiers.WriteOnly); 
      locked = true; 
     } 
     catch (EntryAlreadyInSpaceException) 
     { 
      using (ITransaction tx = _proxy.CreateLocalTransaction()) 
      { 
       try 
       { 
        lockTransTemplate.Unlocked = true; 
        IdLockTrans lockTrans = _proxy.Take(lockTransTemplate, tx, timeout); 
        locked = (lockTrans != null); 
        if (lockTrans != null) 
        { 
         lockTrans.Unlocked = false; 
         _proxy.Write(lockTrans, tx, _leaseTime, 0, UpdateModifiers.WriteOnly); 
        } 
        tx.Commit(); 
       } 
       catch 
       { 
        tx.Abort(); 
        throw; 
       } 
      } 
     } 
     return locked; 
    } 

    public override void Unlock(Id lockedId) 
    { 
     IdLockTrans lockTrans = new IdLockTrans(lockedId); 
     lockTrans.Unlocked = true; 
     try 
     { 
      _proxy.Update(lockTrans, null, _leaseTime, 0, UpdateModifiers.UpdateOnly); 
     } 
     catch (EntryNotInSpaceException) 
     { 
      throw new Exception("IdLockTrans for " + lockTrans.ID 
       + " not found on Unlock. Lock time exceeded lease time."); 
     } 
    } 
+0

Das habe ich umgesetzt. Ich kann den Quellcode nicht veröffentlichen, weil es Eigentum des Unternehmens ist, aber das ist die allgemeine Idee. – ripper234

0

Bei initialisieren Sie noch auf der Suche sind, werfen Sie einen Blick auf Apache Zookeeper:

ZooKeeper für die Aufrechterhaltung der Konfigurationsinformationen ein zentralisierter Dienst ist, Benennen, Bereitstellen von verteilter Synchronisation und Bereitstellen von Gruppendiensten. Alle diese Arten von Diensten werden in der einen oder anderen Form von verteilten Anwendungen verwendet.

Die Zookeeper-Dokumentation enthält Beispiele für how to build a Lock service oben auf Zookeeper.

4

Ihre .Net-Implementierung ist sehr eng mit der vorhandenen Standard-API zum Sperren/Entsperren, die mit der Java-API bereitgestellt wird. Siehe: http://www.gigaspaces.com/docs/JavaDoc8.0/org/openspaces/core/DefaultGigaMap.html

Sie können den Quellcode für diese Java-Klasse als Teil der gs-openspaces-src.zip Datei zur Verfügung gestellt mit dem Produkt gefunden. Das gleiche mit Gigaspaces. NET API sollte geradefwd sein.

0

Verwenden Sie mysql, um einen eindeutigen Schlüssel zu sperren, ist sehr einfach.

Annahme 1:

Sie verwenden Transaktion und Ihre Isolationsebene begangen wird gelesen.

Annahme 2: Sie sperren den Verarbeitungsthread mit einem eindeutigen Schlüssel und geben ihn frei, wenn Ihre Transaktion festgeschrieben wurde.

Dann können Sie diese SQL verwenden als eine Sperre verteilen:

Legen Sie in distributed_lock (key) Werte (# {key}) ON DUPLICATE KEY UPDATE key = Schlüssel;