• 【精】搭建redis cluster集群,JedisCluster带密码访问【解决当中各种坑】!


    转:


    【精】搭建redis cluster集群,JedisCluster带密码访问【解决当中各种坑】!

     版权声明:本文为博主原创文章,转载请看官大人注明出处: https://blog.csdn.net/localhost01/article/details/71436801
    一.搭建redis单机
    本文搭建redis3.0版本,3.0主要增加了redis cluster集群功能。
     
    1.下载地址:http://download.redis.io/releases/redis-3.0.0.tar.gz,将下载文件拷贝到/usr/local
     
    2.解压源码:tar -zxvf redis-3.0.0.tar.gz
     
    3.编译源码:cd /usr/local/redis-3.0.0
    make
     
    4.安装到指定目录: cd /usr/local/redis-3.0.0 
    make PREFIX=/usr/local/redis install
     
    5.进入源码目录,将redis.conf拷贝到安装路径:cd /usr/local/redis
    mkdir conf
    cp /usr/local/redis-3.0.0/redis.conf  /usr/local/redis/bin
     
    6.修改redis.conf配置文件,以后端模式启动:daemonize yes
     
    7.启动redis:cd /usr/local/redis ./bin/redis-server ./redis.conf  //在何处启动的server,一些配置文件就默认在该处生成(如果配置的相对路径)
     
    8.redis.conf配置文件主要配置:
    port 7001  //监听的端口
    # bind 127.0.0.1  //绑定ip,只允许该ip访问,不填默认为*,表示允许所有ip访问
    requirepass "你的密码"  //开启密码
    loglevel debug   //日志级别,开发模式尽量选用debug
    logfile "redis.log"   //日志文件路径,此处使用相对路径,将生成到/usr/local/redis下
    maxmemory 100000000  //允许最大内存占用100m
    appendonly yes  //启用aof
    auto-aof-rewrite-percentage 80  //部署在同一机器的多个redis实例,建议把auto-aof-rewrite错开(可分别写80-100不等),防止瞬间fork,所有redis进程做rewrite,占用大量内存
     
    9.jedis连接redis单机:
    1. <dependency>
    2. <groupId>redis.clients</groupId>
    3. <artifactId>jedis</artifactId>
    4. <version>2.7.0</version>
    5. </dependency>
    1. 连接池整合spring:
    2. <!-- redis连接池(单例) -->
    3. <bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="close">
    4. <constructor-arg name="poolConfig" ref="jedisPoolConfig"/>
    5. <constructor-arg name="host" value="${redis.host}"/>
    6. <constructor-arg name="port" value="${redis.port}"/>
    7. <constructor-arg name="timeout" value="${redis.timeout}"/>
    8. <constructor-arg name="password" value="${redis.pass}"/>
    9. </bean>
    1. <!-- 连接池配置 -->
    2. <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    3. <!-- 最大连接数 -->
    4. <property name="maxTotal" value="150" />
    5. <!-- 最大空闲连接数 -->
    6. <property name="maxIdle" value="30" />
    7. <!-- 最小空闲连接数 -->
    8. <property name="minIdle" value="10" />
    9. <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
    10. <property name="maxWaitMillis" value="3000" />
    11. <!-- 每次释放连接的最大数目 -->
    12. <property name="numTestsPerEvictionRun" value="100" />
    13. <!-- 释放连接的扫描间隔(毫秒) -->
    14. <property name="timeBetweenEvictionRunsMillis" value="3000" />
    15. <!-- 连接最小空闲时间 -->
    16. <property name="minEvictableIdleTimeMillis" value="1800000" />
    17. <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
    18. <property name="softMinEvictableIdleTimeMillis" value="10000" />
    19. <!-- 在获取连接的时候检查有效性, 默认false -->
    20. <property name="testOnBorrow" value="true" />
    21. <!-- 在空闲时检查有效性, 默认false -->
    22. <property name="testWhileIdle" value="true" />
    23. <!-- 在归还给pool时,是否提前进行validate操作 -->
    24. <property name="testOnReturn" value="true" />
    25. <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
    26. <property name="blockWhenExhausted" value="false" />
    27. </bean>
    1. @RunWith(SpringJUnit4ClassRunner.class) // 指定测试用例的运行器 这里是指定了Junit4
    2. @ContextConfiguration("classpath:spring/application*.xml")
    3. public class RedisTest {
    4. @Autowired
    5. private JedisPool pool;
    6. @Test
    7. public void testJedisPool() {
    8. Jedis jedis = null;
    9. String name = null;
    10. try {
    11. jedis = pool.getResource();
    12. jedis.set("testName", "RCL");
    13. name = jedis.get("testName");
    14. } catch (Exception ex) {
    15. ex.printStackTrace();
    16. } finally {
    17. if (jedis != null) {
    18. // 返回给池
    19. jedis.close();
    20. }
    21. Assert.assertEquals("RCL", name);
    22. }
    23. }
    10.如果连接不上,可查看是否防火墙没有将redis端口开放:/etc/sysconfig/iptables添加:
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 7001 -j ACCEPT //7001即redis端口
    重启防火墙
     
     
    二、搭建redis集群
    1.安装ruby环境
    集群管理工具redis-trib.rb依赖ruby环境
    (1)安装ruby:
    yum install ruby yum install rubygems
    (2)安装ruby和redis的接口程序:
    拷贝redis-3.0.0.gem至/usr/local。执行:gem install /usr/local/redis-3.0.0.gem
     
    2.建立redis实例
    (1)建立存放redis群的文件夹及子文件夹(用于存放每个redis实例):
    cd /usr/local    
    mkdir redis-cluster 
    mkdir redis-cluster/7001
    mkdir redis-cluster/7002
    ……
    (2)将刚刚安装的单机redis的/usr/local/redis文件夹拷贝到每个700X文件夹下,(这里我们建立六个实例,三主三从)
    (3)修改每个700X目录下的redis.conf配置文件:
    port 700X   //各自监听的端口
    #bind 127.0.0.1  //这里不绑定,默认允许所有ip访问,或者bind 0.0.0.0
    cluster-enabled yes   //开启集群
    cluster-node-timeout 15000   //15时间内没有收到对方的回复,则单方面认为端节点挂掉
    另外,由于下面我们需要配置集群密码,故之前配置的 requirepass 先删掉,集群成功后再进行配置。
     
    3.启动各个redis:分别进入7001、7002、...7006目录,执行./redis-server ./redis.conf
     
    4.创建集群:/usr/local/redis-cluster/redis-trib.rb create --replicas 1 123.123.123.123:7001 123.123.123.123:7002 123.123.123.123:7003 123.123.123.123:7004 123.123.123.123:7005 123.123.123.123:7006
    注意:
    (1)为保证远程可访问,这里的ip尽量使用公网ip,且创建集群时可先关闭防火墙,否则可以出现一直join……的现象。
    (2)redis集群至少需要3个主节点,每个主节点有一个从节点总共6个节点
    (3)replicas指定为1表示每个主节点有一个从节点
    (4)如果出现[ERR] Sorry, can't connect to node错误:
    1.ruby 和rubygem 版本太低,安装新版本。查看gem版本和redis版本(redis-cli -v可查看redis版本)
    2.查看reids配置文件,bind绑定的允许连接的ip是否正确。
    3.是否redis配置文件还是使用了密码,使用了密码也可能导致这个错误。
    (5)如果出现[ERR] Node 127.0.0.1:7005 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0:
    表示集群时,之前的redis已有数据,那么登录到7005的redis中,执行FLUSHALL即可
    (6)如果出现ERR Slot 0 is already busy (Redis::CommandError):
    用redis-cli登录到每个节点执行flushall和cluster reset即可2.6进入集群:./redis-cli -c  -p 7001 -h 123.123.123.123(-c即-cluster 表示进入集群模式,不加表示进入单机redis)
     
    5.检查集群是否成功:进入集群后,键入cluster info,显示cluster_state:ok,表示成功
     
    6.设置密码:
    (1)登录到每个节点,执行 config set masterauth 你的密码 config set requirepass 你的密码
    (2)随后登入 7001/bin/redis-cli -c -h 112.74.55.239 -p 7004 -a 你的密码,执行: config rewrite
    (3)防火墙开放7001到7006端口,以及redis总线:17001到17006:
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 7001:7006 -j ACCEPT
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 17001:17006 -j ACCEPT
     
    7.JedisCluster连接redis集群
    1. <dependency>
    2. <groupId>redis.clients</groupId>
    3. <artifactId>jedis</artifactId>
    4. <version>2.9.0</version> //2.9.0才支持cluster密码认证,之前版本的jedisCluster.auth("密码")方法里面什么都没有实现,仅仅抛一个JedisClusterException("No way to dispatch this command to Redis Cluster.")
    5. </dependency>
    1. 整合spring:
    2. <!-- redis集群 -->
    3. <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
    4. <constructor-arg index="0">
    5. <set>
    6. <bean class="redis.clients.jedis.HostAndPort">
    7. <constructor-arg index="0" value="${redis.host}"></constructor-arg>
    8. <constructor-arg index="1" value="${redis.port1}"></constructor-arg>
    9. </bean>
    10. <bean class="redis.clients.jedis.HostAndPort">
    11. <constructor-arg index="0" value="${redis.host}"></constructor-arg>
    12. <constructor-arg index="1" value="${redis.port2}"></constructor-arg>
    13. </bean>
    14. <bean class="redis.clients.jedis.HostAndPort">
    15. <constructor-arg index="0" value="${redis.host}"></constructor-arg>
    16. <constructor-arg index="1" value="${redis.port3}"></constructor-arg>
    17. </bean>
    18. <bean class="redis.clients.jedis.HostAndPort">
    19. <constructor-arg index="0" value="${redis.host}"></constructor-arg>
    20. <constructor-arg index="1" value="${redis.port4}"></constructor-arg>
    21. </bean>
    22. <bean class="redis.clients.jedis.HostAndPort">
    23. <constructor-arg index="0" value="${redis.host}"></constructor-arg>
    24. <constructor-arg index="1" value="${redis.port5}"></constructor-arg>
    25. </bean>
    26. <bean class="redis.clients.jedis.HostAndPort">
    27. <constructor-arg index="0" value="${redis.host}"></constructor-arg>
    28. <constructor-arg index="1" value="${redis.port6}"></constructor-arg>
    29. </bean>
    30. </set>
    31. </constructor-arg>
    32. <constructor-arg index="1" value="${redis.timeout}"></constructor-arg>
    33. <constructor-arg index="2" value="${redis.sockettimeout}"></constructor-arg>
    34. <constructor-arg index="3" value="${redis.maxAttempts}"></constructor-arg>
    35. <constructor-arg index="4" value="${redis.pass}"></constructor-arg>
    36. <constructor-arg index="5" ref="jedisPoolConfig"></constructor-arg>
    37. </bean>
    1. @RunWith(SpringJUnit4ClassRunner.class)
    2. @ContextConfiguration("classpath:spring/application*.xml")
    3. public class RedisTest {
    4. @Autowired
    5. private JedisCluster jCluster;
    6. @Test
    7. public void testJCluster() {
    8. jCluster.set("name", "RCL");
    9. String name = jCluster.get("testName");
    10. Assert.assertEquals("RCL", name);
    11. }
     
  • 相关阅读:
    《大型网站技术架构》学习笔记——架构演化
    ASP.NET MVC之Html.RenderAction
    设计模式学习笔记——面向对象设计原则
    设计模式学习笔记——类图
    观察者模式
    泛型接口
    泛型的实例化应用
    多线程第二种方式-实现runnable
    对象中的某个属性不希望被序例化--transient
    对象序例化
  • 原文地址:https://www.cnblogs.com/libin6505/p/10704418.html
Copyright © 2020-2023  润新知