发布时间:2023-06-23 13:30
Redis是一款内存高速缓存数据库,使用C语言编写,是一个key-value存储系统,可持久化保存。
可用于缓存,高速队列,事件发布或订阅等场景。
存储的数据类型
字符串、整数或浮点数。
对整个字符串或字符串的一部分进行操作;对整数或浮点数进行自增或自减操作。
使用场景
(1)缓存: 把常用信息(字符串,图片或者视频等信息)放到redis中,redis作为缓存层,mysql做持久化层,降低mysql的读写压力。
(2)计数器:redis是单线程模型,一个命令执行完才会执行下一个。
注意:String字符串是二进制安全的,所以可以包含任何数据,比如图片、视频或者序列化的对象,最大能存储512M。
存储的数据类型
双向链表。
可以实现栈和队列的功能。
使用场景
(1)消息队列
存储的数据类型
String 类型的无序集合,集合中的元素不能重复。
Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
使用场景
(1)点赞,或点踩,收藏
存储的数据类型
String 类型的有序集合,集合中的元素不能重复。每个元素都会关联一个 double 类型的分数,通过这个分数进行排序。
使用场景
(1)排行榜:榜单可以按照用户关注数,更新时间,字数等打分,做排行。
存储的数据类型
key-value类型的数据,hash特别适合用于存储对象。
使用场景
(1)缓存:相比String更节省空间的维护缓存信息,如用户信息。
为了防止数据丢失以及服务重启时能够恢复数据,Redis支持数据的持久化,主要分为两种方式,分别是RDB和AOF; 当然实际场景下还会使用这两种的混合模式。
RDB持久化是把当前进程数据生成快照保存到磁盘上的过程。
优点:
(1)RDB恢复数据比AOF快。
缺点:
(1)两次快照之间的数据可能会因为系统宕机等问题无法持久化。
redis执行命令,先把数据写入内存,再把命令记录到磁盘上的日志。
为什么AOF是先写数据,再记日志(大多数数据库都是先记日志,再写数据,比如mysql)?
好处:
(1)记日志的时候,就不用再去对命令进行语法检查。
(2)不会阻塞当前的写操作。
问题:
(1)如果在写入数据和记日志之间系统宕机,那么就会丢失数据。
优点:
(1)实现了秒级的持久化。
缺点:
(1)AOF恢复数据比RDB慢。日志文件大,所以redis有重写机制对AOF日志进行瘦身。
内存快照以一定的频率执行,在两次快照之间,使用AOF日志记录这期间的所有命令操作。在第二次快照之后,之前的AOF日志就可以删掉了。
恢复数据,优先AOF,后RDB。
Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
发布者可以向指定的频道(channel)发送消息。
订阅者可以订阅一个或者多个频道(channel),所有订阅此频道的订阅者都会收到此消息。
注意:发出去的消息不会被持久化,也就是订阅者订阅某频道后,只能接收到后续发布到该频道的消息,之前的就接收不到了。
如果有一个频道匹配了一个模式,那么这个频道在给它的订阅者发消息时,也会给该模式的订阅者发消息。
Redis 事务的本质是一组命令的集合。一个事务中会执行多个命令,这些命令会按照顺序串行化的执行,其他客户端提交的命令请求不会插入到事务执行命令序列中。
编译器错误会回滚(语法错误),运行时错误不会回滚(操作类型错误),会继续执行下面的命令。
注: 原子性通过CAS实现。
要避免单点故障,保证高可用,所以Redis 提供了主从复制机制。
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。
主从复制的作用:
主从库之间采用的是读写分离的方式:
主从复制有全量复制(RDB)和增量复制两种。
主从复制原理
为什么全量复制使用RDB而不使用AOF?
在 Redis 主从集群中,哨兵机制是实现主从库自动切换的关键机制,它有效地解决了主从复制模式下故障转移的问题。
哨兵通过发送命令,等待主从库响应,从而监控主从库的运行状态。
当哨兵检测到主库宕机,会自动将某个从库切换成主库,然后通过发布订阅的方式通知其他的从库,让它们切换主库。
Redis 为何这么快?
基于内存。
为何使用单线程?
因为 Redis 是基于内存的操作,CPU 不会成为 Redis 的瓶颈,而对Redis影响最大的可能是机器内存的大小或者网络带宽。且单线程实现简单。
缓存穿透
原因:查询数据在缓存和数据库中都没有,如果攻击者一直高频率的查询此类数据,那么就会对数据库造成巨大压力。
解决方案:
(1)即使在数据库中没有查到数据,也以key-null的形式放到缓存中。
(2)key 值校验(布隆过滤器)。
缓存击穿
原因:查询数据在缓存中没有,在数据库中有,但是因为并发用户量太多,导致并发查询数据库时,对数据库造成巨大压力。
解决方案:
(1)热点数据永不过期。
(2)加互斥锁。
(3)熔断降级。
缓存雪崩
原因:同一时间,大批量缓存到期,但是此时查询量很大,对数据库造成巨大压力。与缓存击穿的区别是,缓存击穿是一条数据,缓存雪崩是大批量数据。
解决方案:
(1)热点数据永不过期。
(2)随机分散过期时间。
缓存污染
原因:某些数据被放到缓存后,很少再被使用,这就造成了资源浪费。
解决方案:
(1)LRU:根据时效性去判断,淘汰最早查询的数据。但是如果一次查询大量数据放到缓存,且这些数据是不被经常使用的,LRU策略就不能及时的淘汰这些数据,造成缓存空间的浪费。
(2)LFU:优先判断被查询的次数,淘汰次数小的数据。如果次数一样,再根据时效性去判断。
缓存篇(05)缓存被污染了,该怎么办?
参考文档