一、redis常见问题
1.缓存穿透: 数据库没有值,缓存也就不会存在。解决:通过设置-1代替或者布隆过滤器
2.缓存击穿: 在缓存失效的瞬间大量请求,造成DB的压力瞬间增大。解决:使用分布式锁
3.缓存雪崩: 大量缓存设置了相同的失效时间,同一时间失效,造成服务瞬间性能急剧下降。解决:基本时间添加随机时间
4.缓存并发: 如果网站并发访问高,一个缓存如果失效,可能出现多个进程同时查询DB,同时设置缓存的情况,如果并发确实很大,这也可能造成DB压力过大,还有缓存频繁更新的问题。解决:对缓存查询加锁,如果KEY不存在,就加锁,然后查DB入缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入DB查询
5.缓存预热: 目的就是在系统上线前,将数据加载到缓存中。
二、redis原理
三、redis常用基本使用
四、redis高级使用
1.、集群模式
1.1、主从同步
原理:从数据库连接主数据库,然送SYNC命令,然后主服务器开始执行BGSAVE命令生成RDB快照文件发送给从数据库(此时主数据库使用缓冲区记录执行的所有写命令),从数据库收到快照以后废弃所有的旧数据,载入收到的快照数据,然后主数据库发送缓存中的数据给从数据库。
优点:实现读写分离、分载主数据库的读压力,从服务器同样可以接收其他的从数据库,分担主的同步压力。
缺点:不具备容错与恢复能力,不支持在线扩容
1.2、哨兵模式
原理:每个哨兵进程以每秒钟一次的频率向整个集群中的master主服务器、slave从服务器以及其他哨兵进程发送一个ping命令,如果实列距离最后一次有效回复ping命令的时间超过down-after-milliseconds选项所指定的值则这个实例会被哨兵进程标记为主管下线,如果一个master主服务器被标记为主观下线则正在监视这个master主服务器的所有哨兵进程,其他的哨兵每秒一次的频率确认master主服务器是不是的确进入主观下线状态,当数量大于配置文件指定的值确认master为主观下线状态,则master主服务器会被标记为客观下线,如果没有则删除主观下线状态。
优点:实现读写分离、分载主数据库的读压力,从服务器同样可以接收其他的从数据库,分担主的同步压力,主从可以自动切换系统更健壮、可用性更高
缺点:redis难在线扩容,在集群容量到达上线扩容会变得复杂
1.3、Cluster分布式模式
原理:在 Redis 的每一个节点上,都有这么两个东西,一个是插槽(slot),它的的取值范围是:0-16383。还有一个就是cluster,可以理解为是一个集群管理的插件。当我们的存取的 Key到达的时候,Redis 会根据 crc16的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作
优点:可动态扩展、无压力
2、淘汰策略与过期策略
2.1、过期策略
2.1.1、定期删除:redis默认每个100ms随机抽取进行检查,是否有过期的key,有过期key则删除,因此,如果只采用定期删除策略,会导致很多key到时间没有删除。
2.1.2、惰性删除:获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除。
2.2、淘汰策略
2.2.1、什么时候触发淘汰机制
通过maxmemory 配置项来设置允许用户使用的最大内存大小,当内存数据集大小达到一定的大小时,就会根据maxmemory-policy noeviction配置项配置的策略来进行数据淘汰。
2.2.2、淘汰机制有哪些
2.2.2.1、olatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
2.2.2.1、allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
2.2.2.1、volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
2.2.2.1、volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
2.2.2.1、allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
2.2.2.1、no-enviction:禁止驱逐数据,永远不过期,仅对写操作返回一个错误,默认为该项
3、持久化策略
3.1、AOF
原理:开启后,redis每执行一条修改数据的命令,都会把这个命令添加到AOF文件中
优点:实时持久化
缺点:AOF文件体积越来越大,需要定期执行重写操作来减低文件体积,加载慢
3.2、RDB
原理:通过bgsave命令出发,然后父进程执行fork操作创建子进程,子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原文件进行原子替换
优点:是一个紧凑压缩的二进制文件,Redis加载RBD恢复数据远远快于AOF的方式
缺点:由于每次生成RBD开销比较大,非实时持久化
五、redis使用场景
5.1、为什么使用redis
单线程、内存、非阻塞I/O多路复用
5.2、redis数据结构使用场景
5.2.1、string
数据结构:
使用场景:最常规的set/get操作,value可以是string也可以是数字。一般做一些复杂的计数功能的缓存。
5.2.2、hash
数据结构:
使用场景:这里value存放的是结构化的对象,比较方便的就是操作其中的某个字段。一般做在线用户
5.2.3、list
数据结构:
使用场景:使用List的数据结构,可以做简单的消息队列的功能。另外还有一个就是,可以利用lrange命令,做基于redis的分页功能,性能极佳,用户体验好。本人还用一个场景,很合适—取行情信息。就也是个生产者和消费者的场景。LIST可以很好的完成排队,先进先出的原则
5.2.4、set
数据结构:
使用场景:因为set堆放的是一堆不重复值的集合。所以可以做全局去重的功能。为什么不用JVM自带的Set进行去重?因为我们的系统一般都是集群部署,使用JVM自带的Set,比较麻烦,难道为了一个做一个全局去重,再起一个公共服务,太麻烦了。另外,就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能
5.2.5、sorted set
数据结构:
使用场景:多了一个权重参数score,集合中的元素能够按score进行排列。可以做排行榜应用,取TOP N操作