您的位置:首页 > 数据库 > Redis

在Linux上(我的服务器是Ubuntu) 用redis-trib.rb搭建redis集群,并在客户端使用spring-data-redis连接(亲测)

2017-09-26 12:21 1156 查看
今天好好讲一下redis集群的搭建方法、遇到问题和解决方法。

首先就是下载安装redis,网上流传两种方式:

1.使用下列命令(不推荐使用这种方式):

sudo apt-get update

sudo apt-get install redis-server

启动 Redis

./redis-server

查看 redis 是否启动?

./redis-cli

以上命令将打开以下终端:

redis 127.0.0.1:6379>

127.0.0.1 是本机 IP ,6379 是 redis 服务端口。现在我们输入 PING 命令。

redis 127.0.0.1:6379> ping

PONG

以上说明我们已经成功安装了redis。

2.直接下载redis安装包到Linux目录下,下载地址(http://download.redis.io/releases/redis-4.0.2.tar.gz);或者使用官方给出方式,用Linux命令下载tar文件:wget http://download.redis.io/releases/redis-4.0.2.tar.gz

解压文件命令:tar -xvf redis-4.0.2.tar.gz

解压后,进入redis文件夹下:

cd redis-4.0.2

然后执行make命令。

之后测试一下,先开启redis-server:

./src/redis-server redis.conf

然后执行

./src/redis-cli

redis> set foo bar

OK

redis> get foo

“bar”

至此,redis已经成功安装。

下面便是redis集群的实现方式。

首先尊重参考博文的版权,给出我参考的博文地址:

http://www.cnblogs.com/cndota/p/6113921.html

http://liubao0312.blog.51cto.com/2213529/1939310

http://www.cnblogs.com/wuxl360/p/5920330.html

接下来是我根据自己的实际情况的解决过程。

首先在/root路径下创建redis-cluster文件夹,在/root/redis-cluster文件夹下创建六个文件夹(7001、7002、7003、7004、7005、7006),然后将redis整个文件夹包括所有文件和文件夹都分别复制到六个文件夹中,每一个文件夹最后都将开启一个redis-server,即最终会有6个redis-server,如下图。



接下来对每个文件夹下的/redis/redis.conf配置文件进行相应修改,比如7001文件夹:

port 6480(端口号)

cluster-enabled yes

daemonize yes

pidfile /var/run/redis_6480.pid

注意:可以先查看端口号是否已经被占用,使用命令 netstat -ano|grep 6480,没有输出即没有被占用。

对另外5个文件夹的redis.conf也进行类似更改,只是端口号不同就可以。

接下来打开6个文件夹下的redis-server,命令:



到这里,6个准备进行集群的redis已经成功打开。



接下来安装配置redis-trib.rb所需的环境ruby。

安装ruby

sudo apt install ruby

成功。

然而,sudo apt install rubygems这个我却下载不了,无奈换一种方式:

– 安装rubygem redis依赖 —

wget http://rubygems.org/downloads/redis-3.3.0.gem

gem install -l redis-3.3.0.gem



最后安装ruby和redis的接口程序

gem install redis

接着,将redis-trib.rb复制到/root/redis-cluster目录下:



运行命令建立redis集群:./redis-trib.rb create –replicas 1 120.77.213.58:6480 120.77.213.58:6481 120.77.213.58:6482 120.77.213.58:6483 120.77.213.58:6484 120.77.213.58:6485

注意:IP地址和redis端口号请改为自己的。说明:redis集群至少需要3个主节点,每个主节点有一个从节点总共6个节点,replicas指定为1表示每个主节点有一个从节点





这里可以测试一下集群完整性:

集群完整性是指所有的槽都分配到了存活的主节点上,只要16384个槽中有一个没有分配给节点则表示集群不完整;

可以使用redis-trib.rb check命令检测之前创建的两个集群是否成功,check命令只需要给出集群中任意一个节点地址就可以完成整个集群的检查工作;



最后,我们打开任意一个redis-cli客户端测试一下集群是否成功:



特别注意:正确启动集群模式(即添加”-c”)的命令是:redis-cli -c -h 120.77.213.58 -p 6480

必须使用-c 启动集群,否则进入节点后访问其他节点的数据会报以下错误:



至此,redis集群已经搭建完成!

(转载)原理:

redis cluster在设计的时候,就考虑到了去中心化,去中间件,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。

Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽 (hash slot)的方式来分配的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384。所以我们在测试的时候看到set 和 get 的时候,直接跳转到了6480端口的节点。

Redis 集群会把数据存在一个 master 节点,然后在这个 master 和其对应的salve 之间进行数据同步。当读取数据时,也根据一致性哈希算法到对应的 master 节点获取数据。只有当一个master 挂掉之后,才会启动一个对应的 salve 节点,充当 master 。

需要注意的是:必须要3个或以上的主节点,否则在创建集群时会失败,并且当存活的主节点数小于总节点数的一半时,整个集群就无法提供服务了。

(转载)总结:

1. 建立集群主要步骤如下:

① 准备节点

② 节点握手【meet命令,是一个异步命令】

③ 分配槽 【cluster addslots {number_start..number_end}】

2. redis cluster 需要至少6个节点,3个主节点 +3个从节点

3. 主从节点必须为复制关系【cluster replicate 主节点ID 命令,建立复制关系】

4. 节点握手协议采用Gossip协议进行通信,通过meet命令建立握手关系,通过ping/pong命令保持正常通信

5. 加入到集群中的节点,在没有分配槽时,无法进行任何读写操作;

这是我的redis集群搭建过程,还请大家批评指正,多多指教,有问题请留言评论区,小树会在第一时间进行回复!

本来想重新写一篇文章的,怕大家可能找不到看不到,就直接在这儿接着写了。

接下来在eclipse中编写javaEE项目并使用spring-data-redis连接redis集群测试一下:

注意:这里我只列出跟spring-data-redis相关的代码和配置文件部分。

1.首先是pom.xml文件引入一下配置:

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.8.4.RELEASE</version>
</dependency>
<!--spring-data-redisr-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.4.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>


在这里我们控制了spring-data-redis和spring-data-commons两个jar包的版本相对应,否则可能因为版本不匹配问题而报以下错误(小树就碰到了,哈哈):

java.lang.NoSuchMethodError: redis.clients.jedis.JedisCluster.set([B[B)Ljava/lang/String

2.接着是spring-context-jedis.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd" default-lazy-init="true">

<description>Jedis Configuration</description>

<!-- 加载配置属性文件 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:jeesite.properties" />

<!-- 配置Cluster -->
<bean id="redisClusterConfiguration"
class="org.springframework.data.redis.connection.RedisClusterConfiguration">
<property name="maxRedirects" value="3"></property>
<!-- 节点配置 -->
<property name="clusterNodes">
<set>
<bean class="org.springframework.data.redis.connection.RedisClusterNode">
<constructor-arg name="host" value="120.77.213.58"></constructor-arg>
<constructor-arg name="port" value="6480"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisClusterNode">
<constructor-arg name="host" value="120.77.213.58"></constructor-arg>
<constructor-arg name="port" value="6481"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisClusterNode">
<constructor-arg name="host" value="120.77.213.58"></constructor-arg>
<constructor-arg name="port" value="6482"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisClusterNode">
<constructor-arg name="host" value="120.77.213.58"></constructor-arg>
<constructor-arg name="port" value="6483"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisClusterNode">
<constructor-arg name="host" value="120.77.213.58"></constructor-arg>
<constructor-arg name="port" value="6484"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisClusterNode">
<constructor-arg name="host" value="120.77.213.58"></constructor-arg>
<constructor-arg name="port" value="6485"></constructor-arg>
</bean>
</set>
</property>
</bean>

<!--JedisPoolConfig 连接池参数配置-->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">

<property name="maxIdle" value="300" /> <!-- 最大能够保持idel状态的对象数  -->
<property name="maxTotal" value="60000" /> <!-- 最大分配的对象数 -->
<property name="testOnBorrow" value="true" /> <!-- 当调用borrow Object方法时,是否进行有效性检查 -->
</bean>

<bean id="connectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<constructor-arg ref="redisClusterConfiguration" />
<constructor-arg ref="jedisPoolConfig" />
</bean>

<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<bean id="valueSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>

<!-- redis模板配置  spring-data-redis提供了一个基础的泛型RedisTemplate封装了基础的crud操作-->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="defaultSerializer" ref="stringRedisSerializer"/>
<property name="keySerializer" ref="stringRedisSerializer"/>
<property name="valueSerializer" ref="valueSerializer"/>

</bean>

</beans>


3.最后就是测试代码部分了,我懒了点,没有使用JUnit编写,就是简单连接服务器上的redis集群并插入100条数据。

@Autowired
private RedisTemplate<String, SmtpDetectConfig> redisTemplate;

@RequestMapping(value="redis",method=RequestMethod.GET)
@ResponseBody
public CommonDTO getRedis() {

redisTemplate.execute(new RedisCallback<Integer>() {
//这里返回值是个上面的RedisCallback<Integer> 中的泛型一直,
public Integer doInRedis(RedisConnection connection) {
int i = 0;
for (; i < 100; i++) {
byte[] key = ("key:" + i).getBytes();
byte[] value = ("value:" + i).getBytes();
connection.set(key, value);
}
//这里返回值是个上面的RedisCallback<Integer> 中的泛型一直,
return i;

}
});

CommonDTO result=new CommonDTO();
result.setMessage("redis.");
result.setResult(null);
return result;
}


4.最后上去服务器查看结果,插入数据成功:



参考博文:

jedis,spring-redis-data 整合使用,版本问题异常

Redis教程,Redis集群搭建与Spring-data-redis的使用(Spring-data-redis使用篇)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: