Redis学习系列

版权声明:本文为作者的原创文章,未经允许不得转载。 https://blog.csdn.net/lele1658676840/article/details/89228939

1、什么是Redis

Redis是一个基于内存的高性能Key-Value数据库

2、Redis为什么这么快

  • 完全基于内存,绝大部分请求是纯粹的内存操作,执行效率高
  • 数据结构简单,对数据的操作也简单
  • 采用单线程,单线程也能处理高并发请求,想多核也可启动多实例;可保证操作的串行执行,从而减少不必要的上下文切换
  • 使用多路I/O复用模型,非阻塞I/O

3、Redis数据类型

  1. String:最基本的数据类型,二进制安全

  2. Hash:String元素组成的散列,特别适合用于存储对象

  3. List:简单的字符串列表,按照插入顺序排序。两端插入

    list的内部实现为一个双向链表,即可以支持反向查找和遍历,更方便操作。

    使用场景:1. 最新消息排行榜;2. 分页:lrange

  4. Set:String类型的无序集合,集合成员是唯一的,不能出现重复数据,通过hash表实现,复杂度O(1)

    set的内部实现是一个value永远为null的HashMap,实际就是通过计算hash来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。

    使用场景:1. 去重列表;2. 存储一些集合性的数据,如微博应用中,关注人和粉丝分别存储在一个集合,Redis还提供了求交集、并集、差集等操作实现共同关注,共同喜好等。

  5. Zset:String类型的有序集合,不允许成员重复,每个元素关联一个double类型的分数,默认小到大排序

    使用场景:1. 排行榜相关;2. 带权重的队列,普通消息score为1,重要信息score为2,倒序取,重要的任务先执行

  6. Redis HyperLogLog 是用来做基数统计的算法

4、Redis持久化方式

  • RDB持久化:Redis会定期保存数据快照到一个rdb文件中,并在启动的时候自动加载rdb文件,恢复之前保存的数据。可以在配置文件中配置Redis进行快照的时机。默认为dump.rdb,会备份dump.rdb

    Redis默认配置:

    • save 900 1 //在900秒内至少有一个key发生变化,触发一次持久化操作
    • save 300 10 //在300秒内至少10个key发生变化,触发一次持久化操作
    • save 60 10000 //在60秒内至少10000个key

    save:阻塞Redis的服务器进程,知道rdb文件被创建完毕

    BGsave:Fork出一个子进程来创建rdb文件,不阻塞服务器进程

    触发时机:

    • 指定时间间隔内,执行指定次数的写操作
    • 执行save或者bgsave命令
    • 执行flushall命令,清空数据库所有数据
    • 执行shutdown命令,保证服务器正常关闭并且不丢失任何数据

    优点:

    • 全量数据快照,适合做备份,适用于灾难恢复
    • 文件比较小,恢复速度快
    • 性能最大化,因为fork出子进程来进行rdb的创建,不阻塞服务

    缺点:

    • 可能会丢失数据
    • 当数据过大时,服务器会暂停几百毫秒或者一秒钟
  • AOF持久化:Redis默认不开启。采用日志追加的形式来记录每个写操作。Redis重启以后,会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

    要开启AOF需要在配置文件设置

    • redis默认关闭,开启需要将no改为yes

      appendonly yes
      
    • 指定本地数据库文件名,默认值为 appendonly.aof

    • 指定更新日志文件

      # appendfsync always  //同步持久化,每次发生数据变化后就立刻写入磁盘,性能差但数据完整性高
      appendfsync everysec  //出厂默认推荐,每秒异步记录一次
      # appendfsync no  //不同步
      
    • 配置重写触发机制

      auto-aof-rewrite-percentage 100
      auto-aof-rewrite-min-size 64mb
      

      当AOF文件大小是上次重写后大小的一倍,并且文件大于64MB的时候触发,一般设置为3GB,64M太小

    • 根据AOF文件恢复数据

      正常情况下,将appendonly.aof文件拷贝到redis的安装目录下的bin目录下,重启redis服务即可,但是在实际开发中可能会因为某些原因导致appendonly.aof文件格式异常,从而导致数据恢复失败,可以通过 redis-check-aof --fix appendonly.aof 进行修复

    • AOF重写机制

      AOF的工作原理就是将写操作追加到文件中,文件的冗余内容会越来越多,所以就有了重写。当AOF文件大小超过了设定阈值,就会触发重写,对AOF文件的内容进行压缩

      重写的原理:Redis会fork出一个子进程,读取内存中的数据,直接生成最终数据的写入命令,最后将旧的AOF文件替换掉

    优点:

    • 带来更高的数据安全
    • 对日志文件的写入是append追加模式,若出现宕机情况,也不会破坏日志文件中已经存在的内容
    • 若日志过大,Redis可以自动启动重写机制
    • 包含一个格式清晰易于理解的日志文件,来记录所有的操作

    缺点:

    • 对于相同数量的数据集,文件相对rdb方式要大,恢复相对较慢
    • 根据同步策略的不同,效率也比rdb要低一些

5、Redis数据的恢复

默认会使用RDB-AOF混合持久化方式

bgsave做镜像全量持久化,AOF做增量持久化

当rdb文件与aof文件共存的情况下,Redis会先检查aof文件是否存在;若不存在则去检查rdb是否存在。

6、Redis主从配置

  1. 常用命令

    • 根据配置文件启动redis:src/redis-server redis.conf
    • 启动redis客户端:redis-cli -p port
    • Slaver连接Master:slaveof host:ip(测试时使用slaveof手动连接master,正式环境下使用配置文件)
    • 关闭Redis:shutdown
    • 查看主从信息:info Replication
  2. Redis配置

    1. 按照1主2从的结构搭建,即一个Master,两个Slaver节点

    2. Redis配置文件redis.conf的配置

      1554047015635

    3. 配置完以后可以根据info Replication查看主从信息

      1. 当Master节点设置了key后,就会异步同步到slaver节点;slaver只能读取数据,不能修改
      2. 当Master挂掉以后,slaver保持原地待命状态,Master重启后,一切照旧
      3. 当slaver挂掉以后,需要重新通过slaveof连接到Master下面
    4. 主节点挂掉以后也可以手动将子节点升级为主节点

      slaveof no one

    5. 上面讲到的需要手动配置,明显不符合实际业务需求,所以可以使用哨兵模式自动检测

      1. sentinel.conf配置文件,修改sentinel monitor host6379 127.0.0.1 6379 1,其它使用默认即可
        host6379 主机名称,随便起 主机IP 端口 1表示选举,某个slaver得到超过1票则成为Master节点
      2. 启动sentinel: ./redis-sentinel …/sentinel.conf

    主从复制总结:

    1. Master可读可写,Slaver只能读,不能写
    2. Master可以对应多个Slaver,但是数量越多压力越大,延迟就可能越严重
    3. Master写入后立即返回,几乎同时将写入异步同步到各个Slaver,所以基本上延迟可以忽略
    4. 可以通过slaveof no one命令将Slaver升级为Master(当Master挂掉时,手动将某个Slaver变为Master)
    5. 可以通过sentinel哨兵模式监控Master,当Master挂掉时自动选举Slaver变为Master,其它Slaver自动重连新的Master

7、redis使用

  1. 导入jedis依赖

  2. 配置Redis连接池属性:一个pool可分配多少个jedis实例,最大空闲连接,最大等待时间,获取连接时检查有效性

  3. 创建连接池,并做相关配置。jedisPool类含有有参构造函数(jedis配置,redis IP地址,redis端口号)

    创建jedisUtil工具类,封装了redis基本操作

    o2o:更新较少的区域信息,头条信息,店铺类别信息

    redis将key在service中定义为常量,操作在serviceImpl中进行

    利用String进行存储

    当缓存中不存在时,将查询到的信息转换成字符串形式

    //定义jackson数据转换操作类
    ObjectMapper mapper = new ObjectMapper();
    String jsonString = mapper.writeValueAsString(查询到的数据);
    jedisString.set(key,jsonString);
    

    如果当缓存中存在当前的key,则需要根据key获取相应的value值,并转换成我们需要的集合

    String jsonString = jedisString.get(key);
    JavaType javaType = mapper.getTypeFactory().constructParametricType(ArrayList.class,Area.class);
    arrayList = mapper.readValue(jsonString,javaType);
    

    清除缓存,编写cacheService,只有一个方法,就是从缓存中清除key(匹配某个前缀的所有key)

    实现类,取出所有的某个前缀开头的key,并放入set集合中,遍历set并删除对应的key

猜你喜欢

转载自blog.csdn.net/lele1658676840/article/details/89228939