Java架构学习(三十)redis高级&redis高可用&主从复制&读写分离&集群&哨兵机制&持久化RDB存储&持久化AOF存储&事务机制&Redis发布订阅

版权声明:本文为博主原创文章,未经博主允许不得转载。如需要授权请联系[email protected] https://blog.csdn.net/leeue/article/details/82622379

redis高级

一、基础回顾

什么是redis?
答:redis是非关系型数据库,使用redis的目的是:减轻数据库访问压力。
数据库是做IO操作,使用redis是内存操作,内存数据库,
效率要比IO效率高。这个就是缓存。

如果数据库值与redis值不同步该怎么解决?
答:清缓存,再同步数据库中的值,然后缓存到redis中。

redis应用场景:减轻数据库访问压力、验证码问题、
             分布式锁、解决分布式数据同步。

使用redis实现分布式锁--- 唯一难道释放锁资源。

二、redis高可用

1、主从复制
   作用:(读写分离、备份、集群、宕机容错机制、高可用)
2、哨兵机制
    作用: 高可用、监听机制
3、Redis持久化机制
    作用:数据恢复、高可用
    rdb存储、aof存储优缺点
4、redis是否存在事务。有事务
5、redis发布订阅 -- 消息中间件
6、缓存雪崩、击穿  -- 架构知识点

三、SpringBoot封装redis

封装代码:
RedisService.java
package com.leeue.service;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
import org.springframework.data.redis.support.collections.RedisZSet;
import org.springframework.stereotype.Service;

@Service
public class RedisService {
    // redis基本数据类型:string list set zset hash
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    // string
    private String strValue = null;
    private List<String> listValue = null;
    private Set<String> setValue = null;
    private Map mapValue = null;
    private Set<TypedTuple<String>> zsetValue = null;

    public void setString(String key, String value) {
        this.setObject(key, value, null);
    }

    public void setString(String key, String value,Long time) {
        this.setObject(key, value, time);
    }

    public void setList(String key, List<String> listValue) {
        this.setObject(key, listValue,null);
    }
    public void setList(String key, List<String> listValue, Long time) {
        this.setObject(key, listValue,time);
    }


    public void setHash(String key, Map<String, Object> mapValue) {
        this.setObject(key, mapValue,null);
    }

    public void setSet(String key, String value) {
        this.setObject(key, value,null);
    }

    public void setZset(String key, String value) {
        this.setObject(key, value,null);
    }

    public void setObject(String key, Object value, Long time) {
        if (StringUtils.isEmpty(key) || null == value) {

            return;
        }
        // 判断类型 存放string类型的
        if (value instanceof String) {
            strValue = (String) value;
            stringRedisTemplate.opsForValue().set(key, strValue);
            if (time != null) {
                stringRedisTemplate.opsForValue().set(key, strValue, time, TimeUnit.SECONDS);
            }
            return;
        }
        // 存放list类型
        if (value instanceof List) {
            listValue = (List<String>) value;
            for (String strList : listValue) {
                stringRedisTemplate.opsForList().leftPush(key, strList);
                if (time != null) {
                    stringRedisTemplate.opsForValue().set(key, strList, time, TimeUnit.SECONDS);
                }
            }
            return;
        }
        // 存放set
        if (value instanceof Set) {
            setValue = (Set<String>) value;
            for (String strSet : setValue) {
                stringRedisTemplate.opsForSet().add(key, strValue);
            }
            return;
        }
        // 存放hash
        if (value instanceof Map) {
            mapValue = (Map) value;
            stringRedisTemplate.opsForHash().putAll(key, mapValue);
            return;
        }
        // 存放Zset 这个不清楚
        if (value instanceof RedisZSet) {
            zsetValue = (Set<TypedTuple<String>>) value;
            for (TypedTuple<String> strZset : zsetValue) {
                stringRedisTemplate.opsForZSet().add(key, zsetValue);
            }

        }
    }
    //默认去调用string类型
    public String getStringKey(String key) {
      return    stringRedisTemplate.opsForValue().get(key);
    }
}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.leeue</groupId>
    <artifactId>30_SpringBoot_Redis</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang -->
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>

    </dependencies>
</project>

application.properties

########################################################
###Redis (RedisConfiguration)
########################################################
# 使用的是第0个库
spring.redis.database=0   
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=123456
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.timeout=5000
Redis怎么存放对象?用什么数据类型好?
答:使用String类型,采用json格式,
   将对象转换程json格式存放到redis中。
   从redis获取到json的值,反序列化对象。

第四、redis主从复制配置

redis高可用机制:
答:redis主从复制:作用:数据备份、读写分离、集群、宕机容错机制
   redis怎么实现主从复制?
      只需要修改配置文件。
   redis持久化机制:
   redis哨兵机制:


redis主从复制只需要修改配置文件

redis只支持一主多从。
图解:
    130为主服务器
    131、132为从服务器
主服务器拥有读、写
从服务器只有读的操作


如果主挂了,redis有个哨兵机制,监听每台服务器上的redis,
如果发现主服务器挂了,会在从服务器中选出一个服务器为主服务器。


如果有服务器挂了,使用keepalived监听,自动重启。
哨兵机制就是选举出主服务器。
如果一直重启失败,就会邮件通知运维人员。

redis高可用:哨兵机制+keepalived监听

这里写图片描述

五、redis主从复制的实现

mysql主从复制实现原理:通过二进制文件来实现。

redis主从复制实现原理:是使用快照文件的,也是实时同步的

搭建服务器集群:第一点使用root账号登陆,第二点关闭所有防火墙。

步骤:

1、在linux找到redis目录下的etc目录下,修改redis.conf文件如图:

这里写图片描述

2、修改如下:

这里写图片描述

3、启动主从redis:
命令:
启动redis
./redis-server /usr/local/redis/etc/redis.conf

连接redis
./redis-cli -h 127.0.0.1 -p 6379 -a '123456'
最后主服务器redis中使用info命令来查看。可以知道配置成功没有

这里写图片描述

从节点不能做写操作:如图:

这里写图片描述

六、Redis哨兵机制(自带)

redis哨兵机制:就是如果主挂了,就会在从服务器中选取一个举做为主服务器。
找到redis安装目录:copy文件到  local下面的redis的etc下

命令:cp sentinel.conf  /usr/local/redis/etc

这里写图片描述

这个设置每隔多少毫秒监听主服务器

这里写图片描述

设置主服务器下面有几台从服务器

这里写图片描述

当主服务器的redis挂了shutdown 哨兵机制打印出来的日志
这里选择了131为主服务器了

这里写图片描述

这里写图片描述

哨兵机制是redis单独程序。

七、redis持久化存储RDB存储

什么是Redis持久化?就是将内存数据保存到硬盘上。
redis持久化是通过AOF与RDB两种模式来实现的。
可以混用。 
灾难备份:
Redis特征:值存放在在内存中。
redis宕机后:值是否会消失,答不会消失。
不会的,redis支持持久化机制:
1、rdb存储:是以二进制文件存储,不是实时才能吃。存储超过10key以上,开始持久化机制。优点体积小。、
2、aof存储:是实时存储。日志文件方式存储。文件大。

rdb存储:在redis.conf里面可以看出

这里写图片描述

这个表示更改了一个key时间隔了900秒,就会进行持久化存储生成一个
dump.rdb文件。更改了10个key300秒进行存储。以此类推。

同时redis如果shotdown   内存中还是有这个文件。
断开连接的时候,会再进行备份一次dump.rdb文件的。


rdb存储在灾难备份的时候不会这样使用的,
因为rdb存储需要达到一定的次数才会备份。

八、Redis持久化AOF存储

aof存储:是以操作日志实时进行存储的,缺点就是体积大。
在redis.conf文件找到appendonly yes

这里写图片描述

在持久化中rdb存储和aof存储是一起使用的。

总结:redis宕机之后,redis值会失效吗?
答:不会,redis默认开启rdb存储的,
注明:redis存储方式在规定的时间内,
     key、value达到一定存储次数才开始做数据持久化。
 如果是断电、直接杀死redis进程,
 导致redis宕机,操作没有达到次数,redis值就会失效。

rdb存储方式在redis断开连接的时候就会进行备份。
最好采用aof方式来进行持久化。因为aof是实时进行保存的。

九、Redis事务机制

redis事务:开启事务命令 : multi   提交事务命令:exec

这里写图片描述

十、redis的发布订阅

redis类似消息中间件的功能就是发布订阅。 点对点进行通讯。

redis发布定义含义:创建一个频道
如图所示就是redis中的发布订阅

这里写图片描述

创建频道命令:SUBSCRIBE  leeue     这边发布
订阅该频道:   publish leeue        这边接受实时显示。

猜你喜欢

转载自blog.csdn.net/leeue/article/details/82622379