1 redis组件特性
Redis VS 其他kv缓存产品
- 支持数据持久化,可以将内存中数据保存在磁盘中,重启时可以再次加载使用
- 不仅仅支持简单的kv类型数据,同时提供list、set、zset、hash等数据结构
- 支持数据备份,即master-slave模式数据备份
Redis的优势
- 性能极高,读的速度是110000 次/s,写的速度是81000 次/s
- 丰富的数据类型,支持String、List、Hash、Set及ZSet
- 原子,所有操作都是原子,多个操作支持事务,即原子性
- 丰富特性,支持publish/subscribe, 通知、key过期等特性
Redis 与其他key-value 存储方式有什么不同?
- Redis 有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。
- Redis 运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存;
- 另一个优点,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性强的事情,同时在磁盘格式方面,Redis是以紧凑的追加方式产生,并不需要随机访问
Redis vs Memcached
1 Memcached 所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型
2 Redis 的速度比Memcached快,memcache单value最大支持1M,而redis最大支持512M
3 memcache只做存储、缓存,不支持可靠性,断电或服务关闭后会丢失内存数据;Redis更倾向内存数据库,如果有持久化需求优先可考虑redis
4 redis支持lua脚本,在复杂业务场景中,可保证业务顺序执行
2 线程和IO模型
Redis是单进程单线程?
Redis 是单进程单线程的,redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销
redis为什么要引入多线程
redis6 引入多线程原因:可以充分利用服务器CPU资源,当前主线程仅能利用一个核,多线程任务可以分摊redis同步IO读写负荷 IO多路复用模型,本质还是同步阻塞IO模型,epoll调用过程是阻塞的,在并发量极高的场景下,会成为性能瓶颈
Redis的多线程部分只是用来处理网络数据的 读写和协议解析,执行命令仍然是单线程顺序执行。所以我们不需要去考虑控制 key、lua、事务,LPUSH/LPOP 等等的并发及线程安全问题。
Redis 将所有数据放在内存中,内存的响应时长大约为100纳秒,对于小数据包,Redis服务器可以处理80,000到100,000 QPS,这也Redis处理的极限了, 对于80%的公司来说,单线程的Redis已经足够使用了。但随着越来越复杂的业务场景,有些公司动不动就上亿的交易量,因此需要更大的QPS。
常见的4种IO模型:
- 阻塞IO
- 同步非阻塞IO
IO多路复用(select/poll, epoll, 信号驱动IO模型)- 异步非阻塞IO
redis中的线程和IO模型 zhuanlan.zhihu.com/p/577222768
4 Redis常见性能问题和解决方案
热key问题
问题原因:当某些key被频繁访问,就会导致Redis的性能下降。 解决方案:使用Redis集群,将热key分散到不同的节点上,或者使用缓存淘汰策略,如LRU、LFU等
redis单线程模型问题
问题原因:在高并发场景下性能不够,Redis采用单线程模型,虽然能够减少并发冲突,但会影响性能 解决方案:使用Redis集群,实现分布式部署,或者使用多个Redis实例来提高性能。
TODO: redis实例和集群
持久化问题
问题原因:redis支持两种持久化,RDB把内存快照写入磁盘,AOF把redis命令写入磁盘。如果持久化频繁,导致redis性能下降。 解决方案:合理设置持久化策略,选择合适持久化方式,或者使用redis集群方式。
网络带宽限制问题
问题原因:网络带宽不足,导致性能下降。 解决方案:使用更高带宽网络,或者使用redis集群实现负载均衡;
内存占用过高问题
解决方案:使用redis持久化机制,数据保存磁盘,减少内存占用;或者采用LRU策略,释放内存空间。
频繁key过期问题
问题: redis中过期key太多,会对性能和内存消耗产生不利影响 解决方案:合理配置过期时间、定期删除和惰性删除策略、使用Redis集群、增加内存设置等方法,可以有效处理Redis中过期key过多的问题。
1 配置适当的过期时间:根据实际需求和业务情况,合理配置Redis中key的过期时间。如果过期时间设置得过短,会造成频繁的key过期和删除操作;如果过期时间设置得过长,会占用过多的内存。因此,需要根据实际情况来选择一个合理的过期时间,避免过期key过多。
2 定期删除过期key:Redis使用定期删除和惰性删除两种策略来处理过期key。定期删除策略是每隔一定的时间,Redis会对数据库中的一部分过期key进行删除,以减少内存占用。可以通过调整“hz”配置值来选择定期删除策略的频率。可以增加“hz”值来增加删除频率,减少过期key的数量。
3 惰性删除过期key:当访问一个key时,Redis会先检查该key是否过期,如果过期则会删除。通过合理的业务设计和访问模式,可以减少访问已过期key的次数,从而减少惰性删除的开销。
4 使用Redis集群:如果单个Redis实例的过期key过多,可以考虑使用Redis集群来分散过期key的负载。Redis集群提供了数据分片和数据复制的机制,可以横向扩展Redis的存储能力和处理能力,从而减轻单个实例的过期key压力。
5 增加内存设置:如果经过以上努力仍然无法解决过期key过多的问题,可以考虑增加Redis实例的内存设置。增加内存可以提高Redis的缓存能力和处理能力,从而更好地处理过期key的操作。
大量全量同步
问题:如果Redis作为主从架构的主节点,频繁进行全量同步会影响性能 解决方案:通过设置主从节点的复制方式为部分重同步(PSYNC),只传输增量数据,减少全量同步的次数和数据量。
大量短连接请求
问题: 客户端发起大量的短连接请求,会导致 Redis 服务器频繁地创建和销毁连接 解决方案:使用连接池技术,复用已经建立的连接,避免频繁地创建和销毁连接。
大量的数据写入
问题:业务场景需要大量的数据写入操作 解决方案:使用 Redis的管道技术,将多个写入操作打包成一个请求发送给 Redis,减少网络通信的开销和延迟,提高写入性能
Redis性能问题很多,常见解决方案:
- 1 使用 Redis集群:将 Redis 数据分布在多个节点上,可以提高 Redis 的性能和可用性,同时可以将数据分散存储,避免单个 Redis 节点负载过高。
- 2 使用 Redis 主从复制:使用主从复制可以将读操作分布到从节点上,减轻主节点的负载,从而提高 Redis 的性能和可用性。
- 3 合理配置Redis:包括调整Redis 的内存限制、网络参数、最大连接数等等,可以提高 Redis的性能和稳定性。
- 4 使用 Redis 持久化机制:使用 AOF 持久化可以将 Redis 的数据写入到硬盘上,避免 Redis进程退出时数据的丢失,提高 Redis 的可用性。
- 5 避免大数据集操作:对于大的数据集,避免一次性读取或写入全部数据,可以分批次进行操作,避免 Redis 阻塞。
- 6 合理选择 Redis 数据结构:对于不同的数据类型,选择合适的 Redis数据结构可以提高 Redis 的性能,例如使用哈希表存储键值对,使用列表存储日志数据等等。
Redis过期键的删除策略?
- expire 如果某个时间段有大量过期数据到期,需要占用大量CPU资源处理过期数据,会影响缓存吞吐量和响应时间
- 惰性删除,当请求数据时发现数据过期,会执行删除 只占用很小系统资源删除数据,但在面对冷数据时,比如数据已过期,但一直没访问,这些数据会一直占用空间,只能靠redis淘汰策略删除
- 随机删除 每隔一段时间,随机取20个key检查,删除其中一些key,如果其中5个key过期,会再次执行。 通过限制删除操作时长和频率,来减少CPU和内存的空间占用影响
5 Redis过期键的删除策略
- 惰性删除,当请求数据时发现数据过期,会执行删除 只占用很小系统资源删除数据,但在面对冷数据时,比如数据已过期,但一直没访问,这些数据会一直占用空间,只能靠redis淘汰策略删除
- 随机删除 每隔一段时间,随机取20个key检查,删除其中一些key,如果其中5个key过期,会再次执行 通过限制删除操作时长和频率,来减少CPU和内存的空间占用影响
6 Redis的淘汰策略
过期删除策略 vs 内存淘汰策略
什么是过期删除策略? Redis可对key设置过期时间,需要相应的机制执行删除过期键值对操作,这就是过期删除策略的工作。 什么是内存淘汰策略? 当redis运行内存超过设置的最大内存后,会使用内存淘汰策略删除符合条件的key。
内存淘汰策略有哪些?
共有8种,分为不进行数据淘汰和进行数据淘汰两类策略
- 1 不进行数据淘汰策略:(redis3.0后,默认策略)当内存超过最大设置后,不淘汰任何数据,如果有新数据写入,报错禁止写入,查询、删除操作不受影响;
- 2 进行数据淘汰策略:分为两类 设置过期时间的数据中淘汰:
- volatile-random:随机淘汰设置了过期时间的任意键值;
- volatile-ttl:优先淘汰更早过期的键值。
- volatile-lru(Redis3.0 之前,默认的内存淘汰策略) LRU算法
- volatile-lfu(Redis 4.0 后新增的内存淘汰策略):淘汰所有设置了过期时间的键值中,最少使用的键值; LFU算法
LRU算法、LFU算法
在所有数据范围内淘汰:
- allkeys-random
- allkeys-lru
- allkeys-lfu
参考 xiaolincoding.com/redis/modul…
7 Redis的同步机制
为什么需要主从复制
数据持久化技术(AOF和RDB)保证即使在服务器重启的情况下,不会丢失数据。但数据都存储在一台机器上,存在单点风险:
- 如果服务器宕机,数据恢复需要时间,恢复期间不能提供服务;
- 如果服务器硬盘故障,数据丢失; 解决单点问题方案:数据备份到其他服务器,并允许备份服务器对外提供服务。
服务器集群之间如何保持一致性?是否每台服务器都可以处理读写?
主服务器可以处理读写操作,写操作会同步给从服务器。从服务器只处理读操作。