1. 简介
本文介绍 Couchbase Java SDK 的核心用法,涵盖基础概念和操作场景:
- 创建 Couchbase 环境
- 连接集群
- 打开数据桶(Bucket)
- 执行基础持久化操作
- 处理文档副本
2. Maven 依赖
使用 Maven 时,在 pom.xml
中添加以下依赖:
<dependency>
<groupId>com.couchbase.client</groupId>
<artifactId>java-client</artifactId>
<version>2.7.2</version>
</dependency>
3. 快速上手
SDK 提供 CouchbaseEnvironment
接口和默认实现类 DefaultCouchbaseEnvironment
,用于管理集群和数据桶的访问配置。默认设置可按需覆盖(详见 3.2 节)。
踩坑提醒:官方文档强调,JVM 中必须保持唯一的 CouchbaseEnvironment
实例,多个实例可能导致不可预测的行为。
3.1. 使用默认环境连接集群
通过集群节点 IP/主机名直接连接,SDK 自动创建默认环境:
// 连接单节点集群(本地开发)
Cluster cluster = CouchbaseCluster.create("localhost");
// 连接多节点集群(生产环境推荐)
Cluster cluster = CouchbaseCluster.create("192.168.4.1", "192.168.4.2");
注意:无需指定所有节点,连接建立后 SDK 会自动发现集群中的其他节点。
3.2. 使用自定义环境
当需要调整默认配置时,可构建自定义环境:
// 创建自定义环境(连接超时10秒,KV操作超时3秒)
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. 打开数据桶
连接集群后,打开目标数据桶:
// 打开无密码的默认桶
Bucket bucket = cluster.openBucket();
// 显式指定桶名(无密码)
Bucket bucket = cluster.openBucket("default");
// 打开无密码的自定义桶
Bucket myBucket = cluster.openBucket("myBucket");
// 打开带密码的桶
Bucket bucket = cluster.openBucket("bucketName", "bucketPassword");
4. 持久化操作
本节演示 CRUD 操作,以人员文档为例:
{
"name": "John Doe",
"type": "Person",
"email": "john.doe@example.com",
"homeTown": "Chicago"
}
最佳实践:type
字段用于区分同桶中的不同文档类型。
4.1. 文档 ID
- Couchbase 文档通过唯一 ID 标识(类似关系数据库的主键)
- ID 必须是 UTF-8 字符串,长度 ≤ 250 字节
- Couchbase 不自动生成 ID,需自行实现,常用策略:
- 自然键派生(如用邮箱地址)
- 随机 UUID(本文示例使用此方案)
4.2. 插入文档
// 构建文档内容
JsonObject content = JsonObject.empty()
.put("name", "John Doe")
.put("type", "Person")
.put("email", "john.doe@example.com")
.put("homeTown", "Chicago");
// 创建文档对象
String id = UUID.randomUUID().toString();
JsonDocument document = JsonDocument.create(id, content);
// 插入文档(ID冲突时抛出 DocumentAlreadyExistsException)
JsonDocument inserted = bucket.insert(document);
// 插入或更新(无则插入,有则更新)
JsonDocument upserted = bucket.upsert(document);
4.3. 获取文档
// 通过ID获取文档(不存在返回null)
JsonDocument retrieved = bucket.get(id);
4.4. 更新文档
// 修改文档内容
JsonObject content = document.content();
content.put("homeTown", "Kansas City");
// 更新文档(无论是否存在)
JsonDocument upserted = bucket.upsert(document);
// 仅更新已存在文档(不存在抛出 DocumentDoesNotExistException)
JsonDocument replaced = bucket.replace(document);
4.5. 删除文档
// 通过文档对象删除
JsonDocument removed = bucket.remove(document);
// 通过ID删除
JsonDocument removed = bucket.remove(id);
删除结果:返回的 JsonDocument
仅包含 ID 和 CAS 属性,内容已被清除。
异常处理:文档不存在时抛出 DocumentDoesNotExistException
。
5. 处理文档副本
5.1. 虚拟桶与副本机制
- Couchbase 将文档分布在 1024 个虚拟桶(vbucket) 中
- 通过文档 ID 的哈希值确定存储位置
- 每个桶可配置 1~3 个副本(replica)
- 副本与主桶存储在不同节点,实现高可用
5.2. 从副本读取文档
当主节点不可用时,可从副本读取:
// 尝试主节点读取,失败后读取副本
JsonDocument doc;
try {
doc = bucket.get(id);
} catch (CouchbaseException e) {
List<JsonDocument> replicas = bucket.getFromReplica(id, ReplicaMode.FIRST);
if (!replicas.isEmpty()) {
doc = replicas.get(0);
}
}
高级场景:获取所有副本并选择最新版本(通过 CAS 值判断):
long maxCasValue = -1;
for (JsonDocument replica : bucket.getFromReplica(id, ReplicaMode.ALL)) {
if (replica.cas() > maxCasValue) {
doc = replica;
maxCasValue = replica.cas();
}
}
性能权衡:副本读取可能返回旧数据,因写入通常异步复制到副本。
6. 总结
本文涵盖了 Couchbase Java SDK 的核心操作场景:
- 环境配置与集群连接
- 桶操作与文档 CRUD
- 副本读取机制