- Redis是什么? key/value数据库
- Redis版本如何进行查看?redis-server-v,redis-cli-v
- Redis默认有多少个数据库?16个数据库
- Redis的核心配置文件是哪个?redis.conf
- Redis常用的配置参数有哪些?
- Redis支持的数据类型有哪些?String,Hash,List,Set,Stream
- Redis支持的字符串操作有哪些?自加:incr自减:decr加: incrby减: decrby ,append,strlen,mset/mget
- Redis中的key的有效时间如何设置 ?expire,pexpire,
- Redis支持的hash操作有哪些?hset/hget,hincrby,hmset/hmget,hexists,hdel,hlen,hkeys/hvals
- Redis持久化数据的方式有哪些?AOF和RDB
- Redis是如何解决哈希冲突的?同一个哈希桶中的多个元素用同一个链表来保存
- Redis中的refresh操作用于解决什么问题?哈希桶中的链表长度越大性能越低
- Redis中的单线程模型如何理解?Redis网络IO和键值对读写都由一个线程完成
Redis持久化的意义?
redis持久化的意义,在于故障修复,数据恢复,可归类到高可用。如果redis重启了,没有持久化的话,redis就会丢失所有的数据,如果通过持久化将数据完成一份备份在磁盘,然后定期比如说同步和备份到一些云存储服务上去,那么就可以保证数据不会丢失全部,还可以恢复一部分数据回来。
如何理解Redis中的RDB方式的持久化?
RDB:Redis DataBase将某一个时刻的内存快照,以二进制的方式写入磁盘。
手动触发:
- save命令:使Redis主线程阻塞,直到RDB持久化完成,才会响应其他客户端发来的命令,所以生产环境一定要慎用。
- bgsave命令:主进程fork出一个子进程进行持久化操作,可以共享主进程的内存数据,并不影响主进程,只有在fork过程中有短暂的阻塞,子进程创建之后,主进程就可以响应客户端请求了,执行完成后,通知主进程,子进程关闭。
自动触发:
- save m n:在m秒内,如果有n个键发生改变,自动触发持久化,通过bgsave执行,如果设置了多个,只要满足其一就会触发;配置文件有默认配置(可以注释掉)
- flushall:用于清空所有的Redis数据库;flushdb清空当前redis所在库数据(默认是0号数据库),会清空RDB文件,会生成dump.rdb,内容为空
- 主从同步:全量同步时会自动触发bgsave命令,生成rdb发送给从节点
优点:
- 整个Redis数据库只包含一个文件dump.rdb,方便持久化。
- 容灾性好,方便备份。直接基于RDB数据文件来重启和恢复redis进程,更加快速
- RDB对redis对外提供的读写服务,影响非常小,可以让redis保持高性能,因为redis主进程只需要fork一个子进程,让子进程执行磁盘IO操作来进行RDB持久化即可。
缺点
- 数据安全性低。RDB是间隔一定时间进行持久化,如果持久化之间redis发生故障,会发生数据丢失。
- 由于RDB是通过fork子进程来协助完成数据持久化工作的,如果数据文件特别大,可能导致整个服务停止服务数毫秒,甚至数秒。
如何理解Redis中的AOF“写后”日志?
AOF:Append Only File 。Redis先执行命令,把数据写入内存,然后才记录日志。记录服务器所处理的每一个写,删除操作,查询不会记录。以文本的方式记录保存。
- 所有的写命令会追加到AOF缓冲中,AOF缓冲区根据对应的策略向硬盘进行同步操作
- 随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩目的
- 当Redis重启时,可以加载AOF文件进行数据恢复。
Redis中AOF方式的写后日志有什么策略?
- Everysec每秒同步,异步完成,性能中,宕机时可能丢失一秒数据
- Always:同步写,可靠性高,数据基本不会丢,但每个写命令都要落盘,性能差
- No 不同步,操作系统控制,性能好,可能丢失数据多。
优点:
- 数据安全
- 通过append-only模式写入,没有任何磁盘寻址的开销,性能高,文件不容易破损
- rewrite模式,定期重写,压缩AOF文件。
- 可以做灾难性的误删除的紧急恢复。
缺点:
- AOF日志文件比RDB数据快照文件大很多,恢复速度慢
- 数据集大的时候,比RDB启动效率低
- 运行效率没有RDB高
Redis中的持久化机制应该如何选择?
- 数据不能丢失时,内存快照和AOF混合使用是一个很好的选择
- 如果允许分钟级别的数据丢失,可只使用RDB
- 如果只用AOF,优先使用 每秒同步 的配置选项,在可靠性和性能之间选取了一个平衡。
Redis在单线程模式下为什么还那么快?
- 纯内存操作
- 单线程避免了多线程的频繁上下文切换问题
- 核心是基于非阻塞的IO多路复用机制
Redis的过期键的删除策略
- 定时过期 设置时间,时间到过期
- 惰性过期 只有访问key的时候,才进行判断是否过期,过期才删除。浪费内存,却最大化节省cpu资源
- 定期过期 每隔一定的时间,会扫描一定数量的数据库的一定数量的key,控制扫描时间和扫描间隔,折中方案,使得cpu和内存资源达到最优的平衡效果。
为什么使用缓存?
- 高性能
- 高可用
Redis主从复制的核心原理
通过执行slaveof命令或设置slaveif选项,让一个服务器去复制另一个服务器的数据。主数据库可以进行读写操作,当写操作导致数据变化时会自动同步给从数据库。而从数据库一般是只读,并接受主数据库同步过来的数据。一个主数据库可以拥有多个从数据库,一个从数据库只能拥有一个主数据库。
全量复制:
- 主节点通过bgsave命令fork子进程进行RDB持久化,
- 主节点通过网络将RDB文件发送给从节点,对主从点的宽带都会带来很大的消耗
- 从节点清空老数据,载入新的RDB文件的过程是阻塞的,无法响应客户端的命令;如果从节点执行bgrewriteAOF,也带来额外的消耗
部分复制
- 复制偏移量:执行复制的双方,主从节点,分别会维护一个复制偏移量offset
- 复制积压缓冲区 FIFO队列
- 服务器运行ID(runid):每个redis节点,都有其运行ID,运行ID由节点在启动时自动生产,主节点会将自己的运行ID发送给从节点,从节点进行保存。从节点Redis进行从连的时候,根据运行ID来判断同步的速度。
如何避免缓存穿透、缓存击穿、缓存雪崩?
缓存雪崩是指缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。
原因:
- 应用初启动,缓存中没有数据,所有的请求都打到数据库上
- 缓存中key同一时间设置到期
- Redis挂了
- key过期时间设置随机,防止同一时间大量数据过期现象发生;
- 给每一个缓存数据增加相应的缓存标记;
- 缓存预热,首先不对外提供服务;
- 互斥锁,只让一个请求进入DB
缓存穿透是指缓存和数据库都没有的数据,导致所有的请求都落到DB上,造成数据库短时间内承受大量请求而崩掉。
- 接口层增加校验,比如id<=0拦截;
- 在对应key-value,写成key-null,防止用户用同一个id暴力攻击
- 布隆过滤器存放所有已经存在的key,key经过hash算法算出来 ,存在,再去查数据库。
缓存击穿是指缓存中没有,但是数据库中有的数据(一般是缓存时间到期),并发用户过多,数据库压力大。和缓存雪崩的不同的是,缓存击穿指并发查同一条数据。
- 设置热点数据永远不过期。
- 加互斥锁,只让一个请求进入DB
简述redis数据结构
String:字符串
List:列表
Hash:哈希表
Set:无序集合
Sorted Set:有序集合
bitmap:布隆过滤器
GeoHash :坐标(经纬度)底层基于Sorted Set
HyperLogLog 统计不重复数据,用于大数据基数统计
Streams:内存版kafaka 消息的订阅发布
如何保证Redis与数据库的数据一致?
当我们进行数据修改时,如果先删缓存,再写数据库,高并发场景下,这时候还没有来得及写数据库,会先读取缓存,发现为空,去读数据库数据(旧值,脏数据),读到的结果写入缓存,这是第一个线程已经把新值写到缓存了,这样缓存中的值就会被覆盖变成脏数据!!!
延时双删,先删除缓存,写数据库,休眠一小会,再次删除缓存
问题:如果数据操作比较频繁,同样会脏数据