はじめに
今回は開発環境でdocker-composeで環境を整えることが多いことを考え、springでdocker-compose上のredis-clusterを使用する方法について書こうと思います。
redisをしっかり使えるようになっていきたいですね。
まずはどんな環境で、どんなコード書いているかなどを記載していきます。
実行手順に関しては最後に一気に行います。
実行環境
redis v6.0.10
spring v5.0.0
docker v19.03.13
.
├── RedisPractice(springのプロジェクト)
│
├── conf
│ ├── redis.conf
│ └── redis.sh
└── docker-compose.yml
環境構築
spring
以下の内容をpox.xmlに追加しておきます
特にここでJedisを入れおいてください。JedisはJavaでredisを使用するためのライブラリです。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
docker-composeの内容
将来的に、複数サービスを管理したいので、docker-copmposeでredis-clusterを立ち上げます。
dockerのネットワークを立ち上げて、その中で管理する形にしたいと思います。
version: '3'
services:
redis:
image: "redis:latest"
command: bash -c "/bin/bash /conf/redis.sh && while true; do echo "up"; sleep 100; done"
ports:
- 7000:7000
- 7001:7001
- 7002:7002
- 7003:7003
- 7004:7004
- 7005:7005
volumes:
- "./conf:/conf:"
networks:
app_net:
ipv4_address: 172.16.239.10
networks:
app_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.16.239.0/24
gateway: 172.16.239.1
docker networkをbridgeで接続し、その中にsubnet(172.16.239.0)を作成しています。
以下がイメージです。
参考情報:https://qiita.com/TsutomuNakamura/items/ed046ee21caca4a2ffd9
以下の記事でbridgeの解説で使われている図を参考に作成しまています。
https://qiita.com/TsutomuNakamura/items/ed046ee21caca4a2ffd9
参考サイト:Docker network 概論
docker-compose up でdocker-composeを起動すると、redisコンテナ内でredis.shを実行する。
以下にredisコンテナにマウントした内容と、実行する内容を記載します。
redis-clusterを起動させるファイルたち
redis-clusterに関しての内容は以下記事にわかりやすく解説されています。一読してみてください。とてもわかります。
https://qiita.com/keitatata/items/44678ad472e61a4606c5
参考サイト:[実演]Redis Clusterの仕組みを完全に理解する
以下にredisコンテナにマウントした内容と、実行する内容を記載します。以下のtreeの内容のconfの内容の説明になります。
.
├── RedisPractice(springのプロジェクト)
│
├── conf(このディレクトリの説明)
│ ├── redis.conf
│ └── redis.sh
└── docker-compose.yml
docker-compose up でdocker-composeを起動すると、redisコンテナ内でredis.shを実行します。
簡単に説明すると、
redisサーバー を 各ポート ごとに /conf/redis.conf の中身の設定で、バックグラウンドで起動する。
その際にクラスターの情報は /conf/nodes.700_ .confファイルに書きこむ。
そのあとredisサーバごとの設定情報をの**/conf/r700_i.log**に書き込む。
最後にクラスターを構築し、1ノードにつき最低何個のレプリカを割り当てる。
です。
redis-server /conf/redis.conf --port 7000 --cluster-config-file /conf/nodes.7000.conf --daemonize yes ;
redis-server /conf/redis.conf --port 7001 --cluster-config-file /conf/nodes.7001.conf --daemonize yes ;
redis-server /conf/redis.conf --port 7002 --cluster-config-file /conf/nodes.7002.conf --daemonize yes ;
redis-server /conf/redis.conf --port 7003 --cluster-config-file /conf/nodes.7003.conf --daemonize yes ;
redis-server /conf/redis.conf --port 7004 --cluster-config-file /conf/nodes.7004.conf --daemonize yes ;
redis-server /conf/redis.conf --port 7005 --cluster-config-file /conf/nodes.7005.conf --daemonize yes ;
redis-cli -p 7000 info 1> /conf/r7000i.log 2> /dev/null;
redis-cli -p 7001 info 1> /conf/r7001i.log 2> /dev/null;
redis-cli -p 7002 info 1> /conf/r7002i.log 2> /dev/null;
redis-cli -p 7003 info 1> /conf/r7003i.log 2> /dev/null;
redis-cli -p 7004 info 1> /conf/r7004i.log 2> /dev/null;
redis-cli -p 7005 info 1> /conf/r7005i.log 2> /dev/null;
yes "yes" | redis-cli --cluster create 172.16.239.10:7000 172.16.239.10:7001 172.16.239.10:7002 172.16.239.10:7003 172.16.239.10:7004 172.16.239.10:7005 --cluster-replicas 1;
redisサーバーの設定ファイルは以下です。
全て大事ですが、cluster-announce-ipを指定せずにハマった過去があります。以下の記事ですので、もし良ければ見てみてください。
https://qiita.com/hudebakononaka/items/bb6376818075b951d5b7
cluster-enabled yes
cluster-node-timeout 5000
bind 0.0.0.0
cluster-announce-ip 127.0.0.1
Springでredisを操作する準備
以下のイメージで動かせるようにします。
今回確認する動作は
GETのパラメーターに値を乗せて、データを保存する。
です。
以下にSpringのコードを乗せています。
Springからのredisの操作に関してはSpring Data Redisドキュメントがわかりやすいです。
https://spring.pleiades.io/spring-data/redis/docs/2.3.6.RELEASE/reference/html/#redis:template
参考サイト : Spring ドキュメント
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RedisController {
@Autowired
private StringRedisTemplate redisTemplate;
@RequestMapping(value="/redis/{key}/{value}" ,method = RequestMethod.GET)
public String registerRedisServer( @PathVariable("key")String redisKey , @PathVariable("value") String redisValue) {
//文字列操作をする場合はrg.springframework.data.redis.core のValueOperationsを使用する
ValueOperations<String, String> stringOoperation = redisTemplate.opsForValue();
stringOoperation.set(redisKey, redisValue);
return "{"+ redisKey +":"+ redisValue +"}";
}
}
Configのファイルのコードは以下の記事を参考にさせていただいています。
https://ksby.hatenablog.com/entry/2018/11/30/065921
参考サイト : Spring Boot 1.5.x の Web アプリを 2.0.x へバージョンアップする ( その19 )( Docker で Redis の環境を構築する2(Redis Cluster 構成))
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import lombok.Data;
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.redis.cluster")
public class RedisConfig {
List<String> nodes;
@Bean
public RedisConnectionFactory connectionFactory() {
return new JedisConnectionFactory(new RedisClusterConfiguration(nodes));
}
}
spring:
redis:
cluster:
nodes: 127.0.0.1:7000,127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003,127.0.0.1:7004,127.0.0.1:7005
max-redirects: 9
実行手順
docker-compose.ymlがあるディレクトリ上で下記を実行してください。
$ docker-compose up -d
上記のコードを使用して、Spring を起動してください。
そのあとに、下記を実行してください。
curl localhost:8080/redis/yes/nonono
上記内容を実行すると、redisサーバーの中に値が保存されているはずです。
以下で試してみましょう。
$ docker exec -it redi_redis_1 bash
# redis-cli -p 7000
127.0.0.1:7000> get "yes"
(error) MOVED 15538 127.0.0.1:7002
127.0.0.1:7000> CTRL+C
# redis-cli -p 7002
127.0.0.1:7002> get "yes"
"nonono"
このようにポート7002に "yes":"nonono"のデータが保存されていました。
今後試してみたいこと
今回は開発環境でdocker-composeで環境を整えることが多いことを考え、docker-composeでredis-clusterを使用する方法について書きました。次回はより本番環境に近いものを考え、redis-clusterをkubernetesで動かし可用性を高める試みでも記事にしようと思います。
今回のコード
私のgithubにコードがありますので、使用したい方は使用してください。
https://github.com/Kota-Yamaguchi/redisPractice
参考文献
https://spring.pleiades.io/spring-data/redis/docs/2.3.6.RELEASE/reference/html/#redis:template
参考サイト : Spring ドキュメント
https://ksby.hatenablog.com/entry/2018/11/30/065921
参考サイト : Spring Boot 1.5.x の Web アプリを 2.0.x へバージョンアップする ( その19 )( Docker で Redis の環境を構築する2(Redis Cluster 構成))
https://qiita.com/TsutomuNakamura/items/ed046ee21caca4a2ffd9
参考サイト:Docker network 概論
https://qiita.com/keitatata/items/44678ad472e61a4606c5
参考サイト:[実演]Redis Clusterの仕組みを完全に理解する