当前位置:首页-文章-行业新闻-正文

redis.conf 7.0 配置和原理全解,生产王者必备

5.5 redis.conf 配置详解 我是 Redis, 当程序员用指令 ./redis-server /path/to/redis.conf 把我启动的时候,第一个参数必须是redis.conf 文件的路径。 这个文件很重要,就好像是你们的 DNA,它能控制我的运行情况,不同的配置会有不同的特性

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 内容传输给多个节点