Redis
一:数据结构
1:(基础)5种基础数据结构:String、Hash、List、Set、Zset
2:(进阶)其他数据结构HyperLogLog、Geo、Pub/Sub
二:分布式锁
1:先拿setnx来抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放,避免死锁。
2:如果在setnx之后执行expire之前意外崩溃了或者重启维护,可以用setex。
三:keys命令
1:redis(4.0之前的是单线程)我们用的是(3.5的),所以keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。
2:scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是这样的话整体花费的时间会比keys指令长。(注:单线程不代表效率低,Nginx也是单线程程序,效率并不低)
3:smembers命令可以返回集合键当前包含的所有元素。
四:异步队列
1:list结构作为队列,rpush生产消息,lpop消费消息,当lpop没有消息的时候,可以适当的sleep一会再重试,还有一个指令叫blpop,在没有消息的时候,可以阻塞到有消息到来。
2:pub/sub订阅者模式,可以实现1:N的消息队列,实现生产一次,消费多次。(使用场景30个人关注了主播,主播发表一条动态,那么30个人都会收到通知)
3:pub/sub订阅者模式,消费者不在线的情况下,生产的消息会丢失,可以使用专业的消息队列如: RocketMQ。
五:持久化
1:Redis提供了不同级别的持久化方式。
2:RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储,实际操作就是fork一个子进程,先将数据写入临时文件,写入成功后,再替换之前的临时文件,用二进制压缩存储。
2.1:RDB的优点:
2.1.1:非常适用于灾难恢复(可以根据需求恢复到不同版本的数据)。
2.1.2:RDB在保存RDB文件的时候,父进程唯一需要做的就是fork出一个子进程,接下来的工作由子进程来做,所以RDB持久化方式可以最大化redis的性能。
2.2:RDB的缺点
2.2.1:如果redis意外停止工作(断电)的情况下,RDB就不太合适,虽然可以配置不同的save时间点,假如设置是五分钟做一次完整的保存,那么redis宕机的话,会损失几分钟数据。
2.2.2:RDB需要经常fork子进程来保存数据到硬盘上,如果数据量较大会比较耗时,虽然AOF也需要fork,但可以调节重写日志文件的频率。
3:AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,以文本的方式记录,可以打开文件看到详细的操作记录。
3.1:AOF的优点
3.1.1:使用AOF会让你的redis更加耐久,可以使用不同的fsync(同步内存中所有已修改的文件数据到储存设备)策略,默认使用每秒fsync策略,一旦出现故障,最多丢失一秒的数据
3.1.2:AOF文件是一个只进行追加的日志文件,所以不需要写入索引,即使某些原因(例如,磁盘满,宕机等),未执行的命令,可以使用工具修复redis-check..什么的工具修复,有需要可以自己查。
3.1.3:如果AOF文件过大的话,redis会在后台对AOF自动进行重写,即使重写过程中发生宕机,现有文件也不会丢失,因为redis在创建新的AOF的过程中,会继续讲命令追加到现有的AOF文件中,新的AOF文件创建完毕后,redis会从旧的AOF文件切换到新的AOF文件,并对新的AOF文件进行追加。
3.1.4:AOF文件有序的保存了对数据库执行的所有写入,因此文件的内容非常容易被人读懂,对文件进行分析和导出也十分简单。(举例:如果不小心执行了清除全部的指令,只要AOF文件未被重写,那么此时停掉服务器,移除AOF文件尾部的清除命令,重启redis,就可以恢复清除之前的数据)
4:redis本身的机制时AOF持久化开启且存在AOF文件时,优先加载AOF文件,AOF关闭或者AOF文件不存在时,加载RDB文件。
五:Pipeline
1:优点:可以将多次IO往返的时间缩减成一次。
2:缺点:pipeline执行的指令之间没有因果关系。
六:主从同步
1: 从服务器能精确的复制主服务器的内容,每次当从服务器和主服务器断开连接时,从服务器会自动重新连接到主服务器,并且无论这期间主服务器发生什么,从服务器都将尝试让自身成为主服务器的精确副本。
2:主要的三个机制:1.当一个主服务器和一个从服务器连接正常时,主服务器会发送命令流来保持对从服务器的更新,以便讲自身的数据的改变复制给从服务器,2.当主服务器和从服务器断开之后,网络问题或者主从意识到连接超时,从服务器重新连接上主服务器会尝试进行部分重同步,会尝试只获取在断开连接期间内丢失的命令,3.当无法进行部分重同步时,从服务器会请求进行全量重同步,例如主服务器创建所有的数据快照,发送给从服务器。
七:淘汰机制
1:主动淘汰:当客户端尝试访问时,key会被发现并主动过期。
2:被动淘汰:一些过期的keys,如果没永远没访问他,那么久没被淘汰,这显然是不对的,解决方案:1.redis每十秒做一次测试随机的20个keys,2.删除过期的keys,3.如果多于25%的keys过期,则重新随机再检测20个keys。
八:缓存雪崩,穿透,击穿
1:雪崩:即同一时间大面积的缓存失效,缓存形同虚设,所有的请求和访问直接对接数据库,如果是核心模块,那么有所依赖的借口几乎都会崩。
1.1:解决办法:1.大量往redis存数据时,把key之间的失效时间加上一定的随机值,即不同的过期时间,解决同一时间出现大量的数据失效。
1.2:设置热点数据永远不过期,有数据更新就相对应的更新缓存。
2:穿透:缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,导致数据库压力过大,严重时会击垮数据库。
2.1:解决方案:1.增加参数校验 2.对单个ip每秒访问次数超限的ip可以适当的限制访问。
3:击穿:指的是一个缓存数据,比较多访问,然后这个数据数据库有,但是在缓存过期的瞬间,请求直接对接数据库,去数据库取数据,瞬间增大数据库压力
3.1:解决方案:1.对并发量大的key设置永不过期,2.互斥锁(缓存中不存在数据,去获取锁,获取成功,去数据库取数据,取到数据更新缓存,释放锁,没取到sleep再重新获取)
九:哨兵机制
1:redis的哨兵系统用于管理多个redis服务器,该系统主要有三点。
2:监控:哨兵监控主从服务器是否正常工作。
3:提醒:当监控到某个redis出现问题,哨兵会发送api向管理员发送警告。
4:故障迁移:当主服务器挂了,哨兵会将从服务器变为主服务器,并让其他的从服务器改为复制这个新的服务器,如果客户端连接旧的主服务器,会向客户端返回新的主服务器地址,继而用新的主服务器代替旧的主服务器。
十:通读策略