Redis
2025-01-22 17:42:06 4 举报
AI智能生成
Redis
作者其他创作
大纲/内容
Redis为什么这么快?
基于内存
底层封装优秀的数据类型
采用io多路复用
select
客户端请求一次可以监听多个套接字最多1024个,服务端准备好了,在遍历获取,底层是数组
poll
和select差不多,底层用链表,解决的连接限制
epoll
用红黑树和链表维护完成和未完成的连接,优化遍历的步骤
延申:什么是nio,bio,io多路复用
阻塞式bio:服务端只能acc一个请求,没准备好客户端等待
nio:和bio差不多只不过如果服务端没准备好,客户端会轮询请求
常用的数据类型和实现
string
问题:传统字符串在传输的时候会有一个字符串截取的问题,还有一个查询复杂度on的问题
sds实现
区别是否小于44字节,是否和redisobject一起分配空间?
embstr
row
如何实现的
hdr结构体
维护一个申请的字节数和使用的字节数
扩容策略
大于1mb就翻倍,小于1mb就加一
int
hash
hashtable
一个表用于存数据
一个表用于rehash
渐进式rehash
本来可能是上面的数据直接搬到下面的数组,渐进式是操作字典的时候同时访问新旧数组,做迁移
当扩容因子大了或者需要扩容时,进行渐进式rehash
ziplist
理解为小的数组,各个元素紧挨着,但是会有一个连锁更新的问题,类似于蝴蝶效应
zset
跳表
在链表基础上创建多级索引,查找的时候根据多级索引一层一层往下找,像跳着找,就叫跳表
新增的时候如何确定层高?
随机层数算法,0.5概率在1级节点,0.25概率在2级节点
ziplist
list
双向链表
ziplist
set
intset
hashtable
持久化机制
aof追加文件
将一个每一次的写操作记录在一个文件中啊,恢复的时候进行重放
备份方式
配置appendonly yes开启
执行一条写命令同步到缓冲区,在根据对应策略做同步
aof文件大,频率高,数据不易丢失,安全性aof更优,频繁备份恢复rdb更优
rdb快照备份
时间间隔内生成数据集的快照是保存到磁盘上,容易备份
备份方式
手动
save
阻塞所有请求少用
bgsave
后台异步快照备份
被动
到conf里面配置900 1,900秒一次更改就备份
Redis用来干嘛
string
用来保存热点数据,配合过期时间做分布式锁,或者保存session等
hash
适合用来保存对象数据,省区string 的 序列化消耗
list
消息队列
set
zset
排行榜
位图
子主题
Redis优点
高性能,毫秒级的操作,封装了各种数据类型,支持分布式,持久化机制等
redis是单线程的嘛?
核心操作是单线程的
比如网络io的键值对读写,减少线程间的切换
持久化
fork一个子线程去处理,不会阻塞主线程
内存淘汰策略
总的分在所有键中和在设置过期时间中
lru
最近最少使用
lfu
最不经常使用
ramdom
随机删
ttl
回收生存时间最短的键
不删除(默认)
no-eviction,会报错OOM
键淘汰策略
主动删除
定时(对键本身而言)
定时器到期时执行函数,将键给删除
缺点:消耗cpu资源,尤其大量key过期
定期(对redis而言)
随机抽取一定数量的键,检查是否过期默认每100ms执行一次
缺点:难平衡频率,设置长了容易浪费内存
被动删除(惰性删除)
只有键访问到了才去删除键
通常采取主动加惰性删除的策略
缓存三兄弟
缓存击穿
大量热点key失效导致大量请求直接打到数据库,被高并发冲垮
方法
用一个互斥锁去保证每次只有一个请求打到数据库
或者提前预热热点数据,设置一个长key
缓存穿透
查询数据库不存在的数据,直接就给穿透了
方法
数据库访问不到就加有过期时间的空值
或者采用布隆过滤器
可以快速判断数据是否不存在,查询布隆过滤器说数据存在,并不一定证明数据库中存在这个数据,但是查询到数据不存在,数据库中一定就不存在这个数据。
缓存雪崩
大量key失效导致,导致大量请求打到数据库上
可以采取不过期或者过期时间随机
集群
主从
主从就是主服务器读写更新给从服务器使之可读
过程
主服务器先通过rdb全量同步,之后维护一个长连接,期间如果断开了,有一个buffer和offset来维护一个增量的同步
哨兵
主要关注高可用,就是主从的升级,监控主从结构,和实现故障转移机制,如果主服务器故障了,能够选举从服务器节点,并通知客户端切换
集群
关注水平扩展和数据分片
16384个哈希槽,key通过CRC16校验放到对应的槽,在增删节点改动槽即可
分布式锁
核心问题:判断库存和删除库存不是原子性的
方案:单机下理论上加锁就行,但是在微服务环境下要加一个全局的jvm锁
简单实现
一开始是setnxex,业务设置过期时间,可能死锁
可能还有锁误删的问题,所以设置uuid作为key,引入lua脚本
方法:用redission实现一个分布式锁
底层实现:一段lua脚本封装了线程id和uuid拼接,作为hash的key,val是可重入次数,hash的过期时间是30s但是有看门狗机制会自动续期每隔十秒
0 条评论
下一页