一、Redisr Sentinel叢集搭建
在linux環境下,使用docker compose安裝redis sentinel叢集的搭建,需要準備的工作:
1.1安裝docker
•下載下傳安裝docker:yum -y install docker
•啟動docker服務:service docker start
•檢查docker是否安裝成功:docker version
1.2安裝docker compose
•安裝指令:sudo pip install -U docker-compose
如果在安裝的過程中,出現連接配接逾時的報錯提示,可以使用如下指令解決:
•pip --default-timeout=100 install -U Pillow,如果未出現報錯,則無需使用該指令
1.3安裝redis鏡像
•安裝指令:docker pull redis
•檢視安裝是否成功指令:docker images
1.4在/usr/local/目錄下建立redis-docker檔案夾
•指令:mkdir redis-docker
在redis-docker目錄下建立redis目錄
•指令:mkdir redis
在redis檔案夾下建立docker-compose.yml檔案,實作redis一主二從,編寫内容:
redis不加密的配置方式:
version: '3'
services:
master:
image: redis
container_name: redis-sentinel-master
ports:
- 6379:6379
volumes:
- ./data:/redisdata
slave1:
image: redis
container_name: redis-sentinel-slave-1
ports:
- 6380:6379
command: redis-server --slaveof redis-sentinel-master 6379
volumes:
- ./data:/redisdata
slave2:
image: redis
container_name: redis-sentinel-slave-2
ports:
- 6381:6379
command: redis-server --slaveof redis-sentinel-master 6379
volumes:
- ./data:/redisdata
redis加密的配置方式:
version: '3'
services:
master:
image: redis
container_name: redis-sentinel-master
command: redis-server --requirepass 123456
ports:
- 6379:6379
volumes:
- ./data:/redisdata
slave1:
image: redis
container_name: redis-sentinel-slave-1
ports:
- 6380:6379
command: redis-server --slaveof redis-sentinel-master 6379 --requirepass 123456 --masterauth 123456
volumes:
- ./data:/redisdata
slave2:
image: redis
container_name: redis-sentinel-slave-2
ports:
- 6381:6379
command: redis-server --slaveof redis-sentinel-master 6379 --requirepass 123456 --masterauth 123456
volumes:
- ./data:/redisdata
主節點的端口,最好和redis的預設端口,即6379保持一緻
•啟動redis,使用如下指令 挂在背景:docker-compose up -d
•如果使用失敗了,可以使用如下指令檢視日志,觀察是什麼原因造成的:
docker logs -f 容器Id
•停止redis:docker-compose down
或者
docker stop 容器Id
docker rm 容器Id
•進入主redis容器中,使用如下指令:docker exec -it 容器Id bash
•重新開機docker:systemctl restart docker
•檢視docker叢集狀态:docker ps -a
如果修改過redis節點的端口和ip,一定要重新開機docker鏡像
1.5在redis-docker檔案夾下建立sentinel檔案
•指令:mkdir redis-docker
在redis-docker目錄下,編寫docker-compose.yml,編寫内容:
version: '3'
services:
sentinel1:
image: redis
container_name: redis-sentinel-sentinel1
ports:
- 26379:26379
command: redis-sentinel /usr/local/redis-docker/sentinel/sentinel.conf
volumes:
- ./sentinel1.conf:/usr/local/redis-docker/sentinel/sentinel.conf
sentinel2:
image: redis
container_name: redis-sentinel-sentinel2
ports:
- 26380:26379
command: redis-sentinel /usr/local/redis-docker/sentinel/sentinel.conf
volumes:
- ./sentinel2.conf:/usr/local/redis-docker/sentinel/sentinel.conf
sentinel3:
image: redis
container_name: redis-sentinel-sentinel3
ports:
- 26381:26379
command: redis-sentinel /usr/local/redis-docker/sentinel/sentinel.conf
volumes:
- ./sentinel3.conf:/usr/local/redis-docker/sentinel/sentinel.conf
1.6在redis-docker檔案夾下編寫sentinel.conf檔案
sentinel.conf内容如下:
port 26379
dir /tmp
# 自定義叢集名,其中 192.168.1.110 為 redis-master 的 ip,6379 為 redis-master 的端口,2 為最小投票數(因為有 3 台 Sentinel 是以可以設定成 2),我自己設定的主節點的ip為所在伺服器的ip
sentinel monitor mymaster 192.168.1.110 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
執行如下指令,複制3份redis-sentinel配置檔案
cp sentinel.conf sentinel1.conf
cp sentinel.conf sentinel2.conf
cp sentinel.conf sentinel3.conf
•啟動redis-sentinel:docker-compose up -d
•檢視redis-sentinel是否啟動狀态:docker-compose ps
•執行如下指令,檢視從redis資訊是否正常:sentinel slaves mymaster
•執行如下指令,檢視redis主節點資訊:sentinel master mymaster
名詞 | 描述 |
---|---|
version | docker檔案的版本 |
image | 指定容器鏡像就是之前拉取的redis鏡像 |
container_name | 給這個鏡像起一個别名 |
restart | always:表名開機自啟動 |
command | 相當于執行一些指令 (–requirepass 指定redis密碼 --appendonly yes 這個指令是用于開啟redis資料持久化) |
ports | 端口映射,将容器的端口映射到對應主控端的端口 |
volumes | 資料卷的映射.因為一旦容器停止了那麼裡面的資料也沒有.是以我們需要把這個資料檔案放在外面,然後映射到容器中 |
二、後端代碼中application.yml檔案中的配置
#Redis叢集哨兵模式
redisSentinel:
sentinelMaster: 192.168.1.110
masterName: mymaster
sentinelNodes: 192.168.1.110:26379,192.168.1.110:26380,192.168.1.110:26381
sentinelPort: 6379
maxIdle: 300
maxTotal: 1000
maxWaitMills: 1000
minEvictableIdleTimeMillis: 300000
numTestPerEvictionRun: 1024
timeBetweenEvictionRunMillis: 30000
testOnBorrow: true
testWhileIdle: true
哨兵模式下,redis叢集相對來說特殊點,這種配置下,後端代碼直接監控并連接配接哨兵節點資訊,并不直接連接配接主節點;是以masterName和sentinel.conf配置檔案中mymaster保持一緻,否則後端會報錯,這是我的了解,如果有不對的地方;sentinelMaster這個參數,可以不配置。
三、後端代碼demo示例
3.1.pom檔案添加依賴,我使用的是jedis1.8.6版本:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3.2建立redis叢集連接配接池配置RedisSentinelPoolConfig.java
/**
* @Description:redis叢集哨兵模式下,用于初始化連接配接池
* @Date: 2019/8/10 15:44
*/
@Configuration
public class RedisSentinelPoolConfig {
@Value("${redisSentinel.maxIdle}")
private Integer maxIdle;
@Value("${redisSentinel.maxTotal}")
private Integer maxTotal;
@Value("${redisSentinel.maxWaitMills}")
private Integer maxWaitMills;
@Value("${redisSentinel.minEvictableIdleTimeMillis}")
private Integer minEvictableIdleTimeMillis;
@Value("${redisSentinel.numTestPerEvictionRun}")
private Integer numTestPerEvictionRun;
@Value("${redisSentinel.timeBetweenEvictionRunMillis}")
private long timeBetweenEvictionRunMillis;
@Value("${redisSentinel.testOnBorrow}")
private boolean testOnBorrow;
@Value("${redisSentinel.testWhileIdle}")
private boolean testWhileIdle;
@Value("${redisSentinel.sentinelMaster}")
private String sentinelMaster;
@Value("${redisSentinel.masterName}")
private String masterName;
@Value("${redisSentinel.sentinelNodes}")
private String sentinelNodes;
@Value("${redisSentinel.sentinelPort}")
private String sentinelPort;
/*
* 初始化JedisPoolConfig連接配接池到spring容器内
*/
@Bean
public JedisPoolConfig jedisPoolConfig(){
JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
//最大空閑數
jedisPoolConfig.setMaxIdle(maxIdle*10);
//連接配接池的最大資料庫連接配接數
jedisPoolConfig.setMaxTotal(maxTotal*10);
//最大建立連接配接等待時間
jedisPoolConfig.setMaxWaitMillis(maxWaitMills*10);
//逐出連接配接的最小空閑時間預設1800000毫秒(30分鐘)
jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
//每次逐出檢查時,逐出的最大數目,如果為負數就是1/abs(n),預設為3
jedisPoolConfig.setNumTestsPerEvictionRun(numTestPerEvictionRun);
//逐出掃描的時間間隔(毫秒),如果為負數,則不運作逐出線程,預設為-1
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunMillis);
//是否從連接配接池中取出連接配接前進行檢驗,如果檢驗失敗,則嘗試從池中取出另一個
jedisPoolConfig.setTestOnBorrow(testOnBorrow);
//在空閑時檢查有效性,預設為false
jedisPoolConfig.setTestWhileIdle(testWhileIdle);
return jedisPoolConfig;
}
/*
* 初始化叢集節點到spring容器内
*/
@Bean
public RedisSentinelConfiguration redisSentinelConfiguration(){
RedisSentinelConfiguration configuration=new RedisSentinelConfiguration();
String[] host=sentinelNodes.split(Constants.COMMA);
for(String redisHost:host){
String[] item=redisHost.split(Constants.COLON);
String ip=item[0];
String port=item[1];
configuration.addSentinel(new RedisNode(ip,Integer.parseInt(port)));
}
configuration.setMaster(masterName);
return configuration;
}
}
3.3建立redis配置RedisConfiguration.java
/**
* redis配置
*
* @create 2018/8/10 17:25
*/
@Configuration
@EnableCaching
public class RedisConfiguration extends CachingConfigurerSupport {
@Autowired
private JedisPoolConfig jedisPoolConfig;
@Autowired
private RedisSentinelConfiguration redisSentinelConfiguration;
@Bean
public JedisConnectionFactory jedisConnectionFactory(){
JedisConnectionFactory jedisConnectionFactory=new JedisConnectionFactory(redisSentinelConfiguration,jedisPoolConfig);
//如果redis沒設定密碼,就不要傳參數,否則會報錯
// jedisConnectionFactory.setPassword(redisPassword);
return jedisConnectionFactory;
}
@Bean
public RedisTemplate<String,Object> redisTemplate(){
RedisTemplate<String,Object> template = new RedisTemplate<String,Object> ();
//設定開啟事務
template.setEnableTransactionSupport(true);
//設定key序列化
StringRedisSerializer stringRedisSerializer=new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setConnectionFactory(jedisConnectionFactory());
template.afterPropertiesSet();
return template;
}
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
//rcm.setDefaultExpiration(60);
return rcm;
}
}
3.4建立RedisSentinelTemplate.java,用于後端代碼操作redis庫
/**
* @Description:redis叢集哨兵模式下,用于操作redis庫
* @Date: 2019/8/10 15:44
*/
@Component
public class RedisSentinelTemplate {
@Autowired
private RedisTemplate<String,Object> redisTemplate;
public void set(String key ,Object value){
redisTemplate.opsForValue().set(key,value);
}
public void set(String key, Object obj, Long expiration) {
redisTemplate.opsForValue().set(key, obj, expiration, TimeUnit.SECONDS);
}
public Object get(String key) {
return redisTemplate.opsForValue().get(key);
}
}
然後在業務子產品注入RedisSentinelTemplate對象,即可進行資料的增删改查
在這裡有一篇文章,寫的也是這種搭建方式,寫的也很不錯,大家可以參考下
1: https://www.cnblogs.com/hckblogs/p/11186311.html
以上内容純屬原創,有些地方也是參考了網上不少教程;這篇文章純屬技術分享,不以任何盈利為目的,如果有侵權的地方,請私信我,我将會進行調整,謝謝!