前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java面试高频知识点总结 Redis

Java面试高频知识点总结 Redis

作者头像
Steve Wang
发布2020-09-24 15:23:49
4440
发布2020-09-24 15:23:49
举报
文章被收录于专栏:从流域到海域从流域到海域

Redis是一种内存型数据库。传统的数据库储存在硬盘中,而Redis数据库存在内存中,所以读写速度非常快。因此redis广泛用于缓存方向,除此之外也经常用于实现分布式锁。redis提供了多种数据类型来支持不同的业务场景。

除此之外,redis支持事务、持久化、LUA脚本、LRU驱动事件、多种集群方案。

为什么要用Redis/为什么要用缓存

高性能高并发

高性能:从内存读取数据比从硬盘读取要快很多。如果数据库中对应的数据改变之后,同步改变缓存中相应的数据即可。

高并发:直接操作缓存能够承受的请求是远远大于直接访问数据库的,所以可以考虑将数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。

Redis常见数据结构

  • String
  • Hash
  • List
  • Set
  • Sorted Set

Redis内存淘汰机制

redis提供6中数据淘汰策略:

  1. volatile-lru:从设置的过期时间数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰。
  2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰。
  3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰。
  4. allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。
  5. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰。
  6. no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。

4.0版本后增加以下两种:

  1. volatile-lfu:从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰。
  2. allkeys-lfu:当内存不足以容纳新写入数据时,在键空间中,移除最不经常使用key。

总结:两种操作对象:已设置过期时间的数据集(server.db[i].expires)和数据集(server.db[i].dict),四种机制lrulfurandomttl(仅针对过期时间数据集)加no-eviction

Redis持久化机制 (重要)

持久化:将内存中的数据写入到硬盘里面。主要是为了之后重用数据(比如重启及其、机器故障之后恢复数据),或者为了防止系统故障而将数据备份到一个远程位置。

Redis不同于memcache很重要的一点在于Redis支持持久化,提供了两种不同的持久化方式快照(snapshotting, RDB),另一种方式是只追加文件(append-only file, AOF)

快照

Redis通过创建快照来获得存储在内存里面的数据在某个时间点上的副本。Redis创建快照之后,可以对快照进行备份,可以将快照复制到其他服务器创建具有相同数据的服务器副本(Redis主从结构,主要用来提高Redis性能),还可以将快照留在原地以便重启服务器的时候使用。

AOF(append-only file)持久化

默认没有开启,可以通过下面的参数开启:

代码语言:javascript
复制
appendonly yes

开启AOF持久化后每执行一条会更改Redis中的数据的命令。Redis就会将该命令写入硬盘中那个的AOF文件。AOF文件个RDV文件位置相同,可以通过dir参数设置。

代码语言:javascript
复制
appendfsync always # 每次有数据修稿发生时都会写入AOF文件,这样会严重降低Redis的速度
appendfsync everysec # 每秒钟同步一次,显式地将多个写命令同步到硬盘
appendfsync no # 让操作系统决定何时进行同步 

为了兼顾数据和写入性能,用户可以考虑appendfsync everysec选项,让Redis每秒同步一次AOF文件,Redis性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只丢失一秒之内产生的数据。当硬盘忙于写入操作的时候,Redis还会优雅的放慢自己的速度以便适应硬盘的最大写入速度。

Redis 4.0开始支持RDB和AOF的混合持久化(默认关闭,可以通过配置项aof-use-rdb-preamble开启)

开启混合持久化之后,AOF重写的时候就直接把RDB的内容写到AOF文件开头,这样做的好处是可以结合RDB和AOF的优点,快速加载的同时避免丢失过多的数据,当然缺点也是有的,AOF里面RDB部分的压缩格式不再是AOF格式,可读性较差。

Redis事务

Redis通过MULTIEXECWATCH等命令来实现事务(transaction)功能。事务提供了一种将多个请求打包,然后一次性的,按顺序的执行多个命令的机制,并且在事务执行期间,服务不会中断事务而改去执行其他客户端的命令请求,它会将事务中的所有命令都执行完毕。

Redis中,事务总是具有原子性(Atomicity)一致性(Consistency)隔离性(Isolation),并且当Redis运行在某种特定的持久化模式下时,事务也具有持久性(Durability)

缓存雪崩和缓存穿透

缓存雪崩

缓存同一时间大面积的失效,所以,后面的请求全都落到数据库上,造成数据库短时间内承受大量请求而崩掉。

解决方法:

  • 事前:尽量保证redis集群的高可用性,发现机器宕机尽快补上。选择合适的内存淘汰策略。
  • 事中:本地ehcache缓存+hystrix限流&降级,避免MySQL崩掉。
  • 事后:利用redis持久化机制保存的数据尽快恢复缓存。
缓存穿透

大量请求的key根本不在缓存中,导致请求直接到了数据库上,根本没有经过缓存这一层。

解决方法:

  • 缓存无效key:如果缓存和数据库都查不到某个key就写一个到redis中并设置过期时间。并不能从根本上解决问题,尽量要将无效的key的过期时间设置短一点。
  • 布隆过滤器:把所有可能请求的值都存放在布隆过滤器中,当用户请求过来,先判断用户发来请求的值是否存在于布隆过滤器中,存在的话才会走正常流程,不存在的话直接放回请求错误信息。

如何解决Redis并发竞争key问题

并发竞争key的问题指的是多个系统同时对一个key进行操作,但最后执行的顺序与我们期望的不同,这样导致了结果的不同。

分布式锁(zookeeper和redis都可以实现分布式锁)

基于zookeeper临时有序节点可以实现分布式锁。大致思想为:每个客户端对某个方法加锁时,在zookeeper上的与该方法对应的指定节点的目录下,生成一个唯一的瞬时有序节点。判断是否获取锁的方式很简单,只需要判断有序节点序号中的最小的一个。当释放锁的时候,只需将这个瞬时节点删除即可。同时,其可以避免服务宕机导致的锁无法释放,而产生的死锁问题。完成业务流程后,删除对应的子节点释放锁。

如何保证缓存与数据库双写时的数据一致性

读请求和写请求串行化,串到一个内存队列里去,这样就可以保证一定不会出现不一致的情况。

最好不要使用这个方案,串行之后系统的吞吐量会大幅度的降低,用比正常情况下多几倍的机器去支撑线上的一个请求。

参考

来自Java Guide面试突击版,百度可得最新版本,这里有删减和修正。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 为什么要用Redis/为什么要用缓存
  • Redis常见数据结构
  • Redis内存淘汰机制
  • Redis持久化机制 (重要)
    • 快照
      • AOF(append-only file)持久化
      • Redis事务
      • 缓存雪崩和缓存穿透
        • 缓存雪崩
          • 缓存穿透
          • 如何解决Redis并发竞争key问题
          • 如何保证缓存与数据库双写时的数据一致性
          • 参考
          相关产品与服务
          云数据库 Redis
          腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档