Redis学习笔记
Redis
Redis的数据结构及其使用场景
- 字符串(String):Redis的分布式锁的实现使用的数据结构,可用于最简单的缓存,例如一个json字符串,计数器,Session共享,分布式ID
- 哈希表(Hash):可用于存储key-value对,适合用于存储对象
- 列表(List):Redis的列表根据指令的不同可当作列队或者栈来使用,可用于消息列队
- 集合(Set):和列表类似,但是不能重复,可以实现交差并集操作
- 有序集合(SortedSet):可以设置顺序
Redis是如何删除过期Key的
- 惰性删除:当读/写某个key时,判读该key是否过期,如果过期则删除
- 主动删除:由于惰性删除无法保证冷数据被及时清理,redis会定期(默认100ms)删除掉一批过期key
缓存雪崩,缓存穿透,缓存击穿
雪崩
缓存同一时间大面积失效,导致剩下的请求都落到数据库上,导致数据库短时间内承受大量请求崩掉
解决方案:
- 缓存数据的过期时间随机设置,防止同一时间大量数据过期现象发生
- 给每一个缓存数据增加相应的缓存标记,记录缓存是否失效,如果缓存标记失效则更新数据缓存。
- 缓存预热
- 互斥锁
穿透
缓存和数据库中都没有的数据,导致所有的请求都落到数据库上
解决方案:
- 接口层增加校验
- 从缓存和数据库都取不到的数据,可以将key-value写为key-null,缓存有效时间可以设置短一点,这样可以防止攻击用户反复用同一个key暴力攻击
- 采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截,避免了对底层存储系统的查询压力。
击穿
缓存击穿是缓存中没有但是数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没有数据而去数据库读取,引起数据库压力瞬间增大,
造成过大压力。和缓存雪崩不同的是,缓存击穿指的是并发查询同一条数据,缓存雪崩是不同数据都过期了。
解决方案:
- 设置热点数据永不过期
- 加互斥锁
Redis的持久化机制
RDB:Redis DataBase
(将某一时刻的内存快照,以二进制的方式写入磁盘)。
手动触发: - save指令,使Redis处于阻塞状态,直到RDB持久化完成,才会响应其他客户端发来的指令,所以在生产环境要慎用。
- bgsabe指令,fork一个子进程进行持久化,主进程旨在fork过程中有短暂的阻塞,子进程创建后,主进程就能响应客户端请求了。
自动触发;
- save m n:在m喵内,如果有n个键发生改变,则自动触发持久化,通过bgsave执行,如果设置多个,只要满足其一条件就会触发,配置文件有默认配置。
- flushall:用于清空redis的所有的数据库,flushdb清空当前redis所在数据库(默认是0号),会清空RDB文件,同时也会生出dump.rdb,内容为空。
- 主从同步:全量同步时会自动触发bgsave指令,生成rdb发送给从节点。
优点:
- 整个Redis数据库中只包含一个文件dump.rdb,方便持久化
- 容灾性号,方便备份
- 性能最大化,fork子进程来完成写操作,让主进程继续处理命令,所以是IO最大化,保证了redis的高性能
- 相对于数据集大时,比AOF的启动效率更高。
缺点:
- 数据安全性低。RDB是隔一段时间进行持久化,如果持久化之间redis发生故障,会发生数据丢失。适用于对数据要求不严格的时候。
- 游湖是通过fork子进程来协助持久化的,因此数据集较大时,可能会导致服务器停止几百毫秒甚至一秒,会占用cpu。
AOF:Append Only File
以日志的形式来记录服务器处理的每一个写,删除操作,以文本的形式记录。
Redis使用遇到的坑
本来想着把本机上运行的redis迁移到docker,打算把原有配置文件直接映射过去,一顿操作
1 | docker run --name myredis |
docker ps -a一看,容器没启动,status Exited(0)
各种百度无果,最后想起来,redis.conf里的daemonize是yes,所以容器刚启动完成就退出了。。