Springboot 2.0.x 集成基于Centos7的Redis集群安装及配置

简介: Springboot 2.0.x 集成基于Centos7的Redis集群安装及配置 Redis简介 Redis是一个基于C语言开发的开源(BSD许可),开源高性能的高级内存数据结构存储,用作数据库、缓存和消息代理。

Springboot 2.0.x 集成基于Centos7的Redis集群安装及配置

Redis简介

Redis是一个基于C语言开发的开源(BSD许可),开源高性能的高级内存数据结构存储,用作数据库、缓存和消息代理。它支持数据结构,如 字符串、散列、列表、集合,带有范围查询的排序集,位图,超级日志,具有半径查询和流的地理空间索引。Redis具有内置复制,Lua脚本,LRU驱逐,事务和不同级别的磁盘持久性,并通过Redis Sentinel和Redis Cluster自动分区。

可以对这些数据类型进行原子性操作,例如 附加到字符串;递增哈希值;将元素推送到列表中;计算集合交集,并集和差异;或则在排序中获得排名最高的成员。为了实现其出色的性能,Redis使用内存数据集。根据您的配置情况,可以通过 每隔一段时间将数据集转存储到磁盘或通过每个命令附加到日志文件来保存它。如果您只需要功能丰富的网络内存缓存,则可以选择禁用持久性。

Redis还支持简单到设置的主从异步复制,具有非常快速的非阻塞第一次同步,自动重新连接以及在网络分割上的部分重新同步。

核心对象

RedisObject,图片来源:一文读懂redis

Redis五种数据结构对应的编码,图片来源:对象处理机制

五种数据结构类型,图片来源:初识Redis

1. Redis中的字符串

 Redis的STRING和其他编程语言或则其他键值存储提供的字符串非常的相似。本文在使用图片表示键值的时候,通常会将键名(key name)和值的类型放在方框的顶部,将值放在方框的里面。

STRING拥有一些和其他键值存储相似的命令,比如GET(获得值)、SET(设置值)和DEL(删除值)。

2. Redis中的列表

Redis对链表(linked-list)结构的支持使得它在键值存储的世界中独树一帜。一个列表结构可以有序的存储多个字符串,和表示字符串时使用的方法一样。

list-key是一个包含三个元素的列表键,注意列表中的元素时可以重复的。

Redis列表可执行的操作和很多编程语言李米娜的列表操作非常的相似:LPUSH命令和RPUSH命令分别用户将元素推送至列表的左端(left end)和右端(right end);LPOP命令和RPOP命令分别用于从列表的左端和右端弹出元素;LINDEX命令用于获取列表在给定位置上的一个元素;LRANGE命令用于获取列表在给定范围上的所有元素。

3. Redis中的集合

Redis的集合和列表都可以存储多个字符串,它们之间的不同在于,列表可以存储多个相同的字符串,而集合则通过使用散列表来保证自己存储的每个字符都是各个相同的(这些散列表只有键,但没有与键相关联的值)。

因为Redis的集合使用无序(unordered)方式存储元素,所以用户不能像使用列表那样,将元素推入到集合的某一端,或者从结合的某一端弹出元素。不过用户可以使用SADD命令将元素添加到集合,或者使用SREM命令从集合里面移除元素。另外,还使用SISMEMBER命令快速地检查一个元素是否已经存在于集合中,或者使用SMEMBERS命令获取集合包含的所有元素(如果集合包含的元素非常多,那么SMEMBERS命令的执行速度可能会很慢,所以请谨慎地使用这个命令)。

4. Redis中的散列

Redis的散列可以存储多个键值对之间的映射。和字符串一样,散列存储的值既可以时字符串又可以时数字值,并且用户同样可以对散列存储的数字值执行自增操作或自减操作。

hash-key是一个包含两个键值对的散列键。

散列在很多方面就像是一个微缩版的Redis,好几个字符串命令都有相应的散列版本。其操作命令:HSET 在散列里面关联起给定的键值对;HGET 获取指定散列键的值;HGETALL 获取散列包含的所有键值对;HDEL 如果给定键存在于散列里面,那么移除这个键。

5. Redis中的有序集合

Redis有序集合和散列一样,都用于存储键值对,其中有序集合的每个键称为成员(member),都是独一无二的,而有序集合的每个值称为分值(score),都必须是浮点数。有序集合是Redis里面唯一既可以根据成员访问元素(这一点和散列一样),又可以根据分值以及分值的排列顺序来访问元素的结构。

zset-key是一个包含两个元素的有序集合键。

和Redis的其他结构一样,用户可以对有序集合执行添加、移除和获取等操作。

Redis集群安装及配置

服务器及节点:

192.168.56.101 7000、1001、7002;

192.168.56.102 7003、7004、7005

1. 安装GCC编译工具,不然可能会编译的过程中出现编译失败情况

yum install gcc g++ gcc-c++ make

2. 下载并安装Redis 官网下载

 

cd /opt
如果未找到wget命令:yum -y install wget
wget http://download.redis.io/releases/redis-4.0.10.tar.gz
tar xzf redis-4.0.10.tar.gz
cd redis-4.0.10
make

 

3. 如果因为编译失败,又残留的文件

make distclean

4. 创建节点

步骤 1:

首先在 192.168.56.101机器上 /opt/redis-4.0.10目录下建 redis-cluster 目录

mkdir /opt/redis-4.0.10/redis-cluster

步骤 2:

 redis-cluster 目录下,创建名为7000、7001、7002的目录

 

mkdir 7000 7001 7002

 

步骤 3:

分别修改这三个配置文件,把如下redis.conf 配置内容粘贴进去

vi 7000/redis.conf 
vi 7001/redis.conf
vi 7002/redis.conf

redis.conf 示例:

复制代码
port 7000
bind 192.168.56.101
daemonize yes
pidfile /var/run/redis_7000.pid
logfile /var/log/redis/redis_7000.log
cluster-enabled yes
cluster-config-file nodes_7000.conf
cluster-node-timeout 10100
dbfilename dump_7000.rdb
appendonly yes
appendfilename "appendonly_7000.aof"
复制代码

说明:

复制代码
#端口7000,7001,7002
port 7000
#默认ip为127.0.0.1,需要改为其他节点机器可访问的ip,否则创建集群时无法访问对应的端口,无法创建集群
bind 192.168.56.101
#redis后台运行
daemonize yes
#pidfile文件对应7000,7001,7002
pidfile /var/run/redis_7000.pid
#开启集群,把注释#去掉
cluster-enabled yes
#集群的配置,配置文件首次启动自动生成 7000,7001,7002          
cluster-config-file nodes_7000.conf
#请求超时,默认15秒,可自行设置 
cluster-node-timeout 10100    
#aof日志开启,有需要就开启,它会每次写操作都记录一条日志
appendonly yes
复制代码

步骤 4:

接着在另外一台机器上(192.168.56.102)重复以上三步,只是把目录改为7003、7004、7005对应的配置文件也按照这个规则修改即可

 5. 启动节点

# 第一台机器上执行 3个节点
for((i=0;i<=2;i++)); do /opt/redis-4.0.10/src/redis-server  /opt/redis-4.0.10/redis-cluster/700$i/redis.conf; done
# 第二台机器上执行 3个节点
for((i=3;i<=5;i++)); do /opt/redis-4.0.10/src/redis-server  /opt/redis-4.0.10/redis-cluster/700$i/redis.conf; done
# 启动单个节点示例
/opt/redis-4.0.10/src/redis-server /opt/redis-4.0.10/redis-cluster/7000/redis.conf

6. 检查服务

检查各 Redis 各个节点启动情况

ps -ef | grep redis           //redis是否启动成功
netstat -tnlp | grep redis    //监听redis端口

安装 netstat :https://www.cnblogs.com/cocoajin/p/4064547.html

7. 安装Ruby

yum -y install ruby ruby-devel rubygems rpm-build
gem install redis

安装过程中可能会出现异常情况发生,比如:

解决办法:https://blog.csdn.net/FengYe_YuLu/article/details/77628094

8. 创建集群

注意:

在任意一台上运行 不要在每台机器上都运行,一台就够了

Redis 官方提供了 redis-trib.rb 这个工具,就在解压目录的 src 目录中

/opt/redis-4.0.10/src/redis-trib.rb create --replicas 1 192.168.56.101:7000 192.168.56.101:7001 192.168.56.101:7002 192.168.56.102:7003 192.168.56.102:7004 192.168.56.102:7005

出现以下内容,则表示集群创建成功了:

复制代码
[root@master1 /]# /opt/redis-4.0.10/src/redis-trib.rb create --replicas 1 192.168.56.101:7000 192.168.56.101:7001 192.168.56.101:7002 192.168.56.102:7003 192.168.56.102:7004 192.168.56.102:7005
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.56.101:7000
192.168.56.102:7003
192.168.56.101:7001
Adding replica 192.168.56.102:7005 to 192.168.56.101:7000
Adding replica 192.168.56.101:7002 to 192.168.56.102:7003
Adding replica 192.168.56.102:7004 to 192.168.56.101:7001
M: 6af67c2741b3001e6d328621ac8a2e539b65d683 192.168.56.101:7000
   slots:0-5460 (5461 slots) master
M: e2f298953141f46b255b0f35372af917afc16205 192.168.56.101:7001
   slots:10923-16383 (5461 slots) master
S: 3516ed59324a7421878b2c17aba44d91ec7e9439 192.168.56.101:7002
   replicates ab5b4535f3382c13d7afb91d005e8a87d830eb46
M: ab5b4535f3382c13d7afb91d005e8a87d830eb46 192.168.56.102:7003
   slots:5461-10922 (5462 slots) master
S: 16822c6d58461f9edaf965aa53efdac59d1adce5 192.168.56.102:7004
   replicates e2f298953141f46b255b0f35372af917afc16205
S: c00dea4a44e01e1f17b29f7b3b95e0c57b06a653 192.168.56.102:7005
   replicates 6af67c2741b3001e6d328621ac8a2e539b65d683
Can I set the above configuration? (type 'yes' to accept): yes
复制代码

输入 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.56.101:7000)
M: 6af67c2741b3001e6d328621ac8a2e539b65d683 192.168.56.101:7000
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: c00dea4a44e01e1f17b29f7b3b95e0c57b06a653 192.168.56.102:7005
   slots: (0 slots) slave
   replicates 6af67c2741b3001e6d328621ac8a2e539b65d683
S: 3516ed59324a7421878b2c17aba44d91ec7e9439 192.168.56.101:7002
   slots: (0 slots) slave
   replicates ab5b4535f3382c13d7afb91d005e8a87d830eb46
M: ab5b4535f3382c13d7afb91d005e8a87d830eb46 192.168.56.102:7003
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 16822c6d58461f9edaf965aa53efdac59d1adce5 192.168.56.102:7004
   slots: (0 slots) slave
   replicates e2f298953141f46b255b0f35372af917afc16205
M: e2f298953141f46b255b0f35372af917afc16205 192.168.56.101:7001
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
复制代码

重启集群过程中,可能出现问题:

[ERR] Node 192.168.56.101:7000 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

解决:

需要将redis-cluster数据文件清空,执行脚本如下:

 

rm -rf /opt/redis-4.0.10/redis-cluster/dump.rdb /opt/redis-4.0.10/redis-cluster/nodes_*.conf /opt/redis-4.0.10/redis-cluster/appendonly.aof

 

9. 关闭集群

 

 推荐:

pkill redis

也可以通过循环节点方式,逐个关闭:

for((i=0;i<=2;i++)); do /opt/redis-4.0.10/src/redis-cli -c -h 192.168.56.101 -p 700$i shutdown; done
for((i=3;i<=5;i++)); do /opt/redis-4.0.10/src/redis-cli -c -h 192.168.56.102 -p 700$i shutdown; done

关闭单个节点:

/opt/redis-4.0.10/src/redis-cli -c -h 192.168.56.101 -p 7000 shutdown

10. 集群验证

步骤1 . 连接集群测试

参数 -C 可连接到集群,因为 redis.conf 将 bind 改为了ip地址,所以 -h 参数不可以省略,-p 参数为端口号

我们在192.168.256.101机器redis 7000 的节点set 一个key

 

/opt/redis-4.0.10/src/redis-cli -h 192.168.56.101 -c -p 7000
执行如下:
set name xushuyi
get name

 

我们在192.168.56.102机器redis 7000 的节点get一个key

 

/opt/redis-4.0.10/src/redis-cli -h 192.168.56.102 -c -p 7000
执行如下:
get name

 

步骤2 . 检查集群状态

/opt/redis-4.0.10/src/redis-trib.rb check 192.168.56.101:7000

步骤3 . 列出集群节点

/opt/redis-4.0.10/src/redis-cli -h 192.168.56.101 -c -p 7000

更详细的,请参考:https://segmentfault.com/a/1190000010682551

11. spring boot 2.0.x 服务集成Redis集群

1. 引入依赖

复制代码
<!-- redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- redis 依赖 commons-pool -->
<dependency>
    <groupId>org.apache.commons</groupId>    
    <artifactId>commons-pool2</artifactId>
</dependency>
复制代码

2. 配置文件

复制代码
# redis 集群配置
spring:
  redis:
    cluster:
      nodes: 192.168.56.101:7000,192.168.56.101:7001,192.168.56.101:7002,192.168.56.102:7003,192.168.56.102:7004,192.168.56.102:7005
    timeout: 6000ms # 连接池超时时间(毫秒)
    # 密码没有可以不填
    password:
    database: 0 # 数据库索引
    lettuce:
      pool:
        max-active: 8 # 连接池最大活跃连接数(使用负值表示没有限制)
        max-idle: 8 # 连接池最大空闲连接数
        max-wait: -1ms # 连接池最大阻塞等待时间 毫秒(使用负值表示没有限制)
        min-idle: 0 # 最小空闲连接数
复制代码

3. 创建RedisConfig配置文件

复制代码
package com.sinosoft.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @ClassName: RedisConfig
 * @Description: Redis配置
 * @author: Created by xushuyi <a href="xu_xxx1002@163.com">Contact author</a>
 * @date: 2019/2/28 16:01
 * @Version: V1.0
 */
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig {


    /**
     * 注入自定义的RedisTemplate
     *
     * @param redisConnectFactory LettuceConnectionFactory
     * @return RedisTemplate
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectFactory);
        // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

}
复制代码

4. 启动入口增加  @EnableCaching

5. 单元测试

复制代码
package com.sinosoft.redis;

import com.sinosoft.AccountApplication;
import lombok.extern.slf4j.Slf4j;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

/**
 * @ClassName: RedisTest
 * @Description: Redis测试
 * @author: Created by xushuyi <a href="xu_shuyi1002@163.com">Contact author</a>
 * @date: 2019/2/28 16:18
 * @Version: V1.0
 */
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class) // SpringJUnit支持,由此引入Spring-Test框架支持!
@SpringBootTest
@Import(AccountApplication.class) // 指定我们SpringBoot工程的Application启动类
@ActiveProfiles(profiles = "dev") // 指定Application启动需要引用的配置文件
@WebAppConfiguration // 由于是Web项目,Junit需要模拟ServletContext,因此我们需要给我们的测试类加上@WebAppConfiguration
public class RedisTest {

    /**
     * 获取RedisTemplate
     */
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 测试前
     */
    @Before
    public void before() {
        log.info("测试前...");
    }

    /**
     * 开始测试
     */
    @Test
    public void redisTest() {
        // 测试通过RedisTemplate操作
        redisTemplate.opsForValue().set("name", "huachunjie");
        Object name = redisTemplate.opsForValue().get("name");
        log.info("获取Redis集群中key为name对应的值:{}", name);
    }

    @After
    public void after() {
        log.info("测试后...");
    }
}
复制代码

6. 基于注解的方式实现

复制代码
    /**
     * 测试Redis缓存
     *
     * @param requestInfo 入参
     * @return
     */
    @Override
    @Cacheable(value = "cacheInfo", key = "#requestInfo.token", condition = "#requestInfo != null")
    public ResponseInfo testRedis(RequestInfo<String> requestInfo) {
        log.info("如果没有进来,则说明启用了Redis缓存...");
        return new ResponseInfo<>(true, "success", 200, null);
    }
复制代码
相关文章
|
4月前
|
存储 负载均衡 NoSQL
【赵渝强老师】Redis Cluster分布式集群
Redis Cluster是Redis的分布式存储解决方案,通过哈希槽(slot)实现数据分片,支持水平扩展,具备高可用性和负载均衡能力,适用于大规模数据场景。
371 2
|
5月前
|
关系型数据库 应用服务中间件 nginx
Docker一键安装中间件(RocketMq、Nginx、MySql、Minio、Jenkins、Redis)
本系列脚本提供RocketMQ、Nginx、MySQL、MinIO、Jenkins和Redis的Docker一键安装与配置方案,适用于快速部署微服务基础环境。
|
2月前
|
NoSQL Java 网络安全
SpringBoot启动时连接Redis报错:ERR This instance has cluster support disabled - 如何解决?
通过以上步骤一般可以解决由于配置不匹配造成的连接错误。在调试问题时,一定要确保服务端和客户端的Redis配置保持同步一致。这能够确保SpringBoot应用顺利连接到正确配置的Redis服务,无论是单机模式还是集群模式。
273 5
|
2月前
|
NoSQL 算法 Redis
【Docker】(3)学习Docker中 镜像与容器数据卷、映射关系!手把手带你安装 MySql主从同步 和 Redis三主三从集群!并且进行主从切换与扩容操作,还有分析 哈希分区 等知识点!
Union文件系统(UnionFS)是一种**分层、轻量级并且高性能的文件系统**,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem) Union 文件系统是 Docker 镜像的基础。 镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
498 5
|
3月前
|
存储 监控 NoSQL
Redis高可用架构全解析:从主从复制到集群方案
Redis高可用确保服务持续稳定,避免单点故障导致数据丢失或业务中断。通过主从复制实现数据冗余,哨兵模式支持自动故障转移,Cluster集群则提供分布式数据分片与水平扩展,三者层层递进,保障读写分离、容灾切换与大规模数据存储,构建高性能、高可靠的Redis架构体系。
|
8月前
|
存储 NoSQL 数据库
Redis 逻辑数据库与集群模式详解
Redis 是高性能内存键值数据库,广泛用于缓存与实时数据处理。本文深入解析 Redis 逻辑数据库与集群模式:逻辑数据库提供16个独立存储空间,适合小规模隔离;集群模式通过分布式架构支持高并发和大数据量,但仅支持 database 0。文章对比两者特性,讲解配置与实践注意事项,并探讨持久化及性能优化策略,助你根据需求选择最佳方案。
316 5
|
3月前
|
NoSQL Java 调度
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
分布式锁是分布式系统中用于同步多节点访问共享资源的机制,防止并发操作带来的冲突。本文介绍了基于Spring Boot和Redis实现分布式锁的技术方案,涵盖锁的获取与释放、Redis配置、服务调度及多实例运行等内容,通过Docker Compose搭建环境,验证了锁的有效性与互斥特性。
255 0
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
|
8月前
|
NoSQL 数据可视化 关系型数据库
安装 Redis
本文主要介绍了Linux系统下Redis的安装步骤,包括卸载旧版本、下载新版本、编译安装以及配置启动等详细操作,并解释了Redis默认端口6379的由来。同时,文章还简要说明了Windows环境下Redis的下载与服务安装方法。最后,推荐了几款Redis可视化管理工具,如RedisView、QuickRedis、AnotherRedisDesktopManager和RedisPlus,提供了它们的功能特点及下载链接,方便用户根据需求选择合适的工具进行数据库管理。
601 1
|
5月前
|
IDE Ubuntu Java
在Ubuntu18.04安装兼容JDK 8的Eclipse集成开发环境的指南。
完成以上步骤后,您将在Ubuntu 18.04系统上成功安装并配置了Eclipse IDE,它将与JDK 8兼容,可以开始进行Java开发工作。如果遇到任何问题,请确保每一步骤都正确执行,并检查是否所有路径都与您的具体情况相匹配。
259 11
|
5月前
|
负载均衡 NoSQL Redis
【赵渝强老师】Redis的主从复制集群
Redis主从复制是指将一台Redis服务器的数据复制到其他Redis服务器,实现数据热备份、故障恢复、负载均衡及高可用架构的基础。主节点负责写操作,从节点同步数据并可提供读服务,提升并发处理能力。
165 5