Redis性能优化:全网最全的一篇
硬件CPU
[*]选择高性能的多核 CPU:Redis 是单线程处理惩罚哀求的,性能取决于单个核心的处理惩罚本事。选择高主频(3 GHz 以上)的 CPU 能有效提高 Redis 的单实例性能。然而,多个 Redis 实例可以并行运行在不同的 CPU 核心上,因此多核 CPU 仍旧有助于提高团体的吞吐量。
[*]避免超线程(Hyper-Threading):在高负载下,超线程技能可能会导致 CPU 争用和缓存冲突,从而影响性能。在 BIOS 中禁用超线程,确保 Redis 实例运行在物理核心上。
内存
[*]足够的内存容量:Redis 完全在内存中运行,所有数据集、缓存和内存快照都需要斲丧内存。建议内存容量至少是数据集大小的 1.5 到 2 倍,确保有足够的内存空间处理惩罚数据并预留给操作系统和其他服务。
[*]利用 ECC 内存:Redis 是内存麋集型应用,ECC(Error-Correcting Code)内存可以检测和修复内存中的单比特错误,提供更高的可靠性和稳固性,特殊是在大规模摆设中。
磁盘
[*]利用 NVMe SSD:虽然 Redis 是内存数据库,但持久化操作(如 RDB 快照和 AOF 持久化)需要磁盘 I/O。NVMe SSD 提供了极高的读写性能,能够显著收缩持久化操作的时间,减少 Redis 因持久化导致的壅闭。
[*]磁盘 RAID 配置:为了提升 I/O 性能和数据可靠性,建议利用 RAID 0 或 RAID 10 配置磁盘阵列。RAID 0 提供最高的性能,但没有冗余;RAID 10 兼顾性能和数据安全。
网络
[*]高带宽低延长网络:Redis 对网络性能要求较高,特殊是在主从复制和集群模式下。利用低延长、高带宽的网络(如 10GbE 或更高),减少网络传输时延,确保数据同步和集群通信的高效性。
[*]优化网络配置:调解 TCP 参数(如tcp_nodelay、tcp_keepalive 等)以减少网络延长和带宽斲丧。在 Linux 系统上,可以在 /etc/sysctl.conf 中进行配置,比方:
net.core.somaxconn = 1024
net.ipv4.tcp_max_syn_backlog = 2048
操作系统
操作系统的配置对 Redis 的性能影响显著。通过合理配置操作系统,可以充分发挥硬件性能,提升 Redis 的处理惩罚本事。
内存锁定与交换
[*]锁定内存:防止 Redis 利用的内存被操作系统交换到磁盘,以免影响性能。在 Redis 配置文件 redis.conf 中启用内存锁定:
maxmemory-policy noeviction
[*]禁用交换(swap):Redis 需要始终在内存中进行操作。设置操作系统的交换分区策略为最低(保举设置为vm.swappiness = 1
),防止 Redis 被交换到磁盘。在 /etc/sysctl.conf 中配置:
vm.swappiness = 1
文件系统和磁盘I/O优化
[*]文件系统选择:保举利用 ext4 或 xfs 文件系统。ext4 是 Linux 默认文件系统,性能稳固;xfs 在处理惩罚大文件写入时性能更好,适合 AOF 持久化场景。
[*]文件形貌符限制:Redis 需要打开大量文件来进行数据操作,增大文件形貌符限制能避免 Too many open files 错误。编辑 /etc/security/limits.conf:
* soft nofile 65536
* hard nofile 65536
[*]设置 mmap counts:调解 vm.max_map_count 参数以支持更大的内存映射,减少 OOM(Out of Memory)错误:
vm.max_map_count = 262144
在 /etc/sysctl.conf 中设置后运行 sysctl -p 使配置见效。
网络参数调优
[*]增加 TCP 参数:调解 TCP 相关参数,减少延长,优化网络传输性能。比方:
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300
Redis实例调优
Redis 配置优化直接影响 Redis 的性能体现。合理配置 Redis 参数,可以提高读写效率,减少壅闭和瓶颈。
内存管理
[*]设置最大内存利用策略:根据应用场景选择合适的内存镌汰策略,如volatile-lru、allkeys-lru、volatile-random、allkeys-random等。一般环境下,利用allkeys-lru可以在内存不敷时优先镌汰近来最少利用的键。
[*]配置内存碎片整理:定期实行内存碎片整理,减少内存碎片,提高内存利用率。可以利用 MEMORY PURGE
命令主动清理内存碎片。
持久化配置
[*]合理设置 AOF 和 RDB:Redis 支持两种持久化方式:AOF(Append Only File)和 RDB(Redis Database)。AOF 记载每次写操作,适合需要高数据安全的场景;RDB 快照是定期生存数据的快照文件,适合性能要求高的场景。根据应用场景选择合适的持久化方式,或两者联合利用。
[*]优化 AOF 刷盘策略:设置 appendfsync 参数决定 AOF 的刷盘策略:
[*]always:每次写操作后都同步刷盘,数据安全性高但性能最差。
[*]everysec:每秒刷盘一次,性能与安全性平衡。
[*]no:操作系统自行决定刷盘时间,性能最好但数据丢失风险高。
[*]减少 RDB 快照频率:假如不需要频繁的持久化,可以减少 RDB 快照的频率,减少磁盘 I/O 操作。可以在 redis.conf 中调解 save 参数,比方:
save 900 1
save 300 10
save 60 10000
网络优化
[*]最大化并发毗连数:调解 maxclients 参数以支持更多的并发毗连数。可以在 redis.conf 中设置:
maxclients 10000
[*]优化复制配置:在主从复制场景下,配置 repl-diskless-sync 选项为 yes 可以减少同步过程中的磁盘 I/O 操作,提升复制性能。
Schema设计优化
选择合适的数据类型
[*]利用 String 存储简单键值对:String 是 Redis 最简单、最基本的数据类型,适用于存储简单的键值对。对于计数器、缓存等场景,可以利用 INCR、DECR 等命令进行高效的原子操作。
[*]利用 Hash 存储对象:当需要存储一个对象的多个字段时,利用 Hash 可以节流内存,提高内存利用率。比方,用户配置或产品信息等场景中,每个对象的多个字段可以利用一个 Hash 存储,减少内存斲丧。
[*]利用 Set 和 Sorted Set 进行聚集操作:假如需要存储不重复的聚集数据,可以利用 Set 数据结构;假如需要对聚集中的元素进行排序,可以利用 Sorted Set,并通过权重(score)进行排序管理,比方排行榜、评分系统等场景。
[*]利用 List 实现队列和栈操作:List 是 Redis 中的双向链表,适用于需要按照插入次序读取的场景,比方消息队列、任务队列等。可以利用 LPUSH、RPUSH、LPOP、RPOP 等命令实现先进先出(FIFO)或先进后出(LIFO)的队列操作。
减少键的大小
[*]利用紧凑的键名:键名的大小会影响 Redis 内存占用,建议利用紧凑的键名,同时保持可读性。避免利用冗长的定名,特殊是在大规模数据存储时,小键名可以显著减少内存占用。
利用 Hash 数据类型来压缩存储
Redis 的 Hash 适合存储多个字段的对象,当字段较少且值较短时,利用 Hash 可以显著减少内存占用。Redis 会将小型 Hash 以 ziplist(压缩列表)的情势存储,这样可以减少内存占用。
[*]优化方法:将多个相关的 String 键值对归并到一个 Hash 中。比方,将用户信息(如姓名、年龄、地址等)存储在一个 Hash 中,而不是利用多个 String 键。
[*]配置参数:调解 hash-max-ziplist-entries 和 hash-max-ziplist-value 参数,增大它们的值,确保更多的 Hash 以压缩列表的情势存储。比方:
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
利用压缩列表(ziplists)来存储小的 List 和 Set
对于小型的 List 和 Set,Redis 可以利用 ziplist(压缩列表)和 intset(整数聚集)来节流内存。压缩列表是一种更紧凑的存储格式,可以有效减少内存占用。
[*]优化方法:确保 List 和 Set 的大小和数据类型符合 ziplist 和 intset 的存储条件,调解相关参数。
[*]配置参数:调解 list-max-ziplist-entries 和 list-max-ziplist-value 参数,增大它们的值,使更多的 List 以压缩列表的情势存储。比方:
list-max-ziplist-entries 512
list-max-ziplist-value 64
[*]利用 Intset:对于只包含整数值的小型 Set,Redis 会自动利用 intset 结构,可以进一步减少内存占用。调解 set-max-intset-entries 参数,确保更多的 Set 利用整数聚集存储。
利用更紧凑的编码格式
利用 Sorted Set 的压缩格式:对于小型的 Sorted Set,可以利用 ziplist 来存储,减少内存占用。调解 zset-max-ziplist-entries 和 zset-max-ziplist-value 参数。比方:
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
数据分片与集群优化
[*]利用 Redis 集群分片数据:在数据量凌驾单个 Redis 实例的内存限制时,可以利用 Redis 集群将数据分布到多个实例中。集群模式下,Redis 将数据按照哈希槽(Hash Slot)进行分片存储,每个分片对应一个或多个节点。根据数据访问模式和业务需求,合理规划分片数量,确保负载平衡和高可用性。
避免大键值对(Big Keys)
[*]避免大键值对:在 Redis 中存储大键值对会影响操作的性能。尽量将大对象分割成多个小对象存储,避免对大键进行操作。比方,将一个包含大量数据的 Hash 拆分为多个小的 Hash 或将大 List 拆分为多个小的 List。
减少内存占用
毕竟是内存,金贵
上面的数据结构优化
数据压缩
[*] 利用更紧凑的字符串编码: Redis 会自动选择得当的字符串编码方式(raw 或 int 编码)。假如某些字符串可以转换为整数,Redis 会利用更紧凑的 int 编码来存储它们。比方,字符串 "12345" 可以转换为整数 12345,Redis 会选择整数编码,减少内存利用
[*] 利用 LZF 压缩 AOF 文件: 假如启用了 AOF(Append Only File)持久化,可以选择利用 LZF 压缩 AOF 文件,减少磁盘和内存的利用。
在 redis.conf 中启用 AOF 压缩:
aof-use-rdb-preamble yes
[*]自界说数据压缩: 对于存储在 Redis 中的特定数据类型,可以考虑在应用层进行压缩,比方利用 gzip 或 snappy 等压缩算法。压缩后的数据可以存储为二进制格式(如字符串),这样可以在保持数据不变的环境下显著减少内存占用。在写入数据之前对数据进行压缩,读取数据时进行解压缩。
减少内存碎片
[*] 优化内存分配: Redis 内部利用 jemalloc 作为内存分配器,可以通过定期优化和整理内存分配来减少内存碎片
实行内存碎片整理:利用 MEMORY PURGE
命令主动清理未利用的内存,减少内存碎片。比方:
MEMORY PURGE
[*]调解 jemalloc 配置: 根据 Redis 的内存利用模式和工作负载,调解 jemalloc 的配置参数,优化内存分配策略,减少内存碎片。比方,可以调解 jemalloc 的垃圾回收频率、碎片归并策略等参数。
减少逾期键的内存占用
[*]利用逾期策略清理无用数据: 对于某些业务场景,可能会有大量逾期的键占用内存。通过设置键的逾期时间,可以自动清理无用的数据,开释内存。设置合理的逾期时间:利用 EXPIRE 命令为键设置合理的逾期时间,定期清理无用数据,开释内存。
[*]利用 TTL 和 Keyspace Notifications: 通过 Redis 的 TTL 命令和 Keyspace Notifications,可以监控键的逾期环境,实时清理和回收内存。
精简数据存储
● 归并重复的数据:对于存储结构相似或内容重复的数据,可以考虑利用更高效的存储方式来减少内存占用。比方,利用共享字符串(String Interning)或引用计数技能,避免冗余数据存储
● 利用 HyperLogLog 和 Bitmap:对于某些数据统计场景,可以利用 HyperLogLog 和 Bitmap 数据结构来替换传统的 Set 或 List 存储方式。这些数据结构具有更低的内存占用,可以在一定范围内提高数据存储的紧凑性。
○ HyperLogLog:适用于大规模去重计数的场景,比方 UV 统计。它利用概率算法,在牺牲部门精度的环境下,可以大幅减少内存利用。
○ Bitmap:适用于布尔值存储和二进制数据处理惩罚,比方位图索引、状态标志等场景
写入优化
写入性能是 Redis 性能优化的一个重要方面。通过优化写入策略,可以显著提高 Redis 的吞吐量和响应时间。
批量写入
[*]利用 Pipeline 批量写入:Pipeline 可以将多个命令批量发送给 Redis,减少网络往返时间,提升写入效率。在高并发写入场景下,利用 Pipeline 可以显著提高吞吐量。
异步写入
[*]利用异步写入模式:在一些非关键场景(如日志记载、数据收罗等),可以利用异步写入模式,避免同步写入导致的壅闭和延长。可以通过异步任务或多线程来实现异步写入,提高系统的响应速度和吞吐量。
减少写操作
[*]优化数据更新频率:尽量减少频繁的写操作,将多次更新归并为一次操作。比方,对于计数器或累加操作,可以利用批量累加的方式,避免频繁的原子操作,减少 Redis 的处理惩罚开销。
查询优化
优化查询性能是 Redis 性能优化的另一个关键环节。通过合理的查询策略和命令选择,可以显著提高 Redis 的查询效率。
利用命令的批量处理惩罚
[*]利用批量处理惩罚命令:对于需要处理惩罚大量数据的操作,利用批量处理惩罚命令(如MGET、MSET等),减少网络往返次数,提高查询性能。
合理利用缓存
[*]设置合理的逾期时间:根据业务需求设置缓存的逾期时间,避免频繁的缓存失效和重建,影响查询性能。可以利用 EXPIRE、TTL 等命令设置和查询键的逾期时间。
优化数据结构查询
[*]选择合适的数据结构:根据查询需求选择合适的数据结构和命令,避免利用复杂度高的命令(如SORT、ZRANGE等),减少CPU和内存开销。比方,利用HASH存储对象属性而不是用STRING存储 JSON 文本。
减少内存碎片
[*]定期实行内存整理:利用MEMORY PURGE
命令开释空闲内存,减少内存碎片,提高查询性能。可以利用 Redis 的 INFO 命令监控内存利用环境和碎片率,定期进行优化
监控与调优
性能监控
[*]利用监控工具:利用 Redis 提供的监控工具(如redis-cli、INFO命令、SLOWLOG等)监控 Redis 的性能和康健状态。也可以集成第三方监控工具(如 Prometheus、Grafana)进行更全面的监控。
参数调优
[*]根据负载调解参数:根据 Redis 的负载环境和业务需求,动态调解 Redis 的参数配置,如内存分配策略、线程池大小、命令超时等。合理设置maxmemory、maxclients、timeout等参数,优化系统性能。
慢查询优化
[*]分析和优化慢查询:利用SLOWLOG记载慢查询日志,分析和优化慢查询,减少查询延长,提高查询性能。可以设置合理的慢查询阈值,监控和优化查询性能瓶颈。
集群调优
[*]调解分片和副本数:根据查询模式和集群规模调解索引的分片和副本数量,以达到最佳查询性能。在集群模式下,合理规划节点和分片布局,确保数据负载平衡和高可用性。
大家在redis实例优化和schema设计优化有什么想法,欢迎评论
页:
[1]