Redis 知识总结
Redis采用的是基于内存的单进程单线程模型的 KV 数据库,由C语言编写,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。
特点:
1.> 完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。它的,数据存在内存中;
2.> 数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;
3.> 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
4.> 使用多路I/O复用模型,非阻塞IO;
5.> 使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;
1、什么是Redis持久化?Redis有哪几种持久化方式?
持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。
Redis 提供了两种持久化方式:RDB(默认) 和AOF
2、 Redis是怎么进行持久化的.
持久化的话是Redis高可用中比较重要的一个环节,因为Redis数据在内存的特性,持久化是有两种方式的。
RDB:RDB 持久化机制,是对 Redis 中的数据执行周期性的持久化。
AOF:AOF 机制对每条写入命令作为日志,以 append-only 的模式写入一个日志文件中,因为这个模式是只追加的方式,所以没有任何磁盘寻址的开销,所以很快,有点像Mysql中的binlog。
两种方式都可以把Redis内存中的数据持久化到磁盘上,然后再将这些数据备份到别的地方去,RDB更适合做冷备,AOF更适合做热备.
tip:两种机制全部开启的时候,Redis在重启的时候会默认使用AOF去重新构建数据,因为AOF的数据是比RDB更完整。
那这两种机制各自优缺点是啥?
(1)我先说RDB吧
优点:
他会生成多个数据文件,每个数据文件分别都代表了某一时刻Redis里面的数据,这种方式,有没有觉得很适合做冷备,完整的数据运维设置定时任务,定时同步到远端的服务器,比如阿里的云服务,这样一旦线上挂了,你想恢复多少分钟之前的数据,就去远端拷贝一份之前的数据就好了。
RDB对Redis的性能影响非常小,是因为在同步数据的时候他只是fork了一个子进程去做持久化的,而且他在数据恢复的时候速度比AOF来的快。
缺点:
RDB都是快照文件,都是默认五分钟甚至更久的时间才会生成一次,这意味着你这次同步到下次同步这中间五分钟的数据都很可能全部丢失掉。AOF则最多丢一秒的数据,数据完整性上高下立判。
还有就是RDB在生成数据快照的时候,如果文件很大,客户端可能会暂停几毫秒甚至几秒,你公司在做秒杀的时候他刚好在这个时候fork了一个子进程去生成一个大快照,哦豁,出大问题。
我们再来说说AOF
优点:
上面提到了,RDB五分钟一次生成快照,但是AOF是一秒一次去通过一个后台的线程fsync操作,那最多丢这一秒的数据。
AOF在对日志文件进行操作的时候是以append-only的方式去写的,他只是追加的方式写数据,自然就少了很多磁盘寻址的开销了,写入性能惊人,文件也不容易破损。
AOF的日志是通过一个叫非常可读的方式记录的,这样的特性就适合做灾难性数据误删除的紧急恢复了,比如公司的实习生通过flushall清空了所有的数据,只要这个时候后台重写还没发生,你马上拷贝一份AOF日志文件,把最后一条flushall命令删了就完事了。
缺点:
一样的数据,AOF文件比RDB还要大。
AOF开启后,Redis支持写的QPS(每秒内查询次数)会比RDB支持写的要低,他不是每秒都要去异步刷新一次日志嘛fsync,当然即使这样性能还是很高,我记得ElasticSearch也是这样的,异步刷新缓存区的数据去持久化,为啥这么做呢,不直接来一条怼一条呢,那我会告诉你这样性能可能低到没办法用的,大家可以思考下为啥哟。
2. 那两者怎么选择?
小孩子才做选择,我全都要,你单独用RDB你会丢失很多数据,你单独用AOF,你数据恢复没RDB来的快,真出什么时候第一时间用RDB恢复,然后AOF做数据补全,真香!冷备热备一起上,才是互联网时代一个高健壮性系统的王道。
3.数据传输的时候断网了或者服务器挂了怎么办啊?
传输过程中有什么网络问题啥的,会自动重连的,并且连接之后会把缺少的数据补上的
Redis的过期策略,是有定期删除+惰性删除两种。
Redis支持存储的五种数据类型及使用场景:
Redis是一种存储key-value的内存型数据库,它的key都是字符串类型,value支持存储5种类型的数据:String(字符串类型)、List(列表类型)、Hash(哈希表类型、即key-value类型)、Set(无序集合类型,元素不可重复)、Zset(有序集合类型,元素不可重复)。
想要知道哪种数据类型适用于哪些场景,无非就是看他们的优点有哪些,然后看这些优点能做到哪些事情。
■ String类型:这种类型就不必过多介绍场景了,相信只要使用过redis的人都用过这种类型,这里就简单举几个例子:保存用户token,保存图片视频等二进制文件等;当存储数字时,还可以使用它的incr命令进行数字的原子性递增,可以用来统计数量。
■ List类型:Redis在存储List类型时,我们可以用LPUSH命令向List的左侧添加数据,然后用RPOP命令从List右侧取出数据,根据这个特性,我们就可以实现一个生产消费模式,生产者向List的一端添加数据,消费者从另一端取出数据,这样就实现了一个消息队列。
■ Set类型:Set类型的特点就是没有重复数据的列表,所以可以使用Set类型进行去重,也可以用于给用户打标签,然后根据标签中的内容给用户推送对应领域的消息。
■ ZSet类型:ZSet的特点是有序的集合,所以,我们可以使用该类型来实现自动排序的功能。例如新闻热搜排行榜,可以给每条新闻设置不同的score来达到自动排序的效果。
■ Hash类型:Hash类型经常用于存储一些对象类型的数据,比如我们可以把User对象存到Hash类型中,当需要修改User的某个属性的值时,可以直接修改对应的属性值,而不用修改整个User对象。
redis缓存穿透、缓存击穿、缓存雪崩及其解决方法
1. 什么是缓存穿透
缓存穿透是指查询一个缓存中和数据库中都不存在的数据,导致每次查询这条数据都会透过缓存,直接查库,最后返回空。当用户使用这条不存在的数据疯狂发起查询请求的时候,对数据库造成的压力就非常大,甚至可能直接挂掉。这种情况的流程就变成下图这样了:
缓存穿透解决方案
解决缓存穿透的方法一般有两种,第一种是缓存空对象,第二种是使用布隆过滤器。
2. 什么是缓存击穿
缓存击穿是指当缓存中某个热点数据过期了,在该热点数据重新载入缓存之前,有大量的查询请求穿过缓存,直接查询数据库。这种情况会导致数据库压力瞬间骤增,造成大量请求阻塞,甚至直接挂掉
缓存击穿解决方案
解决缓存击穿的方法也有两种,第一种是设置key永不过期;第二种是使用分布式锁,保证同一时刻只能有一个查询请求重新加载热点数据到缓存中,这样,其他的线程只需等待该线程运行完毕,即可重新从Redis中获取数据。
3. 什么是缓存雪崩
缓存雪崩是指当缓存中有大量的key在同一时刻过期,或者Redis直接宕机了,导致大量的查询请求全部到达数据库,造成数据库查询压力骤增,甚至直接挂掉。
缓存雪崩解决方案
针对第一种大量key同时过期的情况,解决起来比较简单,只需要将每个key的过期时间打散即可,使它们的失效点尽可能均匀分布。
针对第二种redis发生故障的情况,部署redis时可以使用redis的几种高可用方案部署,高可用方案—主从(masterslave)架构、Redis高可用架构—哨兵(sentinel)机制、Redis高可用架构—Redis集群(Redis Cluster)。
除了上面两种解决方式,还可以使用其他策略,比如设置key永不过期、加分布式锁等。
缓存的雪崩、击穿、穿透是在业务应用缓存时经常会碰到的缓存异常问题,其原因与解决方法如以下表示所示:
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 缓存雪崩 | 大量数据过期或Redis服务器宕机 |
1. 随机过期时间 2. 主从+哨兵的集群 |
| 缓存击穿 | 热点数据过期 | 1. 不设置过期时间 2. 加互斥锁 3. 冗余逻辑过期时间 |
| 缓存穿透 | 请求数据库和Redis都没有的数据 |
1. 缓存空值或缺省值 2. 布隆过滤器 |
Redis的应用场景
1、缓存对象
2、简单的计数
3、分布式锁
4、共享session
5、发红包,发红包需要确保在并发下,红包能只被一个人抢走;将红包拆分成n份,使用redis list类型 存储红包,使用list 的pop 方法抢红包。
6、消息队列
7、黑名单过滤,黑名单数据可以放在redis的set集合中。 可以sismember命令来判断在不在黑名单。
8、抽奖,存储某活动中中奖的用户名,Set 类型因为有去重功能,可以保证同一个用户不会中奖两次.
9、签到统计,在签到打卡的场景中,我们只用记录签到(1)或未签到(0),所以它就是非常典型的二值状态
参考文档:https://blog.csdn.net/m0_71777195/article/details/127688572

浙公网安备 33010602011771号