Redis

读写策略

- CAP(Cache Aside Pattern)旁路缓存模式,适合读请求比较多的系统。

        - 写:更新数据库,直接删除cache

        - 读: 优先读取cache,读不到则从数据库读出来后返回,再更新到cache中

        - 缺点:第一次读肯定不在cache中 + 频繁写会造成cache频繁删除。

- Read/Write Through 读写穿透模式

        - 写:更新缓存,然后同步更新DB。

        - 读:优先读取Cache,不在存在则从数据库读出来,先写入Cache再返回。

- 异步写入模式

        - 与读写模式一致,只不过更新数据库的操作是异步完成的

缓存淘汰策略

- 惰性删除

        - 不主动删除,等到数据被访问时检查是否过期,过期时删除。

- 定时删除

        - 定期选择部分设置了过期时间的键,并删除其中过期的键,如果过期的键超过百分之25,则继续轮询其他的键,直到超过一定时间,默认是25ms。执行太频繁对于CPU不友好。

如果既没有被惰性删除,又没有到达定期删除设置的时间,但是达到了内存的最大值,则会根据配置的策略触发强制删除一些即使没有过期的键,策略包括(LRU)Least Recently Used和(LFU) Least Frenquently Used.

- LRU

        - 最近最多使用,淘汰最近最少被访问的缓存,适合热点数据,例如新闻等时间敏感性的数据。实现简单,适合高并发场景。

- LFU

        - 最少使用,淘汰总访问次数最少的缓存,适合长期累计的数据,例如商品缓存等数据量较大的数据。需要更精准的缓存淘汰机制时使用。

数据类型

        - String字符串:使用了SDS简单动态字符串,性能更好,更安全。适合用来实现对象储存,分布式锁,常用计数,以及分布式会话等功能。

        - List数组:维持一个顺序的数组(quicklist),适合做消息队列,但是无法适用于多消费者消费一个消息的场景

        - HashMap:使用了hashMap作为实现。常用语储存频繁变更的对象。

        - Set:使用了hashMap或整数集合作为实现,因其不可重复的属性,适合用于抽奖,点赞都业务场景

        - ZSet:使用了listPack实现,与Set相比多了一个权重排序的功能,适合于排行榜等排序业务场景

持久化

        - 使用了AOF+RDB快照的方式来持久化内容,防止数据丢失。

        - AOF即将每一次缓存执行的操作,先放入专门的缓存区中,然后再根据redis的配置决定什么时候将这些缓存区中的操作写入磁盘中(由主进程完成,可能会阻塞redis),例如always完成后直接写入,everySec每秒写入一次。

        - 当AOF过大时,会触发重写机制,即将重复的操作删除,只保留最后即最新的一次操作。(由子进程完成的)

        - RDB快照即每隔一段时间,将所有的缓存中的数据,转化成二进制文件,存入磁盘中。由于RDB储存的是数据,而不是所有操作,所以在操作较多时,使用RDB一次性恢复数据,比一条条执行历史操作要更快。

        - 使用AOF+RDB模式,即在触发AOF重写时(AOF文件过大),将内存中的数据存入RDB文件,然后在重写过程中产生的操作以AOF的形式写入RDB文件中。在完成后先从RDB文件恢复数据,再执行AOF文件中的操作。

        - 在RDB生成阶段时,过期键不会被加入到文件中。在加载阶段时,主节点不会加载过期键,从节点会加载所有键。

        - AOF针对没有过期的键会添加到记录中,如果过期了则会生成一条DEL操作。重写时会忽略过期的键。

集群

        - 主从复制+哨兵模式:主节点负责读写,从节点只负责读,然后从主节点定时同步数据到从节点。如果主节点产生故障,则有多个哨兵选举出一个新的主节点。

        - 主从复制中初始化会使用RDB文件模式从主节点同步所有数据到从节点中,之后的操作会以AOF文件的方式同步给从节点。

        - 如果从节点的键过期了,不会做任何处理可以正常读。会等到下一次从主节点同步AOF文件时,同步过期键的DEL操作来删除从节点的过期数据。

        - 脑裂:主节点与从节点网络发生故障,无法同步数据到从节点。哨兵选举出新的主节点后原主节点恢复网络,但是被降级成为从节点,导致数据丢失。解决方案为利用redis的最小从节点连接数与最小从节点响应时间两个参数来检查主节点是否产生网络故障,如果网络故障则禁止主节点从客户端继续写入数据,需要等待哨兵选举出新的主节点后才能放通。

缓存穿透

        - redis在缓存中无法读取到数据时,会尝试从数据库去读,这个操作会比较耗费性能。为了避免有人恶意,一直访问一个不存在的数据(肯定不会存在于内存中)导致频繁访问数据库,我们可以在缓存中针对不存在数据设置一个空值。

缓存击穿/缓存雪崩

        - 击穿:redis中存在热点数据过期并在短时间内会有大量的访问

        - 雪崩:大量数据同一时间过期,造成大量访问数据库

直接访问到数据库造成大量压力。针对击穿我们可以为这些热点数据不要设置过期时间,或者由后台手动更新缓存。针对雪崩,我们可以将不同的数据过期时间随机分布开来。

大Key

        - 大Key是指Value很大的key,由于删除与操作都很费时间,所以会造成主线程和客户端阻塞和内存分布不均等问题。可以使用-cli --bigkeys命令查找大key。

        - 删除大Key时不能直接删除,会阻塞主线程。我们可以使用子线程来实现异步删除,或者分批次删除。

事务回滚

        - redis虽然支持事务功能,但是不支持运行错误时回滚的被动回滚,也就是发生错误时已执行的命令不会回滚。但是你可以主动调用discard命令回滚开启事务后执行的所有命令。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值