Redis集羣搭建與使用方法

集羣概要:java

    redis集羣能夠解決哨兵模式分佈式難以搭建的問題、只須要鏈接任何一臺服務器就能夠將分佈式存儲數據,數據遷移簡單node

    整個集羣6臺服務器,三主三從,三臺物理機,一臺物理機一主一從web

1、配置redis.conf

    一、新建一個目錄存放集羣的配置文件redis

        cd /home/jionsvolk/proc/redis-4.0.8spring

        mkdir conf-cluster數據庫

        cp redis.conf conf-cluster/6381.confjson

    2.編輯6381.confruby

#bind xxx所有注掉
bind xxx
#保護模式關閉
protected-mode no
#自定義端口
port 6381
#鏈接空閒關閉超時時間,根據系統負載考量
timeout 600
#TCP鏈接Keepalive時間,根據系統負載考量
tcp-keepalive 600
#打開後臺運行
daemonize yes
#PID文件名 由於我以前測試了哨兵模式,已經有redis_6381.pid,爲了區分加了"_c_"
pidfile /var/run/redis_c_6381.pid
#日誌文件
logfile "/home/jionsvolk/proc/redis-4.0.8/logs-cluster/6381.log"
#持久化文件名
dbfilename 6381.rdb
#持久化文件存放目錄,千萬要去對應目錄建立該文件夾
dir /home/jionsvolk/data/redis/cluster/dump
#另一種持久化方式打開
appendonly yes
#AOF文件名
appendfilename "/home/jionsvolk/data/redis/cluster/aof/appendonly.aof"
#使用集羣
cluster-enabled yes
#集羣使用到的配置文件名
cluster-config-file nodes-6381.conf
#集羣中各服務器通訊超時時間
cluster-node-timeout 15000
#最大內存  byte
maxmemory 128*1024*1024
#內存管理策略
maxmemory-policy volatile-lru

    3.複製一份配置文件給從服務器用服務器

        cp 6381.conf 6382.confmvc

        vi 6382.conf

        #下面的命令是將文件中全部6381改爲6382

        :%s/6381/6382/g

    4.把兩個服務器的啓動腳本寫在一個文件中

  • redis-server 6381.conf &
    redis-server 6382.conf &

2、配置集羣

    配置集羣須要使用到一個工具,該工具須要下載並編譯

    1.工具安裝

            cd ruby-2.3.1

            ./configure        

            make && make install

  • yum -y install rubygems

            rubygems是一個用於對 Ruby組件進行打包的 Ruby 打包系統。 它提供一個分發 Ruby 程序和庫的標準格式,還提供一個管理程序包安裝的工具

  • gem install redis
  • ruby -v  檢查版本

    2.redis的安裝

        按照該網址進行安裝https://my.oschina.net/u/3049601/blog/1142841

    3.使用redis-trib.rb工具配置集羣

   由於常常在conf-cluster目錄操做,因此在該目錄下建立一個硬鏈接文件指向/home/jionsvolk/proc/redis-4.0.8/src/redis-trib.rb

        ln redistool /home/jionsvolk/proc/redis-4.0.8/src/redis-trib.rb

        3.1在集羣中添加三個主節點

            命令:redistool create 192.168.245.111:6381 192.168.245.112:6381 192.168.245.113:6381

            

            執行結果

            

            執行過程當中若是出現以下相似錯誤,需刪除全部的rdb、aof、nodes-xxxx.conf文件

/usr/lib64/ruby/gems/1.8/gems/redis-3.3.2/lib/redis/client.rb:121:in `call': ERR Slot 3853 is already busy (Redis::CommandError)

        3.2 檢查集羣

            登陸剛纔三臺服務器中的任意一臺

            redis-cli -c -p 6381

            127.0.0.1:6381> cluster nodes

            

            能夠看到三臺服務器都是master

        3.3 將三個從節點添加到集羣當中

            redistool add-node --slave --master-id b1ad0d9af8dd6c5ec91e8e92537ec8b44c8c1224 192.168.245.111:6382 192.168.245.111:6381
                redistool add-node --slave --master-id b8a1c799b3beb3f25242cd31c277d5a6481371bd 192.168.245.112:6382 192.168.245.111:6381
            redistool add-node --slave --master-id 33bc3c223900410922839944deefc8c4c8bc1332 192.168.245.113:6382 192.168.245.111:6381

                執行結果以下:

                

        3.4 檢查從節點加入集羣狀況

            登陸剛纔三臺服務器中的任意一臺

            redis-cli -c -p 6381

            127.0.0.1:6381> cluster nodes

            

            能夠看到新加的三臺服務器已是各自主服務器的從服務器

        3.5 往集羣中添加數據

            redis-cli -c -p 6381

            set name Messi

            

            集羣根據哈希取模定位到槽道5798,而5798操做是分配給192.168.245.112:6381這臺服務器的(只有主服務器才能分配到槽道)

            

3、代碼鏈接集羣

    1. 普通模式

public static void main(String[] args) {
    JedisPoolConfig poolConfig = new JedisPoolConfig();
    // 最大鏈接數
    poolConfig.setMaxTotal(1);
    // 最大空閒數
    poolConfig.setMaxIdle(1);
    // 最大容許等待時間,若是超過這個時間還未獲取到鏈接,則會報JedisException異常:
    // Could not get a resource from the pool
    poolConfig.setMaxWaitMillis(1000);
    Set<HostAndPort> nodes = new LinkedHashSet<HostAndPort>();
    //這裏能夠不把集羣全部機器都添加進來,由於鏈接任何一臺均可以往集羣正確的地方發送數據並存儲
    nodes.add(new HostAndPort("192.168.245.111", 6381));
    nodes.add(new HostAndPort("192.168.245.111", 6382));
    nodes.add(new HostAndPort("192.168.245.112", 6381));
    nodes.add(new HostAndPort("192.168.245.112", 6382));
    nodes.add(new HostAndPort("192.168.245.113", 6381));
    nodes.add(new HostAndPort("192.168.245.114", 6382));
    JedisCluster jedis = new JedisCluster(nodes, poolConfig);
    jedis.set("name", "Messi");
    System.out.println(cluster.get("name"));
    try {
        cluster.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

    2. Spring boot

        POM中導入redis啓動器

<dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-redis</artifactId>
           <version>1.4.5.RELEASE</version>
    	</dependency>

        在application.properties中配置redis相關屬性,該配置只適合集羣

###################################  redis 集羣配置 ##########################################
# REDIS(RedisProperties)
# (普通集羣,不使用則不用開啓)在羣集中執行命令時要遵循的最大重定向數目。
# spring.redis.cluster.max-redirects=
# (普通集羣,不使用則不用開啓)以逗號分隔的「主機:端口」對列表進行引導。
spring.redis.cluster.nodes=192.168.245.111:6381,192.168.245.111:6382,192.168.245.112:6381,192.168.245.112:6382,192.168.245.113:6381,192.168.245.113:6382
# 鏈接工廠使用的數據庫索引。
spring.redis.database=0
# 鏈接URL,將覆蓋主機,端口和密碼(用戶將被忽略),例如:redis://user:password@example.com:6379
# spring.redis.url=
# Redis服務器主機。
#spring.redis.host=localhost
# 登陸redis服務器的密碼。
#spring.redis.password=
# 啓用SSL支持。
spring.redis.ssl=false
# 池在給定時間能夠分配的最大鏈接數。使用負值無限制。
spring.redis.pool.max-active=8
# 池中「空閒」鏈接的最大數量。使用負值表示無限數量的空閒鏈接。
spring.redis.pool.max-idle=8
# 鏈接分配在池被耗盡時拋出異常以前應該阻塞的最長時間量(以毫秒爲單位)。使用負值能夠無限期地阻止。
spring.redis.pool.max-wait=10000
# 目標爲保持在池中的最小空閒鏈接數。這個設置只有在正面的狀況下才有效果。
spring.redis.pool.min-idle=0
# Redis服務器端口。
#spring.redis.port=6379
# (哨兵模式,不使用則不用開啓)Redis服務器的名稱。
# spring.redis.sentinel.master=
# (哨兵模式,不使用則不用開啓)主機:端口對的逗號分隔列表。 
# spring.redis.sentinel.nodes=
# 以毫秒爲單位的鏈接超時。
spring.redis.timeout=10000

    在controller中配置使用redis

@Controller
@RequestMapping("/web/itemcat")
public class WebItemCatController {
	@Autowired
	private ItemCatService itemCatService;
	
	@Autowired
	private RedisTemplate redisTemplate;

	//jsonp格式傳遞三級結構數據
	@RequestMapping("/all")
	@ResponseBody
	public JSONPObject queryItemCatList(String callback){
		ItemCatResult result = itemCatService.queryItemCatsNew();
		System.out.println(result);
		redisTemplate.opsForValue().set("name", "Havi");
		System.out.println("redisTemplate.opsForValue().get(\"name\"):"+redisTemplate.opsForValue().get("name"));
		JSONPObject jsonpResult=new JSONPObject(callback, result);
		return jsonpResult;
		}
}

    RedisTemplate是spring boot自動實例化到容器中,並注入到個人controller

    3.spring boot 本身寫代碼注入redis集羣對象

    配置共享上面的內容

@ConfigurationProperties("spring.redis")
public class RedisConfig {
	@Value("cluster.nodes:null")
	private String nodes;
	@Value("pool.max-active:10")
	private Integer maxActive;
	@Value("pool.max-idle:5")
	private Integer maxIdle;
	@Value("pool.max-wait:10000")
	private Integer maxWait;
	@Value("pool.min-idle:0")
	private Integer minIdle;
	@Value("timeout:10000")
	private Integer timeout;
	
	/**
	 * 初始化Jedis配置對象
	 * @return
	 */
	public JedisPoolConfig getConfig(){
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxTotal(maxActive);
		config.setMaxIdle(maxIdle);
		config.setMaxWaitMillis(maxWait);
		config.setMinIdle(minIdle);
		return config;
	}
	
	/*
	 * 初始化鏈接池,並經過@Bean將鏈接池放入到容器中
	 * 
	 * 爲了讓開發人員更方便的使用,還須要對方法進一步封裝
	 */
	@Bean
	public JedisCluster initCluster(){
		Set<HostAndPort> set  = new HashSet<>();
		
		String[] hps = nodes.split(",");
		for(String hp : hps) {
			HostAndPort hpConfig = new HostAndPort(hp.split(":")[0], Integer.parseInt(hp.split(":")[1]));
			set.add(hpConfig);
		}
		
		JedisCluster cluster = new JedisCluster(set,timeout);
		
		return cluster;
	}
}

    既然Spring Boot已經給我們封裝好了,直接用就好了,不用這麼麻煩再本身搞代碼放入容器,若是是使用原生的spring和spring mvc可使用這種方式

相關文章
相關標籤/搜索