在实际应用当中,为了防止redis宕机出现的单点故障,我们采用了主从高可用模式去实现,这种方式的好处是简单,轻量。
实现原理是redis服务器里面启动一个sentinel,sentinel去监听redis服务,里面有master redis,也有多台slave redis,当客户端调用sentinel获取master服务器,并且发送命令到master服务器,slave会去同步master的数据,这样保证了master与slave的数据同步,当master redis挂了后,在设定的时间sentinel会去选举一个slave作为master,客户端会发现新的master1,连接到新的master1并且把数据传输过去。
在开发之前需要把环境搭好,感谢这篇题主的分享http://www.cnblogs.com/Xrinehart/p/3502213.html,分享了如何搭建redis的主从搭建。下面是java的主从客户端使用
<span style="font-size:14px;">package com.yyc;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
public class redisSentinelConcurrent {
static JedisSentinelPool jedisSentinelPool;
public static void init(){
Set<String> sets = new HashSet<String>();
//设置了哨兵的ip和端口
sets.add("192.168.21.171:26379");
//新建一个jedisSentinelPool masterName需要与服务器配置sentinel.conf里面一样
jedisSentinelPool = new JedisSentinelPool("mymaster",sets);
}
public static void main(String[] args) throws InterruptedException {
init();
final AtomicLong counter = new AtomicLong(0);
final AtomicBoolean stopFlag = new AtomicBoolean(false);
final int threadCount = 100;
for (int i = 0; i < threadCount; i++) {
final String j = i + "";
new Thread(new Runnable() {
@Override
public void run() {
while (!stopFlag.get()) {
Jedis jedis = jedisSentinelPool.getResource();
jedis.set("test"+j, "test"+j);
jedisSentinelPool.returnResource(jedis);
counter.incrementAndGet();
}
}
}).start();
}
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.err.println("*** stop client ***");
stopFlag.set(true);
}
});
long startTime = System.currentTimeMillis();
while (!stopFlag.get()) {
Thread.sleep(1000);
final long count = counter.get();
long currentTime = System.currentTimeMillis();
long qps = count * 1000 / (currentTime - startTime);
System.out.println("qps=" + qps);
if ((currentTime - startTime) / 1000 > 10) {
counter.set(0);
startTime = currentTime;
System.out.println("reset counter");
}
}
}
}</span>
创建一个jedisSentinelPool,其ip是sentinel的ip,使用的方式也很简单,类似与jedis直接操作。经过测试其性能最低,7000的qps,比jedis少几倍。主要是数据同步消耗了性能。但是这种方式解决单点故障的问题,sentinel也可以部署多个,这样一个redis出问题并不会引起程序不能使用。