为什么要用redis好处_为什么用redis做缓存

为什么要用redis好处_为什么用redis做缓存Redis真的那么好用吗?

大家好,又见面了,我是你们的朋友全栈君。


Redis是什么

Redis是一个开源的底层使用C语言编写的key-value存储数据库。可用于缓存、事件发布订阅、高速队列等场景。而且支持丰富的数据类型:string(字符串)、hash(哈希)、list(列表)、set(无序集合)、zset(sorted set:有序集合)

Redis在项目中的应用场景

1、缓存数据

最常用,对经常需要查询且变动不是很频繁的数据 常称作热点数据。

2、消息队列

相当于消息订阅系统,比如ActiveMQ、RocketMQ。如果对数据有较高一致性要求时,还是建议使用MQ)

3、计数器

比如统计点击率、点赞率,redis具有原子性,可以避免并发问题

4、电商网站信息

大型电商平台初始化页面数据的缓存。比如去哪儿网购买机票的时候首页的价格和你点进去的价格会有差异。

5、热点数据

比如新闻网站实时热点、微博热搜等,需要频繁更新。总数据量比较大的时候直接从数据库查询会影响性能

给个爱的理由

在单节点服务器我们通常是这样的

e181c5bab532cd5cc9141dbce270c81cd3998fb7

随着企业的发展、业务的扩展。面对海量的数据,直接使用MySql会导致性能下降,数据的读写也会非常慢。于是我们就可以搭配缓存来处理海量数据。

于是现在我们是这样的:

e288f6aebcd74d3bee3221a60b96c5e7c293caa6

上图只是简述了缓存的作用,当数据继续增大我们需要利用主从复制技术来达到读写分离

数据库层直接与缓存进行交互,如果缓存中有数据直接返回客户端,如果没有才会从MySql中去查询。从而减小了数据库的压力,提升了效率。

平时发布了一款新手机,会有抢购活动。同一时间段,服务端会收到很多的下单请求。

我们需要使用redis的原子操作来实现这个“单线程”。首先我们把库存存在一个列表中,假设有10件库存,就往列表中push10个数,这个数没有实际意义,仅仅只是代表10件库存。抢购开始后,每到来一个用户,就从列表中pop一个数,表示用户抢购成功。当列表为空时,表示已经被抢光了。因为列表的pop操作是原子的,即使有很多用户同时到达,也是依次执行的

题外话:还有的抢购是直接在前端页面限制请求,这些请求直接被前端拦截,并没有到后端服务器

Redis为什么会这么快

1、Redis是纯内存操作,需要的时候需要我们手动持久化到硬盘中

2、Redis是单线程,从而避开了多线程中上下文频繁切换的操作。

3、Redis数据结构简单、对数据的操作也比较简单

4、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求

5、使用多路I/O复用模型,非阻塞I/O

多路I/O复用

I/O 多路复用技术是为了解决进程或线程阻塞到某个 I/O 系统调用而出现的技术,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪,就是这个文件描述符进行读写操作之前),能够通知程序进行相应的读写操作

Redis数据类型应用场景

前面提到了Redis支持五种丰富的数据类型,那么在不同场景下我们该怎么选择呢?

String

字符串是最常用的数据类型,他能够存储任何类型的字符串,当然也包括二进制、JSON化的对象、甚至是base64编码之后的图片。在Redis中一个字符串最大的容量为512MB,可以说是无所不能了。

Hash

常用作存储结构化数据、比如论坛系统中可以用来存储用户的Id、昵称、头像、积分等信息。如果需要修改其中的信息,只需要通过Key取出Value进行反序列化修改某一项的值,再序列化存储到Redis中,Hash结构存储,由于Hash结构会在单个Hash元素在不足一定数量时进行压缩存储,所以可以大量节约内存。这一点在String结构里是不存在的。

List

List的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis 内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。另外,可以利用 lrange 命令,做基于 Redis 的分页功能,性能极佳,用户体验好。

Set

set 对外提供的功能与 list 类似是一个列表的功能,特殊之处在于 set 是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,这个时候就可以选择使用set。

Sorted Set

可以按照某个条件的权重进行排序,比如可以通过点击数做出排行榜的数据应用。

Redis缓存的数据一致性

真正意义上来讲数据库的数据和缓存的数据是不可能一致的,数据分为最终一直和强一致两类。如果业务中对数据的要求必须强一直那么就不能使用缓存。缓存能做的只能保证数据的最终一致性。

我们能做的只能是尽可能的保证数据的一致性。不管是先删库再删缓存 还是 先删缓存再删库,都可能出现数据不一致的情况,因为读和写操作是并发的,我们没办法保证他们的先后顺序。具体应对策略还是要根据业务需求来定,这里就不赘述了。

Redis的过期和内存淘汰

Redis存储数据时我们可以设置他的过期时间。但是这个key是怎么删除的呢?

一开始我认为是定时删除,后来发现并不是这样,因为如果定时删除,需要一个定时器来不断的负责监控这个key,虽然内存释放了,但是非常消耗cpu资源。

Redis过期删除采用的是定期删除,默认是每100ms检测一次,遇到过期的key则进行删除,这里的检测并不是顺序检测,而是随机检测。那这样会不会有漏网之鱼?显然Redis也考虑到了这一点,当我们去读/写一个已经过期的key时,会触发Redis的惰性删除策略,直接回干掉过期的key

内存淘汰是指用户存储的一部分key是可以被Redis自动的删除,从而会出现从缓存中查不到数据的情况。加入我们的服务器内存为2G、但是随着业务的发展缓存的数据已经超过2G了。但是这并不影响我们程序的运行,因为操作系统的可见内存并不受物理内存的限制。物理内存不够用没关系,计算机会从硬盘中划出一片空间来作为虚拟内存。这就是Redis设计两种应用场景的初衷:缓存、持久存储

缓存击穿

缓存只是为了缓解数据库压力而添加的一层保护层,当从缓存中查询不到我们需要的数据就要去数据库中查询了。如果被黑客利用,频繁去访问缓存中没有的数据,那么缓存就失去了存在的意义,瞬间所有请求的压力都落在了数据库上,这样会导致数据库连接异常。

解决方案:

1、后台设置定时任务,主动的去更新缓存数据。这种方案容易理解,但是当key比较分散的时候,操作起来还是比较复杂的

2、分级缓存。比如设置两层缓存保护层,1级缓存失效时间短,2级缓存失效时间长。有请求过来优先从1级缓存中去查找,如果在1级缓存中没有找到相应数据,则对该线程进行加锁,这个线程再从数据库中取到数据,更新至1级和2级缓存。其他线程则直接从2级线程中获取

3、提供一个拦截机制,内部维护一系列合法的key值。当请求的key不合法时,直接返回。

缓存雪崩

缓存雪崩就是指缓存由于某些原因(比如 宕机、cache服务挂了或者不响应)整体crash掉了,导致大量请求到达后端数据库,从而导致数据库崩溃,整个系统崩溃,发生灾难,也就是上面提到的缓存击穿

5e13bd356cef4a4c1d20eae63badc56b22f1ffdb

图片来源自网络

如何避免雪崩:

1、给缓存加上一定区间内的随机生效时间,不同的key设置不同的失效时间,避免同一时间集体失效。

2、和缓存击穿解决方案类似,做二级缓存,原始缓存失效时从拷贝缓存中读取数据。

3、利用加锁或者队列方式避免过多请求同时对服务器进行读写操作。

写在最后

Redis的性能极高,读的速度是110000次/s,写的速度是81000次/s,支持事务,支持备份,丰富的数据类型。

任何事情都是两面性,Redis也是有缺点的:

1、由于是内存数据库,所以单台机器存储的数据量是有限的,需要开发者提前预估,需要及时删除不需要的数据。

2、当修改Redis的数据之后需要将持久化到硬盘的数据重新加入到内容中,时间比较久,这个时候Redis是无法正常运行的。

原文发布时间为:2018-10-30
本文作者: 程序员共成长
本文来自云栖社区合作伙伴“ 程序员共成长”,了解相关信息可以关注“程序员共成长”。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/107225.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • rsync自动同步_文件实时同步

    rsync自动同步_文件实时同步文章目录一、rsync同步简介1.关于rsync2.rsync同步源(备份源)二、配置rsync备份源1.关闭防火墙2.查看rsync是否已安装,一般系统已默认安装rsync3.建立/etc/rsync.conf配置文件4.为备份账户创建数据文件5.保证所有用户对源目录/var/www/html都有读取权限6.启动rsync服务程序7.关闭rsync服务8.编写测试网页三、rsync命令基本用法1.基本格式2.常用选项四、配置发起端1.关闭防火墙2.查看rsync是否已安装,一般

    2022年10月13日
  • SpringBoot + mybatis 分页查询

    SpringBoot + mybatis 分页查询com.github.pagehelper.PageHelper是一款好用的开源免费的Mybatis第三方分页插件。使用的时候,只要简单配置,就可以在查询语句之后得到所需的分页信息。1:在pom.xml中引入依赖项。dependency>groupId>com.github.pagehelpergroupId>artifactId>pagehelperarti

  • 嵌入式语音识别智能家居笔记1

    嵌入式语音识别智能家居笔记11.环境VMware15.5Ubuntu18.04Qt安装包2.共享目录设置VMware->虚拟机->设置->选项->共享文件夹3.QT的linux安装包:qt-opensource-linux-x64-5.9.1.run复制到共享目录打开终端:cd/mnt/hgfs/sharesudo./qt-opensource-linux-x64-5.9.1.run4.直接搭服务器失败(1)sudodate-s2016-…

  • 曾國藩家書摘_曾国藩语录及诠释

    曾國藩家書摘_曾国藩语录及诠释人物简介曾国藩(1811年11月26日-1872年3月12日),中国近代政治家、军事家、理学家、文学家,与胡林翼并称曾胡。曾国藩与李鸿章、左宗棠、张之洞并称“晚清四大名臣”,官至武英殿大学士、两江总督,同治年间封一等毅勇侯,谥文正。人物评价知人之明,谋国之忠,自愧不如元辅;同心若金,功错若石,相期无负平生。-左宗棠吾师道德功业,固不待言,即文章学问,亦卓…

  • 用c语言编写学生成绩管理系统(c语言学生成绩管理系统删除)

    一、课程设计题目①基本要求题目:矩阵乘法。②综合训练:学生成绩管理系统二、设计要求矩阵乘法:编写一个函数实现矩阵A(2行3列)与矩阵B相乘(3行2列),乘积放在C数组中。在主函数中输入相乘的两数组,并输出结果。学生成绩管理:(结构体数组、函数、指针、算法、流程结构及文件等的综合应用)程序说明:有N个学生,每个学生的数据包含学号(不重复)、姓名、三门课的成绩及平均成绩,试设计一学生成绩管理系统,…

  • 再见PowerDesigner,这款国人开源的数据库设计工具Chiner真香

    再见PowerDesigner,这款国人开源的数据库设计工具Chiner真香再见PowerDesigner,这款国人开源的数据库设计工具Chiner真香当我们在项目开发初期时,往往需要设计大量的表,此时使用数据库设计工具就会比较高效!今天给大家推荐一款国人开源的数据库设计工具chiner,界面漂亮,功能强大,希望对大家有所帮助!回顾PowerDesigner相信平时工作中,大家或多或少会使用PowerDesigner来设计数据库,感觉这款工具界面有点古老,界面看着就具年代感,有时候用起来也比较重,来看下之前使用它设计数据库的效果。最近体验了一把chiner,设计数据库

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号