Redis学习总结

Redis

    • Redis是什么?优缺点
    • 持久化方式
      • 为什么要持久化?
    • redis为什么读写速度那么快?
    • Redis数据类型,以及Redis的应用场景
    • 缓存雪崩、缓存穿透和缓存击穿
    • 如何保证redis缓存与数据一致性问题

Redis是什么?优缺点

Redis是使用c语言编写的开源的高性能非关系型数据库,它可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串,值的类型可以为:字符串(string)、哈希(hash:map格式)、列表(list:linkedlist格式)、集合、有序集合。

优点:

  • 读写性能优异, Redis能读的速度是110000次/s,写的速度是81000次/s。
  • 支持数据持久化,支持AOF和RDB两种持久化方式。
  • 支持事务,Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。
  • 数据结构丰富,除了支持string类型的value外还支持hash、set、zset、list等数据结构。
  • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。

缺点

  • 数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。
  • Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。
  • 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
  • Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。

持久化方式

为什么要持久化?

Redis是内存数据库,宕机后数据会消失,Redis重启后快速恢复数据,要提供持久化机制。

  • RDB(快照模式) 默认
    每隔一段时间,给内存拍照;当redis重启的时候,读取快照回复到某一个时间节点;
    优点:RDB是二进制压缩文件,占用空间小,便于传输(传给slaver);恢复数据速度快
    缺点:不保证数据完整性,数据会丢失

  • AOF(日志模式)需手动设置
    redis将每一个指令都记录到日志当中,重启时回去读取这个日志,将所有命令执行一次
    优点:恢复的数据比较完成
    缺点:恢复速度慢

​ 两种持久化方式可以一起使用!

redis为什么读写速度那么快?

  1. Redis 是一个基于内存的数据库,它的数据存储在内存中,这样能够获得非常快的读写速度。相比传统的磁盘数据库,内存数据库能够极大地提高数据的读写性能,从而让 Redis 变得更快;
  2. Redis的进程是单线程的,这意味着Redis不需要考虑线程同步和锁竞争等问题,避免了多线程带来的额外开销和复杂性。
  3. Redis提供了多种高效的数据结构,如字符串、哈希表、列表、集合、有序集合等。这些数据结构不仅能够满足各种不同的应用场景,而且它们的实现都经过了高度优化,从而能够实现极快的读写速度。
  4. Redis 使用异步 I/O 模型,这意味着它能够同时处理多个并发请求,而不需要阻塞等待。这样能够让 Redis 更快地响应客户端请求,从而提高系统的吞吐量。

Redis数据类型,以及Redis的应用场景

Redis 有5种基础的数据结构,分别为:String(字符串)、List(列表)、Hash(字典)、Set(集合)和Zset(有序集合);

  • String(字符串):String 类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。
    string类型是Redis最基本的数据类型,一个键最大能存储512MB。
    使用场景

    • 缓存功能:String字符串是最常用的数据类型,因此,利用Redis作为缓存,配合其他数据库作为存储层,利用Redis支持高并发的特点,可以加快系统的读写速度、降低后端数据库的压力。
    • 计数器:redis是单线程模型,一个命令执行完才会执行下一个,使用Redis作为系统的实时计数器,可以快速实现计数和查询功能。
    • 共享用户Session。
    • 分布式锁:解决了分布式系统中控制共享资源访问的问题。与单体应用不同的是,分布式系统中竞争共享资源的最小粒度从线程升级成了进程。
  • Hash(哈希):Hash是一个Mapmap,Value值本身又是一种键值对结构,如 value={{field1,value1},…fieldN,valueN}}
    应用场景

    • 适用于存储对象。
    • 缓存:相比string更节省空间,维护缓存信息,如用户信息,视频信息等。
    • 电商购物车:以用户id为key,商品id为field,商品数量为value,恰好构成购物车的3个要素。
  • List(列表):List 说白了就是链表(redis 使用双端链表实现的 List),是有序的,value可以重复,可以通过下标取出对应的value值,左右两边都能进行插入和删除数据。
    应用场景

    • 最新列表信息:按照时间排序的这些朋友圈信息、最新动态的时间轴等。
  • Set(集合)Set是String类型的无序集合且元素是唯一;通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
    应用场景

    • 给用户添加标签。
    • 好友、关注、粉丝、感兴趣的人的集合。
    • 黑名单、白名单,有业务出于安全性方面的考虑,设置用户黑名单、IP黑名单、设备黑名单等,sismember命令用来判断用户、ip、设备是否在黑名单中。
    • 随机展示,通过 srandmember 随机返回对应的内容,像一些首页获取动态内容可以这么玩。
    • 微信抽奖小程序。
    • 收藏。
  • Zset(有序集合):它和set一样是不可重复的,区别在于多了score值,用来代表排序的权重。也就是当你需要一个有序的,不可重复的集合列表时,就可以考虑使用这种数据类型。
    应用场景

    • 标签:比如我们博客网站常常使用到的兴趣标签,把相同爱好,关注类似内容的用户利用一个标签把他们进行归并。
    • 共同好友功能。
    • 统计用户的点赞、取消点赞。
    • 排行榜功能。

缓存雪崩、缓存穿透和缓存击穿

缓存雪崩:redis中大量的key同时失效,导致全部去访问数据库;
解决方法:
1.将失效时间分散开,在缓存redis的过期时间上,加上一个随机数;避免同时失效

​ 2.设置缓存标记,记录缓存数据是否过期,如果过期会触发通知另外的线程在后台去跟新实际的key;

​ 3.使用锁或者队列的方式,如果查不到就加上排它锁,其他请求只能进行等待;

缓存穿透: 黑客攻击,使用不存在的数据一直访问;reids中查询不到,这样就会一直去查询数据库

​ 解决方法:
1.使用布隆过滤器,将不存在的数据进行拦截;

​ 2.将空值进行缓存,但过期时间不能太长,防止占用太多redis资源;

​ 3.对redis进行实时监控,当发现redis中的命中率下降的时候进行原因的排查,配合运维人员对访问对象和访问数据进行分析查询,从而进行黑名单的设置限制服务(拒绝黑客攻击)

​ 4.接口校验

缓存击穿:热点数据被频繁访问时突然失效,从而导致大量请求直接访问数据库,导致数据库压力过大
解决方法:
1.用 ReentrantLock(重入锁),tryLock(尝试锁定) 等加锁;

​ 2.通过key值判断取出来的value是不是null;如果是null的话就让一个线程去db中查询,其他的线程进行等待;

​ 3.读取以后再更新到reids;

​ 4.监控数据,适时调整。

如何保证redis缓存与数据一致性问题

采用「先更新数据库,再删除缓存」方案,为了保证两步都成功执行,需配合「消息队列」或「订阅变更日志(Binlog)的方案来做,本质是通过「重试」的方式保证数据最终一致

Redis学习总结_第1张图片
读写分离 + 主从库延迟也会导致缓存和数据库不一致,采用 先更新数据库,再删除缓存 方案,缓解此问题的方案是 延迟双删,凭借经验发送 延迟消息 到队列中,延迟删除缓存,同时也要控制主从库延迟,尽可能降低不一致发生的概率
Redis学习总结_第2张图片

你可能感兴趣的:(redis,学习,数据库)