Redis

Redis

Redis以及缓存的作用

缓存是什么?

缓存是一个高速的数据交换存储器,使用它可以快速的访问和操作数据。

为什么要用缓存?

优点:

  1. 缓存是存储在内存中的,所以性能高;DB的数据存储在磁盘中,内存的操作速度>磁盘操作,所以缓存是非常快的;
  2. 缓存系统更容易实现分布式集群服务(⼀台服务器变成多台相连的服务器集群),可以承受和更多压力;数据库⼀般⽐较难实现分布式部署,因此缓存的负载和性能更容易平⾏扩展和增加。
  3. 存储key-value存储简单,查询效率非常高;
常见的缓存(应用)
分类:
  1. 本地缓存(单机缓存):将服务部署到⼀台服务器上。

    常用的本地缓存:Spring Cache、MyBatis的缓存等

    Spring Cache的实现步骤:
    1. 开启缓存
    2. 编写缓存操作代码
    3. 编写调用缓存代码
    
  2. 分布式缓存(多机缓存):将⼀套服务器部署到多台服务器,并且通过负载分发将⽤户的请求按照⼀定的规则分发到不同服务器企业级应用(可以应用于本地缓存)

    常用的分布式缓存:Redis、Memcached

    Redis的操作流程

Redis 和 Memcached 有什么区别?(高频面试问题)
  1. 存储⽅式不同:memcache 把数据全部存在内存之中,断电后会挂掉,数据不能超过内存⼤⼩;Redis有部份存在硬盘上,这样能保证数据的持久性;(Redis更加稳定)
  2. 数据⽀持类型不同:memcache 对数据类型⽀持相对简单;Redis 有复杂的数据类型;
  3. 存储值最大值⼤⼩不同:Redis 最⼤可以达到 512mb,memcache 只有 1mb。

Redis5大基本数据类型的使用

String—字符串类型

简单的动态字符串(key-value),它是以键值对 key-value的形式进⾏存储的,根据 key 来存储和获取 value 值。

Hash—字典类型

字典类型 (Hash) ⼜被成为散列类型或者是哈希表类型,它是将⼀个键值 (key) 和⼀个特殊的“哈希表”关联起来,这个“哈希表”表包含两列数据:字段和值,它就相当于 Java 中的Map<String,Map<String,String>> 结构。

同理我们也可以使⽤字典类型来存储⽤户信息,并且使⽤字典类型来存储此类信息就⽆需⼿动序列化和反序列化数据了,所以使⽤起来更加的⽅便和⾼效。

List—列表类型

列表类型 (List) 是⼀个使⽤链表结构存储的有序结构,它的元素插⼊会按照先后顺序存储到链表结构中,因此它的元素操作 (插⼊和删除) 时间复杂度为 O(1),所以相对来说速度还是⽐较快的,但它的查询时间复杂度为 O(n),因此查询可能会⽐较慢。

列表的典型使⽤场景有以下两个:

  1. 消息队列:列表类型可以使⽤ rpush 实现先进先出的功能,同时⼜可以使⽤ lpop 轻松的弹出(查询并删除)第⼀个元素,所以列表类型可以⽤来实现消息队列;
  2. ⽂章列表:对于博客站点来说,当⽤户和⽂章都越来越多时,为了加快程序的响应速度,我们可以把⽤户⾃⼰的⽂章存⼊到 List 中,因为 List 是有序的结构,所以这样⼜可以完美的实现分⻚功能,从⽽加速了程序的响应速度。

Set—集合类型

集合类型 (Set) 是⼀个⽆序并唯⼀的键值集合
集合类型的使⽤如下:
集合类型的经典使⽤场景如下:

  1. 微博关注我的⼈和我关注的⼈都适合⽤集合存储,可以保证⼈员不会重复;
  2. 中奖⼈信息也适合⽤集合类型存储,这样可以保证⼀个⼈不会重复中奖。

集合类型(Set)和列表类型(List)的区别如下:

  1. 列表可以存储重复元素,集合只能存储⾮重复元素;
  2. 列表是按照元素的先后顺序存储元素的,⽽集合则是⽆序⽅式存储元素的。

ZSet—有序集合类型

有序集合类型 (Sorted Set) 相⽐于集合类型多了⼀个排序属性 score(分值),对于有序集合 ZSet 来说,每个存储元素相当于有两个值组成的,⼀个是有序结合的元素值,⼀个是排序值。有序集合的存储元素值也是不能重复的,但分值是可以重复的。

有序集合的经典使⽤场景如下:

  • 学⽣成绩排名;
  • 粉丝列表,根据关注的先后时间排序。

Redis的持久化功能

持久化

持久化就是将数据从内存保存到磁盘的过程,它的⽬的就是为了防⽌数据丢失

方式:

  1. RDB(快照方式:Redis database):将某⼀个时刻的内存数据,以⼆进制的⽅式写⼊磁盘;

    优点:

    • RDB 的内容为⼆进制的数据,占⽤内存更⼩,更紧凑,更适合做为备份⽂件
    • RDB 对灾难恢复⾮常有⽤,它是⼀个紧凑的⽂件,可以更快的传输到远程服务器进⾏ Redis 服务恢复
    • 与 AOF 格式的⽂件相⽐,RDB ⽂件可以更快的重启

    缺点:

    • 备份时间不是时刻进行的,可能会丢失一段时间内的文件
    • RDB 需要经常 fork() 才能使⽤⼦进程将其持久化在磁盘上。如果数据集很⼤,fork() 可能很耗时,并且如果数据集很⼤且 CPU 性能不佳,则可能导致 Redis 停⽌为客户端服务⼏毫秒甚⾄⼀秒钟。
  2. AOF(文件追加,append Only file):备份每次操作的命令,并以⽂本的形式追加到⽂件中;

    优点:

    • AOF 持久化保存的数据更加完整,AOF 提供了三种保存策略:每次操作保存、每秒钟保存⼀次、跟随系统的持久化策略保存,其中每秒保存⼀次,从数据的安全性和性能两⽅⾯考虑是⼀个不错的选择,也是 AOF 默认的策略,即使发⽣了意外情况,最多只会丢失 1s 钟的数据;
    • AOF 采⽤的是命令追加的写⼊⽅式,所以不会出现⽂件损坏的问题,即使由于某些意外原因,导致了最后操作的持久化数据写⼊了⼀半,也可以通过 redis-check-aof ⼯具轻松的修复;
    • AOF 持久化⽂件,⾮常容易理解和解析,它是把所有 Redis 键值操作命令,以⽂件的⽅式存⼊了磁盘。即使不⼩⼼使⽤ flushall 命令删除了所有键值信息,只要使⽤ AOF ⽂件,删除最后的flushall 命令,重启 Redis 即可恢复之前误删的数据。

    缺点:

    • 对于相同的数据集来说,AOF ⽂件要⼤于 RDB ⽂件;
    • 在 Redis 负载⽐较⾼的情况下,RDB ⽐ AOF 性能更好;
    • RDB 使⽤快照的形式来持久化整个 Redis 数据,⽽ AOF 只是将每次执⾏的命令追加到 AOF ⽂件中,因此从理论上说,RDB ⽐ AOF 更健壮。
  3. 混合持久化(RDB+AOF)(Redis 4.0 之后新增的⽅式) :在写⼊的时候,先把当前的数据以 RDB 的形式写⼊⽂件的开头再将后续的操作命令以 AOF 的格式存⼊⽂件,这样既能保证 Redis 重启时的速度,⼜能减低数据丢失的⻛险。

    优点:集合了RDB和AOF的优点,使得 Redis 可以更快的启,又减低了⼤量数据丢失的⻛险。

    缺点:

    1. AOF ⽂件中添加了 RDB 格式的内容,使得 AOF ⽂件的可读性变得很差;
    2. 兼容性差,如果开启混合持久化,那么此混合持久化 AOF ⽂件,就不能⽤在 Redis 4.0 之前版本了
持久化策略设置

可以在 redis-cli 命令⾏中执⾏ config set aof-use-rdb-preamble yes 来开启混合持久化,当开启混合持久化时 Redis 就以混合持久化⽅式来作为持久化策略;当没有开启混合持久化的情况下,使⽤config set appendonly yes 来开启 AOF 持久化的策略,当 AOF 和混合持久化都没开启的情况下默认会是 RDB 持久化的⽅式。

常见Redis面试题

缓存雪崩

缓存雪崩是指在短时间内,有⼤量缓存同时过期,导致⼤量的请求直接查询数据库,从⽽对数据库造成了巨⼤的压⼒,严重情况下可能会导致数据库宕机的情况叫做缓存雪崩。

解决方案:
  • 加锁排队:加锁排队可以起到缓冲的作⽤,防⽌⼤量的请求同时操作数据库。

    缺点:增加了系统的响应时间,降低了系统的吞吐量,牺牲了⼀部分⽤户体验。

  • 随机化时间:为了避免缓存同时过期,可在设置缓存时添加随机时间,这样就可以极⼤的避免⼤量的缓存同时失效。

  • 设计二级缓存:⼆级缓存指的是除了 Redis 本身的缓存,再设置⼀层缓存,当 Redis 失效之后,先去查询⼆级缓存。
    例如可以设置⼀个本地缓存,在 Redis 缓存失效的时候先去查询本地缓存⽽⾮查询数据库。

缓存穿透

缓存穿透是指查询数据库和缓存都⽆数据,因为数据库查询⽆数据,出于容错考虑,不会将结果保存到缓存中,因此每次请求都会去查询数据库,这种情况就叫做缓存穿透

解决方案:

  • 缓存空节点
  • 另⼀种⽅式是我们可以把每次从数据库查询的数据都保存到缓存中,为了提⾼前台⽤户的使⽤体验 (解决⻓时间内查询不到任何信息的情况),我们可以将空结果的缓存时间设置的短⼀些,例如 3-5 分钟

缓存击穿

缓存击穿指的是某个热点缓存,在某⼀时刻恰好失效了,然后此时刚好有⼤量的并发请求,此时这些请求将会给数据库造成巨⼤的压⼒,这种情况就叫做缓存击穿。

解决方案:

  • 加锁排队

    此处理⽅式和缓存雪崩加锁排队的⽅法类似,都是在查询数据库时加锁排队,缓冲操作请求以此来减少服务器的运⾏压⼒。

  • 设置永不过期

    对于某些热点缓存,我们可以设置永不过期,这样就能保证缓存的稳定性,但需要注意在数据更改之后,要及时更新此热点缓存,不然就会造成查询结果的误差。

缓存预热(优化点)

缓存预热指的是在系统启动的时候,先把查询结果预存到缓存中,以便⽤户后⾯查询时可以直接从缓存中读取,以节约⽤户的等待时间。

缓存预热的实现思路有以下三种:

  1. 系统启动之后,进行热点缓存的预热(提前加载)
  2. 把需要缓存的⽅法挂载到某个⻚⾯或后端接⼝上,⼿动触发缓存预热;
  3. 设置定时任务,定时⾃动进⾏缓存预热。

了解Redis集群功能

主从同步

主从同步 (主从复制) 是 Redis ⾼可⽤服务的基⽯,也是多机运⾏中最基础的⼀个。我们把主要存储数据的节点叫做主节点 (master),把其他通过复制主节点数据的副本节点叫做从节点 (slave),如下图所示:

优点:

  • 高性能:有了主从同步之后,可以把查询任务分配给从服务器,⽤主服务器来执⾏写操作,这样极⼤的提⾼了程序运⾏的效率,把所有压⼒分摊到各个服务器了;
  • ⾼可⽤:当有了主从同步之后,当主服务器节点宕机之后,可以很迅速的把从节点提升为主节点,为Redis 服务器的宕机恢复节省了宝贵的时间;
  • 防⽌数据丢失:当主服务器磁盘坏掉之后,其他从服务器还保留着相关的数据,不⾄于数据全部丢失。

缺点:当主节点发生异常/宕机时,只能通过人工干预才能恢复主从的正常运行。

哨兵模式

使⽤哨兵模式可以⽤来监控主从同步服务器节点,并在主从服务器出现问题的时候实现⾃动容灾恢复。

原理:

哨兵的⼯作原理是,⾸先每个 Sentinel 会以每秒钟 1 次的频率,向已知的主服务器、从服务器和以及其他Sentinel 实例,发送⼀个 PING 命令。
如果最后⼀次有效回复 PING 命令的时间超过 down-after-milliseconds 所配置的值 (默认 30s),那么这个实例会被 Sentinel 标记为主观下线(疑似出现问题)。
如果⼀个主服务器被标记为主观下线,那么正在监视这个主服务器的所有 Sentinel 节点,要以每秒 1 次的频率确认主服务器的确进⼊了主观下线状态。
如果有⾜够数量 (quorum 配置值) 的 Sentinel 在指定的时间范围内同意这⼀判断,那么这个主服务器被标记为客观下线(确认出现问题)。此时所有的 Sentinel 会按照规则协商⾃动选出新的主节点。

注意:⼀个有效的 PING 回复可以是:+PONG、-LOADING 或者 -MASTERDOWN。如果返回值⾮以上三种回复,或者在指定时间内没有回复 PING 命令, 那么 Sentinel 认为服务器返回的回复⽆效(non-valid)。
Redis集群服务(3.0后新增功能)

Redis Cluster 是⽆代理模式去中⼼化的运⾏模式,客户端发送的绝⼤数命令会直接交给相关节点执⾏,这样⼤部分情况请求命令⽆需转发,或仅转发⼀次的情况下就能完成请求与响应,所以集群单个节点的性能与单机 Redis 服务器的性能是⾮常接近的,因此在理论情况下,当⽔平扩展⼀倍的主节点就相当于请求处理的性能也提⾼了⼀倍,所以 Redis Cluster 的性能是⾮常⾼的。

优点:

  1. 自动实现容灾恢复
  2. 实现多主多从

Redis Cluster 是⽆代理模式去中⼼化的运⾏模式,客户端发送的绝⼤数命令会直接交给相关节点执⾏,这样⼤部分情况请求命令⽆需转发,或仅转发⼀次的情况下就能完成请求与响应,所以集群单个节点的性能与单机 Redis 服务器的性能是⾮常接近的,因此在理论情况下,当⽔平扩展⼀倍的主节点就相当于请求处理的性能也提⾼了⼀倍,所以 Redis Cluster 的性能是⾮常⾼的。

优点:

  1. 自动实现容灾恢复
  2. 实现多主多从
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值