1、安裝
cd /usr/src #進入下載目錄(這個目錄自己定) #安裝依賴 yum install -y wget gcc make tcl #下載源碼包 wget http://download.redis.io/releases/redis-6.0.1.tar.gz #解壓 tar xzf redis-6.0.1.tar.gz #進入redis目錄 cd redis-6.0.1 #編譯與測試 make && make test #PREFIX安裝指定目錄 make install PREFIX=/usr/local/redis
2、啟動redis服務,檢查redis是否安裝成功
#啟動redis服務
[redis-server 目錄]./redis-server
3、搭建哨兵模式
3.1、主從定義和數據節點、哨兵節點端口定義
目標:1主2從 主數據節點端口:6380 從數據節點端口:6381,6382 哨兵節點端口:26380,26381,26382
3.2、在/usr/local/ 下新建一個目錄redis-sentinel,然后創建數據節點和哨兵節點配置和數據文件夾
數據節點配置和數據文件夾 6380,6381,6382 哨兵節點配置和數據文件夾 26380,26381,26382 #創建相關文件夾命令 mkdir /usr/local/redis-sentinel mkdir /usr/local/redis-sentinel/{6380,6381,6382} mkdir /usr/local/redis-sentinel/{26380,26381,26382} #復制redis.conf配置文件 cp /usr/local/redis-6.0.1/redis.conf /usr/local/redis-sentinel/6380/redis_6380.conf cp /usr/local/redis-6.0.1/redis.conf /usr/local/redis-sentinel/6381/redis_6381.conf cp /usr/local/redis-6.0.1/redis.conf /usr/local/redis-sentinel/6382/redis_6382.conf #復制sentinel.conf配置文件 cp /usr/local/redis-6.0.1/redis.conf /usr/local/redis-sentinel/26380/sentinel_26380.conf cp /usr/local/redis-6.0.1/redis.conf /usr/local/redis-sentinel/26381/sentinel_26381.conf cp /usr/local/redis-6.0.1/redis.conf /usr/local/redis-sentinel/26382/sentinel_26382.conf
3.3、數據節點配置(即:redis實例):將redis安裝目錄下配置文件reids.conf拷貝6380,6381,6382文件夾下,將其中一些配置自定義如下(其他配置不變):
#Redis默認不是以守護進程的方式運行,可以通過該配置項修改,使用yes啟用守護進程 daemonize yes #當Redis以守護進程方式運行時,Redis默認會把pid寫入/var/run/redis.pid文件,可以通過pidfile指定 pidfile /var/run/redis_6380.pid #指定Redis監聽端口,默認端口為6379 port 6380 #綁定的主機地址(bind 0.0.0.0允許跨網絡訪問) bind 0.0.0.0 #日志記錄方式,默認為標准輸出,日志輸出至指定日志文件 logfile "./redis-6380.log" #指定本地數據庫存放目錄 dir "/usr/local/redis-sentinel/6380" #當master服務設置了密碼保護時,slave服務連接master的密碼,可以不設置(可選)。設置在slave上,指定master的密碼。 #masterauth admin.123 #設置Redis連接密碼,如果配置了連接密碼,客戶端在連接Redis時需要通過AUTH <password>命令提供密碼,默認關閉,可以不設置(可選),設置在master上,指定master密碼。 #requirepass admin.123 #指定是否在每次更新操作后進行日志記錄,Redis在默認情況下是異步的把數據寫入磁盤,如果不開啟,可能會在斷電時導致一段時間內的數據丟失。 #因為 redis本身同步數據文件是按上面save條件來同步的,所以有的數據會在一段時間內只存在於內存中。默認為no appendonly yes #設置當本機為slave服務時,設置master服務的IP地址及端口,在Redis啟動時,它會自動從master進行數據同步(本例以6380端口的為主,6381和6382為從,故以下只需在6381和6382配置中即可)。此處需要注意。。。 slaveof 127.0.0.0 6380
3.4、哨兵配置:將redis安裝目錄下的sentinel.conf拷貝6380,6381,6382文件夾下,其自定義配置如下:
#============================================自定義配置開始======================================== #Redis默認不是以守護進程的方式運行,可以通過該配置項修改,使用yes啟用守護進程 daemonize yes #指定sentinel端口。(其它哨兵配置需要改否則引起端口沖突) port 26380 #指定本地數據庫存放目錄。(其它哨兵配置需要改成對應路徑) dir "/usr/local/redis-sentinel/26380" #日志記錄方式,默認為標准輸出,日志輸出至指定日志文件。(其它哨兵配置需要改成對應路徑和文件) logfile "/usr/local/redis-sentinel/26380/sentinel_26380.log" #指定別名 主節點地址 端口 哨兵個數(有幾個哨兵監控到主節點宕機執行轉移)。所有的哨兵都指向主節點地址和端口。注意如果是服務器127.0.0.1需要改成服務器ID地址,否則通過Java連接不成功。 sentinel monitor mymaster 127.0.0.0 6380 1 #如果哨兵3s內沒有收到主節點的心跳,哨兵就認為主節點宕機了,默認是30秒 sentinel down-after-milliseconds mymaster 3000 #選舉出新的主節點之后,可以同時連接從節點的個數 sentinel parallel-syncs mymaster 1 #如果10秒后,master仍沒活過來,則啟動failover,默認180s sentinel failover-timeout mymaster 10000 #配置連接redis主節點密碼(可選),所有哨兵配置文件都要加上,如果master主節點配置了密碼。 #sentinel auth-pass mymaster admin.123 #============================================自定義配置結束========================================
4、redis服務啟動
4.1.先啟動主從
[appuser@uxt210196 redis-6.0.1]$ ./src/redis-server /usr/local/redis-sentinel/6380/redis_6380.conf [appuser@uxt210196 redis-6.0.1]$ ./src/redis-server /usr/local/redis-sentinel/6381/redis_6381.conf [appuser@uxt210196 redis-6.0.1]$ ./src/redis-server /usr/local/redis-sentinel/6382/redis_6382.conf 查看服務信息,如果信息返回,證明數據節點沒有起來。查看啟動命令是否正確。注意redis-server啟動不需要加--sentinel [appuser@uxt210196 redis-6.0.1]$ ./src/redis-cli -h 127.0.0.1 -p 6380 info replication # Replication role:master connected_slaves:2 slave0:ip=10.16.70.142,port=6381,state=online,offset=1394550,lag=1 slave1:ip=10.16.70.142,port=6382,state=online,offset=1394550,lag=1 master_replid:bed7630a4c86f762a6f95497ed98379c44d97a88 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:1394690 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:346115 repl_backlog_histlen:1048576
4.2、啟動哨兵
[appuser@uxt210196 redis-6.0.1]$ ./src/redis-sentinel /usr/local/redis-sentinel/26380/sentinel_26380.conf [appuser@uxt210196 redis-6.0.1]$ ./src/redis-sentinel /usr/local/redis-sentinel/26381/sentinel_26381.conf [appuser@uxt210196 redis-6.0.1]$ ./src/redis-sentinel /usr/local/redis-sentinel/26382/sentinel_26382.conf
4.3、查看進程
3個redis-server進程,3個sentinel進程。
[appuser@uxt210196 redis-6.0.1]$ ps -ef |grep redis appuser 4204 1 0 08:53 ? 00:00:17 ./src/redis-server 0.0.0.0:6380 appuser 4213 1 0 08:54 ? 00:00:20 ./src/redis-server 0.0.0.0:6381 appuser 4236 1 0 08:55 ? 00:01:11 ./src/redis-sentinel 0.0.0.0:26380 [sentinel] appuser 4241 1 0 08:55 ? 00:01:11 ./src/redis-sentinel 0.0.0.0:26381 [sentinel] appuser 4354 1 0 09:03 ? 00:00:20 ./src/redis-server 0.0.0.0:6382 appuser 4372 1 0 09:04 ? 00:01:07 ./src/redis-sentinel 0.0.0.0:26382 [sentinel] appuser 5163 5108 0 10:59 pts/0 00:00:00 grep redis
5、啟動嘗試連接
a、首先確定本地能訪問
b、嘗試使用redis后嘗試使用redis desktop manager工具連接下,確保外面能訪問。
c、若外網訪問不了,查看是否沒關防火窗
d、檢查配置文件的bind
6、java連接redis哨兵
public static void main(String[] args) { // 建立連接池配置參數 JedisPoolConfig poolConfig = new JedisPoolConfig(); //控制一個pool最多有多少個狀態為idle(空閑)的jedis實例 poolConfig.setMaxIdle(10); //需要使用哨兵端口,才能實現高可用 String masterName = "mymaster"; Set<String> sentinelSet = new HashSet<String>(); sentinelSet.add("127.0.0.1:26380"); sentinelSet.add("127.0.0.1:26381"); sentinelSet.add("127.0.0.1:26382"); JedisSentinelPool sentinelPool = new JedisSentinelPool(masterName, sentinelSet, poolConfig, 60000); Jedis jedis = null; try { jedis = sentinelPool.getResource(); //設置操作數據庫,不設置默認使用0 jedis.select(1); //測試是否可以設值 jedis.set("name","zhangsan"); //獲取值 System.out.println("redis:"+jedis.get("name")); } catch (Exception e) { e.printStackTrace(); } finally { if (jedis != null) { jedis.close(); } } }
7、SpringBoot整合Redis Sentinel哨兵
7.1、依賴jar
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
7.2、redis哨兵模式配置文件:application.yml
#redis哨兵模式配置文件:application.yml
spring.redis.database=0
spring.redis.sentinel.master=mymaster
spring.redis.sentinel.nodes=127.0.0.1:26380,127.0.0.1:26381,127.0.0.1:26382
7.3、springboot redis哨兵連接配置類(創建redisTemplate緩存操作對象)
package com.hababa.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.data.redis.RedisProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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.RedisOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; import redis.clients.jedis.JedisPoolConfig; /** * @Classname RedisSentinelConfig * @Description * @Date 2020/5/14 9:21 * @Created by */ @EnableCaching @Configuration @ConditionalOnClass(RedisOperations.class) @EnableConfigurationProperties(RedisProperties.class) public class RedisSentinelConfig { @Value("${spring.redis.database}") private int database; @Value("${spring.redis.sentinel.nodes}") private String redisNodes; @Value("${spring.redis.sentinel.master}") private String master = "mymaster"; @Bean public JedisPoolConfig jedisPoolConfig(){ JedisPoolConfig config = new JedisPoolConfig(); return config; } //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); return configuration; } @Bean public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig,RedisSentinelConfiguration sentinelConfig) { JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(sentinelConfig,jedisPoolConfig); return 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(jedisPoolConfig(),redisSentinelConfiguration())); template.afterPropertiesSet(); return template; } }
8、測試springboot是否成功整合redis sentinel
/** * @Classname TestController * @Description 測試springboot是否成功整合redis sentinel * @Date 2020/5/14 14:32 * @Created by */ @RestController @RequestMapping("test") public class TestController { @Autowired RedisTemplate redisTemplate; @Autowired private StringRedisTemplate stringRedisTemplate; @GetMapping("redisHandler") public String redisHandler(){ redisTemplate.opsForValue().set("key_lisi","lisi"); System.out.println(redisTemplate.opsForValue().get("key_lisi")); } }
9、linux shell腳本啟動redis和sentinel (文件名稱:redis_sentinel_start_stop_restart.sh)
9.1、執行腳本需要傳入參數start或者stop或者restart
#!/bin/sh start(){ nohup /usr/local/redis-6.0.1/src/redis-server /usr/local/redis-6.0.1/redis-sentinel/6380/redis.conf nohup /usr/local/redis-6.0.1/src/redis-server /usr/local/redis-6.0.1/redis-sentinel/6381/redis.conf nohup /usr/local/redis-6.0.1/src/redis-server /usr/local/redis-6.0.1/redis-sentinel/6382/redis.conf nohup /usr/local/redis-6.0.1/src/redis-sentinel /usr/local/redis-6.0.1/redis-sentinel/6380/sentinel.conf nohup /usr/local/redis-6.0.1/src/redis-sentinel /usr/local/redis-6.0.1/redis-sentinel/6381/sentinel.conf nohup /usr/local/redis-6.0.1/src/redis-sentinel /usr/local/redis-6.0.1/redis-sentinel/6382/sentinel.conf } stop(){ ps -ef|grep redis|grep -v grep|awk '{print $2}'|while read pid do kill -9 $pid echo " kill $pid success " done } case "$1" in start) start ;; stop) stop ;; restart) stop sleep 1s start ;; *) printf 'Usage: %s {start|stop|restart}\n' "$prog" exit 1 ;; esac