Redis
1.Redis是什么
1.用开源C语言编写的
2.支持网络
3.可以持久化的,也可以设定时间存储数据
4.数据结构为K,V的数据库,内有丰富的数据类型
(String、hash、list、set、sorted set 多种数据类型)
5.基于内存的
6.在关系型数据库之前作为缓存数据库
7.有多种API
8.单线程(节约上下文切换线程的时间,不需要过多消耗CPU),
采用IO多路[socket连接]复用[一个线程]技术,这点就是Redis高吞吐量的原因
9.提供主从复制方案,负载均衡,容灾,分片等
1.1Redis和关系型数据库的区别
关系型数据库主要有:Mysql,Oracle,sqlServer,db2等
区别:
1.关系型数据库在存储数据之前是按照存储字典(也称数据字典)来存储,而Redis不需要。
2.关联性的查询,Redis没有关系型数据库的方便。
【数据字典:数据项、数据结构、数据流、数据存储和处理过程等组成,也称为元数据】
2.Redis的同类产品
2.1缓存类同类产品
缓存类同类产品有:Ehcache、Memcached
1.速度都差不多,没有什么区别
2.Ehcache使用方便,引入一个Jar包即可
3.Memcached是在Redis之前出现的,开启多线程模式,速度极大提高,
但是数据只会存在内存中,宕机不可恢复数据。
4.Redis支持的数据类型多。
在项目选型时,根据需要进行选择。
2.11Redis和Memcached详细对比
需要慎重考虑的部分
1.Memcached单个key-value大小有限,一个value最大只支持1MB,而Redis最大支持512MB
2.Memcached只是个内存缓存,对可靠性无要求;而Redis更倾向于内存数据库,
因此对对可靠性方面要求比较高
3.从本质上讲,Memcached只是一个单一key-value内存Cache;而Redis则是一个
数据结构内存数据库,支持五种数据类型,因此Redis除单纯缓存作用外,还可以
处理一些简单的逻辑运算,Redis不仅可以缓存,而且还可以作为数据库用
4.新版本(3.0)的Redis是指集群分布式,也就是说集群本身均衡客户端请求,
各个节点可以交流,可拓展行、可维护性更强大。
1.性能上:
性能上都很出色,具体到细节,由于Redis只使用单核,而Memcached可以使用多核,
所以平均每一个核上Redis在存储小数据时比
Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,
虽然Redis最近也在存储大数据的性能上进行优化,但是比起 Memcached,还是稍有逊色。
2.内存空间和数据量大小:
MemCached可以修改最大内存,采用LRU算法。Redis增加了VM的特性,突破了物理内存的限制。
3.操作便利上:
MemCached数据结构单一,仅用来缓存数据,而Redis支持更加丰富的数据类型,
也可以在服务器端直接对数据进行丰富的操作,这样可以减少网络IO次数和数据体积。
4.可靠性上:
MemCached不支持数据持久化,断电或重启后数据消失,但其稳定性是有保证的。
Redis支持数据持久化和数据恢复,允许单点故障,但是同时也会付出性能的代价。
5.应用场景:
Memcached:动态系统中减轻数据库负载,提升性能;做缓存,适合多读少写,
大数据量的情况(如人人网大量查询用户信息、好友信息、文章信息等)。
Redis:适用于对读写效率要求都很高,数据处理业务复杂和对安全性要求较高的系统
(如新浪微博的计数和微博发布部分系统,对数据安全性、读写要求都很高)。
2.2消息队列类同类产品
消息队列类同类产品:Kafka
Redis也可以作为消息队列,但是不及同类型的Kafka
Kafka设计的最初目的是一个日志系统,队列中的数据能够持久化一段时间,
生产者能够通过自定义offset来获取之前的消息,Redis没有这种功能。
区别:
1.redis是多个key,kafka是建多个topic。
2.kafka的一个队列可以有多个分组,redis不能。
3.redis可以通过客户端负载到多个集群,进而变相实现单队列拆分成多个小队列。
kafka是专业的消息队列组件,多个订阅者可以分组,同一个组里只有一个订阅者会收到该消息,
这样可以用作负载均衡。redis没有这种专业功能。
4.redis虽然速度快,但是不能保证数据的质量,Kafka可以保证数据不丢失,虽然有延迟。
5.数据量小,可以用redis,数据量大,用专业的Kafka最合适,他们的设计初衷不一样。
3.Redis出现的原因
纯内存存储[当然会持久化]、IO多路复用技术、单线程架构
还有哪个组件是这样呢?
4.Redis的作用
高性能共享:当数据需要被多个不同线程/进程/节点频繁读取时,redis基于内存读写效率高
并发缓冲:当多个写请求需要连接其它数据库时,使用redis做一个缓冲,将多个并发连接
转化为一次连接
5.Redis的优点
Redis利用内存的优势,会根据配置定时将内存中的数据写入硬盘中,这样即使重启依然可以恢复。
1.解决应用服务器的CPU和内存压力
2.减少IO的读操作,减轻应用服务器IO压力
3.数据结构丰富,读取速度快
6.Redis的缺点
1.关联性的查询,Redis没有关系型数据库的方便。
2.不适合需要事务支持的场景,Redis内存写入硬盘有一定的时间间隔,在这个间隔时间内,
数据有可能丢失,虽然Redis针对这种情况,也有优化,但是还是会有可能出现这种情况。
如果对数据有非常严
格的要求,不建议将Redis作为数据库使用。
3.没有索引,没有外键,缺少int/date等基本数据类型。
4.这点也不能算是缺点,每个组件都会有自己的瓶颈:
Redis的瓶颈最有可能是机器内存的大小或者网络带宽
7.Redis的应用场景
1.配合关系型数据库做高速缓存
2.可以持久化特定的数据做排行榜[利用有序集合]
3.计数器[incr命令可以直接+1,保证实时性,比如购买次数,浏览次数,直接在redis操作]
4.分布式会话[搭建以Redis等内存数据库为中心的session服务,session不再由容器管理,
而是由session服务及内存数据库管理]【客户端访问,开始至结束的一个session】
5.分布式锁[秒杀]
6.社交[点赞,关注类似计数器]
7.最新列表
8.消息系统
8.Redis在项目中遇到的问题和常见面试题
8.1缓存穿透问题
1.缓存穿透是什么?
Redis作为关系型数据库前面的挡板时,大量而频繁的查询肯定不存在的key
或者失效的key时,就会穿透redis来给要查询的数据库造成巨大的压力。
2.如何解决?
1)当查询的key不存在redis或者数据库时,就将这个查询的值赋值为Null存在缓存中,
这样进行再次查询时就可以不用重复查询,当如果这个值发生改变的时候,再重新赋值。
2)利用布隆过滤器将关系型数据库中的key都存在bit数组内,
[利用布隆过滤器的hash值,对查询的key取hash值存入bit数组内,存在为1,不存在为0
但是我们知道hash值会发生碰撞,所以不一定相同的输出值有相同的输入值,
所以只能大概率的判断查询的key是否
存在(具体查看布隆过滤器原理)]如果存在,才申请访问。
3)使用互斥锁,缓存不存在时向数据库发起带锁的读取请求,其它并发请求获取不到
锁则休眠重试读取(防高并发失效),如果不是大型的公司,一般用不上互斥锁。
8.2缓存雪崩问题
1.缓存雪崩是什么?
缓存在同一时间大面积失效,此时大量的请求失效的key,造成数据库的高并发连接崩溃
2.如何解决?
1) 提前将热门的数据结果缓存至Redis
2)互斥锁
3)均匀在key前加上随机数值,分布均匀过期时间[比如热门商品过期时间长,
冷门过期时间短
8.3缓存击穿问题
1.缓存击穿是什么?
我个人认为虽然击穿和穿透看起来是两个词,实质上都是对数据库造成压力的影响,
定义的话就是非常热点的数据,突然在某一个时间段高频的被访问,缓存也失效了。
这时候应该就是非常大型的网站遇上的事吧。
2.如何解决?
1.可以设置key永不过期
2.互斥锁,简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即
去加载数据库,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的
SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行
load db的操作并回设缓存;否则,就重试整个get缓存的方法。
8.4Redis双写一致性问题
1.双写一致性是什么?
对数据库进行写操作时会产生的redis缓存与数据库数据不一致的问题。
就是redis的缓存数据和数据库的数据不一样,读取redis缓存的就不准确了。
2.如何解决?(具体的方案可以自行搜索一下)
遇到不同的情况,解决方案不同
1)先更新数据库,再更新缓存
2)先删除缓存,再更新数据库
3)先更新数据库,再删除缓存
8.5Redis持久化
1.RDB
符合一定条件时redis会将内存中所有数据以二进制方式生成一份副本存储到硬盘
redis重启时可以通过该副本恢复数据,生成快照时redis进入阻塞状态。
RDB 是默认开启!
RDB 的优点是比AOF方式更加的高效
RDB 的缺点是最后一次持久化后的数据可能丢失。
[什么时候会数据丢失?
两次保存的时间间隔内,服务器宕机,或者发生断电问题。]
除了默认的时候,还有什么时候RDB持久化?
①在指定的时间间隔内持久化
②服务shutdown会自动持久化
③输入bgsave也会持久化
2.AOF
AOF 是以日志的形式来记录每个写操作,将每一次对数据进行修改,
都把新建、修改数据的命令保存到指定文件中。Redis 重新启动时读取这个文件,
重新执行新建、修改数据的命令恢复数据。
AOF 是手动启动的!
AOF 保存的路径和RDB是一样的#dir ./
AOF 只会保存修改的操作,写操作
当RDB和AOF存在不一致的情况下,会优先按照AOF来恢复。因为AOF是对RDB
的补充。备份周期更短,也就更可靠。
AOF保存策略:
1.产生了修改的数据时
2.每秒执行一次保存
3.不保存,交给系统保存
推荐(并且也是默认)的措施为每秒 fsync 一次,这种 fsync
策略可以兼顾速度和安全性。
****注意:只要是 aof 开启,则无论怎么样都会读取 aop 的配置文件。****
AOF的优点是更安全
AOF的缺点是耗磁盘,速度慢,性能压力,偶尔有bug
总结官方推荐:
如果对数据不敏感,可以选单独用RDB;不建议单独用AOF,因为可能出现Bug;
如果只是做纯内存缓存,可以都不用
8.6Redis主从复制
配置多台 Redis 服务器,以主机和备机的身份分开。主机数据更新后,根据配置和策略,
自动同步到备机的 master/salver 机制,Master 以写为主,Slave 以读为主,
二者之间自动同步数据。
目的:
读写分离提高 Redis 性能;
避免单点故障,容灾快速恢复
原理:
每次从机联通后,都会给主机发送 sync 指令,主机立刻进行存盘操作,发送 RDB 文件,
给从机,从机收到 RDB 文件后,进行全盘加载。之后每次主机的写操作,都会立刻发送
给从机,从机执行相同的命令