Redis相关概念

2021/7/17 19:05:52

本文主要是介绍Redis相关概念,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Redis

​ 是一个开源的, 使用C语言编写的, 将数据缓存到内存中(程序使用时,可以缓存数据,具有临时性和速度快的特点), key–value(键值对的方式存储)的一种非关系型数据库(严格来说不是一种数据库,只是一种数据存储结构),它支持多种数据类型存储(例如: String 字符 Hash 哈希 List 列表 Set 集合 zset 有序集合 ).

关系型数据库和非关系型数据库

关系型:

​ 采用关系模型来组织数据的数据库,表与表,列与列,和字段之间的关系存储数据的

优点:

容易理解

使用方便(有通用的sql语句)

易于维护,丰富的完整性,极大的降低了数据的冗余和数据不一致概率缺点

缺点:

磁盘I/O是并发的瓶颈

由于大量的数据导致查询效率降低

横向扩展困难,无法简单的通过硬件和服务节点来扩展性能和负载能力

当需要对数据库进行升级和扩展时,需要停机和数据迁移(工作量增加)

因为要保证数据的安全性,所以 事务控制+锁 导致性能降低

非关系型:

分布式,不遵循ACID原则的数据存储系统.键值对存储,结构不稳定

优点:

根据所需要的字段直接添加,不需要考虑多表关系.仅取对应的vlue,可以说不是数据库,而是一种数据结构化存储方法的集合

缺点:

只适合存储一些较为简单的数据

不适合复杂查询的数据

不适合持久存储数据

Redis数据类型

String(字符串)

是redis最基本的数据类型,一个key对应一个value

是二进制安全的,意味着他可以包含任何数据,比如 jpg图片或序列化的对象

最大能存储512MB

Hash(哈希)

是一个键值对(key=>value)集合.

是一个String类型的field和value的映射表, 比较适合存储对象

List(列表)

是最简单的字符串列表,按照插入顺序排序,添加元素可以是头部或者尾部

Set(集合)

是String类型的无序集合

是通过哈希表实现的,所以增删改的复杂度都是O(1)

添加一个String元素到key对应的集合中,成功返回1,失败返回0,(Set集合的元素是不重复的)

Zset(sorted set: 有序集合)

和set一样,不同的是每个元素都会关联一个double类型的分数,redis通过分数来为集合中的成员进行排序. 其中的成员是唯一的,但分数却可以重复

设置失效时间

​ 一般不设置失效时间的话redis会默认为永久存在,所以对于大部分数据我们一般希望他们在一定时间内会自动销毁.redis提供了一些命令可以让我们对key设置失效时间

EX (表示以秒为单位)

PX(表示以毫秒为单位) 不区分大小写

例如: ser name “ming” ex 30 表示数据将会在30秒后失效

ttl 键 查询数据的剩余失效时间(秒)

pttl 键 查询数据的剩余失效时间(毫秒)

设置值后设置有效时间

​ expire 键 (秒)

​ pexpire 键 (毫秒)

SpringBoot集成redis

​ Jedis是redis官方推出的一款面向java的客户端,提供了一些接口供java使用

​ Spring-data-redis是spring大家族的一部分,提供了在spring中通过简单的配置访问redis服务,它对redis的底层进行了高度封装,RedisTemplate提供了redis的各种操作

Spring-data-redis针对jedis提供了如下功能:
  1. 连接池自动管理,提供了一个高度封装的"RedsiTemplate"类
  2. 将事务操作封装,由容器操作
  3. 针对数据的"序列化/反序列化"提供了多种操作
    • jdkSerializationRedisSerialization:POJO对象的存取场景,使用JDK本身的序列化机制
    • StringRedisSerialization: key或者value为字符串的场景根据指定的charset对数据的字节序列编码成string,------是最轻量级和高效的策略
    • JacksonjsonRedisSerialization:jackson-json工具提供了javabean与json之间的转换能力,可以将pojo实例化成json格式存储在redis中,也可以将json格式的数据转换成pojo实例.
  4. 针对jedis客户端大量的api进行了归类封装,将同一类型操作封装为Opertion接口
    1. ValueOpertions:简单的K-V操作
    2. SetOprtions:set类型数据操作
    3. ZSetOpertion: zset类型数操作
    4. HashOpertions:针对map类型的数据操作
    5. ListOPertions:针对List类型的数据操作
搭建:

​ 1.添加redis依赖

org.springframework.boot spring-boot-starter-data-redis
  1. 配置连接 redis

    spring:
    redis:
    host: 192.168.31.133
    port: 6379
    password: 123456
    database: 0
    pool:
    max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
    max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
    max-idle: 8 # 连接池中的最大空闲连接
    min-idle: 0 # 连接池中的最小空闲连接
    timeout: 5000ms # 连接超时时间(毫秒)

    3.注入RedisTemplate

    @Autowired

    RedisTemplate redisTemplate

    需要被Redis缓存的类,必须实现序列化接口

主从复制

​ 是将一台Redis服务器的数据复制到其他的Redis服务器上.前者称位主节点,后者为从节点,数据的复制是单向的,只能由主节点到从节点.

​ 使用一个Redis实例作为主机,其余的作为备份,主机与从机的数据完全一致.主机支持写入和读取的操作,而从机只是读取和同步数据的作用.也就是说客户端可以将数据写入主机,由主机自动将数据同步到从机.主从模式和好的解决了数据备份问题,并且主从服务的数据几乎完全一致.因此可以将写入的操作交给主机,读取的操作交给从机.从而实现主从分离的目的.

作用:

​ 1.数据冗余: 主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式.

​ 2.故障恢复: 当主节点出现问题时,可以有从节点提供服务,快速实现故障恢复.

​ 3.负载均衡: 在主从服务的基础上,配合读写分离. 由主节点提供度服务写服务,由从节点提供读 服务,分担服务器负载. 通过多个从节点分担负载.可以大大提高Redis服务器的并发量

​ 4.高可用(集群)基石: 石哨兵和集群能够实施的基础. 主从复制是Redis高可用的基础

哨兵机制:

​ 首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行.其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例

单哨兵: 以独立的进程监控服务器Redis是否正常执行

哨兵集群: 除了监控各个Redis服务器之外,哨兵之间也会互相监控.

缓存穿透–缓存击穿–缓存雪崩

缓存穿透:

​ 数据库中没有key; 客户端利用数据库中没有的key区访问缓存,缓存中没有就去数据库请求,数据库也没有返回空,如果反复此操作,就可能击垮数据库

数据库没有,缓存中也没有

解决办法:
  1. 使用布隆过滤器或者压缩filter去拦截过滤
  2. 将空对象放在缓存中,下次请求就可以直接在缓存中获取,一般会将空对象设置成较短的时间
  3. 拉黑访问的该IP地址
  4. 对访问的参数进行校验,不合法的直接进行拦截

缓存击穿:

​ key在某个时间节点过期了,此时如果有大量的并发请求过来,就会从后端DB加载数据并返回给缓存,但是大量的并发请求可能会直接把DB压垮.

解决方法:
  1. 某个热点的数据设置成永不过期
  2. 可以加一个互斥锁, 如果出现上述情况,那么我们可以在第一个请求上使用一个互斥锁来锁住它,其他线程在这时由于拿不到锁就会等着,等第一个数据查询到时,就将数据放到Redis缓存起来.后面的请求可以直接走缓存

缓存雪崩:

在高并发的情况下,大量的数据失效/缓存层出现故障.于是所有的请求就会到达数据库,数据库由于调用量的增加也会挂掉.

解决办法:
  1. 随机设置失效时间,以免大量key集体失效
  2. 不设置过期时间(极端情况)
  3. 可以加个定时器,在缓存失败前刷进新的缓存
  4. 若是集群部署,可以将热点数据均匀分布在不同的Redis库中也可以避免key全部失效的问题.

总结: 穿透是数据库没有key,击穿是一个热点key突然失效,雪崩是多个key同时失效

事发前:

实现Redis的高可用(主从架构+哨兵),尽量避免Redis挂掉的情况.

事发中:

如果挂掉了,我们可以设置本地缓存+限流,尽量避免我们的数据库被干掉(还可以保证服务能够正常操作)

事发后:

redis持久化,重启后自动从磁盘上加载数据,快速恢复缓存数据

key过期后,Redis的删除机制:

  1. 定时删除:在设置键的时间时,同时设置一个计时器.当键过期时,立即执行对键的删除操作

  2. 惰性操作:当获取键时,判断键是否过期,如果过期,就立即删除返回空,如果没有过期,返回该键

  3. 定期操作:每个一段时间,对键进行一次检查,删除里面的过期键.

    小结:定时删除对CPU不友好,当过期键比较多时就会影响正常的请求; 惰性删除对CPU友好,但是会占用大量的内存.因为如果键没有被删除那么它就会一直占用着内存. 定期删除策略对CPU好内存都比较友好.因为Redis中过期的key是由主线程删除的,为了不阻塞用户的请求,所以删除的时候尽量少量多次.

布隆过滤器

实际上是一个很长的二进制向量和一系列映射函数.布隆过滤器可以用于检索一个元素是否在一个集合中.

优点是空间效率和查询时间都比一般的算法低.缺点是误识别率和删除的困难.

算法:

  1. 首先需要k个hash函数,每个函数可以把key散列成为一个整数.

  2. 初始化时,需要一个长度为n比特的数组,每个比特 初始化都为0

  3. 某个key加入集合时,用k个hash函数计算出他的散列值,并把数组中对应的比特位置变为1

  4. 判断每个key是否在集合中,当查询到所在的比特位时,如果所有的比特位都为1,则可能在集合中

    **注意:**查询出所在的比特位后,如果任何一个点有0,则查询变量一定不存在; 如果都为1,则查询变量可能存在.



这篇关于Redis相关概念的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程