1.前言
由於最近項目上生產,采用三主三從的redis集群做緩存,因此進行單機redis改造。
本次采用的是docker+docker-compose進行部署,redis版本為5.0。
2.准備工作
2.1.redis.conf
在搭建redis集群之前,我們需要修改下redis的配置文件redis.conf。該文件的下載地址:https://github.com/antirez/redis/blob/5.0/redis.conf
需要修改的屬性如下,主要是修改了一些集群配置和運行端口,端口號需要按需修改為6371~6376:
# 設置運行端口 port 6371 # 開啟集群功能 cluster-enabled yes # 任何主機都可以連接到redis bind 0.0.0.0 # 集群節點IP地址 cluster-announce-ip 121.36.xxx.xxx # 節點映射端口 cluster-announce-port 6371 #節點總線端 cluster-announce-bus-port 16371 # 設置節點超時時間,單位毫秒 cluster-node-timeout 15000 # 集群內部配置文件 cluster-config-file "nodes-6391.conf"
# 持久化模式
appendonly yes
cluster-announce-ip:這個IP需要特別注意一下,如果要對外提供訪問功能,需要填寫宿主機的IP,如果不填或者填寫docker分配的IP,可能會導致部分集群節點在跳轉時失敗。
如果填寫沒有填宿主機IP,雖然能單機連接正常使用,但是在使用代碼連接時,如果有自定義配置,則會報錯,初始化失敗。
沒有填寫時會使用內部IP,而代碼連接集群時,雖然配置宿主機IP,但是集群內配置仍為內部IP,連接不上內部IP,則會拋出異常。
2.2.docker-compose.yaml
編寫docker-compose.yml文件用於編排6個Redis容器,具體屬性的作用可以參考下面的注釋:
version: "3" services: redis-master1: image: redis:5.0 # 基礎鏡像 container_name: redis-master1 # 容器名稱 working_dir: /config # 切換工作目錄 environment: # 環境變量 - PORT=6371 # 會使用config/${PORT}.conf這個配置文件 ports: # 映射端口,對外提供服務 - 6371:6371 # redis的服務端口 - 16371:16371 # redis集群監控端口 stdin_open: true # 標准輸入打開 tty: true # 后台運行不退出 network_mode: host # 使用host模式 privileged: true # 擁有容器內命令執行的權限 volumes: - /data/redis/config:/config #配置文件目錄映射到宿主機 entrypoint: # 設置服務默認的啟動程序 - /bin/bash - redis.sh redis-master2: image: redis:5.0 working_dir: /config container_name: redis-master2 environment: - PORT=6372 ports: - 6372:6372 - 16372:16372 stdin_open: true network_mode: host tty: true privileged: true volumes: - /data/redis/config:/config entrypoint: - /bin/bash - redis.sh redis-master3: image: redis:5.0 container_name: redis-master3 working_dir: /config environment: - PORT=6373 ports: - 6373:6373 - 16373:16373 stdin_open: true network_mode: host tty: true privileged: true volumes: - /data/redis/config:/config entrypoint: - /bin/bash - redis.sh redis-slave1: image: redis:5.0 container_name: redis-slave1 working_dir: /config environment: - PORT=6374 ports: - 6374:6374 - 16374:16374 stdin_open: true network_mode: host tty: true privileged: true volumes: - /data/redis/config:/config entrypoint: - /bin/bash - redis.sh redis-slave2: image: redis:5.0 working_dir: /config container_name: redis-slave2 environment: - PORT=6375 ports: - 6375:6375 - 16375:16375 stdin_open: true network_mode: host tty: true privileged: true volumes: - /data/redis/config:/config entrypoint: - /bin/bash - redis.sh redis-slave3: image: redis:5.0 container_name: redis-slave3 working_dir: /config environment: - PORT=6376 ports: - 6376:6376 - 16376:16376 stdin_open: true network_mode: host tty: true privileged: true volumes: - /data/redis/config:/config entrypoint: - /bin/bash - redis.sh
從docker-compose.yml文件中我們可以看到,我們的Redis容器分別運行在6371~6376這6個端口之上。
將容器中的/config配置目錄映射到了宿主機的/data/redis/config目錄,同時還以redis.sh腳本作為該容器的啟動腳本。
2.3.redis.sh
redis.sh腳本的作用是根據environment環境變量中的PORT屬性,以指定配置文件來啟動Redis容器
redis-server /config/${PORT}.conf
2.4.上傳服務器
將我們的文件上傳服務器,忽略config目錄下,6376.conf后的文件,這些文件為運行時創建的。
3.運行集群
啟動容器
docker-compose up -d
進入其中一個容器
docker exec -it redis-master1 /bin/bash
初始化redis集群
redis-cli --cluster create 121.36.xxx.xxx:6371 121.36.xxx.xxx:6372 \ 121.36.xxx.xxx:6373 121.36.xxx.xxx:6374 121.36.xxx.xxx:6375 \ 121.36.xxx.xxx:6376 --cluster-replicas 1
cluster-replicas: 集群集,就是主從節點的比例,1代表主從節點一比一,0則表示沒有從節點。
集群創建過程中會讓你確認配置,輸入yes確認即可。
輸出以下信息則表示集群創建成功:
4.集群相關操作
創建成功后我們可以使用redis-cli命令連接到其中一個Redis服務;
# 單機模式啟動 redis-cli -p 6371 # 集群模式啟動 redis-cli -c -p 6371
查看集群信息
cluster nodes
可以看到滿足三主三從集群要求:
至此集群搭建完成。
5.SpringBoot連接
5.1.引入依賴
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency>
5.2.application.yml
因為spring-boot-starter-data-redis默認的redis客戶端是使用lettuce,因此我們這里也采用lettuce連接池。
spring: redis: password: # Redis服務器連接密碼(默認為空) timeout: 3000ms # 連接超時時間 cluster: nodes: #所有節點地址 - 121.36.151.54:6371 - 121.36.151.54:6372 - 121.36.151.54:6373 - 121.36.151.54:6374 - 121.36.151.54:6375 - 121.36.151.54:6376 max-redirects: 5 #連接失敗最大重連次數 lettuce: pool: max-active: 8 # 連接池最大連接數 max-idle: 8 # 連接池最大空閑連接數 min-idle: 0 # 連接池最小空閑連接數 max-wait: -1ms # 連接池最大阻塞等待時間,負值表示沒有限制
5.3.RedisConfig
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration @AutoConfigureAfter(RedisAutoConfiguration.class) public class RedisConfig { @Bean public RedisTemplate<String, Object> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); template.setConnectionFactory(redisConnectionFactory); return template; } }
使用時直接注入RedisTemplate即可直接使用。
參考文檔:https://www.jianshu.com/p/ca06e437614f