springboot 与 redis 的集成、主从复制、redis集群、redis哨兵模式

SpringBoot 整合Redis

构建springboot项目;项目结构

一、springboot整Redis

1、pom.xml文件添加redis依赖

       <!--
            说明:在SpringBoot2.x之后,原来使用的Jedis被替换为了lettuce
            Jedis:采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用Jedis pool 连接池 ! 更像BIO模式
            lettuce:采用netty,实例可以再多个线程中进行共享,不存在线程不安全的情况,可以减少线程数据了,更像NIO模式
        -->
        <!--redis 依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

2、application.properties文件配置redis

# springboot所有的配置类,都有一个自动配置类,RedisAutoConfiguration
# 自动配置类都会绑定一个properties配置文件,RedisProperties

#配置redis
spring.redis.host=192.168.122.1
spring.redis.port=6379
spring.redis.password=redisRoot

3、在test类测试,操作redis

@SpringBootTest
class SpbApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate; //注入RedisTemplate

    @Test
    void contextLoads() {
        redisTemplate.opsForValue().set("key","studyRedis");
        String result = (String)redisTemplate.opsForValue().get("key");
        System.out.println(result);//studyRedis
    }

}

二:自定义RedisTemplate

1、创建新的包config包,并创建RedisConfig类

@Configuration
public class RedisConfig {

    //自定义RedisTemplate,固定写法
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        RedisTemplate<String, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);

        //Json序列化配置
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        //String 的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        //key 采用String 的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        //hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);

        //value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //hash的value序列化采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();

        return template;
    }
}

2、测试

@SpringBootTest
class SpbApplicationTests {

    //@Autowired
    //private RedisTemplate redisTemplate; //注入原RedisTemplate

    @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate redisTemplate ;//注入自定义的RedisTemplate

    @Test
    void contextLoads() {
        redisTemplate.opsForValue().set("key","studyRedis");
        String result = (String)redisTemplate.opsForValue().get("key");
        System.out.println(result);
    }
}

三:Redis.conf详解

 

1、配置文件unit单位对大小写不敏感
2、多个配置文件组成一个
3、网络配置
	bind 127.0.0.1 #绑定的ip
	protected-mode yes #保护模式
	port 6379 #端口设置
4、通用配置
daemonize yes #以守护进程的方式运行,默认为no,需要改为yes
pidfile /var/run/redis_6379.pid #如果以守护进程运行 ,我需要指定一个pid文件

# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel notice
logfile "" #日志文件的位置名
databases 16 #数据库的数量,默认16个
always-show-logo yes #是否显示logo,默认开启

5、快照SNAPSHOTTING:持久化是会用到,在规定的时间内,执行了多少次操作,则会持久化到文件.rdb和.aof 
#save 时间(s) 
save 900 1 #如果在900s内,至少有1个key进行了修改,就进行持久化操作
save 300 10#如果在300s内,至少有10个key进行了修改,就进行持久化操作
save 60 10000#如果在60s内,至少有1w个key进行了修改,就进行持久化操作

stop-writes-on-bgsave-error yes #持久化出错,是否还需要继续工作
rdbcompression yes #是否压缩rdb文件,需要消耗CPU资源
rdbchecksum yes #保存rdb文件时,进行错误的检查校验
dir ./ #rdb 文件保存的目录

6、REPLICATION复制(主从复制)
7、SECURITY 安全
requirepass redisRoot #设置redis密码 :redisRoot
config set requirepass "redisRoot" #配置redis密码
auth redisRoot #使用密码登录
config get requirepass #查看密码
8、CLIENTS 限制
maxclients 10000 #最大的客户端连接数为1w
maxmemory <bytes> #最大内存设置
maxmemory-policy noeviction #内存到达上限之后的处理策略 
	1、volatile-lru:只对设置了过期时间的key进行LRU(默认值) 
	2、allkeys-lru : 删除lru算法的key 
	3、volatile-random:随机删除即将过期key 
	4、allkeys-random:随机删除   
	5、volatile-ttl : 删除即将过期的 
	6、noeviction : 永不过期,返回错误
	
9、APPEND ONLY MODE aof配置
appendonly no #默认是不开启的,默认是使用rdb方式持久化,在大部分所有的情况下,rdb完全够用
appendfilename "appendonly.aof" #持久化的文件的名字
# appendfsync always #每次修改都会同步,消耗性能
appendfsync everysec #每秒执行一次同步,可能会丢失这1s的数据
# appendfsync no #不执行同步,效率最高,一般不使用

Redis为持久化

Redis为持久化提供了两种方式:

  • RDB:在指定的时间间隔能对你的数据进行快照存储。
  • AOF:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据。
RDB持久化配置:

# 时间策略
save 900 1
save 300 10
save 60 10000

# 文件名称
dbfilename dump.rdb

# 文件保存路径
dir /home/work/app/redis/data/

# 如果持久化出错,主进程是否停止写入
stop-writes-on-bgsave-error yes

# 是否压缩
rdbcompression yes

# 导入时是否检查
rdbchecksum yes
AOF的持久化配置

# 是否开启aof
appendonly yes

# 文件名称
appendfilename "appendonly.aof"

# 同步方式
appendfsync everysec

# aof重写期间是否同步
no-appendfsync-on-rewrite no

# 重写触发配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 加载aof时如果有错如何处理
aof-load-truncated yes

# 文件重写策略
aof-rewrite-incremental-fsync yes


appendfsync everysec 它其实有三种模式:
always:把每个写命令都立即同步到aof,很慢,但是很安全
everysec:每秒同步一次,是折中方案
no:redis不处理交给OS来处理,非常快,但是也最不安全
一般情况下都采用 everysec 配置,这样可以兼顾速度与安全,最多损失1s的数据。

aof-load-truncated yes 如果该配置启用,在加载时发现aof尾部不正确是,会向客户端写入一个log,但是会继续执行,如果设置为 no ,发现错误就会停止,必须修复后才能重新加载。


RDB方式原理:当redis需要做持久化时(执行SAVA或者BGSAVA命令,或者是达到配置条件时执行),redis会fork一个子进程,子进程将数据写到磁盘上一个临时RDB文件中,当子进程完成写临时文件后,将原来的RDB替换掉(默认文件名为dump.rdb)
RDB优缺点:
定时备份,Redis效率高,但是容易造成数据丢失,丢失的多少和备份策略有关

AOF方式原理:AOF就可以做到全程持久化,Redis每执行一个修改数据的命令,都会把这个命令添加到AOF文件中,当Redis重启时,将会读取AOF文件进行“重放”以恢复到 Redis关闭前的最后时刻。
AOF优缺点
AOF基本可以保证数据不丢失,但是AOF持久化文件会变的越来越大。例如我们调用incr test命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的。

redis 发布订阅
redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息.

订阅端(订阅者:subscribe):
    127.0.0.1:6379> subscribe redis-world #订阅redis-world频道
    1) "subscribe"
    2) "redis-world"
    3) (integer) 1
    1) "message" #消息
    2) "redis-world" #频道
    3) "welcome redis world" #消息内容

发送端(发送者:publish):
    127.0.0.1:6379> publish redis-world "welcome redis world" #发布者发布消息到频道
    (integer) 1

使用场景:
1、实时消息
2、在线聊天
3、关注、订阅
更为复杂的使用消息中间件来实现


Redis主从复制
主从复制,是指 将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master/leader),后者称为从节点(slave/follower);数据的复制是单向的,只能由主节点到从节点。master以写为主,slave以读为主。大部分情况下80%的操作是读数据。

主从复制的作用主要包括:
1、数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
2、故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
3、负载均衡:主从复制的基础上,配合读写分离,可以由主节点提供写服务,从节点提供读服务,分担服务器负载,可以提高服务器的并发量。
4、高可用基石:除上述作用外,主从复制还是哨兵和集群能够实施的基础,因此主从复制是Redis的高可用的基础。

一般来说,至少3台服务器,一主二从。(单个redis的内存不好超过20G,最好搭建集群)

环境配置:(只配置从库,因为redis默认为主库)
127.0.0.1:6379> info replication #当前库的信息
# Replication
role:master #当前库的角色
connected_slaves:0 #连接从库的数量
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

复制3个配置文件:
1、端口(端口的话,自己记得就好)
2、pid名
3、log日志文件名
4、dump.rdb名

配置完成后,分别启动数据库。当前3台数据库默认都是主节点,只配置充当从节点的数据库,对它们配置主节点的信息。
slaveof ip port  #配置主机的ip和端口号

当前从节点的配置是通过命令行进行配置的,是暂时的。在实际应用是在redis配置文件中配置的,永久有效,当从节点启动服务就为扮演从节点的角色。

#replicaof <masterip> <masterport> 在配置文件中解注这行,添加主机的ip和端口号即可.
从机只可读,不可写。

主从模式结构1是这样子的:
             |
             |--slave1(从机)
master--|
             |--slave2(从机)
             |

测试:
主机断开连接,从机会依然连接到主机,但是没有写操作了。主机服务正常了,从机可以正常获取到主机写入的数据。如果从机宕机,主机进行了写操作,从机再次开启服务,数据会立马同步到数据。(如果从机是使用命令配置的,开启服务后会变为主机,需要再次配置主机信息使自己变为从机,主机的数据会同步到当前从机)

复制原理:
slave(从机)启动成功连接到master(主机)后会发送一个sync(同步)命令,
主机接到命令,启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,主机将传送整个数据文件到从机,并完成一次完全同步。
全量复制:而从机服务在接收到数据库文件数据后,将其存盘并加载到内存中。
增量复制:主机继续新的所有收集到的修改命令一次传给从机,完成同步,但是只要是重新连接主机,一次完全同步(全量复制)将自动执行

主从模式结构2是这样子的:
(主机)  (从机/主机) (从机)   
master--|--slave1--|slave2
如果master断开了,slave1和slave2没有了主节点,现在可以手动在slave1上配置slaveof no one,是自己成为主机

意思两种模式,在实际开发的过程中都不用。不够灵活,所以,就引出了哨兵模式。


Redis哨兵模式
监控后台主机是否存活,如果不存活了就需要在从机中选举一个作为主机。
哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,单独运行。哨兵通过发送命令,等待redis服务器响应,从而监控运行的多个Redis实例。

哨兵的两个作用:
1、通过发送命令,让Redis服务器返回监控其运行状态,包括服务器和从服务器。
2、当哨兵检测到主机宕机,会自动将从机切换成主机。

一般保证系统的能正常的选举主机,一个哨兵是不够的,一般会设计多个哨兵进行监控,各个哨兵之间还会进行监控,形成多哨兵模式。

多个哨兵模式:当一个哨兵检测到主机不可用,这个现象称为主观下线;当所有的哨兵检测到主机不可用,才认为主机不可用了;哨兵之间会进行一次投票,投票结果由一个哨兵发起,进行failover(故障转移)操作。切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。

哨兵配置(单个)(默认30秒后会选举出一个主机)
1、创建sentinel.conf文件
sentinel monitor myredis 127.0.0.1 6379 1 (主机 端口 1:代表主机不可用,哨兵通过投票得到的最多票数从从机中选出一台作为主机)
2、启动哨兵 redis-sentinel 配置文件sentinel.conf 

当选取主机后,原主机如果正常服务,只能作为当前的主机的从机。

哨兵模式的优缺点:
优点:1)哨兵集群,基于主从复制模式,所有的主从配置优点;
      2)主从可以切换,故障可以转移,系统的可用性会更好
      3)哨兵模式就是主从模式的升级,由手动到自动,功能更加灵活,强大
缺点: 1)Redis在线扩容繁琐,集群容量一旦到达上限,扩容困难
      2)实现哨兵模式的配置繁琐,配置选择项太多

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值