Featured image of post redis配置详讲

redis配置详讲

本文阅读量

概述

本文主要描述了 Redis 各个配置项的作用以及可能的取值,主要针对 Redis 6.24 版本,不同版本的选项会有所不同。

文件配置

include 选项

Redis 支持通过 include 选项来载入其他配置文件

1
# include /path/to/local.conf

模块 选项

Redis 可以通过 loadmodule 选项在启动时加载模块,若服务端无法加载模块,服务端会停止。 可以通过多个 loadmodule 选项加载多个模块

1
2
# loadmodule /path/to/my_module.so
# loadmodule /path/to/other_module.so

网络 选项

bind

bind 选项用于设置监听的 network interface,不设置这个选项相当于 bind 0.0.0.0,可以通过这个选项监听多个 network interface。当设置多个 bind 地址后,Redis 内部会维护多个 Socket,每个 Socket 用于一个 network interface

1
# bind 192.168.1.100 10.0.0.1

protected-mode

开启此选项后, 当 Redis 服务端未使用 bind 选项显式指定要监听的 network interface,并且未设置密码, Redis 服务端只会接受来自 127.0.0.1 和 ::1 的客户端以及 Unix 域的 Socket 进行连接

1
protected-mode yes

port

port 选项用于设置 Redis 监听的 TCP 端口,默认为 6379,设置为 0 表示不监听 TCP 端口

1
port 6379

tcp-backlog

tcp-backlog 用于设置 TCP 连接的排队队列长度,最终就是影响到 listen 接口的 backlog 参数

1
tcp-backlog 511

unixsocket 和 unixsocketperm

unixsocket 和 unixsocketperm 用于设置 Unix 域套接字,默认不开启

1
2
# unixsocket /var/run/redis/redis.sock
# unixsocketperm 700

timeout

当客户端空闲 timeout 秒后,Redis 服务端主动关闭此连接, 0 表示不启用此功能

1
timeout 0

tcp-keepalive

tcp-keepalive设置为非 0 值表示启用协议层的心跳检测功能,此功能是通过 setsockopt 的 SO_KEEPALIVE 选项开启的

1
tcp-keepalive 300

TLS/SSL 选项

通用 选项

daemonize

设置 daemonize 选项为 yes 会使 Redis 以守护进程模式启动,在此模式下,Redis 默认会将 pid 写入 /var/run/redis.pid。 可以通过 pidfile 选项修改写入的文件

1
2
daemonize yes
pidfile /var/run/redis/redis-server.pid

supervised

当你通过 upstart 或者 systemd 运行 Redis 时,Redis 可以和你的 supervision tree 进行交互,可选的选项为:

  • no 无交互
  • upstart 通过向 Redis 发送 SIGSTOP 信号来通知 upstart
  • systemd 通过向 $NOTIFY_SOCKET 写入 READY=1 来通知 systemd
  • auto 通过是否设置了 UPSTART_JOB 或者 NOTIFY_SOCKET 环境变量来决定选项为 upstart 或者 systemd
1
supervised no

loglevel

日志级别,可以设置为: debug、verbose、notice、warning 中的一个。

1
loglevel notice

logfile

logfile 选项用于设置日志输出的路径,若没有设置此路径,则 Redis 会将日志输出到标准输出,若以守护进程模式启动则输出到 /dev/null

1
logfile /var/log/redis/redis-server.log

syslog

1
2
3
syslog-enabled no #是否将日志输出到 syslog
syslog-ident redis  # 对应了系统接口 openlog 的 ident 选项
syslog-facility local0  # 对应了系统接口 openlog 的  facility 选项,设置返回值local0-local7

database

Redis 的数据库个数,当你连接到 Redis 服务器时,默认会选中 0 号数据库,可以通过 SELECT num 命令,选择要使用的数据库(num 表示 0 到 此选项的值减 1 的数据库)

1
databases 16

always-show-logo

默认情况下,Redis 只会在交互模式才显示 ASCII 版本的 logo,可以通过设置此选项为 yes,使 Redis 在任何情况下都显示 logo,使得 Redis 的此行为和 4.0 之前的版本行为保持一致

1
always-show-logo yes

快照 选项

save

save 选项用于设置 Redis 将数据库持久化到硬盘的时间,可以有多个 save 选项。 save 后面的第一个数字表示多少秒进行一次检查,第二个数字表示此时间内有多少个 key 被改变会将数据库持久化到硬盘。

1
2
3
4
5
6
save 900 1         #900s内,如果至少有一个key进行了修改,我们就进行持久化操作
save 300 10        #300s内,如果至少有10个key进行了修改,我们就进行持久化操作
save 60 10000      #60s内,如果至少有10000个key进行了修改,我们就进行持久化操作


dir ./ #rdb持久化保存目录

stop-writes-on-bgsave-error

当最近一次的持久化操作失败后,Redis 会拒绝客户端的写入操作,通过这种行为客户端会知道服务端的不正常现象。 若持久化操作可以正常工作后,服务端会自动允许客户端的写入操作。 如果你自己有 Redis 服务端的监控方案,或者你希望即使持久化失败 Redis 也可以正常工作,则可以将此选项设置为 no

1
stop-writes-on-bgsave-error yes #持久化如果出错了,是否还需要继续工作!

rdbcompression

设置为 yes 表示使用 LZO 算法压缩持久化到硬盘的 string 对象,需要消耗一些cpu资源!

1
rdbcompression yes

rdbchecksum

保存rdb文件的时候,运行错误的时候是否检查校验!

1
rdbchecksum yes

dbfilename

RDB 文件的文件名

1
dbfilename dump.rdb

rdb-del-sync-files

rdb文件是否删除同步锁

1
rdb-del-sync-files no

dir

Redis 的工作目录,RDB 和 AOF文件会保存到此目录

1
dir ./

REPLICATION

replicaof

通过 replicaof (即以前的 slaveof)选项可以将 Redis 实例设置为其他 Redis 服务端的副本

关于 Redis 的复制,有以下几点需要注意:

  • Redis 复制是异步的,但是你可以设置 master 节点,使得 master 节点至少要和指定数量的 replicas 节点连接才提供写服务
  • 当 Redis replicas 节点和 master 节点短暂断开后,replicas 节点可以向 master 节点要求进行部分数据的重传
  • 复制是自动的,不需要用户干预,当发生网络分区后,replicas 节点会自动尝试和 master 节点重连以及进行数据同步
1
replicaof 主节点ip 主节点端口

masterauth

当 master 节点使用了 “requirepass” 选项后,replicas 节点需要配置此选项

1
masterauth <master-password>

masteruser

1
masteruser <username>

replica-serve-stale-data

此选项为以前的 slave-serve-stale-data,replicas 节点和 master 节点断开连接后,replicas 节点根据 replica-serve-stale-data 选项的配置可能有以下行为:

  • 选项设置为 yes(默认值),replicas 节点会继续向客户端提供服务,此时返回给客户端的数据很可能是过期的
  • 选项设置为 no,除了 INFO, replicaOF, AUTH, PING, SHUTDOWN, REPLCONF, ROLE, CONFIG, SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB, COMMAND, POST, HOST, 和 LATENCY 命令外的其他命令,replicas 节点都会返回 “SYNC with master in progress” 给客户端
1
replica-serve-stale-data yes

replica-read-only

设置 replicas 节点是否只读,从 Redis 2.6 开始此选项的默认值为 yes。 需要注意的是只读的 replicas 节点并没有设计为会暴露给网络上不受信任的客户端使用的。 你需要对其进行保护以防实例被滥用。并且只读的 replicas 节点导出了所有如 CONFIG,DEBUG,等管理命令。 你可以使用 ‘rename-command’ 将所有管理/危险 命令进行映射以提高安全性

1
replica-read-only yes

repl-diskless-sync

是否使用socket方式复制数据。目前redis复制提供两种方式,disk和socket。如果新的slave连上来或者重连的slave无法部分同步,就会执行全量同步,master会生成rdb文件。有2种方式:disk方式是master创建一个新的进程把rdb文件保存到磁盘,再把磁盘上的rdb文件传递给slave。socket是master创建一个新的进程,直接把rdb文件以socket的方式发给slave。disk方式的时候,当一个rdb保存的过程中,多个slave都能共享这个rdb文件。socket的方式就的一个个slave顺序复制。在磁盘速度缓慢,网速快的情况下推荐用socket方式

当一个不能续传或者新的 replicas 需要进行“全量同步”时。一个 RDB 文件需要由 master 传送到 replicas。 根据 repl-diskless-sync 选项的不同,RDB 文件有以下两种传输方式:

  1. Disk-backed:Redis master 节点创建一个新的进程并且将 RDB 文件写入磁盘。然后文件通过父进程传输给 replicas 节点
  2. Diskless:Redis master 节点一个新的进程并且直接将 RDB 文件写入到 replica 的 socket 中,不写到磁盘

当进行 disk-backed 复制时,当 RDB 文件生成完毕,多个 replicas 通过排队来同步 RDB 文件。 当进行 diskless 复制时,master 节点会等待一段时间再传输以期望会有多个 replicas 连接进来,这样 master 节点就可以同时同步到多个 replicas 节点

1
repl-diskless-sync no

repl-diskless-sync-delay

当启用 diskless 复制后,可以通过此选项设置 master 节点创建子进程前等待的时间,单位为秒

1
repl-diskless-sync-delay 5

repl-ping-replica-period

Replicas 发送 PING 到 master 的间隔,默认值为 10 秒

1
repl-ping-replica-period 10

repl-timeou

此选项用于设置以下情形的 timeout 判断:

  1. 从 replica 节点的角度来看的 SYNC 过程中的 I/O 传输
  2. 从 replica 节点的角度来看的 master 的 timeout(如 data,pings)
  3. 从 master 节点角度来看的 replica 的 timeout(如 REPLCONF ACK pings)

需要注意的是,此选项必须大于 repl-ping-replica-period,否则在低业务量的情况下会经常发生 timeout。

1
repl-timeout 60

repl-disable-tcp-nodelay

master 和 replicas 节点的连接是否关掉 TCP_NODELAY 选项。 这个实际影响的是 TCP 层的选项,里面会用 setsockopt 设置,默认为 no,表示 TCP 层会禁用 Nagle 算法,尽快将数据发出, 设置为 yes 表示 TCP 层启用 Nagle 算法,数据累积到一定程度,或者经过一定时间 TCP 层才会将其发出

1
repl-disable-tcp-nodelay no

repl-backlog-size

设置复制的 backlog 缓冲大小。当 replicas 节点断开重连后,如果断点发生时的数据还在 backlog 缓冲中, 则不需要全量同步,只需要部分同步。 更大的 backlog 缓冲大小,意味着 replicas 断开重连后,依然可以进行续传的时间越长(支持断开更长时间)。 backlog 缓冲只有在至少一个 replicas 节点连过来的时候 master 节点才需要创建

1
repl-backlog-size 1mb

repl-backlog-ttl

当 replicas 节点断开连接后,master 节点会在一段时间后释放 backlog 缓冲区。 这个选项设置的是当最后一个 replicas 断开链接后,master 需要等待多少秒再释放缓冲区。

需要注意的是 replicas 节点永远都不会释放这个缓冲区,因为它有可能再次连接到 master 节点, 然后尝试进行 “增量同步”

1
repl-backlog-ttl 3600

replica-priority

这是 replicas 节点通过 INFO 接口给出的信息,默认值为 100。 当 master 节点无法正常工作后 Redis Sentinel 通过这个值来决定将哪个 replicas 节点提升为 master 节点。

这个数值越小表示越优先进行提升。如有三个 replicas 节点其 priority 值分别为 10,100,25, Sentinel 会选择 priority 为 10 的节点进行提升。

这个值为 0 表示 replica 节点永远不能被提升为 master 节点

1
replica-priority 100

min-replicas-

用于设置至少有 N 个 replicas 节点延迟少于 M 秒时,master 节点才能进行写操作, 如上面的例子表示至少有 3 个 replicas 节点延迟少于 M 秒时,master 节点才能进行写操作。 将上面参数的任意一个设置为 0 表示不启用此功能,min-replicas-to-write 的默认值为 0,min-replicas-max-lag 的默认值为 10

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

replica-announce-

Redis master 可以通过不同方式列出连接上来的 replicas 节点的地址和端口。 如 Redis Sentinel 等会使用 “INFO replication” 命令来获取 replica 实例信息。 master 的 “ROLE“ 命令也会提供此信息。

这个信息一般来说是通过 replica 节点通过以下方式获取然后报告上来的:

  • IP:通过自动识别连接到 Socket 的信息自动获取
  • Port:一般来说这个值就是 replicas 节点用来接受客户端的连接的监听端口

但是,若启用了端口转发或者 NAT,可能需要其他地址和端口才能连接到 replicas 节点。 这种情况下,需要设置这两个选项,这样 replicas 就会用这两个选项设置的值覆盖默认行为获取的值,然后报告给 master 节点。 根据实际情况,你可以只设置其中某个选项,而不用两个选项都设置

1
2
replica-announce-ip 5.5.5.5
replica-announce-port 1234

KEYS TRACKING

tracking-table-max-keys

1
tracking-table-max-keys 1000000

SECURITY

acllog-max-len

1
acllog-max-len 128

aclfile

1
aclfile /etc/redis/users.acl

requirepass

设置此选项后,客户端需要使用 AUTH PASSWORD 命令进行认证后才能进行其他操作。 当你的服务器有可能被非信任的客户端访问到的时候这个命令是很有用的

注:由于 Redis 非常快,外部用户若进行暴力破解,每秒能尝试超过 150k 个密码。因此你需要使用强度非常高的密码才能保证密码不容易被暴力破解掉

1
requirepass foobared

rename-command

在共享环境下,可以通过 rename-command 命令将一些危险的命令进行重命名

1
2
3
4
5
# 将 CONFIG 命令重命名为难以猜测的命令
rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

# 通过将命令重命名为空字符串从而将其完全 ”kill“ 掉
rename-command CONFIG ""

注:rename-command 命令会被记录到日志和 AOF 文件中或者传输到 replicas 节点,而这可能会是一个安全问题。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# Warning: since Redis is pretty fast an outside user can try up to
# 1 million passwords per second against a modern box. This means that you
# should use very strong passwords, otherwise they will be very easy to break.
# Note that because the password is really a shared secret between the client
# and the server, and should not be memorized by any human, the password
# can be easily a long string from /dev/urandom or whatever, so by using a
# long and unguessable password no brute force attack will be possible.

# Redis ACL users are defined in the following format:
#
#   user <username> ... acl rules ...
#
# For example:
#
#   user worker +@list +@connection ~jobs:* on >ffa9203c493aa99
#
# The special username "default" is used for new connections. If this user
# has the "nopass" rule, then new connections will be immediately authenticated
# as the "default" user without the need of any password provided via the
# AUTH command. Otherwise if the "default" user is not flagged with "nopass"
# the connections will start in not authenticated state, and will require
# AUTH (or the HELLO command AUTH option) in order to be authenticated and
# start to work.
#
# The ACL rules that describe what an user can do are the following:
#
#  on           Enable the user: it is possible to authenticate as this user.
#  off          Disable the user: it's no longer possible to authenticate
#               with this user, however the already authenticated connections
#               will still work.
#  +<command>   Allow the execution of that command
#  -<command>   Disallow the execution of that command
#  +@<category> Allow the execution of all the commands in such category
#               with valid categories are like @admin, @set, @sortedset, ...
#               and so forth, see the full list in the server.c file where
#               the Redis command table is described and defined.
#               The special category @all means all the commands, but currently
#               present in the server, and that will be loaded in the future
#               via modules.
#  +<command>|subcommand    Allow a specific subcommand of an otherwise
#                           disabled command. Note that this form is not
#                           allowed as negative like -DEBUG|SEGFAULT, but
#                           only additive starting with "+".
#  allcommands  Alias for +@all. Note that it implies the ability to execute
#               all the future commands loaded via the modules system.
#  nocommands   Alias for -@all.
#  ~<pattern>   Add a pattern of keys that can be mentioned as part of
#               commands. For instance ~* allows all the keys. The pattern
#               is a glob-style pattern like the one of KEYS.
#               It is possible to specify multiple patterns.
#  allkeys      Alias for ~*
#  resetkeys    Flush the list of allowed keys patterns.
#  ><password>  Add this passowrd to the list of valid password for the user.
#               For example >mypass will add "mypass" to the list.
#               This directive clears the "nopass" flag (see later).
#  <<password>  Remove this password from the list of valid passwords.
#  nopass       All the set passwords of the user are removed, and the user
#               is flagged as requiring no password: it means that every
#               password will work against this user. If this directive is
#               used for the default user, every new connection will be
#               immediately authenticated with the default user without
#               any explicit AUTH command required. Note that the "resetpass"
#               directive will clear this condition.
#  resetpass    Flush the list of allowed passwords. Moreover removes the
#               "nopass" status. After "resetpass" the user has no associated
#               passwords and there is no way to authenticate without adding
#               some password (or setting it as "nopass" later).
#  reset        Performs the following actions: resetpass, resetkeys, off,
#               -@all. The user returns to the same state it has immediately
#               after its creation.
#
# ACL rules can be specified in any order: for instance you can start with
# passwords, then flags, or key patterns. However note that the additive
# and subtractive rules will CHANGE MEANING depending on the ordering.
# For instance see the following example:
#
#   user alice on +@all -DEBUG ~* >somepassword
#
# This will allow "alice" to use all the commands with the exception of the
# DEBUG command, since +@all added all the commands to the set of the commands
# alice can use, and later DEBUG was removed. However if we invert the order
# of two ACL rules the result will be different:
#
#   user alice on -DEBUG +@all ~* >somepassword
#
# Now DEBUG was removed when alice had yet no commands in the set of allowed
# commands, later all the commands are added, so the user will be able to
# execute everything.
#
# Basically ACL rules are processed left-to-right.
#
# For more information about ACL configuration please refer to
# the Redis web site at https://redis.io/topics/acl

# ACL LOG
#
# The ACL Log tracks failed commands and authentication events associated
# with ACLs. The ACL Log is useful to troubleshoot failed commands blocked 
# by ACLs. The ACL Log is stored in memory. You can reclaim memory with 
# ACL LOG RESET. Define the maximum entry length of the ACL Log below.
acllog-max-len 128

# Using an external ACL file
#
# Instead of configuring users here in this file, it is possible to use
# a stand-alone file just listing users. The two methods cannot be mixed:
# if you configure users here and at the same time you activate the exteranl
# ACL file, the server will refuse to start.
#
# The format of the external ACL user file is exactly the same as the
# format that is used inside redis.conf to describe users.
#
# aclfile /etc/redis/users.acl

CLIENTS

maxclients

设置同时连接进来的最大客户端数,默认值为 10000。需要注意的是同时连接进来的客户端数量还受限于 Redis 进程所能创建的最大的文件句柄的数量减去 32(Redis 会保留部分句柄用于内部使用)。

当超过限制后 Redis 会向所有新进来的连接发送错误信息 ”max number of clients reached“ 然后关闭连接

1
maxclients 10000

MEMORY MANAGEMENT

maxmemory

设置 Redis 能使用的最大内存容量,以字节为单位。根据你选择的过期策略(查看下面的 maxmemory-policy 选项), 当 Redis 使用的内存达到限制时,Redis 会尝试删除过期的键。

若 Redis 没有能删除的键,Redis 会拒绝那些如 SET,LPUSH 等会使用更多内存的命令,并且会正常相应那些如 GET 等只读命令。

这个选项通常用于将 Redis 作为 LRU 或者 LFU cache 使用的情况

1
# maxmemory <bytes>

maxmemory-plicy

1
2
3
4
5
6
7
maxmemory-policy noeviction #内存到达上限之后的处理策略
  volatile-lru #从已设置过期时间的数据集中挑选最近最少使用的数据淘汰。(默认值)
  allkeys-lru #从数据集中挑选最近最少使用的数据淘汰
  volatile-random #从已设置过期时间的数据集中任意选择数据淘汰。
  allkeys-random #从数据集中任意选择数据淘汰
  volatile-ttl  #从已设置过期时间的数据集中挑选将要过期的数据淘汰。
  noeviction  #默认,当内存达到限制的时候,不淘汰任何数据,不可写入任何数据集

注:在内存到达限值,并且没有合适的键被删除的情况下,无论选择的是什么过期策略,Redis 都会返回出错

maxmemory-samples

上面的 LRU,LFU 和 minimal TTL 算法都是近似算法,你可以通过改变这个选项来让算法更快还是更精确。 默认值是 5,也就是说 Redis 随机挑出 5 个键,然后选出一个最符合条件的。

对 LRU 来说 5 是比较合适的。10 已经很接近于真正的 LRU,但会消耗更多的 CPU。3 会更快但没有那么精确

1
maxmemory-samples 5

replica-ignore-maxmemory

从 Redis 5 开始,默认情况下,replica 节点会忽略 maxmemory 设置(除非在发生 failover 后,此节点被提升为 master 节点)。 这意味着只有 master 才会执行过期删除策略,并且 master 在删除键之后会对 replica 发送 DEL 命令。

这个行为保证了 master 和 replicas 的一致性,并且这通常也是你需要的,但是若你的 replica 节点是可写的, 或者你希望 replica 节点有不同的内存配置,并且你确保所有到 replica 写操作都幂等的,那么你可以修改这个默认的行为 (请确保你明白你在做什么)

1
replica-ignore-maxmemory yes

注:默认情况下 replica 节点不会执行过期策略,它有可能使用了超过 maxmemory 设定的值的内存。 因此你需要监控 replicas 节点所在的机器并且确保在 master 节点到达配置的 maxmemory 大小时, replicas 节点不会超过物理内存的大小

active-expire-effort

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Redis reclaims expired keys in two ways: upon access when those keys are
# found to be expired, and also in background, in what is called the
# "active expire key". The key space is slowly and interactively scanned
# looking for expired keys to reclaim, so that it is possible to free memory
# of keys that are expired and will never be accessed again in a short time.
#
# The default effort of the expire cycle will try to avoid having more than
# ten percent of expired keys still in memory, and will try to avoid consuming
# more than 25% of total memory and to add latency to the system. However
# it is possible to increase the expire "effort" that is normally set to
# "1", to a greater value, up to the value "10". At its maximum value the
# system will use more CPU, longer cycles (and technically may introduce
# more latency), and will tollerate less already expired keys still present
# in the system. It's a tradeoff betweeen memory, CPU and latecy.
active-expire-effort 1

LAZY FREEING

Redis 有两种方式删除键。一种是使用如 DEL 这样的命令进行的同步删除。 同步删除意味着删除过程中服务端会停止处理新进来的命令。 若要删除的 key 关联了一个小的 object 删除耗时会很短。 若要删除的 key 管理了一个很大的 object,比如此对象有上百万个元素,服务端会阻塞相同长一段时间(甚至超过一秒)。

由于以上原因,Redis 同时提供了一种非阻塞的方式用于删除,比如 UNLINK(非阻塞的 DEL)以及用于 FLUSHALL 和 FLUSHDB 的 ASYNC 选项,这些命令能在后台回收内存。 这些命令能在常数时间内执行完毕。其他线程会在后台尽快回收内存。

DEL,UNLINK 以及用于 FLUSHALL 和 FLUSHDB 的 ASYNC 选项是用户可以控制的。 根据应用的设计,用户可以选择使用阻塞或者非阻塞的方式。 但是作为某些命令的副作用 Redis 服务端有时会删除某些 object 或者 flush 整个数据库。 特别是以下独立于用户操作的情形:

  1. 由于 maxmemory 和 maxmemory policy 配置导致的内存回收动作
  2. 由于过期,当一个 key 过期后(可以查看 EXPIRE 命令获取相关信息),必须回收其内存
  3. 由于某些命令的副作用,比如 STORE 命令,执行 STORE 命令可能需要删除已有的键。SET 命令需要删除已有的旧内容。
  4. 在复制过程中,当一个 replica 节点执行一个全量同步时,replica 需要删除整个数据库的内容以加载传输过来的 RDB 文件。

在上述所有情形中,删除 object 的默认行为都是以阻塞方式删除。当然你可以配置上述四个选项来改变这种默认行为

1
2
3
4
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no

lazyfree-lazy-user-del

1
2
3
4
5
# It is also possible, for the case when to replace the user code DEL calls
# with UNLINK calls is not easy, to modify the default behavior of the DEL
# command to act exactly like UNLINK, using the following configuration
# directive:
lazyfree-lazy-user-del no

THREADED I/O

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# Redis is mostly single threaded, however there are certain threaded
# operations such as UNLINK, slow I/O accesses and other things that are
# performed on side threads.
#
# Now it is also possible to handle Redis clients socket reads and writes
# in different I/O threads. Since especially writing is so slow, normally
# Redis users use pipelining in order to speedup the Redis performances per
# core, and spawn multiple instances in order to scale more. Using I/O
# threads it is possible to easily speedup two times Redis without resorting
# to pipelining nor sharding of the instance.
#
# By default threading is disabled, we suggest enabling it only in machines
# that have at least 4 or more cores, leaving at least one spare core.
# Using more than 8 threads is unlikely to help much. We also recommend using
# threaded I/O only if you actually have performance problems, with Redis
# instances being able to use a quite big percentage of CPU time, otherwise
# there is no point in using this feature.
#
# So for instance if you have a four cores boxes, try to use 2 or 3 I/O
# threads, if you have a 8 cores, try to use 6 threads. In order to
# enable I/O threads use the following configuration directive:
#
# io-threads 4
#
# Setting io-threads to 1 will just use the main thread as usually.
# When I/O threads are enabled, we only use threads for writes, that is
# to thread the write(2) syscall and transfer the client buffers to the
# socket. However it is also possible to enable threading of reads and
# protocol parsing using the following configuration directive, by setting
# it to yes:
#
# io-threads-do-reads no
#
# Usually threading reads doesn't help much.
#
# NOTE 1: This configuration directive cannot be changed at runtime via
# CONFIG SET. Aso this feature currently does not work when SSL is
# enabled.
#
# NOTE 2: If you want to test the Redis speedup using redis-benchmark, make
# sure you also run the benchmark itself in threaded mode, using the
# --threads option to match the number of Redis theads, otherwise you'll not
# be able to notice the improvements.

KERNEL OOM CONTROL

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# On Linux, it is possible to hint the kernel OOM killer on what processes
# should be killed first when out of memory.
#
# Enabling this feature makes Redis actively control the oom_score_adj value
# for all its processes, depending on their role. The default scores will
# attempt to have background child processes killed before all others, and
# replicas killed before masters.

oom-score-adj no

# When oom-score-adj is used, this directive controls the specific values used
# for master, replica and background child processes. Values range -1000 to
# 1000 (higher means more likely to be killed).
#
# Unprivileged processes (not root, and without CAP_SYS_RESOURCE capabilities)
# can freely increase their value, but not decrease it below its initial
# settings.
#
# Values are used relative to the initial value of oom_score_adj when the server
# starts. Because typically the initial value is 0, they will often match the
# absolute values.

oom-score-adj-values 0 200 800

APPEND ONLY MODE

appendonly

默认情况下,Redis 会以异步形式将备份集 dump 到硬盘中。 对于很多应用来说,这种行为足够了,但是对于 Redis 进程崩溃或者断电的情况会导致最近数分钟的数据丢失(取决于 save 选项的设置)。

Append Only File 是 Redis 提供的另一种更好的持久化方式。 比如使用默认的数据同步策略(后面会讲),Redis 在断电等意外情况只会丢失最多一秒的写入数据, 在系统正常而 Redis 进程出错(如崩溃)的情况下只会丢掉最近一次写操作。

AOF 和 RDB 同步策略可以同时启用。当 AOF 启用后,Redis 在启动阶段会加载 AOF 文件, 这是因为相比 RDB,AOF 提供更好的持久性。 可以通过查看 http://redis.io/topics/persistence 获取更多信息。

1
appendonly no #默认是不开启aof模式,默认是使用rdb方式持久化的,在大部分所有的情况下rdb完全够用

appendfilename

append only file 的名称,默认为 appendonly.aof

1
appendfilename "appendonly.aof" #持久化文件名字

appendfsync

fsync() 调用用于告诉操作系统将数据写入硬盘而不是放入输出缓冲区中。 某些系统会马上将数据 flush 到硬盘中,而某些系统只是尽快尝试写入。 Redis 支持以下三种模式:

  • no 不调用 fsync,让操作系统决定什么时候真正写到硬盘
  • always 每次写入都对 append only file 进行 fsync 操作。最慢,也是最安全的选项。
  • everysec 每秒进行一次 fsync 操作,折中的做法。

默认选项为 “everysec”,对安全性和速度进行了折中。 更多信息可以通过查看 http://antirez.com/post/redis-persistence-demystified.html 获取。

当 AOF fsync 策略设置为 always 或者 everysec 并且后台保存进程(bgsave 或者 AOF 日志重写)正在进行大量 I/O 操作, 某些 Linux 配置下,Redis 会阻塞太长时间在 fsync() 调用。目前,没有方法可以避免这种状况, 即使是在其他线程执行 fsync 操作也一样会阻塞我们的同步写 write(2) 操作。

1
2
3
# appendfsync always  #每次修改都会 sync,消耗性能
appendfsync everysec  #每秒执行一次 sync,可能会丢失这1s的数据
# appendfsync no      #不执行sync,这个时候操作系统自己同步数据,速度最快!(缓存区满了,就刷新到磁盘中)

no-appendfsync-on-rewrite

为了缓和这种情况,可以在进行 BGSAVE 或者 BGREWRITEAOF 时禁止 fsync() 操作。 这意味着,当有子进程在保存的时候 Redis 的持久性相当于 “appendfsync none”。

当你的 Redis 延迟过大时可以将 no-appendfsync-on-rewrite 设置为 “yes”, 否则将其保持在 “no” 以保证持久性

1
no-appendfsync-on-rewrite no

auto-aof-rewrite-

自动重写 append only file 选项。 当 AOF 文件增长到一定比例后,Redis 可以自动通过隐式调用 BGREWRITEAOF 命令来重写 AOF 文件。

Redis 会记录上一次 rewrite 的 AOF 文件大小(若从未进行 rewrite,Redis 会使用启动时的 AOF 文件大小)作为基准大小。

Redis 会比较当前大小和基准大小,若当前大小大于一定比例则触发 rewrite。 为了防止增长比例到了但是总数据量还是非常小的情况就触发 rewrite,你还需要指定一个 AOF rewritten 的最小大小。

通过将 auto-aof-rewrite-percentage 设置为 0 可以禁用此功能

1
2
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb # aof文件大于64m的时候,会执行重写操作,并增加文件大小(按上面配置去增加)

aof-load-truncated

当 Redis 启动时可能会发现 AOF 文件被截断了(不完整),这可能是由于系统崩溃了, 特别是 ext4 没有以 data=ordered 选项挂载的情况(在 Redis 崩溃而系统正常的情况下不会发生截断)。

当这种情况发生时,Redis 可以选择终止进程,或者加载 AOF 文件上尽可能多的数据(目前的默认行为)。

当 aof-load-truncated 设置为 yes, Redis 服务端在启动的时候发现加载的 AOF 文件是被截断的会发送一条日志来通知客户。 若 aof-load-truncated 设置为 no,服务端会以错误形式终止进程并拒绝启动。 这是需要用户在重启服务前使用 “redis-check-aof” 工具来修复 AOF 文件。

1
aof-load-truncated yes

注:当 Redis 服务端发现 AOF 文件已经被损坏的情况下,服务端无论如何都会以错误终止进程。 这个选项只会在 Redis 尝试读取更多数据但是发现已经读到 AOF 文件的末尾时才会生效。

aof-use-rdb-preamble

当重写 AOF 文件时,Redis 可以使用 RDB 文件作为 AOF 文件的前导,这样可以更快地进行重写和恢复。

当启用这个功能时 AOF 文件由两部分组成:[RDB file][AOF tail]

当加载 AOF 文件时,Redis 通过以 “REDIS” 字符串开头的 AOF 文件识别出此文件是由 RDB 和 AOF 组合而成的, Redis 会先加载 RDB 部分,然后再加载 AOF 部分

1
aof-use-rdb-preamble yes

LUA SCRIPTING

lua-time-limit

此选项用于控制 Lua 脚本的最长执行时间,单位为毫秒。

当 Lua 脚本的执行时间超出限制后,Redis 会在写入相关日志,并且向客户端返回出错。

当一个长时间运行的脚本超过超大限制后,只有 SCRIPT KILL 和 SHUTDOWN NOSAVE 命令是有效的。 前者可以用于停止尚未进行写操作的脚本。后者用于停掉服务, 当脚本已经开始进行写操作并用户于不想等脚本自然结束,这是唯一的方法。

将这个值设为 0 或者负数表示不限制最大运行时间

1
lua-time-limit 5000

REDIS CLUSTER

cluster-enabled

只有那些以集群的模式启动的节点才能成为 Redis 集群的一部分,普通的 Redis 实例不能成为 Redis 集群的一部分。 为了让 Redis 实例成为集群的节点,需要将 cluster-enabled 设置为 yes

1
cluster-enabled yes

cluster-config-file

每个集群节点都有一个集群配置文件,这个文件不能手动修改,只能由 Redis 节点创建和更新。 每个 Redis 集群节点需要不同的集群配置文件,需要确保同一个系统运行的不同 Redis 实例使用了不同的名称的集群配置文件

1
cluster-config-file nodes-6379.conf

cluster-node-timeout

集群节点的超时时间,以毫秒为单位,当一个节点无法连接超过此选项配置的时间后, 就可以认为此节点处于失败状态。

其他的内部时间限制是此配置值的整数倍。

1
cluster-node-timeout 15000

cluster-replica-validity-factor

当一个 master 处于失败状态,而它的 replica 节点数据太旧的情况下不会进行 failover。

没有一个简单的方法判断 replica 节点的 “data age”,因此需要以下方法来检查:

  1. 如果有多个可用于 failover 的 replicas 节点,他们之间会交换消息以尝试选出具有最好的 replication offset(处理了最多的数据)的节点。 Replicas 会根据 offset 获取 rank,并且它开始进行 failover 的延时与 rank 成正比。
  2. 每个 replica 节点计算最后一次与 master 交互的时间。这个交互可以是 ping 或者是收到命令(如果 master 节点依然是 “connected” 状态), 获取是与 master 连接丢失以来经过的时间(如果复制连接断开)。 如果上一个交互的时间太旧,则 replica 不会尝试 failover。

第二点可以由用户进行调整。当 replicas 节点最后一个与 master 节点交互的时间超过以下时间时,replicas 不会进行 failover。

(node-timeout * replica-validity-factor) + repl-ping-replica-period

比如 node-timeout 为 30 秒,而 replica-validity-factor 为 10,并且假设 repl-ping-replica-period 为 10 秒, 当 replica 最后与 master 交互的时间超过 310 秒时,replica 不会尝试 failover。

replica-validity-factor 设置的过大会导致拥有陈旧数据的 replicas 通过 failover 成为 master, 当这个值太小则会阻止集群选出一个 replica。

为了最大的可用性,可以将 replica-validity-factor 设置为 0, 表示 replicas 总是尝试 failover 成为 master 而不管最后一次与 master 交互的时间。

0 是保证所有集群的所有分区总是能痊愈并且继续提供服务的唯一选择。

1
cluster-replica-validity-factor 10

cluster-migration-barrier

集群的 replicas 节点可以迁移到裸奔的 master 节点(就是没有 replicas 节点的 master 节点)。 当裸奔的 master 节点发生故障后不能进行 failover,因此这个功能提高了整个集群的抗故障能力。

replicas 节点只有在迁移到裸奔的 master 节点后,旧的 master 依然有给定数量的 replicas 节点才能进行迁移。 这个给定数量就是 “migration barrier”,由 cluster-migration-barrier 设置。 cluster-migration-barrier 为 1 表示 replicas 只有在迁移后旧的 master 节点至少还有一个可工作的 replicas 节点才进行迁移。 这个值一般设定为你希望每个 master 需要多少个 replicas 节点。

这个选项的默认为 1。如果你想要禁止迁移只需要将这个选项的值设置为一个很大的数即可。 设置为 0 只有在调试的时候才有用,在生产环境使用这个值是很危险的。

1
cluster-migration-barrier 1

cluster-require-full-coverage

默认情况下 Redis 集群只要发现有一个 hash slot 未被覆盖(没有可用的节点为其提供服务)则会停止提供查询服务。 因此当集群发生部分故障(比如部分的 hash slot 未被覆盖),则会导致整个集群都无法工作。 当所有的 slots 再次被覆盖后,集群会自动恢复到可用状态。

如果你希望在集群发生故障时可用的部分依然可以提供查询服务,可以将 cluster-require-full-coverage 的值设置为 no。

1
cluster-require-full-coverage yes

cluster-replica-no-failover

这个选项用于控制 master 发生故障时是否自动进行 failover。

当设置为 yes 后 master 发生故障时不会自动进行 failover,这时你可以进行手动的 failover 操作

1
cluster-replica-no-failover no

cluster-allow-reads-when-down

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# This option, when set to yes, allows nodes to serve read traffic while the
# the cluster is in a down state, as long as it believes it owns the slots. 
#
# This is useful for two cases.  The first case is for when an application 
# doesn't require consistency of data during node failures or network partitions.
# One example of this is a cache, where as long as the node has the data it
# should be able to serve it. 
#
# The second use case is for configurations that don't meet the recommended  
# three shards but want to enable cluster mode and scale later. A 
# master outage in a 1 or 2 shard configuration causes a read/write outage to the
# entire cluster without this option set, with it set there is only a write outage.
# Without a quorum of masters, slot ownership will not change automatically. 
#
# cluster-allow-reads-when-down no

CLUSTER DOCKER/NAT

在某些部署环境下,Redis 集群的节点地址不能被自动发现,这是因为这些节点是部署在 NAT 网络或者端口是转发的 (典型的情况就是使用了 Docker 或者其他容器)。

为了能让 Redis 集群工作在这种环境下,我们需要进行相关配置让各个节点知道相互之间的外部地址, 这可以通过设置以下选项做到:

  • cluster-announce-ip
  • cluster-announce-port
  • cluster-announce-bus-port

cluster-announce-ip 表示节点的外部地址,cluster-announce-port 表示节点的客户端口, cluster-announce-bus-port 表示集群消息总线端口。

若以上选项未配置,则将会启用正常的 Redis 集群自动检测机制。 若 bus port 未设置,则会将其设置为 port + 10000。

1
2
3
# cluster-announce-ip 10.1.1.5
# cluster-announce-port 6379
# cluster-announce-bus-port 6380

SLOW LOG

慢查询日志表示当一个查询的运行时间超过设置的时间时,系统会将其记录在慢查询日志中。 这个运行时间只包括执行命令需要的时间(只有这个阶段线程是处于阻塞状态并且无法为其他请求提供服务), 不包括 I/O 操作,比如和客户端通讯,发送响应请求等。

你可以设置慢查询日志的两个参数:一个是以微秒为单位的执行时间,超过这个时间的命令将会被记录下来, 另一个选项是慢查询日志的大小(就是一共会保存多少条慢查询日志)。 当一个新的命令需要被记录到慢查询日志并且当前慢查询日志的条数已经到达限制时,会先将最旧的慢查询日志移出队列。

slowlog-log-slower-than 为负数时表示禁用慢查询日志,0 表示记录所有的命令。

slowlog-max-len 没有上限,因此需要注意设置此值的大小,以免消耗过多的内存。

可以通过 SLOWLOG RESET 回收慢查询日志所消耗的内存。

1
2
slowlog-log-slower-than 10000
slowlog-max-len 128

LATENCY MONITOR(延迟监控)

Redis 延迟监视子系统收集的阀值,单位为毫秒,默认值为 0。 Redis 延迟监视子系统在运行时对不同的操作进行采样,以便收集与 Redis 实例延迟相关的数据。

用户可以通过 LATENCY 命令以图表和报告的形式获取延迟相关信息。

系统只会记录时间大于等于 latency-monitor-threshold 的操作。 当 latency-monitor-threshold 设置为 0 表示关闭 Redis 延迟监视子系统。

默认情况下 Redis 延迟监视子系统是处于关闭状态的,当你的系统没有延迟问题,数据收集工作反而会造成性能冲击。 可以通过以下命令在运行的 Redis 系统中启用Redis 延迟监视子系统:

CONFIG SET latency-monitor-threshold <milliseconds>

1
latency-monitor-threshold 0

EVENT NOTIFICATION

Redis 通过 Pub/Sub 机制向客户通知 keyspace 中发生的事件。 这个特性的更多信息可以查看文档: http://redis.io/topics/notifications

举例来说,如果 keyspace 事件通知是启用的,并且有一个客户在数据库 0 执行了如下命令:

1
DEL foo

这时 Redis 会通过 Pub/Sub 机制发送如下两条消息:

1
2
PUBLISH __keyspace@0__:foo del
PUBLISH __keyevent@0__:del foo

可以通过配置 “notify-keyspace-events” 选项来让 Redis 选择发送哪些事件:

  • K Keyspace 事件, 以 keyspace@ 为前缀发布
  • E Keyevent 事件, 以 keyevent@ 为前缀发布
  • g 通用命令 (不是针对特定类型的命令) 比如 DEL, EXPIRE, RENAME 等
  • $ String 命令
  • l List 命令
  • s Set 命令
  • h Hash 命令
  • z Sorted set 命令
  • x Expired 事件 (当一个 key 过期的时候生成)
  • e Evicted 事件 (当一个 key 由于 maxmemory 被回收生成)
  • A 表示 g$lshzxe 的别名,因此 “AKE” 表示所有事件

notify-keyspace-events 的值由上面的 0 到 N 个字符组成。空字符串表示禁止发送通知, 这是 notify-keyspace-events 的默认值。

举个例子:notify-keyspace-events Elg

表示启用 list 命令和通用命令相关的事件通知。

notify-keyspace-events Ex

表示启用过期事件通知。

需要注意的是如果要启用事件通知至少要包含 K 或者 E,否则不会有事件发布。

1
notify-keyspace-events ""

ADVANCED CONFIG

hash-max-ziplist-

当哈希表的项不超过 hash-max-ziplist-entries,并且每一项的长度不超过 hash-max-ziplist-value 使用 ziplist 保存数据

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

list-max-ziplist-size

Redis 的 List 内部是通过 quicklist 实现的(Redis 3.2 开始使用),quicklist 是一个双向链表。 quicklist 的每个节点都是一个 ziplist。list-max-ziplist-size 就是用于配置 quicklist 中的每个节点的 ziplist 的大小。 当这个值配置为正数时表示 quicklist 每个节点的 ziplist 所包含的元素个数是一个确定的数量。 当 list-max-ziplist-size 为负数时表示限制每个 ziplist 的大小,具体有以下含义:

  • -5:最大 64 kb <— 正常环境不推荐
  • -4:最大 32 kb <— 不推荐
  • -3:最大 16 kb <— 可能不推荐
  • -2:最大 8 kb <— 不错
  • -1:最大 4kb <— 不错

默认值为 -2,也是官方最推荐的值,当然你可以根据自己的实际情况进行修改

1
list-max-ziplist-size -2

list-compress-depth

quicklist 中的 ziplist 节点会被压缩。为了 push/pop 操作的高效性,quicklist 的头和尾节点永远都不会被压缩。 list-compress-depth 选项用于控制 quicklist 中压缩的节点的深度,下面的示例中加了中括号的节点表示未压缩。

  • 0 表示不对节点进行压缩,这是默认的值
  • 1 表示对头和尾节点外的其他节点进行压缩, [head]->node->node->…->node->[tail]
  • 2 [head]->[next]->node->node->…->node->[prev]->[tail]
  • 3 [head]->[next]->[next]->node->node->…->node->[prev]->[prev]->[tail]
  • 依次类推
1
list-compress-depth 0

set-max-intset-entries

当 Redis 的集合类型保存的数据均为数字,并且元素个数不超过 set-max-intset-entries 的时候。 Redis 将使用特殊的 intset 结构来保存这个集合。

1
set-max-intset-entries 512

zset-max-ziplist-

类似哈希表和列表,当排序集合的元素个数不超过 zset-max-ziplist-entries 并且每个元素的长度不超过 zset-max-ziplist-value 时,Redis 将使用 ziplist 保存这个排序集合。

1
2
zset-max-ziplist-entries 128
zset-max-ziplist-value 64

hll-sparse-max-bytes

HyperLogLog 稀疏模式的字节限制,包括了 16 字节的头,默认值为 3000。 当超出这个限制后 HyperLogLog 将有稀疏模式转为稠密模式。

将这个值设置为超过 16000 是没必要的,因为这时使用稠密模式更省空间。

1
hll-sparse-max-bytes 3000

stream-node-max-

用于设定 Streams 单个节点的最大大小和最多能保存多个个元素

1
2
stream-node-max-bytes 4096
stream-node-max-entries 100

activerehashing

当启用这个功能后,Redis 对哈希表的 rehash 操作会在每 100 毫秒 CPU 时间中的 1 毫秒进行。 Redis 的哈希表实现的 rehash 策略是一个惰性策略:就是说你对这个哈希表进行越多操作,你将有更多的 rehash 机会, 若你的服务器处于空闲状态则不会有机会完成 rehash 操作,这时哈希表会占用更多内存。

默认情况下会在每一秒中用 10 毫秒来对主哈希表进行 rehash。

如果在你的环境中需要有严格的延迟要求,则需要使用将 activerehashing 配置为 no,比如说需要在 2 毫秒内相应查询操作。 否则你应该将这个选项设置诶 yes,这样可以更及时地释放空闲的内存。

1
activerehashing yes

client-output-buffer-limit

客户端输出缓冲区限制可用于强制断开从服务器读取数据的速度不够快的客户端 (一个常见的原因是 Pub/Sub 客户端处理发布者的消息不够快)。

可以为每种客户端设置不同的限制:

  • normal -> 普通客户端,包括 MONITOR 客户端
  • replica -> 复制客户端
  • pubsub -> 订阅了至少一个频道的客户端

client-output-buffer-limit 选项的语法为:client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>

当一个客户端到达 hard limit 后会马上被断开,或者在到达 soft limit 并持续 soft seconds 秒后会被断开。

默认情况下,普通客户端不会有限制,因为除非主动请求否则他们不会收到信息, 只有异步的客户端才可能发生发送请求的速度比读取响应的速度快的情况。

默认情况下 pubsub 和 replica 客户端会有默认的限制,因为这些客户端是以 Redis 服务端 push 的方式接收数据的。

soft limit 或者 hard limit 都可以设置为 0,这表示不启用此限制。

1
2
3
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

客户端查询缓冲区会累加新的命令。 默认情况下,他们会限制在一个固定的数量避免协议同步失效(比如客户端的 bug)导致查询缓冲区出现未绑定的内存。

但是,如果有类似于巨大的 multi/exec 请求的时候可以修改这个值以满足你的特殊需求。

1
client-query-buffer-limit 1gb

proto-max-bulk-len

在 Redis 协议中,批量请求通常限制在 512 mb 内,可以通过修改 proto-max-bulk-len 选项改变这个限制。

1
proto-max-bulk-len 512mb

hz

默认值是 10,范围是 1 到 500,超过 100 一般都不是一个好主意。 Redis 会通过调用内部函数来完成很多后台任务,比如关闭超时的客户端的连接,清除过期的 key,等等。

Redis 通过 hz 设置的值来决定执行这些任务的频繁程度。

hz 的默认值是 10,可以通过提高这个值来使得 CPU 在空闲的时候使用更多的 CPU 时间来处理后台任务。 但同时这会使得当有很多 key 在同一时间过期时,过期处理会更精确。

很多客户只有在一些需要很低延迟的环境中才会将这个值从 10 提升到 100。

1
hz 10

dynamic-hz

通常来说根据连接上来的客户端数量对 HZ 的值按比例进行调整是有用的。 这很有用,例如,为了避免每次后台任务处理太多的客户端,从而避免高延迟峰值。

默认情况下 HZ 的值为 10,启用 dynamic-hz 后,当有大量客户端连接进来时 HZ 的值会临时性地调高。

启用 dynamic-hz 后,HZ 的配置值将作为基线,当有大量的客户端连接进来时,Redis 会将 HZ 的实际值设置为 HZ 的配置值的整数倍。 通过这种方式,空闲的 Redis 实例只会占用非常小的 CPU 时间,当实例变得繁忙时 Redis 能更快地进行响应(相对未启用 dynamic-hz 的情况)

1
dynamic-hz yes

aof-rewrite-incremental-fsync

当子进程进行 AOF 的重写时,如果启用了 aof-rewrite-incremental-fsync, 子进程会每生成 32 MB 数据就进行一次 fsync 操作。 通过这种方式将数据分批提交到硬盘可以避免高延迟峰值

1
aof-rewrite-incremental-fsync yes

rdb-save-incremental-fsync

当 Redis 保存 RDB 文件时,如果启用了 rdb-save-incremental-fsync 功能, Redis 会每生成 32 MB 数据就执行一次 fsync 操作。 通过这种方式将数据分批提交到硬盘可以避免高延迟峰值。

1
rdb-save-incremental-fsync yes

lfu-

Redis LFU 回收策略(忘了的话可以回顾下 maxmemory 选项)是可以调整的。 在开始的时候使用默认值并且只有在经过对如何提升性能和 key LFU 随时间如何改变进行调查查后才对其更改是一个好的主意。 这可以通过 OBJECT FREQ 命令进行检查。

Redis 的 LFU 实现目前有两个可调整的参数:计数器对数因子(couter logarithm factor) 和 计数器衰退时间(counter decay time)。 在修改这两个参数之前理解这两个参数是很重要的。

每个 key 的 LFU 计数器只有 8 bits,也就是说最大值为 255,因此 Redis 通过对数行为来对计数进行概率性的增加。 当一个 key 被访问后,计数器通过如下方式进行增加(假设计数器的旧值为 old_value):

  • 取出一个 0 到 1 之间的随机数 R
  • 通过如下方式算出概率 P: 1 / (old_value * lfu_log_factor + 1)
  • 只有当 R < P 时,才增加计数器

lfu-log-factor 的默认值为 10。下表是不同计数器对数因子下计数器的改变频率:

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

注:

  • 上表是通过如下命令获得的: redis-benchmark -n 1000000 incr foo redis-cli object freq foo

  • 计数器的初始值为 5,计数器衰减时间是 key 计数器除以 2 (如果值小于 <= 10,则递减)所必须经过的时间,单位为分钟。 lfu-decay-time 的默认值为 1。 0 表示每次都对计数器进行衰减

1
2
# lfu-log-factor 10
# lfu-decay-time 1

ACTIVE DEFRAGMENTATION

活动碎片整理允许 Redis 服务器压缩内存中由于申请和释放数据块导致的碎片,从而回收内存。 碎片是每次申请内存(幸运的是 Jemalloc 出现碎片的几率小很多)的时候会自然发生的。 通常来说,为了降低碎片化程度需要重启服务,或者至少需要清除所有的数据然后重新创建。 得益于 Oran Agra 在 Redis 4.0 实现的这个特性,进程可以在服务运行时以 “热” 方式完成这些目的。

通常来说当碎片化达到一定程度(查看下面的配置)Redis 会使用 Jemalloc 的特性创建连续的内存空间, 并在此内存空间对现有的值进行拷贝,拷贝完成后会释放掉旧的数据。 这个过程会对所有的导致碎片化的 key 以增量的形式进行。

需要重点理解的是:

  1. 这个特性默认是关闭的,并且只有在编译 Redis 时使用我们代码中的 Jemalloc 版本才生效。(这是 Linux 下的默认行为)
  2. 如果没有碎片问题,你永远不需要启用这项特性
  3. 如果你需要试验这项特性,可以通过命令 CONFIG SET activefrag yes 来启用

相关的配置参数可以很好的调整碎片整理过程。如果你不知道这些选项的作用最好使用默认值。

activedefrag

启用碎片整理。

1
activedefrag yes

active-defrag-

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 有至少多少碎片时才开始碎片整理
active-defrag-ignore-bytes 100mb
#有至少多少比例的碎片时才开始碎片整理
active-defrag-threshold-lower 10
#有多少比例的碎片时才开始以最大努力进行碎片整理
active-defrag-threshold-upper 100
#进行碎片整理时至少使用多少比例的 CPU 时间
active-defrag-cycle-min 5
#最大努力进行碎片整理时使用多少 CPU 时间
active-defrag-cycle-max 75
#进行主字典扫描时处理的 set/hash/zset/list 字段的最大数量(就是说在进行主字典扫描时 set/hash/zset/list 的长度小于这个值才会处理,大于这个值的会放在一个列表中延迟处理)
active-defrag-max-scan-fields 1000
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Jemalloc background thread for purging will be enabled by default
jemalloc-bg-thread yes

# It is possible to pin different threads and processes of Redis to specific
# CPUs in your system, in order to maximize the performances of the server.
# This is useful both in order to pin different Redis threads in different
# CPUs, but also in order to make sure that multiple Redis instances running
# in the same host will be pinned to different CPUs.
#
# Normally you can do this using the "taskset" command, however it is also
# possible to this via Redis configuration directly, both in Linux and FreeBSD.
#
# You can pin the server/IO threads, bio threads, aof rewrite child process, and
# the bgsave child process. The syntax to specify the cpu list is the same as
# the taskset command:
#
# Set redis server/io threads to cpu affinity 0,2,4,6:
# server_cpulist 0-7:2
#
# Set bio threads to cpu affinity 1,3:
# bio_cpulist 1,3
#
# Set aof rewrite child process to cpu affinity 8,9,10,11:
# aof_rewrite_cpulist 8-11
#
# Set bgsave child process to cpu affinity 1,10,11
# bgsave_cpulist 1,10-11

GOPHER SERVER

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# Redis contains an implementation of the Gopher protocol, as specified in
# the RFC 1436 (https://www.ietf.org/rfc/rfc1436.txt).
#
# The Gopher protocol was very popular in the late '90s. It is an alternative
# to the web, and the implementation both server and client side is so simple
# that the Redis server has just 100 lines of code in order to implement this
# support.
#
# What do you do with Gopher nowadays? Well Gopher never *really* died, and
# lately there is a movement in order for the Gopher more hierarchical content
# composed of just plain text documents to be resurrected. Some want a simpler
# internet, others believe that the mainstream internet became too much
# controlled, and it's cool to create an alternative space for people that
# want a bit of fresh air.
#
# Anyway for the 10nth birthday of the Redis, we gave it the Gopher protocol
# as a gift.
#
# --- HOW IT WORKS? ---
#
# The Redis Gopher support uses the inline protocol of Redis, and specifically
# two kind of inline requests that were anyway illegal: an empty request
# or any request that starts with "/" (there are no Redis commands starting
# with such a slash). Normal RESP2/RESP3 requests are completely out of the
# path of the Gopher protocol implementation and are served as usually as well.
#
# If you open a connection to Redis when Gopher is enabled and send it
# a string like "/foo", if there is a key named "/foo" it is served via the
# Gopher protocol.
#
# In order to create a real Gopher "hole" (the name of a Gopher site in Gopher
# talking), you likely need a script like the following:
#
#   https://github.com/antirez/gopher2redis
#
# --- SECURITY WARNING ---
#
# If you plan to put Redis on the internet in a publicly accessible address
# to server Gopher pages MAKE SURE TO SET A PASSWORD to the instance.
# Once a password is set:
#
#   1. The Gopher server (when enabled, not by default) will still serve
#      content via Gopher.
#   2. However other commands cannot be called before the client will
#      authenticate.
#
# So use the 'requirepass' option to protect your instance.
#
# To enable Gopher support uncomment the following line and set
# the option from no (the default) to yes.
#
# gopher-enabled no

KEYS TRACKING

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# Redis implements server assisted support for client side caching of values.
# This is implemented using an invalidation table that remembers, using
# 16 millions of slots, what clients may have certain subsets of keys. In turn
# this is used in order to send invalidation messages to clients. Please
# to understand more about the feature check this page:
#
#   https://redis.io/topics/client-side-caching
#
# When tracking is enabled for a client, all the read only queries are assumed
# to be cached: this will force Redis to store information in the invalidation
# table. When keys are modified, such information is flushed away, and
# invalidation messages are sent to the clients. However if the workload is
# heavily dominated by reads, Redis could use more and more memory in order
# to track the keys fetched by many clients.
#
# For this reason it is possible to configure a maximum fill value for the
# invalidation table. By default it is set to 1M of keys, and once this limit
# is reached, Redis will start to evict keys in the invalidation table
# even if they were not modified, just to reclaim memory: this will in turn
# force the clients to invalidate the cached values. Basically the table
# maximum size is a trade off between the memory you want to spend server
# side to track information about who cached what, and the ability of clients
# to retain cached objects in memory.
#
# If you set the value to 0, it means there are no limits, and Redis will
# retain as many keys as needed in the invalidation table.
# In the "stats" INFO section, you can find information about the number of
# keys in the invalidation table at every given moment.
#
# Note: when key tracking is used in broadcasting mode, no memory is used
# in the server side so this setting is useless.
#
# tracking-table-max-keys 1000000

TLS/SSL

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# By default, TLS/SSL is disabled. To enable it, the "tls-port" configuration
# directive can be used to define TLS-listening ports. To enable TLS on the
# default port, use:
#
# port 0
# tls-port 6379

# Configure a X.509 certificate and private key to use for authenticating the
# server to connected clients, masters or cluster peers.  These files should be
# PEM formatted.
#
# tls-cert-file redis.crt 
# tls-key-file redis.key

# Configure a DH parameters file to enable Diffie-Hellman (DH) key exchange:
#
# tls-dh-params-file redis.dh

# Configure a CA certificate(s) bundle or directory to authenticate TLS/SSL
# clients and peers.  Redis requires an explicit configuration of at least one
# of these, and will not implicitly use the system wide configuration.
#
# tls-ca-cert-file ca.crt
# tls-ca-cert-dir /etc/ssl/certs

# By default, clients (including replica servers) on a TLS port are required
# to authenticate using valid client side certificates.
#
# If "no" is specified, client certificates are not required and not accepted.
# If "optional" is specified, client certificates are accepted and must be
# valid if provided, but are not required.
#
# tls-auth-clients no
# tls-auth-clients optional

# By default, a Redis replica does not attempt to establish a TLS connection
# with its master.
#
# Use the following directive to enable TLS on replication links.
#
# tls-replication yes

# By default, the Redis Cluster bus uses a plain TCP connection. To enable
# TLS for the bus protocol, use the following directive:
#
# tls-cluster yes

# Explicitly specify TLS versions to support. Allowed values are case insensitive
# and include "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3" (OpenSSL >= 1.1.1) or
# any combination. To enable only TLSv1.2 and TLSv1.3, use:
#
# tls-protocols "TLSv1.2 TLSv1.3"

# Configure allowed ciphers.  See the ciphers(1ssl) manpage for more information
# about the syntax of this string.
#
# Note: this configuration applies only to <= TLSv1.2.
#
# tls-ciphers DEFAULT:!MEDIUM

# Configure allowed TLSv1.3 ciphersuites.  See the ciphers(1ssl) manpage for more
# information about the syntax of this string, and specifically for TLSv1.3
# ciphersuites.
#
# tls-ciphersuites TLS_CHACHA20_POLY1305_SHA256

# When choosing a cipher, use the server's preference instead of the client
# preference. By default, the server follows the client's preference.
#
# tls-prefer-server-ciphers yes

# By default, TLS session caching is enabled to allow faster and less expensive
# reconnections by clients that support it. Use the following directive to disable
# caching.
#
# tls-session-caching no

# Change the default number of TLS sessions cached. A zero value sets the cache
# to unlimited size. The default size is 20480.
#
# tls-session-cache-size 5000

# Change the default timeout of cached TLS sessions. The default timeout is 300
# seconds.
#
# tls-session-cache-timeout 60
使用 Hugo 构建
主题 StackJimmy 设计