Redis总结
2023-09-11 08:51:23 1 举报
AI智能生成
Redis史上最全总结
作者其他创作
大纲/内容
特点
内存存储
优点:读写性能高
读写单线程
优点:天然原子性,没有并发安全问题
key-value的存储结构
key 只能是String类型
value有五大数据类型
String
对应JAVA中的String
常用命令
set key value
get key value
setnx key value
具有独占的特点(可以用于实现分布式锁)
incr key
设置一个key自增1(可以作为分布式数据id使用)
incrby key incrnum
设置一个key自增 incrnum个长度(incrnum 可正可负)
Hash
对应JAVA 中的 Map
常用命令
hset key feild value
添加一个key的 map数据 ,feild 是map的 key 值是value
hget key feild
hgetall key
获取一个key的 所有map数据
hdel key feild
删除一个key的 map数据
List
对应JAVA中的List
常用命令
lpush key val1 val2 ...
从左边依次添加键为key,值为val1 val2 的list结构数据。值可重复。列出时,先添加的元素,后列出
rpush key val1 val2 ...
从右边依次添加键为key,同上 lpush
lpop key
取出左边第一个元素,取出后元素从队列删除
rpop key
取出右边.... 同上 lpop
lrange key start end
列出键对应的元素,从start索引开始,到end索引结束。如果end为-1表示到倒数第一个结束。不删除元素
lindex key index
列出指定键为key的值中指定索引的元素。index为指定的索引号。不删除元素
Set
对应JAVA的Set
常用命令
sadd key val1 vla2
向key中添加val1 val2,...元素,多个元素不允许重复
smembers key
列出这个key的所有元素
sismember key val
判断集合中是否有这个val元素
sinter key1 key2
列出key1和key2中共同存在的元素 (交集)
sunion key1 key2
列出key1和key2中所有不重复的元素(并集)
sdiff key1 key2
列出key1中有,key2中没有的元素(差集)
ZSet
对应JAVA中的TreeSet
常用命令
zadd key score member
向key中添加一个元素,元素绑定一个score分数值。列出数据时,会根据这个绑定分数值进行排序
zrange key start end withscores
列出索引从start开始到end结束的元素,并且展示元素对应的分数值(升序)
zrevrange key start end withscores
列出索引从start开始到end结束的元素,并且展示元素对应的分数值(降序)
key通用命令(常用)
del key
keys pattern
列出匹配指定模式的键
ttl key
查看key的存活时间 -1永久存活 -2过期
expire key senconds
设置key的存活时间
type key
查看key的类型
scan 0 match user* count 2
从下标0开始查询两个,key中以user开头的value
记录大量用户的登录状态
使用位图数组来记录
命令
setbit key offset value
getbit key offset
bitcount key start end
示例
setbit loginstatus 5000000 1
设置id为5000000的用户为登录状态
getbit loginstatus 5000000
获取id为5000000的用户的登录状态
bitcount loginstatus 0 -1
统计所有登录的用户人数
原理
它是按字节来存的,一个字节是由8个bit位也就是8个0或1,这样一个字节就能存8个用户的状态了
持久化
RDB
工作机制:日志快照(拍摄照片),每一次记录都是当前这一时刻的全量数据
优缺点
优点
所占用的内存小
数据恢复快
缺点
每次记录所需要的时间长
记录间隔长(一旦数据发生丢失,丢失的数据多)
保存方式
save
这个是前台保存,相当于把这个操作加紧读写操作中
数据量非常大的情况下,容易造成redis宕机
原因:redis读写单线程
bgsave
在redis.conf中配置自动保存
AOF
工作机制:日志记录(录视频):对所有的操作都进行记录,是一种增量式的记录
优缺点
优点
每次记录所需要德时间短
记录间隔短(一旦发生数据丢失,丢失的较少)
缺点
所占用的内存较多
针对这个情况的解决方案
执行bgrewriteaof(对AOF文件进行重写)去除掉一些无关的指令
或者在redis.conf配置自动重写
指令
auto-aof-rewrite-percentage 100
重写后,AOF的扩充比例(在基数基础上,达到增长比例后触发重写)
auto-aof-rewrite-min-size 64mb
文件达到指定大小才会触发重写
数据恢复慢
方案
如果追去恢复效率,对数据安全要求不高,使用RDB
如果不追求恢复效率,对数据安全要求高,选择AOF
如果对两个都有要求,那么久混合使用
在redis 4.0中默认就是混合持久化
开启方式在redis.conf中配置aof-use-rdb-preamble yes
高可用
三高:高并发、高性能、高可用
主从架构
优点:架构简单
缺点:一旦主机宕机,则整集群不能对外提供写能力,只能提供读能力
哨兵集群
优点;可以防止主机宕机后,不能对外提供写能力
缺点:不能支持高并发的写操作;增加经济成本
cluster集群
优点:支持高并发的写操作;也有哨兵集群的优点
缺点:读写操作都在主机上;从机只负责数据备份
有16384个槽位,在插入数据时,会对key进行hash运算,在对16384取模,得到对应的槽位,然后插入到对应的主机
槽位分配,可以手动配置。不然在集群启动时,会自动分配。
一旦某个集群全部宕机了,它的槽位不会自动重新分配到其它集群上
数据同步方式
全量复制
主机将数据的rdb文件通过socket通信的方式发送到从机,从机进行同步,在这之前从机会先删除老的数据
增量复制
当从机再次连接上主机时,从机将当前的数据偏移量发送给主机,主机回去缓存中看,这个偏移量是否是在缓存中,如果在就直接把缓存中的数据发送给从机,如果不在就进行全量复制。
淘汰策略
删除策略
定时删除
redis中未使用
定期删除
当一个可以设置过期时间后,会将这key放到过期字典中。然后redis中会有一条线程,去扫描这个过期字典。抽取出W个key进行检测。如果发现这些key有超过0.25的都过期了,那么就会继续扫描再删除。
惰性删除
有一个key过期了,但是没有做定期删除和定时删除,等下次访问时删除
淘汰策略
LRU与LFU解释
举例:key1 9:30、10::00使用;key2 9:40、9:45、9:59使用
LRU(最近最少使用)
删除key2(时间局部概念)相对于key1 10点使用一次,key2的9:59 使用就是最近最少使用的
LFU(最少使用)
删除key1(全局)key1总使用2次 key2总是用3次
过期字典的淘汰策略
volatile-lru
volatile-lfu
volatile-random
随机删除一个
volatile-ttl
移除即将过期的
全局的淘汰策略
allkeys-lru
allkeys-lfu
allkeys-random
缓存问题
缓存穿透
产生原因:大量访问数据库中不存在的数据
解决方案
缓存空对象
会浪费内存,如果内存满了,就会触发淘汰策略
布隆过滤器
相当于一个位图数组,利用桶排序的思想,在Spring的所有bean都初始化完成后,把数据库总的数据查询出来,把数据库中的数据所对应的主键,当做位图数组的下标,把对应的位图数组的值从0变为1
初始的位置:在所有bean都初始化完成后进行
实现方法:监听器
Spring监听器
实现方式:实现ApplicationListener<ContextRefreshedEvent>接口,重写方法onApplicationEvent(ContextRefreshedEvent event)
SpringBoot监听器
缓存击穿
产生原因:刚好大量请求过来访问一个key,但是刚好这个key过期了,造成请求直接到达数据库上了。
解决方案:
对热点数据设置永不过期
使用分布式锁
1、使用redis的setnx来做分布式锁
不可重入
2、使用Redisson的锁
它是可重入的,内部使用的是redis的hash结构来做的
为了保证原子操作,使用lun脚本来执行的
基于服务保护做一些限流操作
缓存雪崩
产生原因:同一时间大量访问不同的key,恰好这些key又在这一时间,同时过期
解决方案
设置key的过期时间分布随机的,防止同时间过期
热点数据永不过期
基于服务保护做一些限流操作
分布式锁
Redis分布式锁
1、可以使用Redis的setnx来做(不可重入锁)
2、使用Redisson的分布式锁(可重入锁)
为了防止主从数据同步导致的加锁失败
解决方案:Redisson的 红锁(RedLock)
红锁的工作机制:加锁时,是向集群中所有的master发起加锁申请,只有超过半数认为加锁成功,最后才是加锁成功
zoopeeker分布式锁
双写一致性
产生原因:数据库中的数据反生改变时,怎样保证redis中的数据也发生改变
解决方案
如果需要保持数据的强一致性:加读写锁
如果不需要,就可以正常执行
Redis为啥快
内存存储
读写单线程,不需要CPU切换
多路复用,提高并发能力1
0 条评论
下一页