Redis是一款开源的基于内存存储的Key-Value模型的No-SQL类型数据库
数据类型:key-String、key-List、key-Set、SortSet、key-Hash、Geo、Bit、Hyper
常用的客户端:1.Jedis 2.Redisson 3.SpringData Redis
Redis底层数据结构:
String类型:SDS(动态字符串,空间预分配、惰性空间释放)
组成:free区域-剩余空间,len区域-长度,buf存放字符数组
ziplist(压缩列表,连锁更新),底层存储键值对的核心技术,节约内存,连续的区域,避免内存碎片
Hash(拉链法),扩容和收缩
Skiplist(跳表),双链式,header:头,tail尾,level层数,length长度,实现快速访问-SortSet
RESP协议:Redis序列化协议,自定义客户端需要使用
现象
击穿:
高并发下,同时访问某个key,可是Key失效了,导致大量的请求落到了数据库上,导致数据库崩溃。
高并发,单Key,失效
解决:1.热点key设置永久有效 2.互斥锁MutexKey 3.同步+双锁检查
穿透:
高并发下,大量访问不存在的Key,导致请求落到了数据库上,从而数据库宕机
解决:1.布隆过滤器(Redisson-封装或者谷歌Gauva(布隆过滤器))Bitmap类型,容错率-哈希函数-误判率
雪崩:
高并发下,大量访问很多key,可是,这些key都失效了,导致请求落到了数据库上
解决:1.设置不同的有效期(有效期+随机时间)2.多重缓存机制 3.锁
倾斜:
集群下,高并发,大量请求某个key,结果都被分配到了固定某台的服务器上,导致这台服务器压力过大
解决:1.采用去中心化
2.从设计的角度去尽可能排除(避免大集合、不适应影响性能的命令:keys、monitor、功能单一,拆解大key)
Redis过期策略
key的生存时间到了,Redis会立即删除吗?不会立即删除。 过期策略:
●定时删除:在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除
●定期删除:Redis每隔一段时间就去会去查看Redis设置了过期时间的key,会再100ms的间隔中默认查看3个key。
●惰性删除:
key过期的时候不删除,每次通过key获取值的时候去检查是否过期,若过期,则删除,返回null(用的时候再检查删除)
当去查询一个已经过了生存时间的key时,Redis会先查看当前key的生存时间是否已经到了,是则直接删除当前key,并且给用户返回一个空值。
Redis采用的过期策略:惰性删除+定期删除
惰性删除流程:在进行get或setnx等操作时,先检查key是否过期,若过期,删除key,然后执行相应操作;若没过期,直接执行相应操作
定期删除流程:遍历每个数据库,检查当前库中的指定个数个key(默认是每个库检查20个key,注意相当于该循环执行20次,循环体时下边的描述)
如果当前库中没有一个key设置了过期时间,直接执行下一个库的遍历。
随机获取一个设置了过期时间的key,检查该key是否过期,如果过期,删除key。
判断定期删除操作是否已经达到指定时长,若已经达到,直接退出定期删除。
Redis的淘汰机制
在Redis内存已经满的时候,添加了一个新的数据,执行淘汰机制。
volatile-lru:在内存不足时,Redis会在设置过了生存时间的key中干掉一个最近最少使用的key。
allkeys-lru:在内存不足时,Redis会在全部的key中干掉一个最近最少使用的key。
volatile-lfu:在内存不足时,Redis会在设置过了生存时间的key中干掉一个最近最少频次使用的key。
allkeys-lfu:在内存不足时,Redis会在全部的key中干掉一个最近最少频次使用的key。
volatile-random:在内存不足时,Redis会在设置过了生存时间的key中随机干掉一个。
allkeys-random:在内存不足时,Redis会在全部的key中随机干掉一个。
volatile-ttl:在内存不足时,Redis会在设置过了生存时间的key中干掉一个剩余生存时间最少的key。
noeviction:(默认)在内存不足时,直接报错。
指定淘汰机制的方式:maxmemory-policy 具体策略,设置Redis的最大内存:maxmemory 字节大小
Redis持久化
Redis提供2种方式实现持久化:1.RDB 2.AOF
RDB
RDB是Redis默认的持久化机制
RDB持久化文件,速度比较快,而且存储的是一个二进制的文件,传输起来很方便。
RDB持久化的时机:
save 900 1:在900秒内,有1个key改变了,就执行RDB持久化。
save 300 10:在300秒内,有10个key改变了,就执行RDB持久化。
save 60 10000:在60秒内,有10000个key改变了,就执行RDB持久化。
RDB无法保证数据的绝对安全。
RDB存储的是数据,时间间隔无法实时持久化
AOF
AOF持久化机制默认是关闭的,Redis官方推荐同时开启RDB和AOF持久化,更安全,避免数据丢失。
AOF持久化的速度,相对RDB较慢的,存储的是一个文本文件,到了后期文件会比较大,传输困难。
AOF持久化时机:
appendfsync always:每执行一个写操作,立即持久化到AOF文件中,性能比较低。
appendfsync everysec:每秒执行一次持久化。
appendfsync no:会根据你的操作系统不同,环境的不同,在一定时间内执行一次持久化。
AOF相对RDB更安全,推荐同时开启AOF和RDB。
AOF存储的是命令(更改数据的命令),可以实时持久化
同时开启RDB和AOF的注意事项:
1.如果同时开启了AOF和RDB持久化,那么在Redis宕机重启之后,需要加载一个持久化文件,优先选择AOF文件。
2.如果先开启了RDB,再次开启AOF,如果RDB执行了持久化,那么RDB文件中的内容会被AOF覆盖掉。
Redis事务
Redis的事务:一次性、顺序性、排他性的执行一个队列中的一系列命令。
Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
集群策略(可以抗更高的并发量,高可用,避免单机故障)
1.Redis主从复制
实现:多台服务器,一主多从
主机负责读写,从机负责读--->读写性能增加,从机和主机保持一致
优点:防止数据的丢失,主机挂了,从机可以立即配置为主机,一定程度上可以解决单点故障。
缺点:1.主机挂了,从机不能自动上位,需要手动配置。
2.主机内存有限
无法解决存储上限的问题
Redis主从同步策略:主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。
2.哨兵机制
主机和从机每一个机器都有一个哨兵,哨兵之间会有相应的联系,如果说master (主机)挂掉了,哨兵会自动选举slave来作为主机,保证服务的高可靠。
保证主库存活,监控主库的状态 无法解决存储上限的问题
缺点:主机决定了当前集群的内存容量,决定整个集群的容量
3.Redis-Cluster 多主多从,去中心化
去中心化模式中一般有三主三从,因为有多个主机,每个主节点只负责读写一部分数据。
去中心化模式中一共有16384个位置 ,多台主机平均分配。
优点:
1.有主从,可以自动切换,保证数据不丢失,服务不停止
2.大大提高了读写性能,集群的内存也成倍增加,完善了哨兵模式下的缺点。
3.提供数据槽,用来存储数据,方便数据的迁移。如果数据迁移,是整个数据操一块迁移。
a.哈希卡槽slot,分片策略(crc16和crc16(key)%16384计算存储的卡槽)
b.请求随机分配到主节点,错误转向
基于Redis实现分布式锁:Redisson(RLock)红锁
结合项目,谈项目中的使用
你们项目中使用多少台机器?