Redissonを使用したRedisのガイド
1. 概要
Redisson is a Redis client for Java。 この記事では、その機能のいくつかを検討し、分散ビジネスアプリケーションの構築を容易にする方法を示します。
Redisに裏打ちされた分散Javaオブジェクトとサービスを提供するRedisson constitutes an in-memory data grid.分散インメモリデータモデルにより、アプリケーションとサーバー間でドメインオブジェクトとサービスを共有できます。
この記事では、Redissonのセットアップ方法、Redissonの動作方法の理解、およびRedissonのオブジェクトとサービスのいくつかについて説明します。
2. Mavenの依存関係
以下のセクションをpom.xml:に追加して、Redissonをプロジェクトにインポートすることから始めましょう
org.redisson
redisson
3.3.0
この依存関係の最新バージョンはhereにあります。
3. 設定
開始する前に、Redisの最新バージョンをセットアップして実行していることを確認する必要があります。 Redisがなく、LinuxまたはMacintoshを使用している場合は、情報hereに従ってセットアップを行うことができます。 Windowsユーザーの場合、この非公式のportを使用してRedisをセットアップできます。
Redisに接続するようにRedissonを構成する必要があります。 Redissonは、次のRedis構成への接続をサポートしています。
-
単一ノード
-
マスターとスレーブノード
-
センチネルノード
-
クラスター化されたノード
-
複製されたノード
クラスター化および複製されたノードのRedisson supports Amazon Web Services (AWS) ElastiCache Cluster and Azure Redis Cache。
Redisの単一ノードインスタンスに接続しましょう。 このインスタンスは、デフォルトポート6379でローカルに実行されています。
RedissonClient client = Redisson.create();
さまざまな構成をRedissonオブジェクトのcreateメソッドに渡すことができます。 これは、別のポートに接続するように構成することも、Redisクラスターに接続するように構成することもできます。 このconfiguration could be in Java code or loaded from an external configuration file。
3.1. Java設定
JavaコードでRedissonを構成しましょう。
Config config = new Config();
config.useSingleServer()
.setAddress("127.0.0.1:6379");
RedissonClient client = Redisson.create(config);
specify Redisson configurations in an instance of a Config objectを実行し、それをcreateメソッドに渡します。 上記では、Redissonに、Redisの単一ノードインスタンスに接続することを指定しました。 これを行うために、ConfigオブジェクトのuseSingleServerメソッドを使用しました。 これは、SingleServerConfigオブジェクトへの参照を返します。
SingleServerConfigオブジェクトには、RedissonがRedisの単一ノードインスタンスに接続するために使用する設定があります。 ここでは、setAddressメソッドを使用してaddress設定を構成します。 これにより、接続先のノードのアドレスが設定されます。 その他の設定には、retryAttempts、connectionTimeout、およびclientNameが含まれます。 これらの設定は、対応するセッターメソッドを使用して構成されます。
Configオブジェクトの次のメソッドを使用して、同様の方法でさまざまなRedis構成用にRedissonを構成できます。
3.2. ファイル構成
Redisson can load configurations from external JSON or YAMLファイル:
Config config = Config.fromJSON(new File("singleNodeConfig.json"));
RedissonClient client = Redisson.create(config);
ConfigオブジェクトのfromJSONメソッドは、文字列、ファイル、入力ストリーム、またはURLから構成をロードできます。
singleNodeConfig.jsonファイルの構成例は次のとおりです。
{
"singleServerConfig": {
"idleConnectionTimeout": 10000,
"pingTimeout": 1000,
"connectTimeout": 10000,
"timeout": 3000,
"retryAttempts": 3,
"retryInterval": 1500,
"reconnectionTimeout": 3000,
"failedAttempts": 3,
"password": null,
"subscriptionsPerConnection": 5,
"clientName": null,
"address": "redis://127.0.0.1:6379",
"subscriptionConnectionMinimumIdleSize": 1,
"subscriptionConnectionPoolSize": 50,
"connectionMinimumIdleSize": 10,
"connectionPoolSize": 64,
"database": 0,
"dnsMonitoring": false,
"dnsMonitoringInterval": 5000
},
"threads": 0,
"nettyThreads": 0,
"codec": null,
"useLinuxNativeEpoll": false
}
対応するYAML設定ファイルは次のとおりです。
singleServerConfig:
idleConnectionTimeout: 10000
pingTimeout: 1000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
reconnectionTimeout: 3000
failedAttempts: 3
password: null
subscriptionsPerConnection: 5
clientName: null
address: "redis://127.0.0.1:6379"
subscriptionConnectionMinimumIdleSize: 1
subscriptionConnectionPoolSize: 50
connectionMinimumIdleSize: 10
connectionPoolSize: 64
database: 0
dnsMonitoring: false
dnsMonitoringInterval: 5000
threads: 0
nettyThreads: 0
codec: ! {}
useLinuxNativeEpoll: false
その構成に固有の設定を使用して、同様の方法でファイルから他のRedis構成を構成できます。 参考までに、JSONおよびYAMLファイル形式を以下に示します。
Java構成をJSONまたはYAML形式で保存するには、ConfigオブジェクトのtoJSONまたはtoYAMLメソッドを使用できます。
Config config = new Config();
// ... we configure multiple settings here in Java
String jsonFormat = config.toJSON();
String yamlFormat = config.toYAML();
Redissonの構成方法がわかったので、Redissonが操作を実行する方法を見てみましょう。
4. 操作
Redisson supports synchronous, asynchronous and reactive interfaces。 これらのinterfaces are thread-safeに対する操作。
RedissonClientによって生成されるすべてのエンティティ(オブジェクト、コレクション、ロック、およびサービス)には、同期メソッドと非同期メソッドがあります。 Synchronous methods bear asynchronous variants。 これらのメソッドには、通常、「Async」が付加された同期バリアントの同じメソッド名が付けられます。 RAtomicLongオブジェクトの同期メソッドを見てみましょう。
RedissonClient client = Redisson.create();
RAtomicLong myLong = client.getAtomicLong('myLong');
同期compareAndSetメソッドの非同期バリアントは次のようになります。
RFuture isSet = myLong.compareAndSetAsync(6, 27);
メソッドの非同期バリアントは、RFutureオブジェクトを返します。 このオブジェクトにリスナーを設定して、使用可能になったときに結果を取得できます。
isSet.handle((result, exception) -> {
// handle the result or exception here.
});
リアクティブオブジェクトを生成するには、RedissonReactiveClient: `++`を使用する必要があります
RedissonReactiveClient client = Redisson.createReactive();
RAtomicLongReactive myLong = client.getAtomicLong("myLong");
Publisher isSetPublisher = myLong.compareAndSet(5, 28);
このメソッドは、Java 9のReactive Streams標準に基づいてリアクティブオブジェクトを返します。
Redissonが提供する分散オブジェクトのいくつかを見てみましょう。
5. オブジェクト
Redisson object is serialized and stored in any of the available Redis nodes backing Redissonの個々のインスタンス。 これらのオブジェクトは、クラスター内で複数のノードに分散でき、単一のアプリケーションまたは複数のアプリケーション/サーバーからアクセスできます。
これらの分散オブジェクトは、java.util.concurrent.atomic package.They support lock-free, thread-safe and atomic operations on objects stored in Redisの仕様に従います。 別のアプリケーションがオブジェクトを読み取っている間は値が更新されないため、アプリケーション/サーバー間のデータの一貫性が保証されます。
RedissonオブジェクトはRedisキーにバインドされます。 これらのキーは、RKeysインターフェイスを介して管理できます。 これらのキーを使用してRedissonオブジェクトにアクセスします。
すべてのキーを取得できます。
RKeys keys = client.getKeys();
すべてのキー名を反復可能な文字列コレクションとして抽出できます。
Iterable allKeys = keys.getKeys();
パターンに準拠したキーを取得できます。
Iterable keysByPattern = keys.getKeysByPattern('key*')
RKeysインターフェイスでは、キーの削除、パターンによるキーの削除、およびキーとオブジェクトの管理に使用できるその他の便利なキーベースの操作も可能です。
Redissonが提供する分散オブジェクトには次のものがあります。
-
ObjectHolder
-
BinaryStreamHolder
-
GeospatialHolder
-
BitSet
-
AtomicLong
-
AtomicDouble
-
トピック
-
BloomFilter
-
HyperLogLog
これらのオブジェクトのうち、ObjectHolder, AtomicLong,とTopic.の3つを見てみましょう。
5.1. オブジェクトホルダー
RBucketクラスで表されるこのオブジェクトは、任意のタイプのオブジェクトを保持できます。 このオブジェクトの最大サイズは512MBです。
RBucket bucket = client.getBucket("ledger");
bucket.set(new Ledger());
Ledger ledger = bucket.get();
RBucketオブジェクトは、保持しているオブジェクトに対してcompareAndSet andgetAndSetなどのアトミック操作を実行できます。
5.2. AtomicLong
RAtomicLongクラスで表されるこのオブジェクトは、java.util.concurrent.atomic.AtomicLongクラスによく似ており、アトミックに更新できるlong値を表します。
RAtomicLong atomicLong = client.getAtomicLong("myAtomicLong");
atomicLong.set(5);
atomicLong.incrementAndGet();
5.3. トピック
Topicオブジェクトは、Redisの「パブリッシュおよびサブスクライブ」メカニズムをサポートします。 公開されたメッセージを聞くには:
RTopic subscribeTopic = client.getTopic("example");
subscribeTopic.addListener(
(channel, customMessage)
-> future.complete(customMessage.getMessage()));
上記では、Topicは「example」チャネルからのメッセージをリッスンするように登録されています。 次に、トピックにリスナーを追加して、そのチャネルからの着信メッセージを処理します。 複数のリスナーをチャネルに追加できます。
「例」チャネルにメッセージを公開しましょう。
RTopic publishTopic = client.getTopic("example");
long clientsReceivedMessage
= publishTopic.publish(new CustomMessage("This is a message"));
これは、別のアプリケーションまたはサーバーから公開できます。 CustomMessageオブジェクトはリスナーによって受信され、onMessageメソッドで定義されているように処理されます。
他のRedissonオブジェクトhereについて詳しく知ることができます。
6. コレクション
Redissonコレクションは、オブジェクトを処理するのと同じ方法で処理します。
Redissonが提供する分散コレクションには以下が含まれます。
-
Map
-
マルチマップ
-
Set
-
SortedSet
-
ScoredSortedSet
-
LexSortedSet
-
List
-
キュー
-
Deque
-
BlockingQueue
-
BoundedBlockingQueue
-
BlockingDeque
-
BlockingFairQueue
-
DelayedQueue
-
PriorityQueue
-
PriorityDeque
これらのコレクションのうち、Map, Set,とList.の3つを見てみましょう。
6.1. Map
Redissonベースのマップは、java.util.concurrent.ConcurrentMapおよびjava.util.Mapインターフェースを実装します。 Redissonには4つのマップ実装があります。 これらは、RMap、RMapCache、RLocalCachedMap、およびRClusteredMapです。
Redissonで地図を作成しましょう。
RMap map = client.getMap("ledger");
Ledger newLedger = map.put("123", new Ledger());map
RMapCacheは、マップエントリの削除をサポートします。 RLocalCachedMapを使用すると、マップエントリをローカルキャッシュできます。. RClusteredMapを使用すると、単一のマップのデータをRedisクラスターマスターノード間で分割できます。
Redissonマップhereについて詳しく知ることができます。
6.2. Set
RedissonベースのSetは、java.util.Setインターフェースを実装します。
Redissonには、3つのSet実装、RSet、RSetCache、およびRClusteredSetがあり、対応するマップと同様の機能を備えています。
RedissonでSetを作成しましょう:
RSet ledgerSet = client.getSet("ledgerSet");
ledgerSet.add(new Ledger());
Redissonセットhereについて詳しく知ることができます。
6.3. List
RedissonベースのListsは、java.util.Listインターフェースを実装します。
RedissonでListを作成しましょう:
RList ledgerList = client.getList("ledgerList");
ledgerList.add(new Ledger());
他のRedissonコレクションhereについて詳しく知ることができます。
7. ロックとシンクロナイザー
アプリケーション/サーバー全体のRedissonのdistributed locks allow for thread synchronization。 Redissonのロックとシンクロナイザーのリストは次のとおりです。
-
Lock
-
FairLock
-
マルチロック
-
ReadWriteLock
-
セマフォ
-
PermitExpirableSemaphore
-
CountDownLatch
LockとMultiLock.を見てみましょう
7.1. Lock
RedissonのLockは、java.util.concurrent.locks.Lockインターフェースを実装しています。
RLockクラスで表されるロックを実装しましょう。
RLock lock = client.getLock("lock");
lock.lock();
// perform some long operations...
lock.unlock();
7.2. マルチロック
RedissonのRedissonMultiLockは、複数のRLockオブジェクトをグループ化し、それらを単一のロックとして扱います。
RLock lock1 = clientInstance1.getLock("lock1");
RLock lock2 = clientInstance2.getLock("lock2");
RLock lock3 = clientInstance3.getLock("lock3");
RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3);
lock.lock();
// perform long running operation...
lock.unlock();
他のロックhereについて詳しく知ることができます。
8. サービス内容
Redissonは、4種類の分散サービスを公開しています。 これらは、Remote Service、Live Object Service、Executor Service、およびScheduled Executor Serviceです。 リモートサービスとライブオブジェクトサービスを見てみましょう。
8.1. リモートサービス
このサービスはJava remote method invocation facilitated by Redisを提供します。 Redissonリモートサービスは、サーバー側(ワーカーインスタンス)とクライアント側の実装で構成されます。 サーバー側の実装は、クライアントによって呼び出されたリモートメソッドを実行します。 リモートサービスからの呼び出しは、同期または非同期にできます。
サーバー側は、リモート呼び出し用のインターフェースを登録します。
RRemoteService remoteService = client.getRemoteService();
LedgerServiceImpl ledgerServiceImpl = new LedgerServiceImpl();
remoteService.register(LedgerServiceInterface.class, ledgerServiceImpl);
クライアント側は、登録されたリモートインターフェイスのメソッドを呼び出します。
RRemoteService remoteService = client.getRemoteService();
LedgerServiceInterface ledgerService
= remoteService.get(LedgerServiceInterface.class);
List entries = ledgerService.getEntries(10);
リモートサービスhereについて詳しく知ることができます。
8.2. ライブオブジェクトサービス
Redisson Live Objectsは、単一のJVMからのみアクセスできる標準のJavaオブジェクトの概念をenhanced Java objects that could be shared between different JVMs in different machinesに拡張します。 これは、オブジェクトのフィールドをRedisハッシュにマッピングすることで実現されます。 このマッピングは、ランタイム構成のプロキシクラスを介して行われます。 フィールドのゲッターとセッターは、Redis hget / hsetコマンドにマップされます。
Redisson Live Objectsは、Redisのシングルスレッドの性質の結果として、アトミックフィールドアクセスをサポートしています。
ライブオブジェクトの作成は簡単です。
@REntity
public class LedgerLiveObject {
@RId
private String name;
// getters and setters...
}
クラスに@REntityで注釈を付け、一意のフィールドまたは識別フィールドに@RIdで注釈を付けます。 これが完了したら、アプリケーションでライブオブジェクトを使用できます。
RLiveObjectService service = client.getLiveObjectService();
LedgerLiveObject ledger = new LedgerLiveObject();
ledger.setName("ledger1");
ledger = service.persist(ledger);
newキーワードを使用して、標準のJavaオブジェクトのようにライブオブジェクトを作成します。 次に、RLiveObjectServiceのインスタンスを使用して、persistメソッドを使用してオブジェクトをRedisに保存します。
オブジェクトが以前にRedisに永続化されている場合、オブジェクトを取得できます。
LedgerLiveObject returnLedger
= service.get(LedgerLiveObject.class, "ledger1");
RLiveObjectServiceを使用して、@RIdで注釈が付けられたフィールドを使用してライブオブジェクトを取得します。
Redisson Live Objectshereについて詳しく知ることができます。
他のRedissonサービスhereについても詳しく知ることができます。
9. パイプライン処理
Redissonはパイプラインをサポートしています。 Multiple operations can be batched as a single atomic operation。 これは、RBatchクラスによって容易になります。 複数のコマンドは、実行される前にRBatchオブジェクトインスタンスに対して集約されます。
RBatch batch = client.createBatch();
batch.getMap("ledgerMap").fastPutAsync("1", "2");
batch.getMap("ledgerMap").putAsync("2", "5");
List> result = batch.execute();
10. スクリプティング
RedissonはLUAスクリプトをサポートしています。 We can execute LUA scripts against Redis:
client.getBucket("foo").set("bar");
String result = client.getScript().eval(Mode.READ_ONLY,
"return redis.call('get', 'foo')", RScript.ReturnType.VALUE);
11. 低レベルのクライアント
RedissonでまだサポートされていないRedis操作を実行したい場合があります。 Redisson provides a low-level client that allows execution of native Redis commands:
RedisClient client = new RedisClient("localhost", 6379);
RedisConnection conn = client.connect();
conn.sync(StringCodec.INSTANCE, RedisCommands.SET, "test", 0);
conn.closeAsync();
client.shutdown();
低レベルクライアントは、非同期操作もサポートします。
12. 結論
この記事では、Redissonと、分散アプリケーションの開発に理想的な機能のいくつかを紹介しました。 分散オブジェクト、コレクション、ロック、およびサービスを調査しました。 また、パイプライン処理、スクリプティング、低レベルクライアントなど、その他の機能のいくつかも検討しました。
JCache API、Spring Cache、Hibernate Cache、Spring SessionsなどのRedisson also provides integration with other frameworks。 他のフレームワークhereとの統合について詳しく知ることができます。
コードサンプルはGitHub projectにあります。