redis缓存(集群)

redis集群搭建

1.安装redis(windows版)

Redis官方是不支持windows的,但是 Microsoft Open Tech group 在 GitHub上开发了一个Win64的版本

项目地址:https://github.com/MSOpenTech/redis

进入后点击releases,选择合适的版本下载,本例子中下载了Redis-x64-3.2.100.zip

将压缩包解压6份放到自己建立的cluster-test文件夹下,并分别取名为7000,7001,7002,7003,7004,7005,本例子中cluster-test放在E盘下

03

因为要让集群正常运作至少需要三个主节点,因此我们创建6个节点,三个主节点三个从节点

2.配置redis

将每个redis文件夹下的redis.windows.conf文件对应位置做如下修改

port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

注意端口号port需要和每个redis端口号对应

参数说明

cluster-enabled 选项用于打开实例的集群模式,

cluster-conf-file 选项则设定了保存节点配置文件的路径, 默认值为nodes.conf 。

nodes.conf 节点配置文件无须人为修改, 它由 Redis 集群在启动时创建, 并在有需要时自动进行更新。

3.创建启动脚本

在redis文件夹下创建7000.bat用于快速启动redis服务器

@echo off
redis-server.exe redis.windows.conf
@pause

其他redis同理

4.准备ruby环境

下载 Ruby 2.4.1-2 (x64)并安装 地址http://rubyinstaller.org/downloads/

5.安装RubyGems

下载rubygems-2.5.1.zip解压,运行里面的setup.rb

因为ruby自带的源很慢,这里切换源

在cmd下运行

gem sources –remove https://rubygems.org/删掉原来的源

gem sources -a https://gems.ruby-china.org/ 添加新的源

gem sources -l 查看现有的源
gem install redis 安装redis依赖

6.创建集群

启动6个redis服务器

https://github.com/antirez/redisunstable 分支中取出最新的 Redis 源码,即点击branches后,点击unstable,点击Clone or download进行下载redis-unstable.zip

解压缩后在命令行中进入解压后的文件夹其中的src文件夹执行

redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

06

打印出配置信息,意思是现在的master是 7000 7001 7002这三台机,redis会对key 做 CRC16 校验和后分别存储这三台机上。没问题就输入 yes。

配置说明

7000端口 分配了 slots:0-5460 的意思是:

对key 做 CRC16 校验和后,值在 0-5460范围内都会存到这台机器里
例如 key=288 对应的CRC16校验和 为 4258,应该存在7000这台机里

PS:使用前应该对业务做梳理,根据系统中key的特点来调整各个机器的slots范围,
不然系统的key基本集中在一两台机器上集群的效果就不大了

参数说明

redis-trib.rb
create, 这表示我们希望创建一个新的集群。
选项 –replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。
之后跟着的其他参数则是实例的地址列表, 我们希望程序使用这些地址所指示的实例来创建新集群。

创建了一个包含三个主节点和三个从节点的集群。

7.利用Jedis(纯java)使用集群

Redis Cluster 缺少客户端库实现。这里采用 Jedis Cluster 进行实现

7.1 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.yztc</groupId>
    <artifactId>JedisImplForRedisCluster_java</artifactId>
    <version>1.0-SNAPSHOT</version>
<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
        <version>2.4.2</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.7.3</version>
    </dependency>
</dependencies>
</project>

7.2 测试类

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

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

public class TestCluster {
    @Test
    public  void cluster(){
        String key = "1417";
        Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
        jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7000));
        JedisCluster jc = new JedisCluster(jedisClusterNodes);

        jc.setnx(key, "bar");
        String value = jc.get(key);
        System.out.println("key-"+key+" slot-"+ JedisClusterCRC16.getSlot(key)+" value-"+value);

        String key2 = "288";
        jc.setnx(key2, "bar2");
        String value2 = jc.get(key);
        System.out.println("key-"+key2+" slot-"+JedisClusterCRC16.getSlot(key2)+" value-"+value2);
    }
}

Jedis Cluster 会自动去发现集群中的节点,所以JedisClusterNodes只需要 add一个实例

输出结果如下

01

key=288算出来的 CRC16校验和是 4258,根据配置 应该存在 7000这台机上
key=1417 算出来的 CRC16校验和是 13096,根据配置 应该存在 7002 这台机上

用redis客户端查看数据存到哪台机器上

在命令行进入任意一个redis的文件夹下输入redis-cli.exe -c -p 7000

04

8.spring+Jedis使用集群

8.1 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.yztc</groupId>
    <artifactId>JredisImplForRedisCluster_spring</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <finalName>springmvc_redis</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>
                4.12
            </version>
        </dependency>
        <!--集成spring环境-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.40</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <!--集成spring对redis的支持-->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>1.8.3.RELEASE</version>
        </dependency>
        <!-- Redis客户端 -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
        <!--对原生api的支持-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <!--需要用到jsp对应标签-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!--日志包-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.24</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.4.2</version>
        </dependency>
    </dependencies>

</project>

8.2 redis.properties

#redis config
redis.host=127.0.0.1
redis.port=7000
redis.timeout=100000
redis.maxIdle=300
redis.maxTotal=600 
redis.timeBetweenEvictionRunsMillis=30000  
redis.minEvictableIdleTimeMillis=30000 
redis.testOnBorrow=true

8.3 applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <context:property-placeholder location="classpath:redis.properties"/>
    <!--==================== redis配置 start ====================-->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal"  value="${redis.maxTotal}" />
        <property name="maxIdle" value="${redis.maxIdle}" />
        <property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}" />
        <property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}" />
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />
    </bean>

    <bean id="jedisClusterFactory" class="com.redis.cluster.util.JedisClusterFactory" >
        <constructor-arg  ref ="jedisPoolConfig"/>
        <constructor-arg  name="host" value="${redis.host}"/>
        <constructor-arg  name="port" value="${redis.port}"/>
    </bean>

    <bean id="redisProvide" class="com.redis.cluster.util.RedisProvide">
        <constructor-arg  ref ="jedisClusterFactory" />
    </bean>

    <!--==================== redis配置 end ====================-->

</beans>

8.4 JedisClusterFactory类

传入host 、port 和JedisPoolConfig 类

package com.redis.cluster.util;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

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


public class JedisClusterFactory {


    private JedisCluster jedisCluster;

    public JedisCluster getJedisCluster() {
        return jedisCluster;
    }

    public JedisClusterFactory(JedisPoolConfig jedisPoolConfig, String host, int port){
        Set<HostAndPort> jedisClusterNodes= new HashSet<HostAndPort>();
        //Jedis Cluster will attempt to discover cluster nodes automatically
        jedisClusterNodes.add(new HostAndPort(host,port));
        jedisCluster=new JedisCluster(jedisClusterNodes,jedisPoolConfig);
    }
}

8.5 CacheSecondLevel接口

package com.redis.cluster.util;

public interface CacheSecondLevel {
    public Object get(String key);

    public Object[] gets(String[] keys);

    public void set(String key, Object obj);

    public void delete(String key);
}

8.6 RedisProvide类

工具类,主要是封装些常用的操作

package com.redis.cluster.util;

import redis.clients.jedis.JedisCluster;

public class RedisProvide implements CacheSecondLevel{
    private JedisCluster jedisCluster;

    public RedisProvide(JedisClusterFactory jedisClusterFactory){
        jedisCluster=jedisClusterFactory.getJedisCluster();
    }

    @Override
    public Object get(String key){
        return jedisCluster.get(key);
    }

    @Override
    public Object[] gets(String[] keys) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void set(String key, Object obj) {
        // TODO Auto-generated method stub
        jedisCluster.set(key, obj.toString());
    }

    @Override
    public void delete(String key) {
        // TODO Auto-generated method stub
        jedisCluster.del(key);
    }
}

8.7 测试类

import com.redis.cluster.util.RedisProvide;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class TestCluster {

    @Autowired
    private RedisProvide provide;

    @Test
    public void test1() {
        provide.set("student", "zhangsan");
        provide.set("customer", "zhaosi");
        System.out.println(provide.get("student"));
        System.out.println(provide.get("customer"));
    }
}

输出结果

02

用redis客户端查看数据存到哪台机器上

05

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值