1. Введение
В этом введении в Couchbase SDK для Java мы демонстрируем, как взаимодействовать с базой данных документов Couchbase, охватывая основные понятия, такие как создание среды Couchbase, подключение к кластеру, открытие блоков данных, использование основных операций сохранения и работа с документом. реплики.
2. Зависимости Maven
Если вы используете Maven, добавьте в файл pom.xml следующее:
<dependency>
<groupId>com.couchbase.client</groupId>
<artifactId>java-client</artifactId>
<version>2.2.6</version>
</dependency>
3. Начало работы
SDK предоставляет интерфейс CouchbaseEnvironment и класс реализации
DefaultCouchbaseEnvironment
, содержащий параметры по умолчанию для управления доступом к кластерам и корзинам. При необходимости настройки среды по умолчанию можно изменить, как мы увидим в разделе 3.2.
Важно: официальная документация Couchbase SDK предупреждает пользователей о том, что в JVM активна только одна среда CouchbaseEnvironment
, поскольку использование двух или более может привести к непредсказуемому поведению.
3.1. Подключение к кластеру со средой по умолчанию
Чтобы SDK автоматически создавал CouchbaseEnvironment
с настройками по умолчанию и связывал его с нашим кластером, мы можем подключиться к кластеру, просто указав IP-адрес или имя хоста одного или нескольких узлов в кластере.
В этом примере мы подключаемся к кластеру с одним узлом на нашей локальной рабочей станции:
Cluster cluster = CouchbaseCluster.create("localhost");
Чтобы подключиться к многоузловому кластеру, мы бы указали как минимум два узла на случай, если один из них будет недоступен, когда приложение попытается установить соединение:
Cluster cluster = CouchbaseCluster.create("192.168.4.1", "192.168.4.2");
Примечание. Нет необходимости указывать каждый узел в кластере при создании начального подключения. CouchbaseEnvironment будет запрашивать
кластер после установления соединения, чтобы обнаружить оставшиеся узлы (если они есть).
3.2. Использование пользовательской среды
Если вашему приложению требуется точная настройка любого из параметров, предоставляемых DefaultCouchbaseEnvironment
, вы можете создать пользовательскую среду, а затем использовать эту среду при подключении к вашему кластеру.
Вот пример, который подключается к кластеру с одним узлом с использованием пользовательской CouchbaseEnvironment
с десятисекундным тайм-аутом подключения и трехсекундным тайм-аутом поиска значения ключа:
CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder()
.connectTimeout(10000)
.kvTimeout(3000)
.build();
Cluster cluster = CouchbaseCluster.create(env, "localhost");
И для подключения к многоузловому кластеру с настраиваемой средой:
Cluster cluster = CouchbaseCluster.create(env,
"192.168.4.1", "192.168.4.2");
3.3. Открытие корзины
После того, как вы подключились к кластеру Couchbase, вы можете открыть одну или несколько корзин.
Когда вы впервые настраиваете кластер Couchbase, установочный пакет автоматически создает корзину с именем «по умолчанию»
с пустым паролем.
Вот один из способов открыть корзину «по умолчанию»
, когда у нее пустой пароль:
Bucket bucket = cluster.openBucket();
Вы также можете указать имя корзины при ее открытии:
Bucket bucket = cluster.openBucket("default");
Для любого другого сегмента с пустым паролем необходимо
указать имя сегмента:
Bucket myBucket = cluster.openBucket("myBucket");
Чтобы открыть корзину с непустым паролем, необходимо указать имя корзины и
пароль:
Bucket bucket = cluster.openBucket("bucketName", "bucketPassword");
4. Операции сохранения
В этом разделе мы покажем, как выполнять операции CRUD в Couchbase. В наших примерах мы будем работать с простыми документами JSON, представляющими человека, как в этом образце документа:
{
"name": "John Doe",
"type": "Person",
"email": "john.doe@mydomain.com",
"homeTown": "Chicago"
}
Атрибут «тип»
необязателен, однако общепринятой практикой является включение атрибута, определяющего тип документа, на случай, если вы решите хранить несколько типов в одном сегменте.
4.1. Идентификаторы документов
Каждый документ, хранящийся в Couchbase, связан с идентификатором
, уникальным для корзины, в которой хранится документ. Идентификатор
документа аналогичен столбцу первичного ключа в строке традиционной реляционной базы данных.
Значения идентификатора
документа должны быть строками UTF-8 размером не более 250 байт.
Поскольку Couchbase не предоставляет механизма автоматической генерации идентификатора
при вставке, мы должны предоставить свой собственный.
Общие стратегии создания идентификаторов
включают получение ключа с использованием естественного ключа, такого как атрибут «email»
, показанный в нашем образце документа, и использование строк UUID .
Для наших примеров мы будем генерировать случайные строки UUID .
4.2. Вставка документа
Прежде чем мы сможем вставить новый документ в нашу корзину, мы должны сначала создать экземпляр JSONObject
, содержащий содержимое документа:
JsonObject content = JsonObject.empty()
.put("name", "John Doe")
.put("type", "Person")
.put("email", "john.doe@mydomain.com")
.put("homeTown", "Chicago");
Затем мы создаем объект JSONDocument
, состоящий из значения id
и JSONObject
:
String id = UUID.randomUUID().toString();
JsonDocument document = JsonDocument.create(id, content);
Чтобы добавить новый документ в корзину, мы используем метод вставки
:
JsonDocument inserted = bucket.insert(document);
Возвращенный JsonDocument
содержит все свойства исходного документа, а также значение, известное как значение «CAS»
(сравнение и замена), которое Couchbase использует для отслеживания версий.
Если документ с предоставленным идентификатором
уже существует в корзине, Couchbase генерирует исключение DocumentAlreadyExistsException
.
Мы также можем использовать метод upsert
, который либо вставит документ (если идентификатор
не найден), либо обновит документ (если идентификатор
найден):
JsonDocument upserted = bucket.upsert(document);
4.3. Получение документа
Чтобы получить документ по его id
, мы используем метод get
:
JsonDocument retrieved = bucket.get(id);
Если документа с заданным идентификатором
не существует , метод возвращает значение null
.
4.4. Обновление или замена документа
Мы можем обновить существующий документ, используя метод upsert
:
JsonObject content = document.content();
content.put("homeTown", "Kansas City");
JsonDocument upserted = bucket.upsert(document);
Как мы упоминали в разделе 4.2, upsert
завершится успешно независимо от того, был ли найден документ с заданным идентификатором
или нет.
Если между моментом первоначального извлечения документа и нашей попыткой добавить измененный документ прошло достаточно времени, существует вероятность того, что исходный документ будет удален из корзины другим процессом или пользователем.
Если нам нужно защититься от этого сценария в нашем приложении, мы можем вместо этого использовать метод replace
, который завершается с ошибкой DocumentDoesNotExistException
, если документ с данным идентификатором
не найден в Couchbase:
JsonDocument replaced = bucket.replace(document);
4.5. Удаление документа
Чтобы удалить документ Couchbase, мы используем метод удаления
:
JsonDocument removed = bucket.remove(document);
Вы также можете удалить по id
:
JsonDocument removed = bucket.remove(id);
Возвращенный объект JsonDocument
имеет только набор свойств id
и CAS
; все остальные свойства (включая содержимое JSON) удаляются из возвращаемого объекта.
Если документа с данным идентификатором
не существует , Couchbase генерирует исключение DocumentDoesNotExistException
.
5. Работа с репликами
В этом разделе обсуждается виртуальная корзина и архитектура реплики Couchbase, а также описывается механизм извлечения копии документа в случае, если первичный узел документа недоступен.
5.1. Виртуальные корзины и реплики
Couchbase распределяет документы корзины по набору из 1024 виртуальных корзин, или vbuckets
, используя алгоритм хеширования идентификатора
документа , чтобы определить vbucket,
в котором будет храниться каждый документ.
Каждое ведро Couchbase также можно настроить для поддержки одной или нескольких реплик
каждого vbucket
. Всякий раз, когда документ вставляется или обновляется и записывается в его vbucket
, Couchbase инициирует процесс репликации нового или обновленного документа в его реплику vbucket
.
В многоузловом кластере Couchbase распределяет виртуальные ведра
и виртуальные ведра- реплики
между всеми узлами данных в кластере. Виртуальное ведро
и его реплика в ведро
хранятся на отдельных узлах данных для достижения определенной степени высокой доступности.
5.2. Извлечение документа из реплики
При извлечении документа по его идентификатору
, если основной узел документа не работает или иным образом недоступен из-за сетевой ошибки, Couchbase выдает исключение.
Приложение может перехватывать исключение и пытаться получить одну или несколько копий документа с помощью метода getFromReplica
.
Следующий код будет использовать первую найденную реплику:
JsonDocument doc;
try{
doc = bucket.get(id);
}
catch(CouchbaseException e) {
List<JsonDocument> list = bucket.getFromReplica(id, ReplicaMode.FIRST);
if(!list.isEmpty()) {
doc = list.get(0);
}
}
Обратите внимание, что при написании приложения можно заблокировать операции записи до тех пор, пока не будут завершены персистентность и репликация. Однако более распространенной практикой по соображениям производительности является возврат приложения из записи сразу после записи в память основного узла документа, поскольку запись на диск по своей природе медленнее, чем запись в память.
При использовании последнего подхода, если основной узел недавно обновленного документа выйдет из строя или перейдет в автономный режим до того, как обновления будут полностью реплицированы, чтение реплики может вернуть или не вернуть последнюю версию документа.
Также стоит отметить, что Couchbase извлекает реплики (если они есть) асинхронно. Поэтому, если ваша корзина настроена для нескольких реплик, нет никакой гарантии относительно порядка, в котором SDK возвращает их, и вы можете захотеть перебрать все найденные реплики, чтобы убедиться, что у вашего приложения есть последняя доступная версия реплики:
long maxCasValue = -1;
for(JsonDocument replica : bucket.getFromReplica(id, ReplicaMode.ALL)) {
if(replica.cas() > maxCasValue) {
doc = replica;
maxCasValue = replica.cas();
}
}
6. Заключение
Мы представили несколько основных сценариев использования, которые вам понадобятся для начала работы с Couchbase SDK.
Фрагменты кода, представленные в этом туториале, можно найти в проекте GitHub .
Узнать больше о SDK можно на официальном сайте документации для разработчиков Couchbase SDK .