以前Spring Data RedisとRedis Sentinelを連携させてみたが、Sentinelを使ってアクセス可能なのはMasterノードだけなので、SlaveにアクセスするにはSlave用のRedisTemplateを用意する必要がある。
そのため、複数のSlaveを用意してRedisからの読み取り操作を分散させたいような場合には、別途仕組みを作る必要がある。
アクセス分散の方法
専用のロードバランサーを利用する
ロードバランサーを利用してRead用にVIPを払い出し、対応するRedisTemplateを用意する。
ヘルスチェックや負荷分散はロードバランサーが代行するためアプリケーションのコードはシンプルになる。
ただし、RedisCacheManagerが単一のRedisTemplateしか利用できないため、Springのキャッシュ機構(@Cacheableつかうやつ)利用時には結局作り込みは必要になる。
RedisTemplateのレイヤで負荷分散する
ロードバランサー用意するのは大掛かりなので、アプリだけで全て完結させる。
そのためのライブラリを作ってみた。
<repositories>
<repository>
<id>nysd.maven</id>
<name>nysd maven repository</name>
<url>http://nysd.github.io/archivar/</url>
</repository>
</repositories>
<deppendencies>
<dependency>
<groupId>spring.support</groupId>
<artifactId>spring-data-redis-support</groupId>
<version>1.6.0.1</version>
</dependency>
</dependencies>
- 読み取り対象ノードに対して定期的にinfo replicationを発行する。(書き込みの方はSentinel利用するので考慮不要)
- info replicationの結果エラーとなるかmaster_sync_in_progressが1の場合、対象ノードは利用不能にマーク。
- Redis操作時には利用可能なノードに対応するRedisTemplateをランダムに一つ選択して処理を実行。
-
@Cacheable利用時にGET操作のみ読み取り専用のRedisTemplateを利用する。