简介
一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
数据类型
Redis支持五种数据类型:String,hash,List,Set,Sorted Set
全局哈希表结构如下:
哈希冲突: redis解决哈希冲突使用的是 链地址法(拉链法)
常见的解决Hash冲突的方案:开放寻址法、链地址法和再哈希法。
- 开放寻址法:原理是当发生hash冲突时,会以当前地址为基准,然后根据寻址方法(探查寻址),去寻找下一次地址。若依旧发生冲突,则继续寻址,直到找到一个空的位置为止。
- 链地址法(拉链法):HashSet其实都是采用的拉链法来解决哈希冲突的,就是在每个位桶实现的时候,我们采用链表(jdk1.8之后采用链表+红黑树)的数据结构来去存取发生哈希冲突的输入域的关键字(也就是被哈希函数映射到同一个位桶上的关键字)
- 再哈希法
持久化
AOF和RDB
数据库是写前日志,而Redis的AOF是写后日志
AOF
1.回写策略
- Always,同写同回,写完立马同步到磁盘上。
- Evevrysec,每秒写回
- No,操作系统控制写回,先写入内存缓冲区,再由操作系统决定何时将缓冲区内容写回。
2.AOF重写机制
每次AOF重写,Redis都会先执行一个内存拷贝,用于重写;然后使用两个日志来保证在重写过程中新写入的数据不会丢失。
AOF是写日志,但是如果要恢复的话,就需要一条一条执行,如果我们有快照,就不需要管理这个过程,而是能够直接获取状态了。
RDB
内存快照 RDB,为什么需要内存快照,为了解决AOF数据恢复过慢问题。
Redis执行的是全量快照,bgsave创建一个子线程,专门用于写入RDB文件,避免了主线程的阻塞。
集群方式
集群方式主要有三种 主从模式,哨兵模式,集群模式
1. 主从模式
主从为了解决单点问题,通常会把数据复制多个副本到其他机器,满足故障恢复和负载均衡等求,主节点负责写数据,从节点负责读数据,主节点定期把数据同步到从节点保证数据的一致性
缺点:主节点宕机则不能工作,写能力单机,性能有限,单节点存储能力有限
2. 哨兵模式
Redis Sentinel 是一个分布式系统, Redis Sentinel为Redis提供高可用性。可以在没有人为干预的情况下阻止某种类型的故障。
监控》告警 》故障恢复:
1.Sentinel定期检查主从服务是否正常工作 2.当故障时会通过API向管理员或其他程序发通知
3.Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器,当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
3. Redis Cluster(集群)
是 redis的分布式解决方案,在3.0版本正式推出
当遇到单机、内存、并发、流量等瓶颈时,可以采用Cluster架构方案达到负载均衡目的。
Cluster 默认会对 key 值使用 crc32 算法进行 hash 得到一个整数值,然后用这个整数值对 16384 进行取模来得到具体槽位。
Cluster 还允许用户强制某个 key 挂在特定槽位上,通过在 key 字符串里面嵌入 tag 标记,这就可以强制 key 所挂在的槽位等于 tag 所在的槽位。
数据库缓存一致性解决方案
- 自动更新:可通过监控数据库的变更,当数据库中的数据发生更改时,自动更新相应的Redis缓存数据,以保证两者一致。可以借助一些开源的消息队列,比如RabbitMQ或者Kafka来实现消息的异步传递,达到自动更新的效果。
- 手动更新:开发人员可以手动在代码中实现对缓存数据的更新,当数据库中的数据发生变更时,手动更新缓存数据。这种方法对于一些特定的场景,比如缓存数据的变更频率比较低的场景适用。
缓存击穿与雪崩
-
缓存击穿:击穿是某个热点key过期或失效,导致大量请求绕过缓存请求数据库导致
解决方案:1.可以使用互斥锁进行资源访问控制 2.分布式锁进行资源访问控制 3.热点数据永不过期 -
缓存雪崩:雪崩是大量缓存集中失效,导致数据库访问激增
解决方案:1.缓存预加载 2.缓存分布式,多级缓存 3.缓存访问限流 4.数据库并发查询控制
小结
每日一小节,进步一大节。