什么是Redis:
Redis,即远程字典服务,是一个开源的,使用C语言编写,支持网络调用,基于内存的可持久化的Key、Value数据库。提供多种语言的API。
为什么要使用Redis?
①内存数据库,读写数据很快
②工作线程是单线程,串行化执行,原子操作,IO线程为多线程操作,避免上下文切换
③IO模型(epoll),天生支撑高并发
④KV模型,V具有类型结构
⑤具有本地方法,计算向数据移动。比如:取交集、取并集
⑥二进制安全,Value最大512M
Redis是单线程的还是多线程的?
6.0之前:工作线程和IO线程使用同一线程,均为单线程
6.0之后:IO线程是多线程,工作线程仍为单线程
Redis持久化的两种方式
***RDB:***存储数据结果,关注点在数据。在指定时间间隔内将内存中的数据集中写入到磁盘中,也就是快照,数据恢复是将快照直接读到内存中。
Redis会单独创建一个子进程来进行持久化,会先将数据写入到一个临时文件中,等你的持久化结束后,再用本次得到临时文件替换上次持久化后的文件。fork函数的作用是复制一个与当前进程一样的进程,但是我们要清楚的是子进程只会读取共享内存中的数据,它并不会执行任何写操作,当子进程在进行持久化的过程中,如果有写入操作的时候,主进程会将更改数据的之前进行copy一份更改数据的数据页出来,并将主进程中k这个指针指向新拷贝出来的数据页地址上,但是在这个过程中,子进程读取的还是之前未修改的数据,此后新进程的所有数值和原来的进程一致,但是一个新进程,并且作为原进程的子进程。
>
优点: 1.恢复数据比较快
2.备份的文件就是原始内存数据的大小,不会额外增加数据占用
缺点: 1.快照时间有间隔,不能实时备份,丢失的数据可能比较多
2.开启子进程备份数据,在数据集比较庞大时,fork()可能会非常耗时,造成服务器在一定时间内停止处理客户端。
***AOF:***将客户端的每个写操作命令以日志的形式记录下来,追加到appendonly.aof的文件末尾,在redis服务器重启的时候,会加载aof文件中的所有命令,来达到数据恢复的目的。
当有写命令请求时,会追加到AOF缓存区内,AOF缓存区根据AOF持久化策略将操作同步到磁盘的AOF缓存区中,当AOF文件大小超过重写策略或者手动重写策略时,会对AOF文件进行重写来压缩AOF文件容量。redis服务重启时,会重新加载AOF文件中的写操作来进行数据恢复。
(值得注意的是,尽管重写后的AOF文件与原有的AOF文件在逻辑上保存的数据信息是一致的,但是AOF重写通过合并冗余命令、优化命令序列、移除无效命令和合并批量操作等方式,实现了对AOF文件容量的有效压缩,同时保证了数据的一致性和完整性)
优点:数据安全性高,不易丢失数据,而且AOF有序的保存了所有写操作,可读性很强
缺点:AOF方式生成文件体积变大,数据恢复速度比较慢
Resdi中的Lua脚本语言
EVAL,是Redis2.6.0版本后内置Lua解释器,可使用EVAL命令对Lua脚本进行求值
保证多个命令的原子性:当某个脚本正在运行的时候,不会有其它脚本或Redis命令被执行。脚本的效果要么是不可见的,要么是已完成的。
实战:Lua脚本操作Redis:一次扣减一个商品的库存
Redis缓存的穿透、击穿与雪崩
①缓存穿透:是指查询一个不存在的数据,导致请求直接绕过缓存层,打到数据库,而数据库层也没有该数据,从而无法将结果缓存起来,导致每次请求都要查询数据库,给数据库带来巨大的压力。
例:比如你有一个商品系统,我们商品的ID都是正整数。如果有外来攻击者发送大量商品ID为负数的请求,这些请求在缓存数据库中都不存在,你想想是不是会让数据库压力骤增。
解决方案:
1. 对于查询结果为空的数据,也将其缓存起来,但需要设置一个较短的过期时间 ,因为空值缓存的数据本身没有实际价值,它仅仅是一个标记,表示某个查询结果不存在,而且我们的内存中的缓存资源是有限的,将过期时间设置短是为了确保缓存空间能够有效被利用,避免被无用的空值缓存长期占用。还有一个原因是避免数据污染,如果空值缓存的过期时间很长,那么在这个期间,有相应的数据被添加到数据库,但是缓存仍然存放着空值,那么这些新的数据也无法被访问,便有了数据污染。
2.接口校验:也就是设置黑名单。在API层面增加校验功能,对于非法的请求直接拒绝,不进入后续处理流程。
3.布隆过滤器:在查询缓存之前,先通过布隆过滤器判断该数据是否存在,若不存在则直接返回,不查询数据库。
②缓存击穿:是指在缓存中的某个热点key突然过期,此时有大量并发请求进来访问这个key,导致所有请求都打到你的数据库中,给数据库带来巨大的压力。
例:在电商系统中,某个热门商品的缓存信息突然过期,但是呢,这个商品正处于商品促销高峰期,大量的用户同时访问这个商品的详情页,这时导致所有请求都直接查询数据库。
解决方案:
1.热点数据预加载:在热点数据即将过期的时候,通过定时任务或监控段将数据提前加载到缓存中。
2.对于热点数据,设置永不过期,但需要注意的是这种方式可能会浪费缓存空间。
3.使用互斥锁:在访问热点的时候,通过互斥锁控制并发访问,确保只有一个请求能够查询数据库并更新缓存。
③缓存雪崩:是指缓存中的大量key在同一时间过期,导致这些key的访问请求全部打到数据库,给数据库带来了巨大的压力,甚至可能会导致数据库崩溃。
例:在电商系统中,为了减轻缓存的存储压力,可能会将大量商品的缓存设置相同的过期时间。当这些商品的缓存同时过期时,如果有大量的用户同时访问这些商品,那么所有的请求都会直接查询数据库。
解决方案:
1.设置错峰:即在设计缓存的过期时间时,加上一个随机值,是的缓存的过期时间分散开来,避免大量key同时失效。
2.使用多级缓存:构建多级缓存架构,比如Nginx缓存+Redis缓存+其他缓存,分散缓存压力。
3.设置缓存标记:记录缓存数据是否过期,如果过期则触发后台线程去实时更新实际的key
4.提前预热缓存:在系统低峰期,提前将即将访问的数据加载到缓存里,以应对即将到来的高并发访问。
Redis的过期删除策略
①惰性删除
放任键过期不管,但是每次从键空间中获取键的时候,都检查取得的键是否过期,如过期则删除,如未过期,则返回改键。
②定期删除
每个一段时间程序就会对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键以及要检查多少个数据库,由算法决定。
Redis的内存删除策略
由于过期删除策略不一定能完全删除过期的键,而Redis的内存上升到一定的大小,就会触发内存淘汰策略。
Redis提供8种数据淘汰策略:
LRU:Least recently used 最近最少使用
LFU:Least-frequently used 一直最少使用
淘汰策略名称 | 策略含义 | 解释 | |
---|---|---|---|
默认策略 | noevication | 不淘汰数据,写不进去返回错误 | 不删除任意数据,这时如果内存不足时会直接返回错误 |
只针对过期的keys | volatile-lru | 根据LRU算法,挑选数据淘汰 | 从设置过期时间的数据集中,选择最近这段时间内使用次数最少的数据项释放 |
volatile-lfu | 根据LFU算法挑选淘汰数据 | 淘汰设置了过期时间的key中使用次数最少的数据 | |
volatile-random | 随机挑选数据淘汰(4.0版本以上) | 淘汰设置了过期时间的数据集中,进行淘汰 | |
volatile-ttl | 挑选越早过期的数据进行删除 | 从设置了过期的数据集中,释放马上过期的数据 | |
所有keys | allkey-lru | 根据LRU算法进行删除 | 在所有的数据中,选择最近使用的次数最少的数据释放 |
allkey-lfu | 根据LFU算法挑选数据淘汰(4.0版本以上) | 在所有的数据中选择使用次数最少的数据项释放 | |
allkey-random | 随机挑选数据释放 | 随机选择一个数据释放 |
Redis主从同步机制
从服务器向主服务器发送同步命令Sync
主服务器接收到同步命令以后,会执行bgsave命令,后台生成一个rdb文件,并使用一个缓存区,记录从现在开始执行的所有写的命令。
当主服务器执行完bgsave命令后,会把rdb文件发送给从服务器。
从服务器接收到整个rdb文件以后,将它加载到内存中,之后主服务器把缓冲区的命令同步,从服务器就会执行这些命令(为了保证两边一致)
以上处理完之后,主服务器每执行一个写命令,都会将写命令发送给从服务器。
如何保证Redis和Mysql数据库数据一致性
缓存更新策略:
1.先删缓存再更新数据库
2.先更新数据再删缓存
3.普通双删
4.延迟双删
通常使用延迟双删来保证缓存与数据库的一致性。
延迟双删:先删缓存,再更新数据库,然后等待3-5s再删除缓存。
Redis的集群方式有哪些
①主从复制模式:在此模式下,有个主节点负责处理写入请求,而从节点则复制主节点的数据并提供读取服务。
优点:实现简单,能实现数据冗余,通过读写分离提高系统性能。
缺点:需要手动进行故障转移,无法自动处理主节点故障;不支持自动的数据分区,难以做到水平扩展。
②哨兵模式:Sentinel是Redis提供的一个高可用性解决方案,它能监控主从节点的状态, 并在主节点出现故障的时候自动完成故障转移。
优点:解决了主从模式下手动故障转移的问题,提供了自动化监控和故障恢复机制
缺点:虽然比主从模式增加了自动化,但仍然不支持自动化的数据分区,且随着节点数量增加,管理和配置的复杂性也会增大。
③Redis Cluster模式:Redis Cluster是官方正式支持的分布式解决方案,它采用数据分片技术,将数据分散在多个节点上。
优点:真正实现了分布式存储,每个节点都可以处理读写请求,具备良好的水平扩展能力;内置了数据自动分割,故障检测与转移功能。
量增加,管理和配置的复杂性也会增大。`**
③Redis Cluster模式:Redis Cluster是官方正式支持的分布式解决方案,它采用数据分片技术,将数据分散在多个节点上。
优点:真正实现了分布式存储,每个节点都可以处理读写请求,具备良好的水平扩展能力;内置了数据自动分割,故障检测与转移功能。
缺点:相比其他模式更复杂,需要更多的网络资源和配置管理;客户端需要支持集群特性,Slot的数据操作可涉及多个节点,有一定复杂度。