Einführung in das Couchbase SDK für Java

1. Einleitung

In dieser Einführung in das Couchbase SDK für Java zeigen wir, wie Sie mit einer Couchbase-Dokumentendatenbank interagieren. Dabei werden grundlegende Konzepte wie das Erstellen einer Couchbase-Umgebung, das Herstellen einer Verbindung zu einem Cluster, das Öffnen von Datenbereichen, das Verwenden der grundlegenden Persistenzoperationen und das Arbeiten mit Dokumenten behandelt Repliken.

2. Maven-Abhängigkeiten

Wenn Sie Maven verwenden, fügen Sie Ihrer pom.xml-Datei Folgendes hinzu:

 com.couchbase.client java-client 2.2.6 

3. Erste Schritte

Das SDK bietet die CouchbaseEnvironment- Schnittstelle und eine Implementierungsklasse DefaultCouchbaseEnvironment mit Standardeinstellungen für die Verwaltung des Zugriffs auf Cluster und Buckets. Die Standardumgebungseinstellungen können bei Bedarf überschrieben werden, wie in Abschnitt 3.2 gezeigt wird.

Wichtig: In der offiziellen Couchbase SDK-Dokumentation wird der Benutzer darauf hingewiesen , dass nur eine CouchbaseEnvironment in der JVM aktiv ist, da die Verwendung von zwei oder mehr zu unvorhersehbarem Verhalten führen kann.

3.1. Herstellen einer Verbindung zu einem Cluster mit einer Standardumgebung

Damit das SDK automatisch eine CouchbaseEnvironment mit Standardeinstellungen erstellt und sie unserem Cluster zuordnet , können wir eine Verbindung zum Cluster herstellen, indem wir einfach die IP-Adresse oder den Hostnamen eines oder mehrerer Knoten im Cluster angeben.

In diesem Beispiel stellen wir eine Verbindung zu einem Cluster mit einem Knoten auf unserer lokalen Workstation her:

Cluster cluster = CouchbaseCluster.create("localhost");

Um eine Verbindung zu einem Cluster mit mehreren Knoten herzustellen, geben wir mindestens zwei Knoten an, falls einer von ihnen nicht verfügbar ist, wenn die Anwendung versucht, die Verbindung herzustellen:

Cluster cluster = CouchbaseCluster.create("192.168.4.1", "192.168.4.2");

Hinweis: Es ist nicht erforderlich, beim Erstellen der ersten Verbindung jeden Knoten im Cluster anzugeben. Die CouchbaseEnvironment fragt den Cluster ab, sobald die Verbindung hergestellt ist, um die verbleibenden Knoten (falls vorhanden) zu ermitteln.

3.2. Verwenden einer benutzerdefinierten Umgebung

Wenn Ihre Anwendung eine Feinabstimmung der von DefaultCouchbaseEnvironment bereitgestellten Einstellungen erfordert , können Sie eine benutzerdefinierte Umgebung erstellen und diese Umgebung dann verwenden, wenn Sie eine Verbindung zu Ihrem Cluster herstellen.

Hier ist ein Beispiel, das mithilfe einer benutzerdefinierten CouchbaseEnvironment mit einem Verbindungszeitlimit von zehn Sekunden und einem Zeitlimit für die Suche nach Schlüsselwerten von drei Sekunden eine Verbindung zu einem Cluster mit einem einzelnen Knoten herstellt :

CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder() .connectTimeout(10000) .kvTimeout(3000) .build(); Cluster cluster = CouchbaseCluster.create(env, "localhost");

Und um eine Verbindung zu einem Cluster mit mehreren Knoten mit der benutzerdefinierten Umgebung herzustellen:

Cluster cluster = CouchbaseCluster.create(env, "192.168.4.1", "192.168.4.2");

3.3. Einen Eimer öffnen

Sobald Sie eine Verbindung zum Couchbase-Cluster hergestellt haben, können Sie einen oder mehrere Buckets öffnen.

Wenn Sie zum ersten Mal einen Couchbase-Cluster einrichten, erstellt das Installationspaket automatisch einen Bucket mit dem Namen "default" mit einem leeren Kennwort.

Hier ist eine Möglichkeit, den "Standard" -Eimer zu öffnen, wenn er ein leeres Passwort hat:

Bucket bucket = cluster.openBucket();

Sie können den Bucket-Namen auch beim Öffnen angeben:

Bucket bucket = cluster.openBucket("default");

Für alle anderen Eimer mit einem leeren Kennwort, Sie müssen die Eimer Namen angeben:

Bucket myBucket = cluster.openBucket("myBucket");

Um einen Bucket mit einem nicht leeren Kennwort zu öffnen, müssen Sie den Namen und das Kennwort des Buckets angeben:

Bucket bucket = cluster.openBucket("bucketName", "bucketPassword");

4. Persistenzoperationen

In diesem Abschnitt zeigen wir, wie CRUD-Operationen in Couchbase ausgeführt werden. In unseren Beispielen arbeiten wir mit einfachen JSON-Dokumenten, die eine Person darstellen, wie in diesem Beispieldokument:

{ "name": "John Doe", "type": "Person", "email": "[email protected]", "homeTown": "Chicago" }

Das Attribut "Typ" ist nicht erforderlich. Es ist jedoch üblich, ein Attribut einzuschließen, das den Dokumenttyp angibt, falls mehrere Typen im selben Bucket gespeichert werden sollen.

4.1. Dokument-IDs

Jedes in Couchbase gespeicherte Dokument ist mit einer ID verknüpft , die für den Bucket eindeutig ist, in dem das Dokument gespeichert wird. Die Dokument- ID entspricht der Primärschlüsselspalte in einer herkömmlichen relationalen Datenbankzeile.

Dokument- ID- Werte müssen UTF-8-Zeichenfolgen mit 250 oder weniger Bytes sein.

Da Couchbase keinen Mechanismus zum automatischen Generieren der ID beim Einfügen bietet, müssen wir unseren eigenen bereitstellen.

Zu den gängigen Strategien zum Generieren von IDs gehören die Schlüsselableitung mithilfe eines natürlichen Schlüssels, z. B. das in unserem Beispieldokument gezeigte Attribut "E-Mail" , und die Verwendung von UUID- Zeichenfolgen.

In unseren Beispielen werden zufällige UUID- Zeichenfolgen generiert .

4.2. Einfügen eines Dokuments

Bevor wir ein neues Dokument in unseren Bucket einfügen können, müssen wir zuerst eine Instanz von JSONObject erstellen , die den Inhalt des Dokuments enthält:

JsonObject content = JsonObject.empty() .put("name", "John Doe") .put("type", "Person") .put("email", "[email protected]") .put("homeTown", "Chicago");

Als Nächstes erstellen wir ein JSONDocument- Objekt, das aus einem ID- Wert und dem JSONObject besteht :

String id = UUID.randomUUID().toString(); JsonDocument document = JsonDocument.create(id, content);

Um dem Bucket ein neues Dokument hinzuzufügen, verwenden wir die Einfügemethode :

JsonDocument inserted = bucket.insert(document);

Das zurückgegebene JsonDocument enthält alle Eigenschaften des Originaldokuments sowie einen Wert, der als "CAS" -Wert (Compare-and-Swap) bezeichnet wird und von Couchbase für die Versionsverfolgung verwendet wird.

Wenn ein Dokument mit der angegebenen ID bereits im Bucket vorhanden ist, löst Couchbase eine DocumentAlreadyExistsException aus .

Wir können auch die Upsert- Methode verwenden, mit der entweder das Dokument eingefügt wird (wenn die ID nicht gefunden wird) oder das Dokument aktualisiert wird (wenn die ID gefunden wird):

JsonDocument upserted = bucket.upsert(document);

4.3. Ein Dokument abrufen

Um ein Dokument anhand seiner ID abzurufen , verwenden wir die Methode get :

JsonDocument retrieved = bucket.get(id);

If no document exists with the given id, the method returns null.

4.4. Updating or Replacing a Document

We can update an existing document using the upsert method:

JsonObject content = document.content(); content.put("homeTown", "Kansas City"); JsonDocument upserted = bucket.upsert(document);

As we mentioned in section 4.2, upsert will succeed whether a document with the given id was found or not.

If enough time has passed between when we originally retrieved the document and our attempt to upsert the revised document, there is a possibility that the original document will have been deleted from the bucket by another process or user.

If we need to guard against this scenario in our application, we can instead use the replace method, which fails with a DocumentDoesNotExistException if a document with the given id is not found in Couchbase:

JsonDocument replaced = bucket.replace(document);

4.5. Deleting a Document

To delete a Couchbase document, we use the remove method:

JsonDocument removed = bucket.remove(document);

You may also remove by id:

JsonDocument removed = bucket.remove(id);

The JsonDocument object returned has only the id and CAS properties set; all other properties (including the JSON content) are removed from the returned object.

If no document exists with the given id, Couchbase throws a DocumentDoesNotExistException.

5. Working With Replicas

This section discusses Couchbase's virtual bucket and replica architecture and introduces a mechanism for retrieving a replica of a document in the event that a document's primary node is unavailable.

5.1. Virtual Buckets and Replicas

Couchbase distributes a bucket's documents across a collection of 1024 virtual buckets, or vbuckets, using a hashing algorithm on the document id to determine the vbucket in which to store each document.

Each Couchbase bucket can also be configured to maintain one or more replicas of each vbucket. Whenever a document is inserted or updated and written to its vbucket, Couchbase initiates a process to replicate the new or updated document to its replica vbucket.

In a multi-node cluster, Couchbase distributes vbuckets and replica vbuckets among all the data nodes in the cluster. A vbucket and its replica vbucket are kept on separate data nodes in order to achieve a certain measure of high-availability.

5.2. Retrieving a Document From a Replica

When retrieving a document by its id, if the document's primary node is down or otherwise unreachable due to a network error, Couchbase throws an exception.

You can have your application catch the exception and attempt to retrieve one or more replicas of the document using the getFromReplica method.

The following code would use the first replica found:

JsonDocument doc; try{ doc = bucket.get(id); } catch(CouchbaseException e) { List list = bucket.getFromReplica(id, ReplicaMode.FIRST); if(!list.isEmpty()) { doc = list.get(0); } }

Note that it is possible, when writing your application, to have write operations block until persistence and replication are complete. However the more common practice, for reasons of performance, is to have the application return from writes immediately after writing to memory of a document's primary node, because disk writes are inherently slower than memory writes.

When using the latter approach, if a recently updated document's primary node should fail or go offline before the updates have been fully replicated, replica reads may or may not return the latest version of the document.

It is also worth noting that Couchbase retrieves replicas (if any are found) asynchronously. Therefore if your bucket is configured for multiple replicas, there is no guarantee as to the order in which the SDK returns them, and you may want to loop through all the replicas found in order to ensure that your application has the latest replica version available:

long maxCasValue = -1; for(JsonDocument replica : bucket.getFromReplica(id, ReplicaMode.ALL)) { if(replica.cas() > maxCasValue) { doc = replica; maxCasValue = replica.cas(); } }

6. Conclusion

We have introduced some basic usage scenarios that you will need in order to get started with the Couchbase SDK.

Code snippets presented in this tutorial can be found in the GitHub project.

Weitere Informationen zum SDK finden Sie auf der offiziellen Couchbase SDK-Entwicklerdokumentationsseite.