Redis是个大话题,只要是去面试Java开发,几乎必问。基础一点的问Redis是什么东西?用来做什么?Redis支持哪些数据类型?Redis的性能为什么那么好?复杂一点的就会问到缓存穿透、缓存击穿、缓存雪崩等问题。而我在面试的时候也被问到了Redis为什么用来做缓存的问题。

所以我觉得很有必要总结一下Redis作为缓存使用,可能会引发的问题。以达到温故而知新的效果

ps:在本文章中,就不讨论Redis能用来干啥?这种基础问题了

一、Redis简介:

在讨论Redis作为缓存使用,可能会引发的问题之前,我们得了解官方是怎么定义Redis

Redis是一个开源的内存中的数据结构存储系统,它可以用作:数据库、缓存和消息中间件。

它支持多种类型的数据结构,如字符串(Strings),散列(Hash),列表(List),集合(Set),有序集合(Sorted Set或者是ZSet)。

Redis 内置了复制(Replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(Transactions) 和不同级别的磁盘持久化(Persistence),并通过 Redis哨兵(Sentinel)和自动分区(Cluster)提供高可用性(High Availability)。

Redis也提供了两种持久化策略,这些策略可以让用户将自己的数据保存到磁盘上面进行存储。根据实际情况,可以每隔一定时间将数据集以快照的形式保存在磁盘(RDB策略),或者将所有操作成功的命令追加到命令日志中(AOF策略),它会在执行命令时,将被执行的命令复制到硬盘里面,实现实时持久化数据的效果。当然,根据实际开发的需求,你也可以关闭持久化功能,单纯的将Redis作为一个高效的网络的缓存数据功能使用。

二、Redis作为缓存使用,可能会引发的问题(重点)

Redis由C语言开发,并且将数据存储在内存中,可以说Redis完全是基于内存进行操作,对数据读写的速度极快、性能极好。官方提供的数据是可以达到每秒100000+的吞吐量(每秒内查询次数),如此优秀的机制使Redis极其适合作为缓存使用。

1.缓存穿透

程序在处理缓存时,一般是先从缓存查询,如果缓存没有这个key(理解为数据),则会从数据库中查询,并将查询到的数据保存到缓存中去。

好,问题来了,如果有个坏心眼的人向服务器发起请求,去查询一个一定不存在的数据,由于缓存中没有查到对应的数据时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,缓存形同虚设,这就是缓存穿透

解决方案:

1)最粗暴也是最常用的方法就是,如果一个查询的数据为空(不管是数据不存在还是系统故障),我们就把这个空结果进行缓存,但要把它的过期时间设置得很短,最长不超过5分钟,这样能有效的解决缓存穿透问题。

2)其次,可以采用布隆过滤器,也能解决缓存穿透问题

2.缓存击穿

缓存击穿和缓存穿透在本质上很相似,都是查询数据时缓存失去了作用,导致请求直接去数据库查询数据,但是造成缓存失效的原因却是天差地别。

大量用户在同一时间内访问某热点数据时,存储在缓存中的热点数据却突然失效(过期时间),结果就是大量的请求直接访问数据库,使数据库的压力变大,甚至导致数据库宕机,这就是缓存击穿。

解决方案:比较常用的方法是加互斥锁(mutex)保证数据的一致性。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去访问数据库,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set另一个请求所需要的数据,当操作返回成功时,再进行访问数据库的操作并回设缓存;否则,就重试整个get缓存的方法。

3.缓存雪崩

如果缓存的数据集中在一段时间内大批失效,而不巧的是在这段时间内又有大量用户发起请求访问数据,这样就会造成大量的缓存击穿,所有的请求都会直接去访问数据库,导致数据库在短时间内宕机,这就是缓存雪崩。

ps:这里我使用了夸张的修辞手法。缓存雪崩不一定会造成数据库宕机,但缓存如果发生雪崩现象,那肯定是很严重的

解决方案:

1)加锁排队。加互斥锁,添加信息队列

2)数据预热。可以通过缓存Reload机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀

3)设置热点缓存永不过时

笔者: 以上问题及解决方案纯粹个人见解,如果有错误的地方,还请指正

Redis作为缓存可能会出现的问题及解决方案

Redis是个大话题,只要是去面试Java开发,几乎必问。基础一点的问Redis是什么东西?用来做什么?Redis支持哪些数据类型?Redis的性能为什么那么好?复杂一点的就会问到缓存穿透、缓存击穿、缓存雪崩等问题。而我在面试的时候也被问到了Redis为什么用来做缓存的问题。

所以我觉得很有必要总结一下Redis作为缓存使用,可能会引发的问题。以达到温故而知新的效果

ps:在本文章中,就不讨论Redis能用来干啥?这种基础问题了

一、Redis简介:

在讨论Redis作为缓存使用,可能会引发的问题之前,我们得了解官方是怎么定义Redis

Redis是一个开源的内存中的数据结构存储系统,它可以用作:数据库、缓存和消息中间件。

它支持多种类型的数据结构,如字符串(Strings),散列(Hash),列表(List),集合(Set),有序集合(Sorted Set或者是ZSet)。

Redis 内置了复制(Replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(Transactions) 和不同级别的磁盘持久化(Persistence),并通过 Redis哨兵(Sentinel)和自动分区(Cluster)提供高可用性(High Availability)。

Redis也提供了两种持久化策略,这些策略可以让用户将自己的数据保存到磁盘上面进行存储。根据实际情况,可以每隔一定时间将数据集以快照的形式保存在磁盘(RDB策略),或者将所有操作成功的命令追加到命令日志中(AOF策略),它会在执行命令时,将被执行的命令复制到硬盘里面,实现实时持久化数据的效果。当然,根据实际开发的需求,你也可以关闭持久化功能,单纯的将Redis作为一个高效的网络的缓存数据功能使用。

二、Redis作为缓存使用,可能会引发的问题(重点)

Redis由C语言开发,并且将数据存储在内存中,可以说Redis完全是基于内存进行操作,对数据读写的速度极快、性能极好。官方提供的数据是可以达到每秒100000+的吞吐量(每秒内查询次数),如此优秀的机制使Redis极其适合作为缓存使用。

1.缓存穿透

程序在处理缓存时,一般是先从缓存查询,如果缓存没有这个key(理解为数据),则会从数据库中查询,并将查询到的数据保存到缓存中去。

好,问题来了,如果有个坏心眼的人向服务器发起请求,去查询一个一定不存在的数据,由于缓存中没有查到对应的数据时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,缓存形同虚设,这就是缓存穿透

解决方案:

1)最粗暴也是最常用的方法就是,如果一个查询的数据为空(不管是数据不存在还是系统故障),我们就把这个空结果进行缓存,但要把它的过期时间设置得很短,最长不超过5分钟,这样能有效的解决缓存穿透问题。

2)其次,可以采用布隆过滤器,也能解决缓存穿透问题

2.缓存击穿

缓存击穿和缓存穿透在本质上很相似,都是查询数据时缓存失去了作用,导致请求直接去数据库查询数据,但是造成缓存失效的原因却是天差地别。

大量用户在同一时间内访问某热点数据时,存储在缓存中的热点数据却突然失效(过期时间),结果就是大量的请求直接访问数据库,使数据库的压力变大,甚至导致数据库宕机,这就是缓存击穿。

解决方案:比较常用的方法是加互斥锁(mutex)保证数据的一致性。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去访问数据库,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set另一个请求所需要的数据,当操作返回成功时,再进行访问数据库的操作并回设缓存;否则,就重试整个get缓存的方法。

3.缓存雪崩

如果缓存的数据集中在一段时间内大批失效,而不巧的是在这段时间内又有大量用户发起请求访问数据,这样就会造成大量的缓存击穿,所有的请求都会直接去访问数据库,导致数据库在短时间内宕机,这就是缓存雪崩。

ps:这里我使用了夸张的修辞手法。缓存雪崩不一定会造成数据库宕机,但缓存如果发生雪崩现象,那肯定是很严重的

解决方案:

1)加锁排队。加互斥锁,添加信息队列

2)数据预热。可以通过缓存Reload机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀

3)设置热点缓存永不过时

笔者: 以上问题及解决方案纯粹个人见解,如果有错误的地方,还请指正

Redis作为缓存可能会出现的问题及解决方案的更多相关文章

  1. 高并发简单解决方案————redis队列缓存+mysql 批量入库(ThinkPhP)

    问题分析 问题一:要求日志最好入库:但是,直接入库mysql确实扛不住,批量入库没有问题,done.[批量入库和直接入库性能差异] 问题二:批量入库就需要有高并发的消息队列,决定采用redis lis ...

  2. HAProxy 的负载均衡服务器,Redis 的缓存服务器

    问答社区网络 StackExchange 由 100 多个网站构成,其中包括了 Alexa 排名第 54 的 StackOverflow.StackExchang 有 400 万用户,每月 5.6 亿 ...

  3. spring使用redis做缓存

    缓存 什么是缓存? 在高并发下,为了提高访问的性能,需要将数据库中 一些经常展现和不会频繁变更的数据,存放在存取速率更快的内存中.这样可以 降低数据的获取时间,带来更好的体验 减轻数据库的压力 缓存适 ...

  4. 知乎技术分享:从单机到2000万QPS并发的Redis高性能缓存实践之路

    本文来自知乎官方技术团队的“知乎技术专栏”,感谢原作者陈鹏的无私分享. 1.引言 知乎存储平台团队基于开源Redis 组件打造的知乎 Redis 平台,经过不断的研发迭代,目前已经形成了一整套完整自动 ...

  5. Spring Boot + Mybatis + Redis二级缓存开发指南

    Spring Boot + Mybatis + Redis二级缓存开发指南 背景 Spring-Boot因其提供了各种开箱即用的插件,使得它成为了当今最为主流的Java Web开发框架之一.Mybat ...

  6. 从单机到2000万 QPS 并发的 Redis 高性能缓存实践之路

    1.引言 知乎存储平台团队基于开源Redis 组件打造的知乎 Redis 平台,经过不断的研发迭代,目前已经形成了一整套完整自动化运维服务体系,提供很多强大的功能.本文作者陈鹏是该系统的负责人,本次文 ...

  7. c#实例化继承类,必须对被继承类的程序集做引用 .net core Redis分布式缓存客户端实现逻辑分析及示例demo 数据库笔记之索引和事务 centos 7下安装python 3.6笔记 你大波哥~ C#开源框架(转载) JSON C# Class Generator ---由json字符串生成C#实体类的工具

    c#实例化继承类,必须对被继承类的程序集做引用   0x00 问题 类型“Model.NewModel”在未被引用的程序集中定义.必须添加对程序集“Model, Version=1.0.0.0, Cu ...

  8. Redis之缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级

    目录 Redis之缓存雪崩.缓存穿透.缓存预热.缓存更新.缓存降级 1.缓存雪崩 2.缓存穿透 3.缓存预热 4.缓存更新 5.缓存降级 Redis之缓存雪崩.缓存穿透.缓存预热.缓存更新.缓存降级 ...

  9. Redis 多级缓存架构和数据库与缓存双写不一致问题

    采用三级缓存:nginx本地缓存+redis分布式缓存+tomcat堆缓存的多级缓存架构 时效性要求非常高的数据:库存 一般来说,显示的库存,都是时效性要求会相对高一些,因为随着商品的不断的交易,库存 ...

随机推荐

  1. Windows 10 WSL 2.0安装并运行Docker

    在Windows 10 2004版本,微软更新WSL到了2.0,WSL 2.0已经拥有了完整的Linux内核!今天来测试一下,是否可以安装docker!  一.开启WSL 以管理员运行Powershe ...

  2. CODING DevOps 系列第四课:DevOps 中的质量内建实践

    什么是质量内建 随着时间的推移,我们项目的开发效率会逐渐降低,直到几年之后整个项目可能就无法维护,只能推倒重来.具体的表现首先就是随着时间推移,我们会发现整个需求列表里面能做的需求越来越少,因为每当我 ...

  3. Day7-微信小程序实战-交友小程序首页UI

    一般都是直接用微信提供的组件来进行布局的 在小程序中最好少用id,尽量用class 轮播图就是直接用swiper 直接在微信开发者文档里面->组件->swiper->示例代码 < ...

  4. Beta冲刺<4/10>

    这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 Beta冲刺 这个作业的目标 Beta冲刺--第四天(05.22) 作业正文 如下 其他参考文献 ... B ...

  5. Mac上使用brew另装ruby和gem的新玩法

    [本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究.若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!] 众所周知,Mac ...

  6. h5请求签名加密

    签名说明 签名对 url + method + 业务参数 进行统一签名,防止重放和篡改 客户端js对加密逻辑和appSecret进行混淆加密处理,增加破解难度 客户端本地存储appid 和 appSe ...

  7. Nginx使用upstream实现负载均衡

    如果Nginx没有仅仅只能代理一台服务器的话,那它也不可能像今天这么火,Nginx可以配置代理多台服务器,当一台服务器宕机之后,仍能保持系统可用.具体配置过程如下: 1. 在http节点下,添加ups ...

  8. Python之浅谈运算符

    目录 格式化输出的三种方式 第一种格式化方式(3.0) 第二种格式化方式(3.4) 第三种格式化方式(3.6) 基本运算符 逻辑运算符 相等运算符 比较运算符 算术运算符 位运算符 流程控制 if判断 ...

  9. django admin 添加用户出现外键约束错误

    今天在做mxonline项目时,注册了用户表进admin后,想在后台添加一个用户试试,结果出现了错误,经过一番搜索发现以下两个解决方法,不过我只用了一种 报错信息: IntegrityError: ( ...

  10. 程序员的修炼-我们为什么会编写BUG

    在最近的一周,我维护的业务系统出现了很多坏毛病,一周七天crash掉了4次,每次都需要都是因为一点很小的问题,触发了蝴蝶效应,导致整个系统全盘崩溃,于是产生除了叙述本篇的想法,当然这并不是为了掩盖我在 ...