深圳网站建设就q479185700顶上,我的网站360搜索被做跳转,网站策划书包含的内容,湖南有实力竞价优化服务【JavaGuide面试总结】Redis篇下1.如何使用 Redis 事务#xff1f;2.如何解决 Redis 事务的缺陷#xff1f;3.说说Redis bigkey吧4.大量 key 集中过期问题怎么解决的5.如何保证缓存和数据库数据的一致性#xff1f;6.缓存穿透有哪些解决办法#xff1f;7.缓存击穿有哪些解决…
【JavaGuide面试总结】Redis篇·下1.如何使用 Redis 事务2.如何解决 Redis 事务的缺陷3.说说Redis bigkey吧4.大量 key 集中过期问题怎么解决的5.如何保证缓存和数据库数据的一致性6.缓存穿透有哪些解决办法7.缓存击穿有哪些解决方法8.缓存雪崩有哪些解决方法1.如何使用 Redis 事务
Redis 可以通过 MULTIEXECDISCARD 和 WATCH 等命令来实现事务(transaction)功能。 MULTI
OKSET PROJECT heihei
QUEUEDGET PROJECT
QUEUEDEXEC
1) OK
2) JavaGuideMULTI 命令后可以输入多个命令Redis 不会立即执行这些命令而是将它们放到队列当调用了 EXEC 命令后再执行所有的命令。
这个过程是这样的
开始事务MULTI命令入队(批量操作 Redis 的命令先进先出FIFO的顺序执行)执行事务(EXEC)。
你也可以通过 DISCARD命令取消一个事务它会清空事务队列中保存的所有命令。
你可以通过WATCH命令监听指定的 Key当调用 EXEC 命令执行事务时如果一个被 WATCH 命令监视的 Key 被 其他客户端/Session 修改的话整个事务都不会被执行。
# 客户端 1SET PROJECT RustGuide
OKWATCH PROJECT
OKMULTI
OKSET PROJECT JavaGuide
QUEUED# 客户端 2
# 在客户端 1 执行 EXEC 命令提交事务之前修改 PROJECT 的值SET PROJECT GoGuide# 客户端 1
# 修改失败因为 PROJECT 的值被客户端2修改了EXEC
(nil)GET PROJECT
GoGuide2.如何解决 Redis 事务的缺陷
Redis 事务在运行错误的情况下除了执行过程中出现错误的命令外其他命令都能正常执行。并且Redis 是不支持回滚roll back操作的。因此Redis 事务其实是不满足原子性的而且不满足持久性。
Redis 从 2.6 版本开始支持执行 Lua 脚本它的功能和事务非常类似。我们可以利用 Lua 脚本来批量执行多条 Redis 命令这些 Redis 命令会被提交到 Redis 服务器一次性执行完成大幅减小了网络开销。
一段 Lua 脚本可以视作一条命令执行一段 Lua 脚本执行过程中不会有其他脚本或 Redis 命令同时执行保证了操作不会被其他指令插入或打扰。
如果 Lua 脚本运行时出错并中途结束出错之后的命令是不会被执行的。并且出错之前执行的命令是无法被撤销的。因此严格来说通过 Lua 脚本来批量执行 Redis 命令也是不满足原子性的。 3.说说Redis bigkey吧
简单来说如果一个 key 对应的 value 所占用的内存比较大那这个 key 就可以看作是 bigkey
那么如何发现 bigkey 呢
1、使用 Redis 自带的 --bigkeys 参数来查找
# redis-cli -p 6379 --bigkeys
...
1 lists with 17 items (20.00% of keys, avg size 17.00)
0 hashs with 0 fields (00.00% of keys, avg size 0.00)
4 strings with 4831 bytes (80.00% of keys, avg size 1207.75)
0 streams with 0 entries (00.00% of keys, avg size 0.00)
0 sets with 0 members (00.00% of keys, avg size 0.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00这个命令会扫描(Scan) Redis 中的所有 key 会对 Redis 的性能有一点影响。并且这种方式只能找出每种数据结构 top 1 bigkey
2、分析 RDB 文件
通过分析 RDB 文件来找出 big key网上有现成的工具可以直接拿来使用 4.大量 key 集中过期问题怎么解决的
给 key 设置随机过期时间。开启 lazy-free惰性删除/延迟释放 。lazy-free 特性是 Redis 4.0 开始引入的指的是让 Redis 采用异步方式延迟释放 key 使用的内存将该操作交给单独的子线程处理避免阻塞主线程。 5.如何保证缓存和数据库数据的一致性
下面单独对 Cache Aside Pattern旁路缓存模式 来聊聊。
Cache Aside Pattern 中遇到写请求是这样的更新 DB然后直接删除 cache 。
如果更新数据库成功而删除缓存这一步失败的情况的话简单说两个解决方案
缓存失效时间变短不推荐治标不治本 我们让缓存数据的过期时间变短这样的话缓存就会从数据库中加载数据。增加 cache 更新重试机制常用 如果 cache 服务当前不可用导致缓存删除失败的话我们就隔一段时间进行重试重试次数可以自己定。如果多次重试还是失败的话我们可以把当前更新失败的 key 存入队列中等缓存服务可用之后再将缓存中对应的 key 删除即可。 6.缓存穿透有哪些解决办法
缓存穿透说简单点就是大量请求的 key 是不合理的根本不存在于缓存中也不存在于数据库中 。这就导致这些请求直接到了数据库上根本没有经过缓存这一层对数据库造成了巨大的压力可能直接就被这么多请求弄宕机了。
防止缓存穿透的方法
做好参数校验一些不合法的参数请求直接抛出异常信息返回给客户端。比如查询的数据库 id 不能小于 0、传入的邮箱格式不对的时候直接返回错误消息给客户端等等。缓存 null 值如果缓存和数据库都查不到某个 key 的数据就写一个value为null的值到 Redis 中去并设置过期时间。这种方式可以解决请求的 key 变化不频繁的情况使用布隆过滤器布隆过滤器是一个非常神奇的数据结构通过它我们可以非常方便地判断一个给定数据是否存在于海量数据中
把所有可能存在的请求的值都存放在布隆过滤器中当用户请求过来先判断用户发来的请求的值是否存在于布隆过滤器中。不存在的话直接返回请求参数错误信息给客户端 我们先来看一下当一个元素加入布隆过滤器中的时候会进行哪些操作
使用布隆过滤器中的哈希函数对元素值进行计算得到哈希值有几个哈希函数得到几个哈希值。根据得到的哈希值在位数组中把对应下标的值置为 1。
我们再来看一下当我们需要判断一个元素是否存在于布隆过滤器的时候会进行哪些操作
对给定元素再次进行相同的哈希计算得到值之后判断位数组中的每个元素是否都为 1如果值都为 1那么说明这个值在布隆过滤器中如果存在一个值不为 1说明该元素不在布隆过滤器中。 7.缓存击穿有哪些解决方法
缓存击穿中请求的 key 对应的是 热点数据 该数据 存在于数据库中但不存在于缓存中通常是因为缓存中的那份数据已经过期 。这就可能会导致瞬时大量的请求直接打到了数据库上对数据库造成了巨大的压力可能直接就被这么多请求弄宕机了。
防止缓存击穿的方法
设置热点数据永不过期或者过期时间比较长。针对热点数据提前预热将其存入缓存中并设置合理的过期时间比如秒杀场景下的数据在秒杀结束之前不过期。请求数据库写数据到缓存之前先获取互斥锁保证只有一个请求会落到数据库上减少数据库的压力。 8.缓存雪崩有哪些解决方法
缓存雪崩描述的就是这样一个简单的场景缓存在同一时间大面积的失效导致大量的请求都直接落到了数据库上对数据库造成了巨大的压力。
另外缓存服务宕机也会导致缓存雪崩现象导致所有的请求都落到了数据库上。
防止缓存雪崩的方法
针对 Redis 服务不可用的情况
采用 Redis 集群避免单机出现问题整个缓存服务都没办法使用。限流避免同时处理大量的请求。
针对热点缓存失效的情况
设置不同的失效时间比如随机设置缓存的失效时间。缓存永不失效不太推荐实用性太差。设置二级缓存。