首先準備三臺redis服務。高可用基本上都是選用大於3臺服務
先設置主從關係:
先選用一個節點爲主節點。我這裏用6380作爲主。在其他兩個服務redis.conf中增加slaveof 127.0.0.1:6380
因爲是要做哨兵模式。所以每個節點都要設置可以寫。在三個服務中redis.conf更改 slave-read-only爲no。
並且找到masterauth XXXXX 修改。這個密碼主節點的密碼。最好對於這三個redis服務密碼都設置一樣。
這樣主從就搞好了。接下來做哨兵
在三個redis服務中增加這個文件
sentinel.conf這樣配置 每個文件的端口需要自行更改
====================================================================
port 26370 #
bind 0.0.0.0
# 禁止保護模式
protected-mode no
# 配置監聽的主服務器,這裏sentinel monitor代表監控,mymaster代表服務器的名稱,可以自定義,192.168.11.128代表監控的主服務器,6379代表端口,2代表只有兩個或兩個以上的哨兵認爲主服務器不可用的時候,纔會進行failover操作。
sentinel myid 4bb87fdc9adb28a64463d734ef7afee092fad9bb
# sentinel author-pass定義服務的密碼,mymaster是服務名稱,123456是Redis服務器密碼
# sentinel auth-pass <master-name> <password>
sentinel monitor mymaster 127.0.0.1 6380 2
sentinel down-after-milliseconds mymaster 7000
# Generated by CONFIG REWRITE
sentinel failover-timeout mymaster 15000
sentinel auth-pass mymaster root123456abc
sentinel known-slave mymaster 127.0.0.1 6379
sentinel known-slave mymaster 127.0.0.1 6370
daemonize yes #守護進程
=======================================================================================
配置好後。如果啓動。關掉其中主服務。有的不會自動切換。在redis.conf和sentinel.con 修改bind 0.0.0.0 和protected-mode no
然後就是把服務啓動。
redis服務啓動命令 :redis-server.exe redis.windows.conf
哨兵啓動命令:redis-server.exe sentinel.conf --sentinel
關掉redis主服務。就會看到哨兵會自動切換。但是切換會有點幾秒的延遲。
接下來就是springboot整合了在yml中增加redis配置
第一步:
spring:
redis:
host: localhost # Redis服務器地址
database: 0 # Redis數據庫索引(默認爲0)
port: 6379 # Redis服務器連接端口
password: root123456abc # Redis服務器連接密碼(默認爲空)
jedis:
pool:
max-active: 8 # 連接池最大連接數(使用負值表示沒有限制)
max-wait: -1ms # 連接池最大阻塞等待時間(使用負值表示沒有限制)
max-idle: 8 # 連接池中的最大空閒連接
min-idle: 0 # 連接池中的最小空閒連接
timeout: 10000
sentinel:
master: mymaster
nodes: localhost:26379,localhost:26380,localhost:26370
第二步增加此類
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisNode; import org.springframework.data.redis.connection.RedisSentinelConfiguration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; import redis.clients.jedis.JedisPoolConfig; import java.net.UnknownHostException; @Configuration public class RedisSentinelConfig extends CachingConfigurerSupport { @Value("${spring.redis.host}") private String host; @Value("${spring.redis.port}") private int port; @Value("${spring.redis.timeout}") private int timeout; @Value("${spring.redis.database}") private int database; @Value("${spring.redis.password}") private String password; @Value("${spring.redis.sentinel.nodes}") private String redisNodes; @Value("${spring.redis.sentinel.master}") private String master; //redis哨兵配置 @Bean public RedisSentinelConfiguration redisSentinelConfiguration(){ RedisSentinelConfiguration configuration = new RedisSentinelConfiguration(); String[] host = redisNodes.split(","); for(String redisHost : host){ String[] item = redisHost.split(":"); String ip = item[0]; String port = item[1]; configuration.addSentinel(new RedisNode(ip, Integer.parseInt(port))); } configuration.setMaster(master); configuration.setPassword("root123456abc"); return configuration; } @Bean @ConfigurationProperties(prefix = "redis.jedis") public JedisPoolConfig jedisPoolConfig1(){ JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setTestOnBorrow(true); return jedisPoolConfig; } //連接redis的工廠類 @Autowired private JedisPoolConfig jedisPoolConfig; @Autowired private RedisSentinelConfiguration redisSentinelConfiguration; @Bean public JedisConnectionFactory jedisConnectionFactory() { JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisSentinelConfiguration, jedisPoolConfig); return jedisConnectionFactory; } //配置RedisTemplate,設置添加序列化器,key 使用string序列化器,value 使用Json序列化器,還有一種簡答的設置方式,改變defaultSerializer對象的實現。 @Autowired private JedisConnectionFactory jedisConnectionFactory; @Bean public RedisTemplate<Object, Object> redisTemplate() { //StringRedisTemplate的構造方法中默認設置了stringSerializer RedisTemplate<Object, Object> template = new RedisTemplate<>(); //設置開啓事務 template.setEnableTransactionSupport(true); //set key serializer StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); template.setKeySerializer(stringRedisSerializer); template.setHashKeySerializer(stringRedisSerializer); template.setConnectionFactory(jedisConnectionFactory()); template.afterPropertiesSet(); return template; } @Bean @ConditionalOnMissingBean public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { StringRedisTemplate template = new StringRedisTemplate(); template.setEnableTransactionSupport(true); template.setConnectionFactory(redisConnectionFactory); return template; } }
這樣就大功告成了。實現了高可用。