1. 程式人生 > >Redis叢集環境搭建(筆記)

Redis叢集環境搭建(筆記)

一、序言

之前文章 http://blog.csdn.net/strburnchang/article/details/78634226 介紹了redis單機版服務搭建過程。

這次是來學習叢集版redis搭建及其使用。因硬體條件限制,僅在一臺伺服器做demo

二、Redis單機版搭建過程

三、Redis叢集版搭建過程。

1、Redis叢集架構圖,


架構細節:

(1)所有的redis節點彼此互聯(PING-PONG機制),內部使用二進位制協議優化傳輸速度和頻寬.

(2)節點的fail是通過叢集中超過半數的節點檢測失效時才生效.

(3)客戶端與redis節點直連,不需要中間proxy.客戶端不需要連線叢集所有節點,連線叢集中任何一個可用節點即可

(4)redis-cluster把所有的物理節點對映到[0-16383]slot,cluster 負責維護node<->slot<->value

注:

Redis 叢集中內建了 16384 個雜湊槽,當需要在 Redis 叢集中放置一個 key-value 時,redis 先對 key 使用 crc16 演算法算出一個結果,然後把結果對 16384 求餘數,這樣每個 key 都會對應一個編號在 0-16383 之間的雜湊槽,redis 會根據節點數量大致均等的將雜湊槽對映到不同的節點

2、叢集搭建

叢集中應該至少有三個節點,每個節點有一備份節點。需要6臺伺服器。搭建偽分散式,需要

6redis例項。

(因環境限制,僅是在同一臺伺服器上使用6個不同埠啟動redis個例項,3個作為主節點,3個作為備用節點)

(1)搭建步驟

A、建立6個redis例項並指定埠(7001-7006)

在redis目錄下建立 redis-cluster目錄

cd /usr/local/redis/;mkdir redis-cluster


將redis原始碼複製6份放到redis-cluster目錄下


B、修改redis配置檔案(六個都需要改)

vi ./redis01/etc/redis.conf

將cluster-enable yes註釋開啟

然後修改對應埠 port  7001(其他依次為 7002 ...)

C、安裝ruby環境(因為叢集執行需要一個ruby指令碼)

1yum install ruby

2、安裝redis叢集需要的包

gem install redis -v 3.3.3  

[[email protected] /usr/local/redis]#gem install redis -v 3.3.3
Fetching: redis-3.3.3.gem (100%)
Successfully installed redis-3.3.3
Parsing documentation for redis-3.3.3
Installing ri documentation for redis-3.3.3
1 gem installed

D、寫一個shell指令碼用來啟動redis叢集所有服務

vim start-all.sh

#!/bin/bash
clusterpath="/usr/local/redis/redis-cluster/"
cd $clusterpath
redis_arr=(01 02 03 04 05 06)
for num in ${redis_arr[@]}
do
    echo "start ${num}nth redis server..."
    cd redis${num}/bin/
    redis-server ../etc/redis.conf
    cd ..
    cd ..
done

chmod +x start-all.sh

啟動所有rediss例項

./start-all.sh


E、使用redis-trib.rb建立叢集

命令 

./redis-trib.rb create --replicas 1 192.168.1.102:7001 192.168.1.102:7002 192.168.1.102:7003 192.168.1.102:7004 192.168.1.102:7005  192.168.1.102:7006

發現這個命令會出錯。說我沒有許可權。然後給前面加了ruby 表明是ruby指令碼。

ruby ./redis-trib.rb create --replicas 1 192.168.1.102:7001 192.168.1.102:7002 192.168.1.102:7003 192.168.1.102:7004 192.168.1.102:7005  192.168.1.102:7006

這個也出錯,說不能連線到7001節點。百度了下,是因為redis配置檔案中已經打開了認證功能(密碼),所以挨著關閉了。


更改配置檔案之後,再重新啟動節點 

./start-all.sh
ruby ./redis-trib.rb create --replicas 1 192.168.1.102:7001 192.168.1.102:7002 192.168.1.102:7003 192.168.1.102:7004 192.168.1.102:7005  192.168.1.102:7006

成功


F、建立cluster過程可能會遇到一些問題:

參考:http://www.2bowl.info/centos7%E4%B8%8A%E6%90%AD%E5%BB%BAredis-cluster/

1)、>>> Creating cluster

[ERR] Node 192.168.1.102:7001 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

解決方法:

刪除每個節點下的dump.rdb檔案

或挨個進行flushdb

redis-cli -h 192.168.1.102 -p 6390 
flushdb

2)、/usr/local/share/gems/gems/redis-3.3.3/lib/redis/client.rb:121:in call': ERR Slot 741 is already busy (Redis::CommandError)
from /usr/local/share/gems/gems/redis-3.3.3/lib/redis.rb:2705:in
block in method_missing’
from /usr/local/share/gems/gems/redis-3.3.3/lib/redis.rb:58:in block in synchronize'
from /usr/share/ruby/monitor.rb:211:in
mon_synchronize’
from /usr/local/share/gems/gems/redis-3.3.3/lib/redis.rb:58:in synchronize'
from /usr/local/share/gems/gems/redis-3.3.3/lib/redis.rb:2704:in
method_missing’
from ./redis-trib.rb:212:in flush_node_config'
from ./redis-trib.rb:776:in
block in flush_nodes_config’
from ./redis-trib.rb:775:in each'
from ./redis-trib.rb:775:in
flush_nodes_config’
from ./redis-trib.rb:1296:in create_cluster_cmd'
from ./redis-trib.rb:1701:in


解決方法:由於上一次的配置不正確導致的,重新刪除節點中node.conf檔案,重啟節點即可

四、使用redis的java客戶端jedis

1、新增maven依賴

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>

2、建立測試類

package com.gs.redis;

import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

import java.util.HashSet;
import java.util.Set;

public class TestRedis {

    private final String REDIS_HOST = "192.168.1.102";

    @Test
    public void testJedisCluster() throws Exception {
        //建立一個JedisCluster物件
        Set<HostAndPort> nodes = new HashSet<HostAndPort>();
        nodes.add(new HostAndPort(REDIS_HOST, 7001));
        nodes.add(new HostAndPort(REDIS_HOST, 7002));
        nodes.add(new HostAndPort(REDIS_HOST, 7003));
        nodes.add(new HostAndPort(REDIS_HOST, 7004));
        nodes.add(new HostAndPort(REDIS_HOST, 7005));
        nodes.add(new HostAndPort(REDIS_HOST, 7006));
        //在nodes中指定每個節點的地址
        //jedisCluster在系統中是單例的。
        JedisCluster jedisCluster = new JedisCluster(nodes);
        jedisCluster.set("name", "zhangsan");
        jedisCluster.set("value", "100");
        String name = jedisCluster.get("name");
        String value = jedisCluster.get("value");
        System.out.println(name);
        System.out.println(value);


        //系統關閉時關閉jedisCluster
        jedisCluster.close();
    }

}

到此,redis叢集搭建完成。後面會再記錄redis整合spring(單機版和叢集版本)