实现功能描述:
redis服务器进行Master-slaver-slaver-....主从配置,通过2台sentinel进行failOver故障转移,自动切换,采用该代码完全可以直接用于实际生产环境。
题外话:
一般来说这样的部署足以支持数以百万级的用户,但如果数量实在是太高,此时redis的Master-Slaver主从不一定能够满足,因此进行redis的分片。
本文不讲解redis的分片,但如果你使用了,需要注意的按照另一篇文章的介绍:Sentinel&Jedis看上去是个完美的解决方案,这句话只说对了一半,
在无分片的情况是这样,但我们的应用使用了数据分片-sharing,数据被平均分布到4个不同的实例上,每个实例以主从结构部署,Jedis没有提供
基于Sentinel的ShardedJedisPool,也就是说在4个分片中,如果其中一个分片发生主从切换,应用所使用的ShardedJedisPool无法获得通知,所有
对那个分片的操作将会失败。文章中提出了解决方案,请参考《基于Redis Sentinel的Redis集群(主从&Sharding)高可用方案》
该代码模拟多线程向redis中set/get。
1、maven依赖配置
org.springframework.data
spring-data-redis
1.4.1.RELEASE
redis.clients
jedis
2.6.2
org.apache.commons
commons-lang3
3.3.2
2、redis.properties
# Redis settings
#sentinel1的IP和端口
im.hs.server.redis.sentinel1.host=192.168.62.154
im.hs.server.redis.sentinel1.port=26379
#sentinel2的IP和端口
im.hs.server.redis.sentinel2.host=192.168.62.153
im.hs.server.redis.sentinel2.port=26379
#sentinel的鉴权密码
im.hs.server.redis.sentinel.masterName=155Master
im.hs.server.redis.sentinel.password=hezhixiong
#最大闲置连接数
im.hs.server.redis.maxIdle=500
#最大连接数,超过此连接时操作redis会报错
im.hs.server.redis.maxTotal=5000
im.hs.server.redis.maxWaitTime=1000
im.hs.server.redis.testOnBorrow=true
#最小闲置连接数,spring启动的时候自动建立该数目的连接供应用程序使用,不够的时候会申请。
im.hs.server.redis.minIdle=300
3、spring-redis.xml
4、RedisServiceImpl.java
package com.gaojiasoft.test.redis;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@Service("redisService")
public class RedisServiceImpl {
private Logger logger = LoggerFactory.getLogger("RedisServiceImpl");
@Autowired
RedisTemplate redisTemplate;
// 线程池
private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(
256, 256, 30L, TimeUnit.SECONDS,
new LinkedBlockingQueue(),
new BasicThreadFactory.Builder().daemon(true)
.namingPattern("redis-oper-%d").build(),
new ThreadPoolExecutor.CallerRunsPolicy());
public void set(final String key, final String value) {
redisTemplate.execute(new RedisCallback