redis作为一种高性能的内存数据库,广泛应用于各种业务场景。然而,随着业务规模的扩大和数据量的增长,redis的性能问题逐渐凸显出来。
为了提高redis的性能,本文将深入探讨redis性能优化方案,包括参数配置、数据结构、多线程、集群分片等方面。
一、性能测试工具
1.1、redis-benchmark
在聊redis性能优化方案之前,我们来了解一下redis性能测试工具 redis-benchmark。
redis 包含一个名为 redis-benchmark 的实用程序,它可以模拟 n 个客户端同时发送 m 个查询的命令执行情况。该实用程序提供了一组默认的测试,你也可以提供一组自定义的测试。

1.2、影响redis性能的因素
有多种因素会直接影响redis的性能。这里,我们分析一些,因为它们可以改变所有benchmark测试的结果。但请注意,一个典型的redis实例,运行在低速、未调优过的系统上,提供的性能对大多数应用来说也是够好的。
- 网络带宽和延迟常常是直接影响性能。启动benchmark程序前,使用ping程序快速检查客户端和服务器之间的延迟是一种好习惯。在很多现实的场景中,redis吞吐量先受到网络限制,然后才是cpu。
- cpu是另一个重要的因素。作为单线程的,redis喜欢高速有大缓存而不是有多个核的cpu。当客户端和服务器运行在同一个系统上,cpu就是redis-benchmark的限制因素。
- 相同的硬件上,运行在虚拟机上的redis会比运行在真实系统上的redis慢。
- 当服务器和客户端benchmark程序运行同一系统上时,tcp/ip回路和unix域套接字都可使用。
- 大量使用管道化(即长管道)时,比起使用tcp/ip,unix域套接字的性能提升会有所下降。
- 使用以太网访问redis,数据大小保持小于以太网报文大小(大约1500字节),使用管道化汇集多条命令特别有效。实际上,处理10字节,100字节,1000字节的查询几乎是一样的吞吐量。如下图。

- 在有多个cpu插口的服务器上,redis的性能依赖于numa配置和进程位置。

- 使用高级配置,客户端连接数也是很重要的因素。

其他要考虑的事情
benchmark的一个重要目的是得到可重复的结果,这样才能和其他测试的结果进行比较。
- 如果打算使用rdb或aof,请确保系统中没有其他i/o活动。避免把rdb或aof文件在nas或nfs上共享,或放在其他影响网络带宽或延迟的设备上(比如amazon ec2的ebs)。
- 设置redis的日志级别(参数loglevel)为warning 或notice。避免把日志放在远程文件系统上。
p.s.以上图来源于redis官方文档中,想了解更详细的可以进入redis官方文档中查看。

二、性能优化方案
2.1、硬件配置优化
网络优化
- 使用高性能网络设备: 确保redis服务器和客户端之间的网络连接是高性能的,采用千兆以太网或更高速的网络设备。
- 调整内核参数: 针对高负载的情况,优化操作系统的网络相关内核参数,包括调整tcp连接数、缓冲区大小等。
- 使用连接池: 在客户端使用连接池,避免频繁地打开和关闭网络连接,减少连接的建立和断开开销。
内存优化
- 使用高性能内存条:选择具有较高速度和低延迟的内存条。
- 增加内存容量: redis是一个内存数据库,更多的内存通常意味着更好的性能,特别是当你的数据集逐渐增大时。确保服务器上安装了足够的内存,以满足数据存储的需求。
- 合理设置maxmemory参数: 设置maxmemory参数,防止redis使用过多内存导致系统出现性能问题。
- 使用内存碎片整理: 定期查找和整理内存碎片。
2.2、参数配置优化
redis的性能参数需要结合实际的应用场景来调整,以达到最佳的性能表现。
- 设置合理的 maxmemory 参数:maxmemory 参数用于限制 redis 内存的使用量。如果设置过小,可能会导致 redis 频繁 lru 淘汰,影响性能。如果设置过大,可能会导致 redis 内存不足,导致服务不可用。
- 设置合理的 maxmemory-policy 参数:maxmemory-policy 参数用于指定 redis 在内存不足时采取的策略。
- 设置合理的 timeout 参数:timeout 参数用于指定客户端连接超时时间。如果设置过小,可能会导致客户端连接频繁断开,影响性能。如果设置过大,可能会导致客户端连接时间过长,影响性能。
- 设置合理的 loglevel 参数:loglevel 参数用于指定 redis 日志级别。如果设置过高,可能会导致 redis 日志输出过多,影响性能。如果设置过低,可能会导致重要的日志信息丢失,影响排错。
2.3、数据结构优化
redis支持多种数据结构,每种数据结构都有自己的特点和适用场景。选择合适的数据结构可以节省内存空间,减少网络开销,提高查询速度。例如:
- 避免使用过大的键名或值,因为它们会占用更多的内存和网络带宽。
- 避免使用过多的层级结构,因为它们会增加查询的复杂度和开销。
- 避免使用过于稀疏的数据结构,因为它们会浪费内存空间。例如,如果你需要存储一个大量空值的矩阵,可以考虑使用压缩列表或位图等更紧凑的数据结构。
2.4、使用合理的过期策略
redis 的过期策略可以有效提升 redis 的性能。以下是一些使用合理的过期策略优化 redis 性能的技巧:
- 根据数据使用情况设置合理的过期时间:过期时间设置过短,会导致 redis 频繁进行 lru 淘汰,影响性能。过期时间设置过长,会导致 redis 内存使用率过高,影响性能。
- 根据数据访问频率设置合理的过期策略:对于经常访问的数据,可以设置较长的过期时间。对于不经常访问的数据,可以设置较短的过期时间。
- 使用惰性过期:惰性过期是指 redis 在访问键时才判断键是否过期。惰性过期可以降低 lru 淘汰对性能的影响。
2.5、使用合适的持久化机制
- rdb持久化是指定期将redis内存中的数据快照保存到磁盘上,它的优点是文件紧凑,恢复速度快,适合做备份和灾难恢复。它的缺点是可能会丢失最近一次快照之后的数据,以及在执行快照时会占用一定的cpu和内存资源。
- aof持久化是指将redis执行的每个写操作记录到一个日志文件中,它的优点是数据实时性高,可以保证数据的完整性和一致性。它的缺点是文件较大,恢复速度慢,以及在追加日志时会增加磁盘io的压力。
- rdb + aof:在同一个实例中可以组合 aof 和 rdb一起使用,也就是我们常说的混合模式。
如果你的业务对数据的实时性要求较高,或者不能容忍数据的丢失,可以选择aof持久化,或者同时开启rdb和aof持久化,让aof优先于rdb恢复数据。
如果你的业务对数据的实时性要求不高,或者可以容忍一定的数据丢失,你可以选择rdb持久化,或者关闭持久化,只依赖主从复制来保证数据的可用性。
2.6、使用合理的集群方案
redis 集群可以有效提升 redis 的性能。
- 主从复制模式:主从复制模式是最简单的集群模式。在主从复制模式中,一个节点作为主节点,其他节点作为从节点。主节点负责写入数据,从节点负责读取数据也就是我们说的读写分离。
- 哨兵模式:哨兵模式是一种高可用的集群模式。在哨兵模式中,每个节点都作为哨兵节点。哨兵节点负责监控主节点的状态,如果主节点发生故障,哨兵节点会自动选举出新的主节点。哨兵模式也适用于读写分离。
- 集群模式:集群模式是一种负载均衡的集群模式。在集群模式中,每个节点都平等,可以进行写入和读取数据。如果在成本允许的情况下使用此集群模式可以大大的提升redis的性能。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论