• redis集群搭建


    一 redis的安装

    Redis是c语言开发的。
    安装redis需要c语言的编译环境。如果没有gcc需要在线安装:yum install gcc-c++

    第一步:获取源码包:wget http://download.redis.io/rele...

    第二步:解压缩redis:tar zxvf redis-3.0.0.tar.gz

    第三步:编译。进入redis源码目录(cd redis-3.0.0)。执行 make

    第四步:安装。make install PREFIX=/usr/local/redis

    PREFIX参数指定redis的安装目录。一般软件安装到/usr目录下

    这样Redis就成功装在了我们的usr/local/redis目录下。

    第五步:设置后台启动:
    [root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis/bin/
    (把/root/redis-3.0.0/redis.conf复制到/usr/local/redis/bin目录下)

    修改配置文件:把daemonize后面的参数改为yes
    修改配置文件:

    测试启动:[root@localhost bin]# ./redis-server redis.conf

    查看redis进程:
    [root@localhost bin]# ps aux|grep redis

    二 redis集群的搭建

    2.1 redis集群(redis-cluster)原理

    3.0版本之前的redis是不支持集群的,3.0版本之前想要搭建redis集群的话需要中间件来找到存值和取值的对应节点。

    3.0版本以后的redis集群架构图:

    3.0版本以后的redis集群架构图

    那么这是如何实现的呢???

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

    根据下图应该更容易理解了。(图片来源:http://www.cnblogs.com/liyaso...
    集群原理

    redis集群投票机制

    redis集群中有多台redis服务器不可避免会有服务器挂掉。redis集群服务器之间通过互相的ping-pong判断是否节点可以连接上。如果有一半以上的节点去ping一个节点的时候没有回应,集群就认为这个节点宕机了。

    上面就是我们常说的为了容错而生的redis集群投票机制。
    redis集群投票机制

    2.2 redis集群(redis-cluster)的搭建

    redis集群搭建起来很简单,我们这里用一台虚拟机模拟搭建包含6个redis服务器的集群,实际工作中与使用多台服务器搭建是一个操作。

    我们上面已经装好了一个redis实例,现在我们需要把它复制6份并修改相应端口。

    第一步: 新建redis-cluster文件夹
    新建redis-cluster文件夹

    第二步:复制redis实例

    [root@Snailclimb local]# cp redis/bin redis-cluster/redis1

    如果你复制过去的redis实例有dump.rdb文件的话最好也要删除。

    第三步:修改配置文件

    修改bin目录下的redis.conf配置文件
    修改配置文件

    第四步:继续复制5个redis实例

    我们用上面的redis实例复制5个redis实例,然后把他们的配置文件的端口号改为7002-7006

    继续复制5个redis实例

    第五步 :新建一个执行脚本:
    [root@Snailclimb redis-cluster]# vim start-all.sh
    脚本内容如下:

    cd redis1/bin
    ./redis-server redis.conf
    cd ..
    cd ..
    cd redis2/bin
    ./redis-server redis.conf
    cd ..
    cd ..
    cd redis3/bin
    ./redis-server redis.conf
    cd ..
    cd ..
    cd redis4/bin
    ./redis-server redis.conf
    cd ..
    cd ..
    cd redis5/bin
    ./redis-server redis.conf
    cd ..
    cd ..
    cd redis6/bin
    ./redis-server redis.conf

    为脚本赋予执行权限:

    [root@Snailclimb redis-cluster]# chmod u+x start-all.sh

    同时启动6个redis实例:

    [root@Snailclimb redis-cluster]# ./start-all.sh

    第六步:将redis-trib.rb复制到redis-cluster目录下面:

    将redis-trib.rb复制到redis-cluster目录下面
    并为脚本赋予执行权限:
    [root@Snailclimb redis-cluster]# chmod u+x redis-trib.rb

    第七步:安装ruby和ruby运行环境

    yum install ruby

    yum install rubygems

    gem install redis-3.0.0.gem

    第八步:使用ruby脚本搭建集群:

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

    查看集群:
    查看集群

    注意:端口修改错误或者没有将cluster-enabled yes前的注释去掉都会导致集群搭建失败。总的来说,redis集群搭建还是很简单的。

    这样一个完整的redis集群就已经搭建完毕了。。。

    三 redis单机版与集群版的测试使用

    添加Maven依赖:

            <!-- Redis客户端 -->
            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>2.7.2</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>

    单机版redis测试:

        @Test
        public void testJedis() throws Exception {
            // 创建一个连接Jedis对象,参数:host、port
            Jedis jedis = new Jedis("192.168.25.130", 6379);
            // 直接使用jedis操作redis。所有jedis的命令都对应一个方法。
            jedis.set("bwcx9393", "欢迎关注Java面试通关手册");
            String string = jedis.get("bwcx9393");
            System.out.println(string);//输出内容:欢迎关注微信公众号:Java面试通关手册
            // 关闭连接
            jedis.close();
        }
    

    使用连接池测试单机版redis:

        @Test
        public void testJedisPool() throws Exception {
            // 创建一个连接池对象,两个参数host、port
            JedisPool jedisPool = new JedisPool("192.168.25.130", 6379);
            // 从连接池获得一个连接,就是一个jedis对象。
            Jedis jedis = jedisPool.getResource();
            // 使用jedis操作redis
            String string = jedis.get("bwcx9393");
            System.out.println(string);//输出内容:欢迎关注微信公众号:Java面试通关手册
            // 关闭连接,每次使用完毕后关闭连接。连接池回收资源。
            jedis.close();
            // 关闭连接池。
            jedisPool.close();
        }
    

    测试集群版redis:

        @Test
        public void testJedisCluster() throws Exception {
            // 创建一个JedisCluster对象。有一个参数nodes是一个set类型。set中包含若干个HostAndPort对象。
            Set<HostAndPort> nodes = new HashSet<>();
            nodes.add(new HostAndPort("192.168.25.130", 7001));
            nodes.add(new HostAndPort("192.168.25.130", 7002));
            nodes.add(new HostAndPort("192.168.25.130", 7003));
            nodes.add(new HostAndPort("192.168.25.130", 7004));
            nodes.add(new HostAndPort("192.168.25.130", 7005));
            nodes.add(new HostAndPort("192.168.25.130", 7006));
            JedisCluster jedisCluster = new JedisCluster(nodes);
            // 直接使用JedisCluster对象操作redis。
            jedisCluster.set("test", "123");
            String string = jedisCluster.get("test");
            System.out.println(string);
            // 关闭JedisCluster对象
            jedisCluster.close();
        }

    四 如何在JavaWeb项目中实现单机和集群无缝切换使用

    我们如何才能在项目中实现自己想用的单机redis就用单机redis想用redis集群就用redis集群而不要修改项目代码呢???

    创建相应类和接口
    创建相应类和接口
    接口:

    import java.util.List;
    
    public interface JedisClient {
    
        String set(String key, String value);
        String get(String key);
        Boolean exists(String key);
        Long expire(String key, int seconds);
        Long ttl(String key);
        Long incr(String key);
        Long hset(String key, String field, String value);
        String hget(String key, String field);
        Long hdel(String key, String... field);
        Boolean hexists(String key, String field);
        List<String> hvals(String key);
        Long del(String key);
    }

    集群版使用:

    import java.util.List;
    
    import redis.clients.jedis.JedisCluster;
    
    public class JedisClientCluster implements JedisClient {
        
        private JedisCluster jedisCluster;
        
    
        public JedisCluster getJedisCluster() {
            return jedisCluster;
        }
    
        public void setJedisCluster(JedisCluster jedisCluster) {
            this.jedisCluster = jedisCluster;
        }
    
        @Override
        public String set(String key, String value) {
            return jedisCluster.set(key, value);
        }
    
        @Override
        public String get(String key) {
            return jedisCluster.get(key);
        }
    
        @Override
        public Boolean exists(String key) {
            return jedisCluster.exists(key);
        }
    
        @Override
        public Long expire(String key, int seconds) {
            return jedisCluster.expire(key, seconds);
        }
    
        @Override
        public Long ttl(String key) {
            return jedisCluster.ttl(key);
        }
    
        @Override
        public Long incr(String key) {
            return jedisCluster.incr(key);
        }
    
        @Override
        public Long hset(String key, String field, String value) {
            return jedisCluster.hset(key, field, value);
        }
    
        @Override
        public String hget(String key, String field) {
            return jedisCluster.hget(key, field);
        }
    
        @Override
        public Long hdel(String key, String... field) {
            return jedisCluster.hdel(key, field);
        }
    
        @Override
        public Boolean hexists(String key, String field) {
            return jedisCluster.hexists(key, field);
        }
    
        @Override
        public List<String> hvals(String key) {
            return jedisCluster.hvals(key);
        }
    
        @Override
        public Long del(String key) {
            return jedisCluster.del(key);
        }
    
    }

    单机版使用:

    
    import java.util.List;
    
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    
    public class JedisClientPool implements JedisClient {
        
        private JedisPool jedisPool;
    
        public JedisPool getJedisPool() {
            return jedisPool;
        }
    
        public void setJedisPool(JedisPool jedisPool) {
            this.jedisPool = jedisPool;
        }
    
        @Override
        public String set(String key, String value) {
            Jedis jedis = jedisPool.getResource();
            String result = jedis.set(key, value);
            jedis.close();
            return result;
        }
    
        @Override
        public String get(String key) {
            Jedis jedis = jedisPool.getResource();
            String result = jedis.get(key);
            jedis.close();
            return result;
        }
    
        @Override
        public Boolean exists(String key) {
            Jedis jedis = jedisPool.getResource();
            Boolean result = jedis.exists(key);
            jedis.close();
            return result;
        }
    
        @Override
        public Long expire(String key, int seconds) {
            Jedis jedis = jedisPool.getResource();
            Long result = jedis.expire(key, seconds);
            jedis.close();
            return result;
        }
    
        @Override
        public Long ttl(String key) {
            Jedis jedis = jedisPool.getResource();
            Long result = jedis.ttl(key);
            jedis.close();
            return result;
        }
    
        @Override
        public Long incr(String key) {
            Jedis jedis = jedisPool.getResource();
            Long result = jedis.incr(key);
            jedis.close();
            return result;
        }
    
        @Override
        public Long hset(String key, String field, String value) {
            Jedis jedis = jedisPool.getResource();
            Long result = jedis.hset(key, field, value);
            jedis.close();
            return result;
        }
    
        @Override
        public String hget(String key, String field) {
            Jedis jedis = jedisPool.getResource();
            String result = jedis.hget(key, field);
            jedis.close();
            return result;
        }
    
        @Override
        public Long hdel(String key, String... field) {
            Jedis jedis = jedisPool.getResource();
            Long result = jedis.hdel(key, field);
            jedis.close();
            return result;
        }
    
        @Override
        public Boolean hexists(String key, String field) {
            Jedis jedis = jedisPool.getResource();
            Boolean result = jedis.hexists(key, field);
            jedis.close();
            return result;
        }
    
        @Override
        public List<String> hvals(String key) {
            Jedis jedis = jedisPool.getResource();
            List<String> result = jedis.hvals(key);
            jedis.close();
            return result;
        }
    
        @Override
        public Long del(String key) {
            Jedis jedis = jedisPool.getResource();
            Long result = jedis.del(key);
            jedis.close();
            return result;
        }
    
    }

    applicationContext-redis.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
        
        <!-- 连接redis单机版 -->
        <bean id="jedisClientPool" class="xx.xx.xx.JedisClientPool">
            <property name="jedisPool" ref="jedisPool"></property>
        </bean>
        <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
            <constructor-arg name="host" value="192.168.25.130"/>
            <constructor-arg name="port" value="6379"/>
        </bean>
        <!-- 连接redis集群 -->
    <!--     <bean id="jedisClientCluster" class="xx.xx.xx.JedisClientCluster">
            <property name="jedisCluster" ref="jedisCluster"/>
        </bean>
        <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
            <constructor-arg name="nodes">
                <set>
                    <bean class="redis.clients.jedis.HostAndPort">
                        <constructor-arg name="host" value="192.168.25.130"></constructor-arg>
                        <constructor-arg name="port" value="7001"></constructor-arg>
                    </bean> 
                    <bean class="redis.clients.jedis.HostAndPort">
                        <constructor-arg name="host" value="192.168.25.130"></constructor-arg>
                        <constructor-arg name="port" value="7002"></constructor-arg>
                    </bean> 
                    <bean class="redis.clients.jedis.HostAndPort">
                        <constructor-arg name="host" value="192.168.25.130"></constructor-arg>
                        <constructor-arg name="port" value="7003"></constructor-arg>
                    </bean> 
                    <bean class="redis.clients.jedis.HostAndPort">
                        <constructor-arg name="host" value="192.168.25.130"></constructor-arg>
                        <constructor-arg name="port" value="7004"></constructor-arg>
                    </bean> 
                    <bean class="redis.clients.jedis.HostAndPort">
                        <constructor-arg name="host" value="192.168.25.130"></constructor-arg>
                        <constructor-arg name="port" value="7005"></constructor-arg>
                    </bean> 
                    <bean class="redis.clients.jedis.HostAndPort">
                        <constructor-arg name="host" value="192.168.25.130"></constructor-arg>
                        <constructor-arg name="port" value="7006"></constructor-arg>
                    </bean> 
                </set>
            </constructor-arg>
        </bean> -->
    </beans>

    测试代码:

    public class JedisClientTest {
    
        @Test
        public void testJedisClient() throws Exception {
            //初始化spring容器
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-redis.xml");
            //从容器中获得JedisClient对象
            JedisClient jedisClient = applicationContext.getBean(JedisClient.class);
            jedisClient.set("aaa", "111");
            String string = jedisClient.get("aaa");
            System.out.println(string);
            
            
        }
    }

    这样在实际项目中我们无需修改代码就可以实现单机和集群版的相关切换

  • 相关阅读:
    《白骨精学习法》 21世纪职场必备学习技巧
    英雄不问出处
    整理ArcSDE 安装过程出现问题以及解决方法系列
    ArcEngine9.1结合VS2005开发技巧2则
    推荐一界面控件DotNetBar(含附件)
    常用易忘记Oracle命令(待续)
    ArcSDE中间件技术的生命力(蔡晓兵)
    ArcSDE 的存储机制
    (收藏)ITPUB的ORACLE之常用FAQ V1.0
    ORA01691错误
  • 原文地址:https://www.cnblogs.com/zhangfengshi/p/13154807.html
Copyright © 2020-2023  润新知