5.redis主從高可用

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


    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章