Lettuce
GitHub概要
redis/lettuce
Advanced Java Redis client for thread-safe sync, async, and reactive usage. Supports Cluster, Sentinel, Pipelining, and codecs.
ホームページ:https://lettuce.io
スター5,663
ウォッチ204
フォーク1,056
作成日:2014年5月10日
言語:Java
ライセンス:MIT License
トピックス
asynchronousaws-elasticacheazure-redis-cachejavareactiveredisredis-clientredis-clusterredis-sentinel
スター履歴
データ取得日時: 2025/10/22 10:05
キャッシュライブラリ
Lettuce
概要
Lettuceは、Javaアプリケーション向けの高度なRedisクライアントライブラリです。
詳細
Lettuce(レタス)は、RedisのオフィシャルクライアントファミリーとしてRedis社が公式サポートするJava向けRedisクライアントです。2024年にRedisのオフィシャルクライアントファミリーに加わり、MITライセンスの下でオープンソースとして提供されています。スレッドセーフな設計により、複数のスレッドが単一の接続を安全に共有でき、同期、非同期、リアクティブ、Kotlinコルーチンの4つのプログラミングモデルをサポートしています。NettyをベースとしたノンブロッキングI/Oアーキテクチャにより、高いパフォーマンスと低レイテンシを実現し、Redis Sentinel、Redis Cluster、パイプライン処理、自動再接続、SSL/TLS、Pub/Sub等の豊富な機能を提供します。Java 8のCompletionStageインターフェースを活用し、アプリケーションがデータの受信方法を細かく制御できる仕組みを提供しています。
メリット・デメリット
メリット
- スレッドセーフ: 単一接続を複数スレッドで安全に共有可能
- 高性能: NettyベースのノンブロッキングI/Oによる高スループット
- 豊富なAPIモデル: 同期、非同期、リアクティブ、コルーチンに対応
- 堅牢な接続管理: 自動再接続とコマンドバッファリング機能
- Redis機能完全サポート: 全コマンドセットとデプロイメントモデル対応
- 公式サポート: Redis社による公式サポートと継続的な開発
- Springとの統合: Spring Data Redisとの優れた統合性
デメリット
- 学習コスト: 多様なAPIモデルと高度な機能の習得が必要
- ブロッキング操作の制約: BLPOPやMULTI/EXECは専用接続が必要
- メモリ使用量: 豊富な機能による若干のメモリオーバーヘッド
- 設定の複雑さ: 高度な機能使用時の設定が複雑になる場合がある
主要リンク
書き方の例
基本的な接続と操作
import io.lettuce.core.*;
// Redis クライアントの作成
RedisClient client = RedisClient.create("redis://localhost:6379");
// 接続の確立
StatefulRedisConnection<String, String> connection = client.connect();
// 同期コマンドの取得
RedisCommands<String, String> commands = connection.sync();
// 基本操作
commands.set("key", "Hello, Lettuce!");
String value = commands.get("key");
System.out.println(value); // "Hello, Lettuce!"
// リソースの解放
connection.close();
client.shutdown();
非同期API
import io.lettuce.core.api.async.RedisAsyncCommands;
import java.util.concurrent.CompletableFuture;
RedisClient client = RedisClient.create("redis://localhost:6379");
StatefulRedisConnection<String, String> connection = client.connect();
RedisAsyncCommands<String, String> async = connection.async();
// 非同期でSET操作
RedisFuture<String> setResult = async.set("async-key", "async-value");
// 非同期でGET操作
RedisFuture<String> getValue = async.get("async-key");
// 結果の取得
setResult.thenAccept(result -> System.out.println("SET result: " + result));
getValue.thenAccept(value -> System.out.println("GET result: " + value));
// 複数の操作を並行実行
List<RedisFuture<String>> futures = new ArrayList<>();
for (int i = 0; i < 10; i++) {
futures.add(async.set("key-" + i, "value-" + i));
}
// 全ての操作完了を待機
LettuceFutures.awaitAll(1, TimeUnit.MINUTES,
futures.toArray(new RedisFuture[0]));
リアクティブAPI
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import reactor.core.publisher.Mono;
RedisClient client = RedisClient.create("redis://localhost:6379");
StatefulRedisConnection<String, String> connection = client.connect();
RedisReactiveCommands<String, String> reactive = connection.reactive();
// リアクティブストリーム
Mono<String> setMono = reactive.set("reactive-key", "reactive-value");
Mono<String> getMono = reactive.get("reactive-key");
// チェーン処理
setMono
.then(getMono)
.doOnNext(value -> System.out.println("Value: " + value))
.subscribe();
// 複数の値を処理
reactive.mget("key1", "key2", "key3")
.flatMapIterable(values -> values)
.filter(value -> value.hasValue())
.map(value -> value.getValue())
.doOnNext(System.out::println)
.subscribe();
Redis Cluster接続
import io.lettuce.core.cluster.RedisClusterClient;
import io.lettuce.core.cluster.api.StatefulRedisClusterConnection;
// クラスターノードの設定
RedisURI node1 = RedisURI.create("redis://localhost:7000");
RedisURI node2 = RedisURI.create("redis://localhost:7001");
RedisURI node3 = RedisURI.create("redis://localhost:7002");
// クラスタークライアントの作成
RedisClusterClient clusterClient = RedisClusterClient
.create(Arrays.asList(node1, node2, node3));
// クラスター接続
StatefulRedisClusterConnection<String, String> connection =
clusterClient.connect();
RedisAdvancedClusterCommands<String, String> commands =
connection.sync();
// クラスター操作
commands.set("cluster-key", "cluster-value");
String value = commands.get("cluster-key");
// 読み取り設定(レプリカから読み取り)
connection.setReadFrom(ReadFrom.REPLICA);
connection.close();
clusterClient.shutdown();
SSL/TLS接続
// SSL/TLS接続設定
RedisURI redisUri = RedisURI.Builder.redis("secure.redis.com")
.withPort(6380)
.withSsl(true)
.withPassword("secure-password")
.withDatabase(0)
.build();
RedisClient client = RedisClient.create(redisUri);
StatefulRedisConnection<String, String> connection = client.connect();
// SSL接続でのコマンド実行
RedisCommands<String, String> commands = connection.sync();
commands.set("secure-key", "secure-value");
Pub/Sub機能
import io.lettuce.core.pubsub.RedisPubSubListener;
import io.lettuce.core.pubsub.StatefulRedisPubSubConnection;
// Pub/Sub接続
StatefulRedisPubSubConnection<String, String> pubsubConnection =
client.connectPubSub();
// リスナーの設定
pubsubConnection.addListener(new RedisPubSubListener<String, String>() {
@Override
public void message(String channel, String message) {
System.out.println("Received: " + message + " from " + channel);
}
@Override
public void subscribed(String channel, long count) {
System.out.println("Subscribed to " + channel);
}
@Override
public void unsubscribed(String channel, long count) {
System.out.println("Unsubscribed from " + channel);
}
});
// チャンネル購読
RedisPubSubCommands<String, String> pubsub = pubsubConnection.sync();
pubsub.subscribe("news", "updates");
// メッセージ送信(別の接続から)
RedisCommands<String, String> publisher = client.connect().sync();
publisher.publish("news", "Breaking news!");