Redis概念和集群搭建

一、redis的安装

redis是一个key-value的缓存工具,3.0后的版本可以搭建集群,作用强大,像新浪微博就在用redis做缓存,下面介绍redis3.0的安装步骤:
1、下载redis的源码包

wget http://download.redis.io/releases/redis-3.2.3.tar.gz

2、解压源码包

tar -zxvf redis-3.2.3.tar.gz

3、安装

cd redis-3.2.3
make
make install PREFIX=/usr/local/redis

表示把redis安装在/usr/local/redis路径下

4、启动redis
(1)前端启动模式(一般不用)

cd /usr/local/redis/bin
./redis-server

(1)后端启动模式(推荐)

  1. 从redis的源码目录(redis3.2.3)中复制redis.conf到redis的安装目录(/usr/local/redis/bin)
  2. 修改配置文件 daemonize 改为yes
  3. 后端启动redis
    ./redis-server redis.conf
  4. 查看redis的运行端口
    ps aux|grep redis

redis默认是运行在6379端口,如果查看到6379端口是redis占用,则说明redis启动成功

二、redis的常用命令和数据结构

常用数据类型

String
Hash
List
Set
SortedSet

Redis常用命令

首先进入redis的端口命令:

cd /usr/local/redis/bin
./redis-cli

在redis端口上执行命令:

127.0.0.1:6379> set a 10 设置一个key
OK
127.0.0.1:6379> get a 获取一个key
“10”
127.0.0.1:6379> incr a 自增
127.0.0.1:6379> decr a 自减
127.0.0.1:6379> del a 删除一个key
127.0.0.1:6379> keys * 获取所有key
127.0.0.1:6379> expire key 1000 设置key的过期时间为1000
127.0.0.1:6379> ttl key 查看key的过期时间

三、Redis集群概念和搭建

1. redis-cluster架构图

这里写图片描述

redis-cluster把所有的物理节点映射到 [0-16383] slot(槽)上,cluster 负责维护node<->slot<->value

Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点

例如:

这里写图片描述

上图中把槽分在了四个redis-server上,对于下面两个值:

Key:a
使用上面所说的算法,计算a的hash值,例如值为100,100这个槽在server1上,所以a应该放到server1.

Key:hello
Hash值:10032,此槽在server2上。Hello应该存在server2

服务器性能比较好的Server,可以分配多一点的槽,用于存放更多的key

2. redis-cluster投票:容错

这里写图片描述

(1)领着投票过程
集群中所有master参与,如果半数以上master节点与master节点通信超过(cluster-node-timeout),认为当前master节点挂掉

(2)什么时候整个集群不可用(cluster_state:fail)?

  1. 如果集群任意master挂掉,且当前master没有slave(备份集群).集群进入fail状态,也可以理解成集群的slot映射[0-16383]不完成时进入fail状态. ps : redis-3.0.0.rc1加入cluster-require-full-coverage参数,默认关闭,打开集群兼容部分失败.

  2. 如果集群超过半数以上master挂掉,无论是否有slave集群进入fail状态.
    ps:当集群不可用时,所有对集群的操作做都不可用,收到((error) CLUSTERDOWN The cluster is down)错误

3. 搭建redis集群

1. 安装ruby

yum install ruby
yum install rubygems

这里写图片描述

在源码包内,redis-trib.rb是redis集群管理工具

2. 安装redis-ruby接口

gem install redis-3.0.0.gem

3. 集群搭建(搭建6个实例的redis集群)

第一步:创建6个redis实例,端口号从7001~7006

  1. 把usr/local中创建目录redis-cluster
  2. 把usr/local/redis下的bin拷贝到redis-cluster中的redis01中
  3. 在redis-cluster复制redis01 5份,分别为01,02,03,04,05,06
    这里写图片描述

第二步:修改redis01-redis06的redis.conf配置文件

  1. 修改端口号
    redis01:7001
    redis02:7002
    redis03:7003
    redis04:7004
    redis05:7005
    redis06:7006
    这里写图片描述

  2. 打开cluster-enable前面的注释(vim中,可以通过底线模式/cluster-enable搜索)
    这里写图片描述

第三步:把创建集群的ruby脚本redis-trib.rb复制到redis-cluster目录下

这里写图片描述

第四步:启动6个redis实例
创建startall.sh文件,执行文件,一次性打开全部redis

这里写图片描述

可以看到:7001-7006的redis实例都打开了

第五步:创建集群
[root@localhost redis-cluster]# ./redis-trib.rb create –replicas 1 192.168.172.129:7001 192.168.172.129:7002 192.168.172.129:7003 192.168.172.129:7004 192.168.172.129:7005 192.168.172.129:7006

创建过程的日志:

[root@localhost redis-cluster]# ./redis-trib.rb create –replicas 1 192.168.172.129:7001 192.168.172.129:7002 192.168.172.129:7003 192.168.172.129:7004 192.168.172.129:7005 192.168.172.129:7006

Creating cluster
Connecting to node 192.168.172.129:7001: OK
Connecting to node 192.168.172.129:7002: OK
Connecting to node 192.168.172.129:7003: OK
Connecting to node 192.168.172.129:7004: OK
Connecting to node 192.168.172.129:7005: OK
Connecting to node 192.168.172.129:7006: OK
Performing hash slots allocation on 6 nodes…
Using 3 masters:
192.168.172.129:7001
192.168.172.129:7002
192.168.172.129:7003
Adding replica 192.168.172.129:7004 to 192.168.172.129:7001
Adding replica 192.168.172.129:7005 to 192.168.172.129:7002
Adding replica 192.168.172.129:7006 to 192.168.172.129:7003
M: 7173445e703f00577bdcf09ab84aff73f289afcc 192.168.172.129:7001
slots:0-5460 (5461 slots) master
M: 4a838fbc3ec9def285d9e0984f4530ce1d27d31f 192.168.172.129:7002
slots:5461-10922 (5462 slots) master
M: e805eaee8324884cbc32bd31442ef890fc8000f0 192.168.172.129:7003
slots:10923-16383 (5461 slots) master
S: 14c27ed8835602c1cf77c548ae0847c85ca35b79 192.168.172.129:7004
replicates 7173445e703f00577bdcf09ab84aff73f289afcc
S: 0c8604f4ac89d0f783d7e6a01d88f00e17c2a733 192.168.172.129:7005
replicates 4a838fbc3ec9def285d9e0984f4530ce1d27d31f
S: dc8b4155a067c23f1b5269bdf269fd19f42bdc61 192.168.172.129:7006
replicates e805eaee8324884cbc32bd31442ef890fc8000f0
Can I set the above configuration? (type ‘yes’ to accept): yes
Nodes configuration updated
Assign a different config epoch to each node
Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join…..
Performing Cluster Check (using node 192.168.172.129:7001)
M: 7173445e703f00577bdcf09ab84aff73f289afcc 192.168.172.129:7001
slots:0-5460 (5461 slots) master
M: 4a838fbc3ec9def285d9e0984f4530ce1d27d31f 192.168.172.129:7002
slots:5461-10922 (5462 slots) master
M: e805eaee8324884cbc32bd31442ef890fc8000f0 192.168.172.129:7003
slots:10923-16383 (5461 slots) master
M: 14c27ed8835602c1cf77c548ae0847c85ca35b79 192.168.172.129:7004
slots: (0 slots) master
replicates 7173445e703f00577bdcf09ab84aff73f289afcc
M: 0c8604f4ac89d0f783d7e6a01d88f00e17c2a733 192.168.172.129:7005
slots: (0 slots) master
replicates 4a838fbc3ec9def285d9e0984f4530ce1d27d31f
M: dc8b4155a067c23f1b5269bdf269fd19f42bdc61 192.168.172.129:7006
slots: (0 slots) master
replicates e805eaee8324884cbc32bd31442ef890fc8000f0
[OK] All nodes agree about slots configuration.
Check for open slots…
Check slots coverage…
[OK] All 16384 slots covered.

到这个时候,集群就已经搭建完成

4. 测试集群

redis01/redis-cli -h 192.168.172.129 -p 7001 –c (-c代表使用集群,一定要带上)

这里写图片描述

从上图看到,进入7001端口的redis,设置一个值a = 100,然而取该值得时候是从7003取出,这是由redis集群做的事情

5. 关闭集群

./redis-cli -p 7001 shutdown
./redis-cli -p 7002 shutdown
./redis-cli -p 7003 shutdown
./redis-cli -p 7004 shutdown
./redis-cli -p 7005 shutdown
./redis-cli -p 7006 shutdown

四、用Redis Desktop Manager连接redis

刚开始连接时,无法连接
这里写图片描述
这是我第一时间想到,CentOS默认开启防火墙,可能是端口没打开,所以导致链接不上,于是把端口打开:

vim /etc/sysconfig/iptables

加上打开6379 和 7001:7006端口规则,或者直接关闭防火墙:

service iptables stop

然而关闭了防火墙,还是无法访问到该端口,这时我又想到可能是Selinux作怪,于是我连Selinux也关闭了

vim /etc/selinux/config

在 SELINUX=enforcing 前面加个#号注释掉它
然后新加一行
SELINUX=disabled

关闭了iptables和Selinux之后,这时还是无法连接到redis,这时我注意到auth身份认证问题,找了资料发现,redis是默认保护模式,只能本虚拟机访问,不允许其他ip访问,所以可以这么做:

  1. 注释redis.conf文件中的:bind 127.0.0.1(在一段文字之前打#号为注释)
  2. 在redis.conf中添加 requirepass 123,表示连接密码为123

这时便连接成功了
这里写图片描述

五、使用Jedis操作Redis

使用的是jedis-2.7.2.jar,并通过Maven添加依赖:
这里写图片描述

1. 单机版Redis

public class TestJedis {

    @Test
    public void testJedisSingle() {
        //创建一个jedis的对象。
        Jedis jedis = new Jedis("192.168.25.153", 6379);
        //调用jedis对象的方法,方法名称和redis的命令一致。
        jedis.set("key1", "jedis test");
        String string = jedis.get("key1");
        System.out.println(string);
        //关闭jedis。
        jedis.close();
    }

    /**
     * 使用连接池
     */
    @Test
    public void testJedisPool() {
        //创建jedis连接池
        JedisPool pool = new JedisPool("192.168.172.129", 6379);
        //从连接池中获得Jedis对象
        Jedis jedis = pool.getResource();
        String string = jedis.get("key1");
        System.out.println(string);
        //关闭jedis对象
        jedis.close();
        pool.close();
    }
}

2. 集群版Redis

public void testJedisCluster() {
        HashSet<HostAndPort> nodes = new HashSet<>();
        nodes.add(new HostAndPort("192.168.172.129", 7001));
        nodes.add(new HostAndPort("192.168.172.129", 7002));
        nodes.add(new HostAndPort("192.168.172.129", 7003));
        nodes.add(new HostAndPort("192.168.172.129", 7004));
        nodes.add(new HostAndPort("192.168.172.129", 7005));
        nodes.add(new HostAndPort("192.168.172.129", 7006));

        JedisCluster cluster = new JedisCluster(nodes);

        cluster.set("key1", "1000");
        String string = cluster.get("key1");
        System.out.println(string);

        cluster.close();
    }

六、Spring整合Redis

1. 单机版整合

<!-- 连接池配置 -->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!-- 最大连接数 -->
        <property name="maxTotal" value="30" />
        <!-- 最大空闲连接数 -->
        <property name="maxIdle" value="10" />
        <!-- 每次释放连接的最大数目 -->
        <property name="numTestsPerEvictionRun" value="1024" />
        <!-- 释放连接的扫描间隔(毫秒) -->
        <property name="timeBetweenEvictionRunsMillis" value="30000" />
        <!-- 连接最小空闲时间 -->
        <property name="minEvictableIdleTimeMillis" value="1800000" />
        <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
        <property name="softMinEvictableIdleTimeMillis" value="10000" />
        <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
        <property name="maxWaitMillis" value="1500" />
        <!-- 在获取连接的时候检查有效性, 默认false -->
        <property name="testOnBorrow" value="true" />
        <!-- 在空闲时检查有效性, 默认false -->
        <property name="testWhileIdle" value="true" />
        <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
        <property name="blockWhenExhausted" value="false" />
    </bean> 
    <!-- jedis客户端单机版 -->
    <bean id="redisClient" class="redis.clients.jedis.JedisPool">
        <constructor-arg name="host" value="192.168.172.129"></constructor-arg>
        <constructor-arg name="port" value="6379"></constructor-arg>
        <constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg>
    </bean>

2. 集群版整合

<!-- 连接池配置 -->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!-- 最大连接数 -->
        <property name="maxTotal" value="30" />
        <!-- 最大空闲连接数 -->
        <property name="maxIdle" value="10" />
        <!-- 每次释放连接的最大数目 -->
        <property name="numTestsPerEvictionRun" value="1024" />
        <!-- 释放连接的扫描间隔(毫秒) -->
        <property name="timeBetweenEvictionRunsMillis" value="30000" />
        <!-- 连接最小空闲时间 -->
        <property name="minEvictableIdleTimeMillis" value="1800000" />
        <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
        <property name="softMinEvictableIdleTimeMillis" value="10000" />
        <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
        <property name="maxWaitMillis" value="1500" />
        <!-- 在获取连接的时候检查有效性, 默认false -->
        <property name="testOnBorrow" value="true" />
        <!-- 在空闲时检查有效性, 默认false -->
        <property name="testWhileIdle" value="true" />
        <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
        <property name="blockWhenExhausted" value="false" />
    </bean> 

<bean id="redisCluster" class="redis.clients.jedis.JedisCluster">
        <constructor-arg name="nodes">
            <set>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.172.129"></constructor-arg>
                    <constructor-arg name="port" value="7001"></constructor-arg>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.172.129"></constructor-arg>
                    <constructor-arg name="port" value="7002"></constructor-arg>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.172.129"></constructor-arg>
                    <constructor-arg name="port" value="7003"></constructor-arg>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.172.129"></constructor-arg>
                    <constructor-arg name="port" value="7004"></constructor-arg>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.172.129"></constructor-arg>
                    <constructor-arg name="port" value="7005"></constructor-arg>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.172.129"></constructor-arg>
                    <constructor-arg name="port" value="7006"></constructor-arg>
                </bean>
            </set>
        </constructor-arg>
        <constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg>
    </bean>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值