在實際應用當中,爲了防止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出問題並不會引起程序不能使用。