1. 程式人生 > >Redis Sentinel高可用叢集Java客戶端

Redis Sentinel高可用叢集Java客戶端

java客戶端Jedis在2.2.2及以上版本實現了對Sentinel的支援,只要是通過命令:
redis-cli -h 192.168.110.71 -p 6000  sentinel get-master-addr-by-name shard_a
1) "192.168.110.71"
2) "6379"
查詢分片shard_a的主伺服器地址,實現程式碼如下:
  1. private HostAndPort initSentinels(Set<String> sentinels, final String masterName) {  
  2.     HostAndPort master = null;  
  3.     boolean
     sentinelAvailable = false;  
  4.     log.info("Trying to find master from available Sentinels...");  
  5.     for (String sentinel : sentinels) {  
  6.       final HostAndPort hap = toHostAndPort(Arrays.asList(sentinel.split(":")));  
  7.       log.fine("Connecting to Sentinel " + hap);  
  8.       Jedis jedis = null;  
  9.       try
     {  
  10.         jedis = new Jedis(hap.getHost(), hap.getPort());  
  11.         List<String> masterAddr = jedis.sentinelGetMasterAddrByName(masterName);  
  12.         // connected to sentinel...
  13.         sentinelAvailable = true;  
  14.         if (masterAddr == null || masterAddr.size() != 2) {  
  15.           log.warning("Can not get master addr, master name: "
     + masterName + ". Sentinel: " + hap  
  16.               + ".");  
  17.           continue;  
  18.         }  
  19.         master = toHostAndPort(masterAddr);  
  20.         log.fine("Found Redis master at " + master);  
  21.         break;  
  22.       } catch (JedisConnectionException e) {  
  23.         log.warning("Cannot connect to sentinel running @ " + hap + ". Trying next one.");  
  24.       } finally {  
  25.         if (jedis != null) {  
  26.           jedis.close();  
  27.         }  
  28.       }  
  29.     }  
  30.     if (master == null) {  
  31.       if (sentinelAvailable) {  
  32.         // can connect to sentinel, but master name seems to not
  33.         // monitored
  34.         thrownew JedisException("Can connect to sentinel, but " + masterName  
  35.             + " seems to be not monitored...");  
  36.       } else {  
  37.         thrownew JedisConnectionException("All sentinels down, cannot determine where is "
  38.             + masterName + " master is running...");  
  39.       }  
  40.     }  
  41.     log.info("Redis master running at " + master + ", starting Sentinel listeners...");  
  42.     for (String sentinel : sentinels) {  
  43.       final HostAndPort hap = toHostAndPort(Arrays.asList(sentinel.split(":")));  
  44.       MasterListener masterListener = new MasterListener(masterName, hap.getHost(), hap.getPort());  
  45.       masterListeners.add(masterListener);  
  46.       masterListener.start();  
  47.     }  
  48.     return master;  
  49.   }  

關於在java應用中如何使用,請參考如下程式碼例項:

  1. package cn.slimsmart.redis.demo.sentinel;  
  2. import java.util.HashSet;  
  3. import java.util.Set;  
  4. import redis.clients.jedis.Jedis;  
  5. import redis.clients.jedis.JedisSentinelPool;  
  6. publicclass JedisSentinelTest {  
  7.     publicstaticvoid main(String[] args) {  
  8.         Set<String> sentinels = new HashSet<String>();  
  9.         sentinels.add("192.168.100.90:6000");  
  10.         sentinels.add("192.168.110.71:6000");  
  11.         /** 
  12.          * masterName 分片的名稱 
  13.          * sentinels Redis Sentinel 服務地址列表 
  14.          */
  15.         JedisSentinelPool poolA = new JedisSentinelPool("shard_a", sentinels);  
  16.         JedisSentinelPool poolB = new JedisSentinelPool("shard_b", sentinels);  
  17.         //獲取Jedis主伺服器客戶端例項
  18.         Jedis jedisA = poolA.getResource();  
  19.         jedisA.set("key""abc");  
  20.         Jedis jedisB = poolB.getResource();  
  21.         jedisB.set("key""xyz");  
  22.         System.out.println("jedisA key:"+jedisA.get("key"));  
  23.         System.out.println("jedisB key:"+jedisB.get("key"));  
  24.         //輸出結果
  25.         //jedisA key:abc
  26.         //jedisB key:xyz
  27.     }  
  28. }  
由上面程式碼可以看出jedis的JedisSentinelPool需要指定分片名稱即主服務名稱(masterName),這樣根據需求硬編碼將快取資料新增到對應的分片中,無法自動分片。若使用ShardedJedisPool,當分片發生主從切換無法獲得通知,所有對那個分片的操作將會失敗。下面我們介紹一個開源專案sharded-jedis-sentinel-pool,能及時感知所有分片主從切換行為,進行連線池重建。
專案原始碼:https://github.com/warmbreeze/sharded-jedis-sentinel-pool
一、ShardedJedisSentinelPool實現分析
1.建構函式

public ShardedJedisSentinelPool(final GenericObjectPoolConfig poolConfig, List<String> masters, Set<String> sentinels) 
類似之前的Jedis Pool的構造方法,需要引數poolConfig提供諸如maxIdle,maxTotal之類的配置,masters是一個List,用來儲存所有分片Master在Sentinel中配置的名字(注意master的順序不能改變,因為Shard演算法是依據分片位置進行計算,如果順序錯誤將導致資料儲存混亂),sentinels是一個Set,其中存放所有Sentinel的地址(格式:IP:PORT,如127.0.0.1:26379),順序無關;
2.初始化連線池
在建構函式中,通過方法
private List<HostAndPort> initSentinels(Set<String> sentinels, final List<String> masters) 
取得當前所有分片的master地址(IP&PORT),對每個分片,通過順次連線Sentinel例項,獲取該分片的master地址,如果無法獲得,即所有Sentinel都無法連線,將休眠1秒後繼續重試,直到取得所有分片的master地址,程式碼塊如下: 
  1. for (String masterName : masters) {  
  2.             HostAndPort master = null;  
  3.             boolean fetched = false;  
  4.             while (!fetched && sentinelRetry < MAX_RETRY_SENTINEL) {  
  5.                 for (String sentinel : sentinels) {  
  6.                     final HostAndPort hap = toHostAndPort(Arrays.asList(sentinel.split(":")));  
  7.                     log.fine("Connecting to Sentinel " + hap);  
  8.                     try {  
  9.                         Jedis jedis = new Jedis(hap.getHost(), hap.getPort());  
  10.                         master = masterMap.get(masterName);  
  11.                         if (master == null) {  
  12.                             List<String> hostAndPort = jedis.sentinelGetMasterAddrByName(masterName);  
  13.                             if (hostAndPort != null && hostAndPort.size() > 0) {  
  14.                                 master = toHostAndPort(hostAndPort);  
  15.                                 log.fine("Found Redis master at " + master);  
  16.                                 shardMasters.add(master);  
  17.                                 masterMap.put(masterName, master);  
  18.                                 fetched = true;  
  19.                                 jedis.disconnect();  
  20.                                 break;  
  21.                             }  
  22.                         }  
  23.                     } 

    相關推薦

    Redis Sentinel可用叢集Java客戶

    java客戶端Jedis在2.2.2及以上版本實現了對Sentinel的支援,只要是通過命令:redis-cli -h 192.168.110.71 -p 6000  sentinel get-master-addr-by-name shard_a1) "192.168.11

    Redis Sentinel 可用叢集搭建(redis4.0)

    前言 什麼是哨兵 Redis Sentinel出生於2012年,Redis 2.4穩定後首次釋出,它是一個旨在管理Redis叢集的系統。 哨兵的任務 監控(Monitoring):Sentinel會不斷地檢查你的主伺服器和從伺服器是否運作正常 提醒

    SDR(spring.data.redis)與Sentinel可用叢集Redis客戶Jedis配置

    依賴 <dependency> <groupId>junit</groupId> <artifactId>junit<

    Redis叢集 Java客戶Jedis的使用

    Java客戶端Jedis  這裡只講Jedis常規用法和五種資料結構的方法(關於叢集的搭建以後再寫)      2.稍微修飾下    3.執行效果 4.相應的jar包(第一個不相容,沒用,junit4.4:@test 做測試所需) 二,redis資料型別(

    Redis Cluster可用叢集線上遷移操作記錄【轉】

    之前介紹了redis cluster的結構及高可用叢集部署過程,今天這裡簡單說下redis叢集的遷移。由於之前的redis cluster叢集環境部署的伺服器效能有限,需要遷移到高配置的伺服器上。考慮到是線上生產環境,決定線上遷移,遷移過程,不中斷服務。操作過程如下: 一、機器環境

    企業級Redis開發運維從入門到實踐 (25)— Redis Sentinel(哨兵)的客戶連線

    客戶端連線 請求響應流程 既然已經實現高可用為什麼不直接直連? 高可用涉及的是服務高可用、完成自動的故障轉移;故障轉移後客戶端無法感知將無法保證正常的使用。 需要保證的是服務高可用 和 客戶端高可用。

    輕鬆搭建Redis快取可用叢集

    1、Redis叢集方案比較哨兵模式在redis3.0以前的版本要實現叢集一般是藉助哨兵sentinel工具來監控master節點的狀態,如果master節點異常,則會做主從切換,將某一臺slave作為master,哨兵的配置略微複雜,並且效能和高可用性等各方面表現一般,特別是

    redis sentinel 可用(HA)方案部署,及python應用示例

    簡介 介紹 redis sentinel(哨兵)叢集的部署,配置一主兩從的redis叢集,並通過 python 程式例項講解通過 redis sentinel 訪問叢集 什麼是哨兵(Sentinel)模式 Redis sentinel 為 Redis 叢集提供了高可

    Redis建立可用叢集教程【Windows環境】

    在這個網際網路時代,在高併發和高流量可能隨時爆發的情況下,單機版的系統或者單機版的應用已經無法生存,越來越多的應用開始支援叢集,支援分散式部署了。而Redis作為快取伺服器的比較出色的一員,它在出生的時候就被設定支援叢集,本篇就是介紹Redis叢集的介紹和搭建過程!使用的

    【Linux(CentOS7)下應用的安裝部署】:八、搭建Redis+sentinel可用服務

    Step 1:Redis的下載安裝 官網下載redis 解壓並安裝: [[email protected] ~]# cd /home/ [[email protected] home]# wget http://download.redis.io/r

    Redis|Sentinel 可用架構

    一 前言 Redis-Sentinel是Redis官方推薦的高可用性(HA)解決方案,當用Redis做Master-slave的高可用方案時,假如master宕機了,Redis本身(包括它的很多客戶端)都沒有實現自動進行主備切換,而Redis-sentinel本身也是一個獨立執行的程序,它能監控多個maste

    (六)javaredis可用java連線哨兵sentinel原理

    先來看下java連線redis主從結構圖: redis主從 需要在java中指定讀和寫redis源,而且是固定的,當主節點宕機之後,整個redis將不能使用,有明顯的單點問題。 使用sentinel哨兵之後為: Senti

    基於Sentinel(哨兵)搭建實現Redis可用叢集

    概述 Redis哨兵為Redis提供了高可用性。實際上這意味著你可以使用哨兵模式建立一個可以不用人為干預而應對各種故障的Redis部署。 哨兵模式還提供了其他的附加功能,如監控,通知,為客戶端提供配置。 下面是在巨集觀層面上哨兵模式的功能列表: 監控:哨兵不斷的檢查mast

    Redis可用叢集-哨兵模式(Redis-Sentinel)搭建配置教程【Windows環境】

    No cross,no crown . 不經歷風雨,怎麼見彩虹。 Redis哨兵模式,用現在流行的話可以說就是一個“哨兵機器人”,給“哨兵機器人”進行相應的配置之後,這個”機器人”可以7*24小時工作,它能能夠自動幫助你做一些事情,如監控,提醒,自動處

    Redis 可用叢集管理工具Sentinel

    Sentinel是一個管理redis例項的工具,它可以實現對redis的監控、通知、自動故障轉移。sentinel不斷的檢測redis例項是否可以正常工作,通過API向其他程式報告redis的狀態,如果redis master不能工作,則會自動啟動故障轉移程序,將其中的一個

    採用 redis主從 + 哨兵(sentinel) + vip漂移搭建一套redis可用叢集

    一、單個例項 當系統中只有一臺redis執行時,一旦該redis掛了,會導致整個系統無法執行。 單個例項 二、備份 由於單臺redis出現單點故障,就會導致整個系統不可用,所以想到的辦法自然就是備份(一般工業界認為比較安全的備份數應該是3份)。當一臺redis出現問題了,另一臺

    基於SentinelJava客戶操作Redis

    在上篇文章中我們已經實現了Redis基於Sentinel的主從切換了,那麼我們怎麼在java程式中來使用呢,下面我就來簡單的介紹一下。 首先我們需要引入java中操作redis的jar包,我專案是使用maven控制的,因此我在pom.xml中引入 <

    java客戶Jedis操作Redis Sentinel 連線池

     pom.xml配置     <dependency>     <groupId>org.springframework.data</groupId>     <artifactId>spring-data-redis<

    【轉載】java 客戶鏈接不上redis解決方案 (jedis)

    主機 rom number table 出現 gin 現在 start http 本文出自:http://blog.csdn.net/lulidaitian/article/details/51946169 出現問題描述: 1.Could not get a resou

    Redis Sentinel安裝與部署,實現redis可用

    config pom else turn int 修改 align 表示 boot.s 前言   對於生產環境,高可用是避免不了要面對的問題,無論什麽環境、服務,只要用於生產,就需要滿足高可用;此文針對的是redis的高可用。   接下來會有系列文章,該系列是對spring