关于java:redisconf-70-配置和原理全解生产王者必备

7次阅读

共计 23643 个字符,预计需要花费 60 分钟才能阅读完成。

5.5 redis.conf 配置详解

我是 Redis,当程序员用指令 ./redis-server /path/to/redis.conf 把我启动的时候,第一个参数必须是redis.conf 文件的门路。

这个文件很重要,就如同是你们的 DNA,它能管制我的运行状况,不同的配置会有不同的个性和人生,它把握我的人生命运,管制着我如何实现高可用、高性能。正当的配置能让我更快、更省内存,并施展我最大的劣势让我更平安运行。

以下这些配置大家必知必会,须要大家把握每个配置背地的技术原理,学会交融贯通并在生产中正确配置,解决问题。避免出现技术悬浮,原理说的叭叭叭,配置像个大傻瓜。

本文配置文件版本是 Redis 7.0。

5.5.1 惯例通用配置

这些是我的惯例配置,每个 Redis 启动必备参数,你肯定要把握,波及到网络、模块插件、运行模式、日志等。

MODULES

这个配置能够加载模块插件加强我的性能,常见的模块有 RedisSearch、RedisBloom 等。对于模块加载能够参考【5.6 布隆过滤器原理与实战】章节集成布隆过滤器便是通过以下配置实现加载布隆过滤器插件。

loadmodule /opt/app/RedisBloom-2.2.14/redisbloom.so

NETWORK

这部分都是与网络相干的配置,很重要滴,配置不当将会有平安和性能问题。

bind

bind用于绑定 本机的网络接口(网卡),留神是本机。

每台机器可能有多个网卡,每个网卡都有一个 IP 地址。配置了 bind,则示意我只容许来自本机指定网卡的 Redis 申请。

MySQL:“bind 是用于限度拜访你的机器 IP 么?”

非也,留神,这个配置指的并不是只有 bind 指定的 IP 地址的计算机能力拜访我。如果想限度指定的主机连贯我,只能通过防火墙来管制,bind 参数不也能起到这个作用。

举个例子:如果我所在的服务器有两个网卡,每个网卡有一个 IP 地址,IP1,IP2。

配置 bind IP1,则示意只能通过这个网卡地址来的网络申请拜访我,也能够应用空格宰割绑定多个网卡 IP。

我的默认配置是bind 127.0.0.1 -::1 示意绑定本地回环地址 IPv4 和 Ipv6。- 示意当 ip 不存在也能启动胜利。

protected-mode

MySQL:网络世界很危险滴,你如何保障平安?

默认开启保护模式,如果没有设置明码或者没有 bind 配置,我 只容许在本机连贯我,其它机器无奈连贯

如果想让其它机器连贯我,有以下三种形式。

  1. 配置为 protected-mode no(不倡议,地球很危险滴,防人之心不可无)。
  2. protected-mode yes,配置 bind 绑定本机的 IP。
  3. protected-mode yes,除了设置 bind 以外,还能够通过 requirepass magebyte设置明码为 magebyte,让其余机器的客户端能应用明码拜访我。

bind、protected-mode、requirepass 之间的关系

  • bind:指定的是我所在服务器网卡的 IP,不是指定某个能够拜访我的机器。
  • protected-mode:保护模式,默认开启,如果没有设置明码或者 bind IP,我只承受本机拜访(没明码 + 保护模式启动 = 本地拜访)。
  • requirepass,Redis 客户端连贯我通行的明码。

如果参数设置为 bind 127.0.0.1 -::1,不论 protected-mode 是否开启,只能本机用 127.0.0.1 连贯,其余外机无奈连贯。

在生产环境中,为了平安,不要敞开 protected-mode,并设置 requirepass 参数配置明码和 bind 绑定机器的网卡 IP。

port 6379

用于指定我监听的客户端 socket 端口号,默认 6379。设置为 0 则不会监听 TCP 连贯,我想没人设置为 0 吧。

tcp-backlog 511

用于在 Linux 零碎中管制 TCP 三次握手 已实现连贯队列 (实现三次握手后)的长度,如果已实现连贯队列曾经满则无奈放入,客户端会报read timeout 或者 connection reset by peer 的错。

MySQL:“在高并发零碎中这玩意须要调大些吧?”

是的,我的默认配置是 511,这个配置的值不能大于 Linux 零碎定义的 /proc/sys/net/core/somaxconn 值,Linux 默认的是 128。

所以我在启动的时候你会看到这样的正告:WARNING: The TCP backlog setting of 511 cannot be enforced because kern.ipc.somaxconn is set to the lower value of 128.

当零碎并发量大并且客户端速度迟缓的时候,在高并发零碎中,须要设置一个较高的值来防止客户端连贯速度慢的问题。

须要别离调整 Linux 和 Redis 的配置。

倡议批改为 2048 或者更大 ,Linux 则在 /etc/sysctl.conf 中增加 net.core.somaxconn = 2048 配置,并且在终端执行 sysctl -p即可。

码哥应用 macOS 零碎,应用 sudo sysctl -w kern.ipc.somaxconn=2048即可。

timeout

timeout 60 单位是秒,如果在 timout 工夫内客户端跟我没有数据交互(客户端不再向我发送任何数据),我将敞开该客户端连贯。

注意事项

  • 0 示意永不断开。
  • timeout 对应源码 server.maxidletime
tcp-keepalive

tcp-keepalive 300 单位是秒,官网倡议值是 300。这是一个很有用的配置,实现 TCP 连贯复用。

用处

用于客户端与服务端的长连贯,如果设置为非 0,则应用 SO_KEEPALIVE 周期性发送 ACK 给客户端,俗话就是 用来定时向客户端发送 tcp_ack 包来探测客户端是否存活,并放弃该连贯。不必每次申请都建设 TCP 连贯,毕竟创立连贯是比较慢的。

惯例配置

这些都是我的惯例配置,比拟通用,你必须理解。你能够把这些配置写到一个特有文件中,其余节点能够应用 include /path/to/other.conf 配置来加载并复用该配置文件的配置。

daemonize

配置 daemonize yes 示意应用守护过程的模式运行,默认状况下我是以非守护线程的模式运行(daemonize no),开启守护过程模式,会生成一个 .pid文件存储过程号。

你也能够配置 pidfile /var/run/redis_6379.pid 参数来指定文件的生成目录,当敞开服务的时候我会主动删除该文件。

loglevel

指定我在运行时的日志记录级别。默认是 loglevel notice。有以下几个选项能够配置。

  • debug:会记录很多信息,次要用于开发和测试。
  • verbose:许多用途不大的信息,然而比 debug 少,如果发现生产呈现一些问题无从下手,可应用该级别来辅助定位。
  • notice:生产个别配置这个级别。
  • warning:只会记录十分重要 / 要害的的日志。
logfile

指定日志文件目录,默认是 logfile "",示意只在规范控制台输入。

须要留神的是,如果应用规范控制台输入,并且应用守护过程的模式运行,日志会发送到 /dev/null。

databases

设置数据库数量,我的默认配置是 databases 16。默认的数据库是 DB 0,应用集群模式的时候,database 只有一个,就是 DB 0

5.5.2 RDB 快照长久化

MySQL:“要怎么开启 RDB 内存快照文件实现长久化呢?”

RDB 快照长久化相干的配置,必须把握,合理配置能我实现宕机疾速复原实现高可用。

save

应用 save <seconds> <changes> 开启长久化,比方 save 60 100 示意 60 秒内,至多执行了 100 个写操作,则执行 RDB 内存快照保留。

不关怀是否失落数据,你也能够通过配置 save "" 来禁用 RDB 快照保留,让我性能腾飞,冲出三界外。

默认状况的我会依照如下规定来保留 RDB 内存快照。

  • 在 3600 秒 (一个小时) 内,至多执行了一次更改。
  • 在 300 秒 (5 分钟) 内,至多执行了 100 个更改。
  • 在 60 秒后,至多执行了 10000 个更改。

也能够通过 save 3600 1 300 100 60 10000 配置来显示设置。

stop-writes-on-bgsave-error

MySQL:“bgsave 失败的话,进行接管写申请要怎么配置?”

默认配置为 stop-writes-on-bgsave-error yes,它的作用是 如果 RDB 内存快照长久化开启并且最初一次 bgsave 失败的话就进行接管写申请。

我通过这种强硬的形式来告知程序员数据长久化不失常了,否则可能没人晓得 RDB 快照长久化出问题了。

bgsave 后盾过程能失常工作,我会主动容许写申请。如果你对此曾经有相干的监控,即便磁盘出问题(磁盘空间有余、没有权限等)的状况下仍旧解决写申请,那么设置成 no 即可。

rdbcompression

MySQL:“RDB 内存快照文件比拟大,能够压缩么?”

我的默认配置是 rdbcompression yes,意味着 对 RDB 内存快照文件中的 String 对象应用 LZF 算法做压缩。这个十分有用,能大大减少文件大小,受益匪浅呀,倡议你开启。

如果你不想损失因为压缩 RDB 内存快照文件的 CPU 资源,那就设置成 no,带来的结果就是文件比拟大,传输占用更大的带宽(要三思啊,老伙计)。

rdbchecksum

默认配置是 rdbchecksum yes,从 5.0 版本开始,RDB 文件开端会写入一个 CRC64 检验码,能起到肯定的纠错作用,然而要 失落大概 10% 的性能损失,你能够设置胜利 no 敞开这个性能来取得更快的性能。

敞开了这个性能,RDB 内存快照文件的校验就是 0,代码会主动跳过查看。

举荐你敞开,让我快到令人发指。

你还能够通过 dbfilename 参数来指定 RDB 内存快照文件名,默认是 dbfilename dump.rdb

rdb-del-sync-files

默认配置是 rdb-del-sync-files no,主从进行全量同步时,通过传输 RDB 内存快照文件实现,没有开启 RDB 长久化的实例在同步实现后会删除该文件,通常状况下放弃默认即可。

dir

我的工作目录,留神这是目录而不是文件,默认配置是dir ./。比方寄存 RDB 内存快照文件、AOF 文件。

5.5.3 主从复制

这部分配置很重要,波及到主从复制的方方面面,是高可用的基石,重点看待啊伙计们。

replicaof

主从复制,应用replicaof <masterip> <masterport> 配置将以后实例成为其余 Redis 服务的从节点

  • masterip,就是 master 的 IP。
  • masterport,master 的端口。

有以下几点须要留神。

  • 我应用异步实现主从复制,当 Master 节点的 slave 节点数量小于指定的数量时,你能够设置 Master 节点进行解决写申请。
  • 主从复制如果断开的工夫较短,slave 节点能够执行局部从新同步,须要正当设置 backlog size,保障这个缓存区能残缺保留断连期间 Master 承受写申请的数据,防止出现全量复制,具体配置前面会细说。
  • 主从复制是主动的,不须要用户干涉。

masterauth

如果以后节点是 slave,且 master 节点配置了 requirepass 参数设置了明码,那么 slave 节点必须应用该参数配置为 master 的明码,否则 master 节点将回绝该 slave 节点的申请。

配置形式为 masterauth <master-password>

masteruser

在 6.0 以上版本,如果应用了我的 ACL 平安性能,只配置 masterauth 还不够。因为默认用户不能运行 PSYNC 命令或者主从复制所须要的其余命令。

这时候,最好配置一个专门用于主从复制的非凡用户,配置形式为 masteruser <username>

replica-serve-stale-data

MySQL:“当 slave 节点与 master 失去连贯,导致主从同步失败的时候,还能解决客户端申请么?”

slave 节点能够有以下两种行为来决定是否解决客户端申请。

  • 配置为 yes,slave 节点能够持续解决客户端申请,然而数据可能是旧的,因为新的没同步过去。也可能是空的,如果是第一次同步的话。
  • 配置为 no,slave 节点将返回谬误 MASTERDOWN Link with MASTER is down and replica-serve-stale-data is set to no给客户端。然而以下的指令还是能够执行:INFO, REPLICAOF, AUTH, SHUTDOWN, REPLCONF, ROLE, CONFIG, SUBSCRIBE,UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB, COMMAND, POST,HOST and LATENCY

我的默认配置是 replica-serve-stale-data yes

replica-read-only

这个配置用于管制 slave 实例是否接管写指令,在 2.6 版本后默认配置为 yes,示意 slave 节点只解决读申请,如果为 no 则可读可写。

我倡议放弃默认配置,让 slave 节点只作为正本实现高可用。想要进步写性能,应用集群模式横向拓展更好。

repl-diskless-sync

主从复制过程中,新退出的 slave 节点和 slave 节点重连后无奈进行增量同步,须要进行一次全量同步,master 节点会生成 RDB 内存快照文件传输给 slave 节点。

所以这个配置是用于管制传输方式的,传输方式有两种。

  • Disk-backed(磁盘备份):master 节点创立新过程将 RDB 内存快照文件写到磁盘,主过程逐渐将这个文件传输到不同 slave 节点。
  • Diskless(无盘备份):master 节点创立一个新过程间接把 RDB 内存快照内容写到 Socket,不会将 RDB 内存快照文件长久化到磁盘。

应用磁盘备份的形式,master 保留在磁盘的 RDB 内存快照文件能够让多个 slave 复用。

应用无盘备份的话,当 RDB 内存快照文件传输开始,如果以后有多个slave 节点与 master 建设连贯,我会应用并行传输的形式将 RDB 内容传输给多个节点。

默认的配置是 repl-diskless-sync yes,示意应用无盘备份。在磁盘速度很慢,而网络超快的状况下,无盘备份会更给力。如果网络很慢,有可能会呈现数据失落,举荐你改成 no。

repl-diskless-sync-delay

应用无盘复制的话,如果此刻有新的 slave 发动全量同步,须要期待之前的传输结束能力开启传输。

所以能够应用配置 repl-diskless-sync-delay 5 参数指定一个延迟时间,这个单位是秒,让 master 节点期待一会,让更多 slave 节点连贯再执行传输。

因为一旦开始传输,master 节点无奈响应新的 slave 节点的全量复制申请,只能在队列中期待下一次 RDB 内存快照传输。

想要敞开这个性能,设置为 0 即可。

repl-diskless-load

mastar 节点有两种形式传输 RDB,slave 节点也有两种形式加载 master 传输过去的 RDB 数据。

  • 传统形式:承受到数据后,先长久化到磁盘,再从磁盘加载 RDB 文件复原数据到内存中,这是传统形式。
  • diskless-load:从 Socket 中一边承受数据,一边解析,实现无盘化。

一共有三个取值可配置。

  • disabled:不应用 diskless-load 形式,即采纳磁盘化的传统形式。
  • on-empty-db:平安模式下应用 diskless-load(也就 slave 节点数据库为空的时候应用 diskless-load)。
  • swapdb:应用 diskless-load 形式加载,slave 节点会缓存一份以后数据库的数据,再清空数据库,接着进行 Socket 读取实现加载。缓存一份数据的目标是避免读取 Socket 失败。

须要留神的是,diskless-load 目前在试验阶段,因为 RDB 内存快照数据并没有长久化到磁盘,因而有可能造成数据失落;

另外,该模式会占用更多内存,可能会导致 OOM。

repl-ping-replica-period

默认配置repl-ping-replica-period 10 示意 slave 每 10 秒 PING 一次 master。

repl-timeout

很重要的一个参数,slave 与 master 之间的复制超时工夫,默认配置是repl-timeout 60,示意在 60 秒内 ping 不通,则断定超时。

超时蕴含以下三种状况。

  • slave 角度,全量同步期间,在 repl-timeout 工夫内没有收到 master 传输的 RDB 内存快照文件。
  • slave 角度,在 repl-timeout 工夫内没有收到 master 发送的数据包或者 ping。
  • master 角度,在 repl-timeout 工夫内没有收到 REPCONF ACK(复制偏移量 offset)确认信息。

当检测到超时,将会敞开 master 与 slave 之间的连贯,slave 会发动从新建设主从连贯的申请,对于内存数据比拟大的零碎,能够增大 repl-timeout 的值。

你须要留神的是,这个配置肯定要大于 repl-ping-replica-period的值,否则每次心跳监测都超时。

repl-disable-tcp-nodelay

当 slave 与 master 全量同步(slave 发送 psync/sync 指令给 master)实现后,后续的增量同步是否设置成 TCP_NODELAY

如果设置成 yes,master 将合并小的 TCP 包从而节俭带宽,然而会减少同步提早(40 ms),造成 master 与 slave 数据不统一;设置成 no,则 master 会立刻发送数据给 slave,没有提早。

默认配置 repl-disable-tcp-nodelay no

repl-backlog-size

设置主从复制积压缓冲区(backlog)容量大小,这是一个环形数组,失常主从同步不波及到 repl-backlog。当主从断开重连,repl-backlog 的作用就进去了

缓冲区用于寄存断连期间 master 承受的写申请数据,当主从断开重连,通常不须要执行全量同步,只须要将断连期间的局部数据传递到 slave 即可。

主从复制积压缓冲区越大,slave 能够接受的断连工夫越长。

默认配置是 repl-backlog-size 1mb,倡议依据每秒流量大小和断开重连工夫长,设置大一点,比方 128 mb。

repl-backlog-ttl

用于配置当 master 与 slave 断连多少秒之后,master 清空主从复制积压缓冲区(repl-backlog)。配置成 0,示意永远不清空。默认配置repl-backlog-ttl 3600

replica-priority

slave 优先级,这个配置是给哨兵应用的,当 master 节点挂掉,哨兵会抉择一个 priority 最小的 slave 节点作为新的 master,这个值越小没接越优先选中。

如果是 0,那意味着这个 slave 将不能选中成为 master,默认配置是 replica-priority 100

min-slaves-to-write 和 min-slaves-max-lag

这两个配置要一起设置才有意义,如果有一个配置成 0,示意敞开该个性。

先看默认配置含意。

min-replicas-to-write 3
min-replicas-max-lag 10

如果 master 发现超过 3 个 slave 节点连贯 master 提早大于 10 秒,那么 master 就进行接管客户端写申请。这么做的目标是为了尽可能保障主从数据一致性。

master 会记录每个 slave 最近一次发来 ping 的工夫,把握每个 slave 的运行状况。

tracking-table-max-keys

我在 Redis 6.0 版本,实现了服务端辅助实现客户端缓存的个性,须要追踪客户端有哪些 key。当某个 key 被批改,我须要把这个生效信息发送到对应的客户端将本地缓存生效,这个配置就是用于指定追踪表保留的最大 key 数量,一旦超过这个数量,即便这个 key 没有被批改,为了回收内存我也会强制这个 key 所在的客户端缓存值生效。

设置 0 示意不限度,须要留神的是,如果应用播送模式实现键追踪,则不须要额定内存,疏忽这个配置。

应用播送模式的有余就是与这个 key 无关的客户端也会收到生效音讯。

5.5.4 平安

正是因为我快的一塌糊涂,攻击者一秒钟能够尝试 100 万个明码,所以你应该应用十分强壮的明码。

ACL

ACL 日志的最大长度,默认配置 acllog-max-len 128 示意最大 128 mb。

另外,应用 aclfile /etc/redis/users.acl 配置 ACL 文件所在位置。

requirepass

以后 Redis 服务器的拜访明码,默认是不须要明码拜访,网络危险,必须设置,如 requirepass magebyte660设置明码为“magebyte666”。

maxclients

设置客户端同时连贯的最大数量,默认设置是 maxclients 10000。达到最大值,我将敞开客户端新的连贯,并发送一个 max number of clients reached 谬误给客户端。

5.5.5 内存治理

作为用内存保留数据的我,这部分的配置也相当重要。

maxmemory

设置应用内存最大字节,当内存达到限度,我将尝试依据配置的内存淘汰策略(参见 maxmemory-policy)删除一些 key。倡议你不要设置太大的内存,避免执行 RDB 内存快照文件或者 AOF 重写的时候因数据太大而阻塞过长时间。

举荐最大设置为 maxmemory 6GB

如果淘汰策略是 noeviction,当收到写申请,我将回复谬误给客户端,读申请仍然能够执行。

如果你把我当做一个 LRU 或 LFU 缓存零碎的时候,那请用心关注以下配置。

maxmemory-policy

设置内存淘汰策略,定义当内存满时如何淘汰 key,默认配置是 noeviction

  • volatile-lru -> 在设置过期工夫的 key 中应用近似 LRU 驱赶。
  • allkeys-lru -> 在所有 key 中应用近似 LRU 驱赶。
  • volatile-lfu -> 在过期 key 中应用近似 LFU 驱赶。
  • allkeys-lfu -> 在所有 key 中应用近似 LFU。
  • volatile-random -> 在设置了过期工夫的 key 中随机删除一个。
  • allkeys-random -> 在所有的 key 中随机删除一个。
  • volatile-ttl -> 谁快过期就删谁。
  • noeviction -> 不删除任何 key,内存满了间接返回报错。

maxmemory-samples

LRU, LFU and minimal TTL algorithms 不是准确的算法,是一个近似的算法(次要为了节俭内存)。

所以须要你本人衡量速度和精确度。默认会抽取 5 个 key,抉择一个最近起码应用的 key 淘汰,你能够扭转这个数量。

默认的 5 能够提供不错的后果。配置 10 会十分靠近实在的 LRU 然而会消耗更多的 CPU,配置 3 会更快,然而就不那么准确了。

replica-ignore-maxmemory

从 Redis 5.0 开始,默认状况下 slave 节点会疏忽 maxmemory 配置,除非在故障转移后或手动将其晋升为 master。这意味着只有 master 才会执行内存淘汰策略 ,当 master 删除 key 后会发送 DEL 指令给 slave。

默认配置replica-ignore-maxmemory yes

active-expire-effort

我有两种形式删除过期数据。

  • 后盾周期性选取局部数据删除。
  • 惰性删除,当拜访申请到某个 key 的时候,发现该 key 曾经过期则删除。

这个配置用于指定过期 key 滞留在内存中的比例,默认值是 1,示意最多只能有 10 % 的过期 key 驻留在内存中,值设置的越小,那么一次淘汰周期内需须要耗费的 CPU 将会更多,因为须要删除更多的过期数据。

5.5.6 惰性开释

MySQL:“能够应用非阻塞的形式删除 bigkey 么?”

我提供了两种删除 key 的根本命令用于删除数据。

  • DEL 指令:这是一个阻塞的删除,执行该指令会进行解决写申请,应用同步的形式去回收 DEL 删除的对象的内存。如果这个 key 对应的 value 是一个十分小的对象,DEL 执行的工夫十分短,工夫复杂度为 O(1) 或者 O(log n)。如果 key 对应的 value 十分大,比方汇合对象的数据蕴含百万个元素,服务器将阻塞很长时间(几秒钟)能力实现操作。
  • UNLINK(非阻塞删除)、(异步删除) FLUSHALL ASYNC/FLUSHDB ASYNC:后盾回收内存,这些指令在常量级别工夫内执行,会应用一个新的线程在后盾渐进的删除并开释内存(Lazy Free 机制)。

lazyfree-lazy-eviction

因为 maxmemory 和 maxmemory-policy 策略配置,我会删除一些数据,避免内存爆掉。应用 lazyfree-lazy-eviction yes 示意应用 lazy free 机制,该场景开启 lazy free 可能会导致淘汰数据的内存开释不及时,呈现内存超限。

lazyfree-lazy-expire

对于设置了 TTL 的键,过期后删除。如果想启用 lazy free 机制删除,则配置 lazyfree-lazy-eviction yes

lazyfree-lazy-server-del

针对有些指令在解决已存在的键时,会带有一个隐式的 DEL 键的操作。

rename 命令,当指标键已存在,我会先删除指标键,如果这些指标键是一个 big key,那可能会呈现阻塞删除的性能问题。此参数设置就是解决这类问题,倡议配置 lazyfree-lazy-server-del yes 开启。

replica-lazy-flush

该配置针对 slave 进行全量数据同步,在加载 master 的 RDB 内存快照文件之前,会先运行 flashall清理数据的时候是否采纳异步 flush 机制。

举荐你应用 replica-lazy-flush yes配置,可缩小全量同步耗时,从而缩小 master 因输入缓冲区暴涨引起的内存增长。

lazyfree-lazy-user-del

意思是是否将 DEL 指令的默认行为替换成 lazy free 机制删除,成果就跟 UNLINK 一样,只有配置成 lazyfree-lazy-user-del yes

lazyfree-lazy-user-flush

FLUSHDB, FLUSHALL, SCRIPT FLUSH, FUNCTION FLUSH能够应用额定参数 ASYNC|SYNC 决定应用同步还是异步操作,当没有指定这个可选项,能够通过 lazyfree-lazy-user-flush yes 示意应用异步删除。

IO 多线程

大家晓得我是单线程模型解决读写申请,然而有一些操作能够应用其余线程解决,比方 UNLINK,I/O 读写操作。

在 6.0 版本,我提供了 I/O 多线程解决 Socket 读写,利用 I/O 多线程能够进步客户端 Socket 读写性能。

默认配置是敞开的,我只倡议当你的机器至多是 4 核 CPU 或者更多的状况启用,并且配置的线程数少于机器总 CPU 核数,配置超过 8 个线程对晋升没什么帮忙。

当你的机器是四核 CPU,那能够尝试配置应用 2~3 个 I/O 线程,如果是 8 核 CPU,个别只须要配置 6 个线程。

如下配置示意开启 I/O 线程组,线程组的 I/O 线程数量为 3。

io-threads-do-reads yes
io-threads 3

5.5.7 AOF 长久化

除了 RDB 内存快照文件作为长久化伎俩以外,还能应用 AOF(Append only file) 实现长久化,AOF 是一种可选的长久化策略提供更好数据安全性。

默认配置下,我最多只会失落一秒的数据,你甚至能够配置更高级别,最多只失落一次 write 操作,但这样会对损耗性能。

appendonly

appendonly yes 示意开启 AOF 长久化,能够同时开启 AOF 和 RDB 内存快照长久化,如果开启了 AOF,我会先加载 AOF 用于复原内存数据。

appendfilename

指定 AOF 文件名称,默认名字是 appendonly.aof。为了不便,你能够配置 appenddirname 指定 AOF 文件存储目录。

appendfsync

调用操作系统的 fsync()函数通知操作系统把输入缓冲区的数据长久化到磁盘,AOF 文件刷写的频率有三种。

  • no:不去被动调用 fsync(),让操作系统本人决定何时写磁盘。
  • always:每次 write 操作之后都调用 fsync(),十分慢,然而数据安全性最高。
  • everysec:每秒调用一次 fsync(),一个折中的策略,最多失落一秒的数据。

默认配置是 appendfsync everysec,举荐大家这么设置,兼顾了速度和数据安全。

no-appendfsync-on-rewrite

当 appendfsync 的配置设置成 always或者 everysec,当初有一个后盾 save 过程(可能是生成 RDB 内存快照的 bgsave 过程,也有可能是 AOF rewrite 过程)正在进行大量的磁盘 I/O 操作,会造成调用 fsync()执行太长,后续其余想要调用 fsync() 的过程就会阻塞。

为了缓解这个问题,能够应用以下配置 no-appendfsync-on-rewrite yes 示意当曾经有 bgsavebgrewriteaof 后盾过程在调用 fsync() 时,不再开启新过程执行 AOF 文件写入。

这样的话,就会呈现以后有子过程在做 bgsave 或者其余的磁盘操作时,我就无奈持续写 AOF 文件,这意味着可能会失落更多数据。

如果有提早问题,请将此选项改为 yes。否则将其保留为 no。从长久化的角度来看,no是最平安的抉择。

AOF 重写

为了避免 AOF 文件过大,antirez 大佬给我搞了个 AOF 重写机制。

auto-aof-rewrite-percentage 100 示意以后 AOF 文件大小超过上一次重写的 AOF 文件大小的百分之多少(如果没有执行过 AOF 重写,那就参照原始 AOF 文件大小),则执行 AOF 文件重写操作。

除了这个配置,你还要配置 auto-aof-rewrite-min-size 64mb 用于指定触发 AOF 重写操作的文件大小。

如果该 AOF 文件大小小于该值,即便文件增长比例达到 100%,我也不会触发 AOF 重写操作,这是为了避免 AOF 文件其实很小,然而满足增长百分比时的多余 AOF 重写操作。

如果配置为auto-aof-rewrite-percentage 0,示意禁用 AOF 重写性能,倡议大家开启 AOF 重写,避免文件过大。

aof-load-truncated

MySQL:如果 AOF 文件是损坏的,你还加载数据还原到内存中么?

加载 AOF 文件把数据还原到内存中,文件可能是损坏的,比方文件开端是谬误的。这种状况个别是因为宕机导致,尤其是应用 ext4 文件系统挂载时没配置 data=ordered 选项。

在这种状况下,我能够间接报错,或者尽可能的读取可读的 AOF 内容。

如果配置成 aof-load-truncated yes,我仍然会加载并读取这个损坏的 AOF 文件,并记录一个谬误日志告诉程序员。

配置成 aof-load-truncated no,我就会报错并回绝启动服务,你须要应用 redis-check-aof 工具修复 AOF 文件,再启动 Redis。如果修复后还是谬误,我仍然报错并回绝启动。

aof-use-rdb-preamble

这就是赫赫有名的 RDB-AOF 混合长久化性能,配置成 aof-use-rdb-preamble yes(必须先开启 AOF),AOF 重写生成的文件将同时蕴含 RDB 格局的内容和 AOF 格局内容。

混合长久化是在 AOF 重写实现的,开启混合长久化后,fork 出的子过程先将内存数据以 RDB 的形式写入 AOF 文件,接着把 RDB 格局数据写入 AOF 文件期间收到的增量命令从重写缓冲区以 AOF 格局写到文件中。

写入实现后告诉主过程更新统计信息,并把含有 RDB 格局和 AOF 格局的 AOF 文件替换旧的 AOF 文件。

这样的益处是能够联合 RDB 和 AOF 的长处,实现疾速加载同时防止失落过多数据,毛病是 AOF 文件的 RDB 局部内容不是 AOF 格局,可读性差(都是程序解析读取,哪个傻瓜程序员去读这个呀),强烈推荐你应用这个来保障长久化。

aof-timestamp-enabled

我在 7.0 版本新增的个性,大体就是讲 AOF 当初反对工夫戳了,你能够做到基于工夫点来复原数据。

默认是是 aof-timestamp-enabled no 示意敞开该个性,你能够依照理论需要抉择开启。

5.5.7 Cluster 集群

Redis Cluster 集群相干配置,应用集群形式的你必须器重和通晓。别嘴上原理说的有条有理,而集群有哪些配置?如何配置让集群快到飞起,实现真正的高可用却一头雾水,通过上面这些配置详解也让你对集群原理更加粗浅。

cluster-enabled

一般的 Redis 实例是不能成为集群的一员,想要将该节点退出 Redis Cluster,须要设置 cluster-enabled yes

cluster-config-file

cluster-config-file nodes-6379.conf 指定集群中的每个节点文件。

集群中的每个节点都有一个配置文件,这个文件并不是让程序员编辑的,是我本人创立和更新的,每个节点都要应用不同的配置文件,肯定要确保同一个集群中的不同节点应用的是不同的文件。

cluster-node-timeout

设置集群节点不可用的最大超时工夫,节点生效检测。集群中当一个节点向另一个节点发送 PING 命令,然而指标节点未在给定的时限内返回 PING 命令的回复时,那么发送命令的节点会将指标节点标记为 PFAIL(possible failuer,可能已生效);

如果 master 节点超过这个工夫还是无响应,则用它的从节点将启动故障迁徙,升级成主节点。

默认配置是 cluster-node-timeout 15000,单位是毫秒数。

cluster-port

该端口是集群总线监听 TCP 连贯的端口,默认配置为 cluster-port 0,我就会把端口绑定为客户端命令端口 + 10000(客户端端口默认 6379,所以绑定为 16379 作为集群总线端口)。每个 Redis Cluster 节点都须要凋谢两个端口:

  • 一个用于服务于客户端的 TCP 端口,比方 6379.
  • 另一个称为集群总线端口,节点应用集群总线进行故障监测、配置更新、故障转移等。客户端不要与集群总线端口通信,另外请确保在防火墙关上这两个端口,否则 Redis 集群之间将无奈通信

cluster-replica-validity-factor

该配置用于决定当 Redis Cluster 集群中,一个 master 宕机后,如何抉择一个 slave 节点实现故障转移主动复原(failover)。如果设置为 0,则不论 slave 与 master 之间断开多久,都有资格成为 master。

上面提供了两种形式来评估 slave 的数据是否太旧。

  • 如果有多个 slave 能够 failover,他们之间会通过替换信息选出领有领有最大复制 offset 的 slave 节点。
  • 每个 slave 节点计算上次与 master 节点交互的工夫,这个交互蕴含最初一次 ping 操作、master 节点传输过去的写指令、上次与 master 断开的工夫等。如果上次交互的工夫过来很久,那么这个节点就不会发动 failover。

针对第二点,交互工夫能够通过配置定义,如果 slave 与 master 上次交互的工夫大于 (node-timeout * cluster-replica-validity-factor) + repl-ping-replica-period,该 slave 就不会产生 failover。

例如,`node-timeout = 30秒,cluster-replica-validity-factor=10repl-ping-slave-period=10秒,示意 slave 节点与 master 节点上次交互工夫曾经过来了 310 秒,那么 slave 节点就不会做 failover。

调大 cluster-replica-validity-factor 则容许存储过旧数据的 slave 节点晋升为 master,调小的话可能会导致没有 slave 节点能够升为 master 节点。

思考高可用,倡议大家设置为 cluster-replica-validity-factor 0

cluster-migration-barrier

没有 slave 节点的 master 节点称为孤儿 master 节点,这个配置就是用于防止出现孤儿 master。

当某个 master 的 slave 节点宕机后,集群会从其余 master 中选出一个充裕的 slave 节点迁徙过去,确保每个 master 节点至多有一个 slave 节点,避免当孤立 master 节点宕机时,没有 slave 节点能够升为 master 导致集群不可用。

默认配置为 cluster-migration-barrier 1,是一个迁徙临界值。

含意是:被迁徙的 master 节点至多还有 1 个 slave 节点能力做迁徙操作。比方 master A 节点有 2 个以上 slave 节点,当集群呈现孤儿 master B 节点时,A 节点充裕的 slave 节点能够迁徙到 master B 节点上。

生产环境倡议维持默认值,最大可能保障高可用,设置为十分大的值或者配置 cluster-allow-replica-migration no 禁用主动迁徙性能。

cluster-allow-replica-migration 默认配置为 yes,示意容许主动迁徙。

cluster-require-full-coverage

默认配置是 yes,示意为当 redis cluster 发现还有哈希槽没有被调配时禁止查问操作。

这就会导致集群局部宕机,整个集群就不可用了,当所有哈希槽都有调配,集群会主动变为可用状态。

如果你心愿 cluster 的子集仍然可用,配置成 cluster-require-full-coverage no

cluster-replica-no-failover

当配置成 yes,在 master 宕机时,slave 不会做故障转移升为 master。

这个配置在多数据中心的状况下会很有用,你可能心愿某个数据中心永远不要降级为 master 节点,否则 master 节点就漂移到其余数据中心了,失常状况设置成 no。

cluster-allow-reads-when-down

默认是 no,示意当集群因主节点数量达不到最小值或者哈希槽没有齐全调配而被标记为生效时,节点将进行所有客户端申请。

设置成 yes,则容许集群生效的状况下仍然可从节点中读取数据,保障了高可用。

cluster-allow-pubsubshard-when-down

配置成 yes,示意当集群因主节点数量达不到最小值或者哈希槽没有齐全调配而被标记为生效时,pub/sub 仍然能够失常运行。

cluster-link-sendbuf-limit

设置每个集群总线连贯的发送字节缓冲区的内存应用限度,超过限度缓冲区将被清空(次要为了避免发送缓冲区发送给慢速连贯时有限延长时间的问题)。

默认禁用,倡议最小设置 1gb,这样默认状况下集群连贯缓冲区能够包容至多一条 pubsub 音讯(client-query-buffer-limit 默认是 1gb);

5.5.8 性能监控

慢查问日志

慢查问(Slow Log)日志是我用于记录慢查问执行工夫的日志零碎,只有查问超过配置的工夫,都会记录。slowlog 只保留在内存中,因而效率很高,大家不必放心会影响到 Redis 的性能。

执行工夫不包含 I/O 操作的工夫,比方与客户端建设连贯、发送回复等,只记录执行命令执行阶段所须要的工夫。

你能够应用两个参数配置慢查问日志零碎。

  • slowlog-log-slower-than:指定对执行工夫大于多少微秒(microsecond,1 秒 = 1,000,000 微秒)的查问进行记录,默认是 10000 奥妙,举荐你先执行基线测试失去一个基准工夫,通常这个值能够设置为基线性能最大提早的 3 倍。
  • slowlog-max-len:设定最多保留多少条慢查问的日志,slowlog 自身是一个 FIFO 队列,当超过设定的最大值后,我会把最旧的一条日志删除。默认配置 128,如果设置太大会占用多大内存。

提早监控

提早监控(LATENCY MONITOR)零碎会在运行时抽样局部命令来帮忙你剖析 Redis 卡顿的起因。

通过 LATENCY命令,能够打印一些视图和报告,零碎只会记录大于等于指定值的命令。

默认配置 latency-monitor-threshold 0,设置 0 示意敞开这个性能。没有提早问题,没必要开启开启监控,因为会对性能造成很大影响。

在运行过程中你狐疑有提早性能问题,想要监控的话能够应用 CONFIG SET latency-monitor-threshold <milliseconds>开启,单位是毫秒。

5.5.9 高级设置

这部分配置次要围绕以下几个方面。

  • 指定不同数据类型依据不同条数下应用不同的数据结构存储,合理配置能做到更快和更省内存。
  • 客户端缓冲区相干配置。
  • 渐进式 rehash 资源管制。
  • LFU 调优。
  • RDB 内存快照文件、AOF 文件同步策略。

Hashes(散列表)

在 Redis 7.0 版本散列表数据类型有两种数据结构保留数据,别离为散列表和 listpack。当数据量很小时,能够应用更高效的数据结构存储,从而达到在不影响性能的状况下节俭内存。

  • hash-max-listpack-entries 512:指定应用 listpack 存储的最大条目数。
  • hash-max-listpack-value 64:listpack 中,条目 value 值最大字节数,倡议设置成 1024。

在 7.0 版本以前,应用的是 ziplist 数据结构,配置如下。

hash-max-ziplist-entries 512
hash-max-ziplist-value 64

Lists(列表)

Lists 也能够应用一种非凡形式进行编码来节俭大量内存空间。在 Redis 7.0 之后,Lits 底层的数据结构应用 linkedlist 或者 listpack。

Redis 3.2 版本,List 外部是通过 linkedlist 和 quicklist 实现,quicklist 是一个双向链表,quicklist 的每个节点都是一个 ziplist,从而实现节俭内存。

元素少时用 quicklist,元素多时用 linkedlist。listpack 的目标就是用于代替 ziplist 和 quicklist。listpack 也叫 紧凑列表,它的特点就是用一块间断的内存空间来紧凑地保留数据,同时为了节俭内存空间

list-max-ziplist-size

7.0 版本之前 list-max-ziplist-size 用于配置 quicklist 中的每个节点的 ziplist 的大小。当这个值配置 为负数时示意 quicklist 每个节点的 ziplist 最多可存储元素数量,超过该值就会应用 linkedlist 存储。

list-max-ziplist-size 为正数时示意限度每个 quicklistNode 的 ziplist 的内存大小,超过这个大小就会应用 linkedlist 存储数据,每个值有以下含意:

  • -5:每个 quicklist 节点上的 ziplist 大小最大 64 kb <— 失常环境不举荐
  • -4:每个 quicklist 节点上的 ziplist 大小最大 32 kb <— 不举荐
  • -3:每个 quicklist 节点上的 ziplist 大小最大 16 kb <— 可能不举荐
  • -2:每个 quicklist 节点上的 ziplist 大小最大 8 kb <— 不错
  • -1:每个 quicklist 节点上的 ziplist 大小最大 4kb <— 不错

默认值为 -2,也是官网最举荐的值,当然你能够依据本人的理论状况进行批改。

list-max-listpack-size

7.0 之后,配置批改为 list-max-listpack-size -2 则示意限度每个 listpack 大小,不再赘述。

list-compress-depth

压缩深度配置,用来配置压缩 Lists 的,当 Lists 底层应用 linkedlist 也是能够压缩的,默认是 list-compress-depth 0示意不压缩。个别状况下,Lists 的两端拜访的频率高一些,所以你能够思考把两头的数据进行压缩。

不同参数值的含意如下。

  • 0,敞开压缩,默认值。
  • 1,两端各有一个节点不压缩。
  • 2,两端各有两个节点不压缩。
  • N,顺次类推,两端各有 N 个节点不压缩。

须要留神的是,head 和 tail 节点永远都不会被压缩。

Sets(无序汇合)

Sets 底层的数据结构能够是 intset(整形数组)和 Hashtable(散列表),intset 你能够了解成数组,Hashtable 就是一般的散列表(key 存的是 Sets 的值,value 为 null)。有没有感觉 Sets 应用散列表存储是意想不到的事件?

set-max-intset-entries

当汇合的元素都是 64 位以内的十进制整数时且长度不超过 set-max-intset-entries 配置的值(默认 512),Sets 的底层会应用 intset 存储节俭内存。增加的元素大于 set-max-intset-entries配置的值,底层实现由 intset 转成散列表存储。

SortedSets(有序汇合)

在 Redis 7.0 版本之前,有序汇合底层的数据结构有 ziplist 和 skipist,之后应用 listpack 代替了 ziplist。

7.0 版本之前,当汇合元素个数小于 zset-max-ziplist-entries配置,同时且每个元素的值大小都小于 zset-max-ziplist-value 配置(默认 64 字节,举荐调大到 128)时,我将应用 ziplist 数据结构存储数据,无效缩小内存应用。与此相似,7.0 版本之后我将应用 listpack 存储。

## 7.0 之前的配置
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
## 7.0 之后的配置
zset-max-listpack-entries 128
zset-max-listpack-value 64

HyperLogLog

HyperLogLog 是一种高级数据结构,统计基数的利器。HyperLogLog 的存储构造分为密集存储构造和稠密存储构造两种,默认为稠密存储构造,而咱们常说的占用 12K 内存的则是密集存储构造,稠密构造占用的内存会更小。

hll-sparse-max-bytes

默认配置是 hll-sparse-max-bytes 3000,单位是 Byte,这个配置用于决定存储数据应用稠密数据结构(sparse)还是浓密数据结构(dense)。

如果 HyperLogLog 存储内容大小大于 hll-sparse-max-bytes 配置的值将会转换成浓密的数据结构(dense)。

举荐的值是 0~3000,这样 PFADD 命令的并不会慢多少,还能节俭空间。如果内存空间绝对 cpu 资源更不足,能够将这个值晋升到 10000。

Streams(流)

Stream 是 Redis 5.0 版本新增的数据类型。Redis Streams 是一些由基数树(Radix Tree)连贯在一起的节点通过 delta 压缩后形成的,这些节点与 Stream 中的音讯条目(Stream Entry)并非一一对应,而是 每个节点中都存储着若干 Stream 条目,因而这些节点也被称为宏节点或大节点。

stream-node-max-bytes 4096

单位为 Byte,默认值 4096,用于设定每个宏节点占用的内存下限为 4096,0 示意无限度。

stream-node-max-entries 100

用于设定每个宏节点存储元素个数。默认值 100,0 示意无限度。当一个宏节点存储的 Stream 条目达到下限,新增加的条目会存储到新的宏节点中。

rehash

我采纳的是渐进式 rehash,这是一个惰性策略,不会一次性把所有数据迁徙完,而是扩散到每次申请中,这样做的目标是避免数据太多要迁徙阻塞主线程。

在渐进式 rehash 的同时,举荐你应用 activerehashing yes开启定时辅助执行 rehash,默认状况下每一秒执行 10 次 rehash 放慢迁徙速度,尽可能开释内存。

敞开该性能的话,如果这些 key 不再沉闷不被被拜访到,rehash 操作可能不再有机会实现,会导致散列表占用更多内存。

客户端输入缓冲区限度

这三个配置是用来强制断开客户端连贯的,当客户端没有及时把缓冲区的数据读取结束,我会认为这个客户端可能完蛋了(一个常见的起因是 Pub/Sub 客户端解决发布者的音讯不够快),于是断开连接。

一共分为三种不同类型的客户端,别离设置不同的限度。

  • normal(一般),一般客户端,包含 MONITOR 客户端。
  • replica(正本客户端),slave 节点的客户端。
  • pubsub(公布订阅客户端),至多订阅了一个 pubsub 频道或者模式的客户端。

client-output-buffer-limit的语法如下。

client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>

<class> 示意不同类型的客户端,当客户端的缓冲区内容大小达到 <hard limit> 后我就立马断开与这个客户端的连贯,或者达到 <soft limit> 并继续了 <soft seconds> 秒后断开。

默认状况下,一般客户端不会限度,只有后异步的客户端才可能发送发送申请的速度比读取响应速度快的问题。比方 pubsub 和 replica 客户端会有默认的限度。

soft limit 或者 hard limit 设置为 0,示意不启用此限度。默认配置如下。

client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60

client-query-buffer-limit

每个客户端都有一个 query buffer(查问缓冲区或输出缓冲区),用于保留客户端发送命令,Redis Server 从 query buffer 获取命令并执行。

如果程序的 Key 设计不合理,客户端应用大量的 query buffer,导致 Redis 很容易达到 maxmeory 限度。最好限度在一个固定的大小来防止占用过大内存的问题。

如果你须要发送微小的 multi/exec 申请的时候,那能够适当批改这个值以满足你的非凡需要。

默认配置为 client-query-buffer-limit 1gb

maxmemory-clients

这是 7.0 版本个性,每个与服务端建设连贯的客户端都会占用内存(查问缓冲区、输入缓冲区和其余缓冲区),大量的客户端可能会占用过大内存导致 OOM,为了防止这个状况,我提供了一种叫做(Client Eviction)客户端驱赶机制用于限度内存占用。

配置形式有两种。

  • 具体内存值,maxmemory-clients 1g来限度所有客户端占用内存总和。
  • 百分比,maxmemory-clients 5% 示意客户端总和内存占用最多为 Redis 最大内存配置的 5%。

默认配置是 maxmemory-clients 0 示意无限度。

MySQL:“达到最大内存限度,你会把所有客户端连贯都开释么?”

不是的,一旦达到限度,我会优先尝试断开应用内存最多的客户端。

proto-max-bulk-len

批量申请(单个字符串的元素)内存大小限度,默认是 proto-max-bulk-len 512mb,你能够批改限度,但必须大于等于 1mb。

hz

我会在后盾调用一些函数来执行很多后台任务,比方敞开超时连贯,清理不再被申请的过期的 key,rehash、执行 RDB 内存快照和 AOF 长久化等。

并不是所有的后台任务都须要应用雷同的频率来执行,你能够应用 hz 参数来决定执行这些工作的频率。

默认配置是 hz 10,示意每秒执行 10 次,更大的值会耗费更多的 CPU 来解决后台任务,带来的成果就是更快的清理过期 key,清理的超时连贯更准确。

这个值的范畴是 1~500,不过并不举荐设置大于 100 的值。大家应用默认值就好,或者最多调高到 100。

dynamic-hz

默认配置是 dynamic-hz yes,启用 dynamic-hz 后,将启用自适应 HZ 值的能力。hz 的配置值将会作为基线,Redis 服务中的理论 hz 值会在基线值的根底上依据已连贯到 Redis 的客户端数量主动调整,连贯的客户端越多,理论 hz 值越高,Redis 执行定期工作的频率就越高。

aof-rewrite-incremental-fsync

当子过程进行 AOF 重写时,如果配置成 aof-rewrite-incremental-fsync yes,每生成 4 MB 数据就执行一次 fsync操作,分批提交到硬盘来防止高提早峰值,举荐开启。

rdb-save-incremental-fsync

当我在保留 RDB 内存快照文件时,如果配置成 db-save-incremental-fsync yes,每生成 4MB 文件就执行一次 fsync操作,分批提交到硬盘来防止高提早峰值,举荐开启。

LFU 调优

这个配置失效的前提是内存淘汰策略设置的是 volatile-lfuallkeys-lfu

  • lfu-log-factor 用于调整 Logistic Counter 的增长速度,lfu-log-factor 值越大,Logistic Counter 增长越慢。默认配置 10。

    以下是表格是官网不同 factor 配置下,计数器的扭转频率。留神:表格是通过如下命令取得的:redis-benchmark -n 1000000 incr foo redis-cli object freq foo

    factor 100 hits 1000 hits 100K hits 1M hits 10M hits
    0 104 255 255 255 255
    1 18 49 255 255 255
    10 10 18 142 255 255
    100 8 11 49 143 255
  • lfu-decay-time 用于调整 Logistic Counter 的衰减速度,它是一个以分钟为单位的数值,默认值为 1;lfu-decay-time 值越大,衰减越慢。

5.5.9 在线内存碎片整顿

MySQL:“什么是在线内存碎片整顿?”

Active (online) defragmentation 在线内存碎片整顿指的是主动压缩内存分配器调配和 Redis 频繁做更新操作、大量过期数据删除,开释的空间(不够间断)无奈失去复用的内存空间。

通常来说当碎片化达到肯定水平(查看上面的配置)Redis 会应用 Jemalloc 的个性创立间断的内存空间,并在此内存空间对现有的值进行拷贝,拷贝实现后会开释掉旧的数据。这个过程会对所有的导致碎片化的 key 以增量的模式进行。

须要留神的是

  1. 这个性能默认是敞开的,并且只有在编译 Redis 时应用咱们代码中的 Jemalloc 版本才失效。(这是 Linux 下的默认行为)。
  2. 在理论应用中,倡议是在 Redis 服务呈现较多的内存碎片时启用(内存碎片率大于 1.5),失常状况下尽量放弃禁用状态。
  3. 如果你须要试验这项个性,能够通过命令 CONFIG SET activefrag yes来启用。

清理的条件

activefrag yes:内存碎片整顿总开关,默认为禁用状态 no。

active-defrag-ignore-bytes 200mb:内存碎片占用的内存达到 200MB。

active-defrag-threshold-lower 20:内存碎片的空间占比超过零碎调配给 Redis 空间的 20%。

在同时满足下面三项配置时,内存碎片主动整顿性能才会启用。

CPU 资源占用

MySQL:如何防止主动内存碎片整顿对性能造成影响?

清理的条件有了,还须要调配清理碎片占用的 CPU 资源,保障既能失常清理碎片,又能防止对 Redis 解决申请的性能影响。

active-defrag-cycle-min 5:主动清理过程中,占用 CPU 工夫的比例不低于 5%,从而保障能失常开展清理工作。

active-defrag-cycle-max 20:主动清理过程占用的 CPU 工夫比例不能高于 20%,超过的话就立即进行清理,防止对 Redis 的阻塞,造成高提早。

整顿力度

active-defrag-max-scan-fields 1000:碎片整顿扫描到 set/hash/zset/list 时,仅当 set/hash/zset/list 的长度小于此阀值时,才会将此键值对退出碎片整顿,大于这个值的键值对会放在一个列表中提早解决。

active-defrag-threshold-upper 100:内存碎片空间占操作系统调配给 Redis 的总空间比例达此阈值(默认 100%),我会尽最大致力整顿碎片。倡议你调整为 80。

jemalloc-bg-thread

默认配置为 jemalloc-bg-thread yes,示意启用革除脏页后盾线程。

绑定 CPU

你能够将 Redis 的不同线程和过程绑定到特定的 CPU,缩小上下文切换,进步 CPU L1、L2 Cache 命中率,实现最大化的性能。

你能够通过批改配置文件或者 taskset 命令绑定。

可分为三个模块。

  • 主线程和 I/O 线程:负责命令读取、解析、后果返回。命令执行由主线程实现。
  • bio 线程:负责执行耗时的异步工作,如 close fd、AOF fsync 等。
  • 后盾过程:fork 子过程(RDB bgsave、AOF rewrite bgrewriteaof)来执行耗时的命令。

Redis 反对别离配置上述模块的 CPU 亲合度,默认状况是敞开的。

  • server_cpulist 0-7:2,I/O 线程(蕴含主线程)相干操作绑定到 CPU 0、2、4、6。
  • bio_cpulist 1,3,bio 线程相干的操作绑定到 CPU 1、3。
  • aof_rewrite_cpulist,aof rewrite 后盾过程绑定到 CPU 8、9、10、11。
  • bgsave_cpulist 1,10-11,bgsave 后盾过程绑定到 CPU 1、10、11。

注意事项

  1. Linux 下,应用 「numactl –hardware」 查看硬件布局,确保反对并开启 NUMA。
  2. 线程要尽可能散布在 不同的 CPU,雷同的 node,设置 CPU 亲和度才无效,否则会造成频繁上下文切换。
  3. 你要相熟 CPU 架构,做好充沛的测试。否则可能事与愿违,导致 Redis 性能降落。
正文完
 0