关于Redis 3.0.7 的集群部署 及 jedis2.8 与 spring3.2 整合 的测试笔记

Redis 从 3.0 开始 支持服务器端集群:通过HashSlot 分区,同时支持Master-slave 主从模式,别的不多说,这篇主要记录下我在集群部署时遇到的一些问题及解决办法:


环境:centos 6.4

软件:redis 3.0.7 , Ruby , jedis 2.8


请确保linux 可以联网!


开始部署Redis:

1. 下载Redis3.0.7  点击打开链接

2. 创建一个新目录用于Redis安装测试   mkdir /lbbhd

3.  将文件copy到一个新目录  cp /root/Downloads/redis-3.0.7.tar.gz  /lbbhd

4. 解压  tar -zxvf redis-3.0.7.tar.gz 

5. 安装 Redis      cd redis-3.0.7 ; make ; cd src/ ; make install;

6. 在 redis-3.0.7 中 有一个默认的配置文件 redis.conf       cat ../redis.conf    在这个配置文件中 有一段关于 REDIS CLUSTER 的配置项说明,有兴趣可以看下


  我在这就不一一介绍了,官方文档有一份最简配置

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


7  启动多个Redis实例

首先 mkdir redis_clus1ter 创建一个集群文件,用于存储配置文件等

然后 cd redis_cluster   ; mkdir 7000 7001 7002 7003 7004 7005 7006 7007 7008  创建9个文件夹 对应不同的Redis实例

       将前文提到的 redis.conf 复制到7000 ~ 7008 文件夹下

       文档提供的最简配置有点小问题,在 文件中  属性  cluster-config-file 设置的是相对路径,这个路径是相对于 Redis Server 启动文件来说的

举个例子,如图:


我在 7000 和 7001 两个文件夹里 都生成了redis.conf 文件,内容也只是 port 不同, 此时我们来启动一下Redis

首先启动 7000

如图 启动成功。 然后启动 7001....

如图 提示 每个不同的节点 要使用不同的 配置文件,这个文件指的就是 cluster-config-file 

这个文件在哪呢?

就生成在redis  src 目录下(这个文件会生成在当前目录下,例如在Desktop执行启动7001节点,那么这个文件就生成在桌面), 所以我们在这对redis.conf 做一下小小的修改,将相对路径nodes.conf 改为 /lbbhd/redis_cluster/7000/nodes.conf 绝对路径,7000为文件夹名字,7000~7008 , 这个文件不用管,redis自己会生成会更新,只需要提供一个路径就可以。

第二点修改 将redis 改为后台启动 daemonize 属性 设置为 yes。

        将配置文件cp到 7000~7008 修改port 及 cluser-config-file 路径。

启动9个Redis实例:


---------------------------------------------------------- Redis 准备工作到此告一段落

Redis 集群 需要Ruby支持,下面安装相关软件:

 yum install ruby 

yum install rubygems

gem install redis

--------------------------------------------------------安装完成之后开始Redis 集群命令

cd /lbbhd/redis-3.0.7/src

./redis-trib.rb create --replicas 2 192.168.1.193:7000 192.168.1.193:7001 192.168.1.193:7002 192.168.1.193:7003 192.168.1.193:7004 192.168.1.193:7005 192.168.1.193:7006 192.168.1.193:7007 192.168.1.193:7008


输入 yes 


 集群完成!

刚才命令中的 --replicas属性 指定从节点个数,后边9个节点会根据指定的从节点分配每个Master的slave

前三个7000,7001,7002 为master   7003,7004为7000的slave 7005,7006为7001的slave 7007,7008为7002的slave;


连接7000  通过info 或 info replication 查看主从信息。

-----------------------------------------------------------集群测试


 

---------------------------------------------------主从测试

将有数据的master 关闭一个 ,redis是否能够另外的master 来代替,数据是否丢失


如上图。将7002关闭之后,redis集群自动在7007,7008 两个slave中选个一个升级为master,且存储在7002上的a7000依然可以查询;

注:Redis Cluster is not able to guarantee strong consistency. 在某些特殊情况下,Redis会存在丢失写的情况。



重新启动7002 ,7002会自动成为7008的slave。


错误:

(error) MOVED 5798 192.168.1.193:7005  使用 ./redis-cli -c -p port 启动  -c代表集群模式


关于 redis-trib.rb 命令:

➜  redis-3.0.7 src/redis-trib.rb                    
Usage: redis-trib <command> <options> <arguments ...>

  create          host1:port1 ... hostN:portN
                  --replicas <arg>
  check           host:port
  fix             host:port
  reshard         host:port
                  --from <arg>
                  --to <arg>
                  --slots <arg>
                  --yes
  add-node        new_host:new_port existing_host:existing_port
                  --slave
                  --master-id <arg>
  del-node        host:port node_id
  set-timeout     host:port milliseconds
  call            host:port command arg arg .. arg
  import          host:port
                  --from <arg>
  help            (show this help)

For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
可以通过check 来检查集群节点,如果某些节点出现问题,可以通过fix来修复
例如 (ERROR)CLUSTERDOWN the cluster is down ;


关于Redis3.0的集群暂告一段落,下半部分是关于 jedis2.8客户端 与 spring 整合的一些想法和操作。

---------------------------------------------------------------------------------jedis2.8 与 spring 整合----------------------------------------------------------

1.下载jedis2.8    下载地址点击打开链接

2. 2.8版本的jedis 需要 common-pool2 的支持

3. 创建一个java项目RedisDemo,导入需要的jar包

4. 测试

package com.zm.redis.demo;

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

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

/**
 * 根据jedis文档提供的代码操作Redis集群
 */
public class RedisBasicDemo {
	
	 public static void main(String[] args) {
		 test();
	 }

	private static void test() {
		Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
		//在添加集群节点的时候只需要添加一个,其余同一集群的阶段会被自动加入
		jedisClusterNodes.add(new HostAndPort("192.168.1.193", 7000));
		JedisCluster jc = new JedisCluster(jedisClusterNodes);
		jc.set("foo", "bar");
		String value = jc.get("foo");
		System.out.println(value);
	}
	 
}

5. 实际应用时,每次都new一个对象自然不可取。在创建JedisCluster对象的过程中,最终结果会得到两个Map对象:

  private Map<String, JedisPool> nodes = new HashMap<String, JedisPool>();
  private Map<Integer, JedisPool> slots = new HashMap<Integer, JedisPool>();
第一个map中 key 是 host:port (如 192.168.1.193:7000) 对应的value 是JedisPool;

第二个map中 key 是 前文说的HashSlot(16384个)  对应的value 是JedisPool;


简单来说 当jedis 执行get(key)操作时,首先通过JedisClusterCRC16.getSlot(key)求得 对应的HashSlot 然后得到对应的jedisPool,然后通过getResource()在池中获取一个jedis对象,用来操作Redis。

6. 多说了一些,管理对象首先想到的就是spring ,下边就是相关配置

交给Spring 管理的对象是 JedisCluster,该类没有getter,setter方法,所以使用构造方法注入;

public JedisCluster(Set<HostAndPort> nodes) {
    this(nodes, DEFAULT_TIMEOUT);
  }

  public JedisCluster(Set<HostAndPort> nodes, int timeout) {
    this(nodes, timeout, DEFAULT_MAX_REDIRECTIONS);
  }

  public JedisCluster(Set<HostAndPort> nodes, int timeout, int maxRedirections) {
    this(nodes, timeout, maxRedirections, new GenericObjectPoolConfig());
  }

  public JedisCluster(Set<HostAndPort> nodes, final GenericObjectPoolConfig poolConfig) {
    this(nodes, DEFAULT_TIMEOUT, DEFAULT_MAX_REDIRECTIONS, poolConfig);
  }

  public JedisCluster(Set<HostAndPort> nodes, int timeout, final GenericObjectPoolConfig poolConfig) {
    this(nodes, timeout, DEFAULT_MAX_REDIRECTIONS, poolConfig);
  }

  public JedisCluster(Set<HostAndPort> jedisClusterNode, int timeout, int maxRedirections,
      final GenericObjectPoolConfig poolConfig) {
    super(jedisClusterNode, timeout, maxRedirections, poolConfig);
  }

  public JedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout, int soTimeout,
      int maxRedirections, final GenericObjectPoolConfig poolConfig) {
    super(jedisClusterNode, connectionTimeout, soTimeout, maxRedirections, poolConfig);
  }
如上代码 都是构造方法,可以根据需要自己设置

配置文件spring-config.xml

<!-- properties 文件位置 -->
	<bean id="propertyConfigurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>classpath:resources.properties</value>
			</list>
		</property>
	</bean>

	<!-- jedisPool 配置  简单配置,其余属性自行查找  org.apache.commons.pool2.impl.GenericObjectPoolConfig 等父类-->
	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
	    <property name="maxTotal" value="${pool.maxTotal}" />
	    <property name="maxIdle" value="${pool.maxIdle}" />
	    <property name="minIdle" value="${pool.minIdle}" /> 
	</bean>
	<!-- 程序中要使用的操作redis集群的对象 -->
	<bean id="jedisClusterClient" class="redis.clients.jedis.JedisCluster">
	    <!-- 构造方法注入 
	    节点集合(只写一个就可以,集群中其余的节点会自动加载进来) , 超时时间,最大重连次数,数据池配置对象
	 public JedisCluster(Set<HostAndPort> jedisClusterNode, int timeout, int maxRedirections,final GenericObjectPoolConfig poolConfig) -->
    	<constructor-arg name="jedisClusterNode" >
			 <set>
	            <bean class="redis.clients.jedis.HostAndPort">
	                <constructor-arg name="host" value="${redis.host}"/>
	                <constructor-arg name="port" value="${redis.port}"/>
	            </bean>
		     </set>      	    
    	</constructor-arg>
	    <constructor-arg name="timeout" value="${redis.timeOut}"/>
	    <constructor-arg name="maxRedirections" value="${redis.maxRedirections}"/>
	    <constructor-arg name="poolConfig" ref="jedisPoolConfig"/>
	</bean>

resources.properties

pool.maxTotal=5
pool.maxIdle=5
pool.minIdle=0

redis.timeOut= 2000
redis.maxRedirections = 5

redis.host = 192.168.1.193
redis.port = 7000

配置完成。


最后提供一个简单的Demo demo



还我的图!


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值