1.Redis是一个开源的底层使用C语言编写的key-value存储数据库。
数据类型(原子性的操作):string(字符串)、hash(哈希)、list(列表)、set(无序集合)、zset(sorted set:有序集合)
2.应用场景
- 缓存数据
- 消息队列
相当于消息订阅系统,比如ActiveMQ、RocketMQ。如果对数据有较高一致性要求时,还是建议使用MQ)
- 计数器
比如统计点击率、点赞率,redis具有原子性,可以避免并发问题
-
电商网站信息
大型电商平台初始化页面数据的缓存。比如去哪儿网购买机票的时候首页的价格和你点进去的价格会有差异。
-
热点数据
比如新闻网站实时热点、微博热搜等,需要频繁更新。总数据量比较大的时候直接从数据库查询会影响性能
3.缓存的作用:
当数据继续增大我们需要利用主从复制技术来达到读写分离
数据库层直接与缓存进行交互,如果缓存中有数据直接返回客户端,如果没有才会从MySql中去查询。从而减小了数据库的压力,提升了效率。
客户端-->数据库层-->缓存-->mysql
4.Redis数据类型的应用场景
String
字符串是最常用的数据类型,他能够存储任何类型的字符串,包括二进制、JSON化的对象、甚至是base64编码之后的图片。在Redis中一个字符串最大的容量为512MB
Hash
常用作存储结构化数据、比如论坛系统中可以用来存储用户的Id、昵称、头像、积分等信息。如果需要修改其中的信息,只需要通过Key取出Value进行反序列化修改某一项的值,再序列化存储到Redis中,Hash结构存储,由于Hash结构会在单个Hash元素在不足一定数量时进行压缩存储,所以可以大量节约内存。
List
List的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis 内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。另外,可以利用 lrange 命令,做基于 Redis 的分页功能,性能极佳,用户体验好。
Set
set 对外提供的功能与 list 类似是一个列表的功能,特殊之处在于 set 是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,这个时候就可以选择使用set。
ZSet
可以按照某个条件的权重进行排序,比如可以通过点击数做出排行榜的数据应用。
5.Redis缓存的数据保持最终一致性
6.Redis存储数据可以设置他的过期时间
Redis过期删除机制:
Redis过期删除采用的是定期删除,默认是每100ms检测一次,遇到过期的key则进行删除,进行随机检测。对于漏网之鱼:当我们去读/写一个已经过期的key时,会触发Redis的惰性删除策略,直接回干掉过期的key。
内存淘汰是指用户存储的一部分key是可以被Redis自动的删除,从而会出现从缓存中查不到数据的情况。
缓存击穿:缓存只是为了缓解数据库压力而添加的一层保护层,当从缓存中查询不到我们需要的数据就要去数据库中查询了。如果被黑客利用,频繁去访问缓存中没有的数据,那么缓存就失去了存在的意义,瞬间所有请求的压力都落在了数据库上,这样会导致数据库连接异常。
如何避免缓存击穿:
1、后台设置定时任务,主动的去更新缓存数据。这种方案容易理解,但是当key比较分散的时候,操作起来还是比较复杂的
2、分级缓存。比如设置两层缓存保护层,1级缓存失效时间短,2级缓存失效时间长。有请求过来优先从1级缓存中去查找,如果在1级缓存中没有找到相应数据,则对该线程进行加锁,这个线程再从数据库中取到数据,更新至1级和2级缓存。其他线程则直接从2级线程中获取
3、提供一个拦截机制,内部维护一系列合法的key值。当请求的key不合法时,直接返回。
缓存雪崩:指缓存由于某些原因(比如 宕机、cache服务挂了或者不响应)整体crash掉了,导致大量请求到达后端数据库,从而导致数据库崩溃,整个系统崩溃,发生灾难-->(缓存击穿)。
如何避免雪崩:
1、给缓存加上一定区间内的随机生效时间,不同的key设置不同的失效时间,避免同一时间集体失效。
2、和缓存击穿解决方案类似,做二级缓存,原始缓存失效时从拷贝缓存中读取数据。
3、利用加锁或者队列方式避免过多请求同时对服务器进行读写操作。
7.Redis持久化:
Redis 将数据存储于内存中,或被配置为使用虚拟内存。通过两种方式可以实现数据持久化:使用截图的方式,将内存中的数据不断写入磁盘;或使用类似 MySQL 的日志方式,记录每次更新的日志。前者性能较高,但是可能会引起一定程度的数据丢失;后者相反。
8.Redis的缺点:
- 由于是内存数据库,所以单台机器存储的数据量是有限的,需要开发者提前预估,需要及时删除不需要的数据。
- 当修改Redis的数据之后需要将持久化到硬盘的数据重新加入到内容中,时间比较久,这个时候Redis是无法正常运行的。