跳转到主要内容

这是本节的多页打印视图。 .

返回本页常规视图.

Redis

开源内存数据结构存储
配置
    配置 PostgreSQL 集群
参数
    使用 21 个参数自定义 redis 组件
管理
    创建、移除、扩展 redis 集群
剧本
    可在此模块中使用的 Ansible 剧本
监控
    仪表板、指标、记录和告警规则。
常见问题
    关于 redis 模块的常见问题

1 - 配置

描述您想要的 redis 集群

Redis 的实体模型与 PostgreSQL 几乎相同, 也包括集群实例的概念。这里的集群不是指原生 Redis 集群模式。

REDIS 模块与 PGSQL 模块的核心区别是 Redis 使用单节点多实例部署而不是 1:1 部署: 通常在一个物理/虚拟机节点上部署多个 Redis 实例以充分利用多核 CPU。 因此,配置管理 Redis 实例的方式与 PGSQL 略有不同。

在 Pigsty 管理的 Redis 中,节点完全从属于集群,这意味着目前 不允许在一个节点上部署两个不同集群的 Redis 实例。 但是,这不影响在一个节点上部署多个独立的 Redis 主副本实例。


Redis 身份

Redis 身份参数 是定义 Redis 集群时的必需参数。

名称 属性 描述 示例
redis_cluster 必需,集群级别 集群名称 redis-test
redis_node 必需,节点级别 节点序列号 1,2
redis_instances 必需,节点级别 实例定义 { 6001 : {} ,6002 : {}}

Redis 模式

Pigsty 中有三种可用的 redis_mode

  • standalone:以独立(主从)模式设置 Redis
  • cluster:将此 Redis 集群设置为 Redis 原生集群
  • sentinel:将 Redis 设置为独立 Redis HA 的哨兵

以下是三个示例:

  • 1 节点,一个主节点和一个从节点的 Redis 独立集群:redis-ms
  • 1 节点,3 实例的 Redis 哨兵集群:redis-sentinel
  • 2 节点,6 实例的 Redis 集群:redis-cluster
redis-ms: # redis classic primary & replica
  hosts: { 10.10.10.10: { redis_node: 1 , redis_instances: { 6379: { }, 6380: { replica_of: '10.10.10.10 6379' } } } }
  vars: { redis_cluster: redis-ms ,redis_password: 'redis.ms' ,redis_max_memory: 64MB }

redis-meta: # redis sentinel x 3
  hosts: { 10.10.10.11: { redis_node: 1 , redis_instances: { 26379: { } ,26380: { } ,26381: { } } } }
  vars:
    redis_cluster: redis-meta
    redis_password: 'redis.meta'
    redis_mode: sentinel
    redis_max_memory: 16MB
    redis_sentinel_monitor: # primary list for redis sentinel, use cls as name, primary ip:port
      - { name: redis-ms, host: 10.10.10.10, port: 6379 ,password: redis.ms, quorum: 2 }

redis-test: # redis native cluster: 3m x 3s
  hosts:
    10.10.10.12: { redis_node: 1 ,redis_instances: { 6379: { } ,6380: { } ,6381: { } } }
    10.10.10.13: { redis_node: 2 ,redis_instances: { 6379: { } ,6380: { } ,6381: { } } }
  vars: { redis_cluster: redis-test ,redis_password: 'redis.test' ,redis_mode: cluster, redis_max_memory: 32MB }

限制

  • 一个 Redis 节点只能属于一个 Redis 集群,这意味着您不能同时将一个节点分配给两个不同的 Redis 集群。
  • 在每个 Redis 节点上,您需要为 Redis 实例分配唯一的端口号以避免端口冲突。
  • 通常,同一个 Redis 集群将使用相同的密码,但 Redis 节点上的多个 Redis 实例不能设置不同的密码(因为 redis_exporter 只允许一个密码)。
  • Redis 集群具有内置 HA,而独立 HA 需要在哨兵中手动配置,因为我们不确定您是否有可用的哨兵。 幸运的是,配置独立 Redis HA 很简单:使用哨兵配置 HA

2 - 参数

使用 21 个参数定制 redis

redis 模块中有 21 个参数。

参数 类型 级别 注释
redis_cluster string C redis 集群名称,必需的身份参数
redis_instances dict I 此 redis 节点上的 redis 实例定义
redis_node int I redis 节点序列号,必需的节点整数 ID
redis_fs_main path C redis 主数据挂载点,默认为 /data
redis_exporter_enabled bool C 在 redis 节点上安装 redis exporter?
redis_exporter_port port C redis exporter 监听端口,默认为 9121
redis_exporter_options string C/I redis exporter 的 cli 参数和额外选项
redis_safeguard bool G/C/A 防止清除正在运行的 redis 实例?
redis_clean bool G/C/A 初始化期间清除现有的 redis?
redis_rmdata bool G/C/A 清除 redis 服务器时移除 redis 数据?
redis_mode enum C redis 模式:standalone、cluster、sentinel
redis_conf string C redis 配置模板路径,除 sentinel 外
redis_bind_address ip C redis 绑定地址,空字符串将使用主机 IP
redis_max_memory size C/I 每个 redis 实例使用的最大内存
redis_mem_policy enum C redis 内存逐出策略
redis_password password C redis 密码,空字符串将禁用密码
redis_rdb_save string[] C redis rdb 保存指令,使用空列表禁用
redis_aof_enabled bool C 启用 redis 追加文件?
redis_rename_commands dict C 重命名 redis 危险命令
redis_cluster_replicas int C redis 集群中一个主节点的副本数量
redis_sentinel_monitor master[] C sentinel 主节点列表,仅限 sentinel 集群

默认值

默认参数在 roles/redis/defaults/main.yml 中定义

#redis_cluster:        <CLUSTER> # redis 集群名称,必需的身份参数
#redis_node: 1            <NODE> # redis 节点序列号,必需的节点整数 ID
#redis_instances: {}      <NODE> # 此 redis 节点上的 redis 实例定义
redis_fs_main: /data              # redis 主数据挂载点,默认为 `/data`
redis_exporter_enabled: true      # 在 redis 节点上安装 redis exporter?
redis_exporter_port: 9121         # redis exporter 监听端口,默认为 9121
redis_exporter_options: ''        # redis exporter 的 cli 参数和额外选项
redis_safeguard: false            # 防止清除正在运行的 redis 实例?
redis_clean: true                 # 初始化期间清除现有的 redis?
redis_rmdata: true                # 清除 redis 服务器时移除 redis 数据?
redis_mode: standalone            # redis 模式:standalone、cluster、sentinel
redis_conf: redis.conf            # redis 配置模板路径,除 sentinel 外
redis_bind_address: '0.0.0.0'     # redis 绑定地址,空字符串将使用主机 IP
redis_max_memory: 1GB             # 每个 redis 实例使用的最大内存
redis_mem_policy: allkeys-lru     # redis 内存逐出策略
redis_password: ''                # redis 密码,空字符串将禁用密码
redis_rdb_save: ['1200 1']        # redis rdb 保存指令,使用空列表禁用
redis_aof_enabled: false          # 启用 redis 追加文件?
redis_rename_commands: {}         # 重命名 redis 危险命令
redis_cluster_replicas: 1         # redis 集群中一个主节点的副本数量
redis_sentinel_monitor: []        # sentinel 主节点列表,仅在 sentinel 集群上工作

redis_cluster

名称:redis_cluster,类型:string,级别:C

redis 集群名称,必需的身份参数。

无默认值,您必须明确定义它。

符合正则表达式 [a-z][a-z0-9-]*,建议使用与组名相同的名称并以 redis- 开头


redis_node

名称:redis_node,类型:int,级别:I

redis 节点序列号,在 redis 集群中需要唯一的整数

您必须为每个 redis 节点明确定义节点 ID。整数从 0 或 1 开始。


redis_instances

名称:redis_instances,类型:dict,级别:I

此 redis 节点上的 redis 实例定义

无默认值,您必须使用此参数在每个 redis 节点上明确定义 redis 实例。

这是一个原生 redis 集群定义的示例

redis-test: # redis 原生集群:3m x 3s
  hosts:
    10.10.10.12: { redis_node: 1 ,redis_instances: { 6379: { } ,6380: { } ,6381: { } } }
    10.10.10.13: { redis_node: 2 ,redis_instances: { 6379: { } ,6380: { } ,6381: { } } }
  vars: { redis_cluster: redis-test ,redis_password: 'redis.test' ,redis_mode: cluster, redis_max_memory: 32MB }

端口号在节点中应该是唯一的,value 中的 replica_of 应该是同一 redis 集群的实例成员。

redis_instances:
    6379: {}
    6380: { replica_of: '10.10.10.13 6379' }
    6381: { replica_of: '10.10.10.13 6379' }

redis_fs_main

名称:redis_fs_main,类型:path,级别:C

redis 主数据挂载点,默认为 /data

默认值:/data,并且 /data/redis 将用作 redis 数据目录。


redis_exporter_enabled

名称:redis_exporter_enabled,类型:bool,级别:C

在 redis 节点上安装 redis exporter?

默认值为 true,这将在此 redis_node 上启动一个 redis_exporter


redis_exporter_port

名称:redis_exporter_port,类型:port,级别:C

redis exporter 监听端口,默认为 9121

默认值:9121


redis_exporter_options

名称:redis_exporter_options,类型:string,级别:C/I

redis exporter 的 cli 参数和额外选项,将添加到 /etc/default/redis_exporter

默认值为空字符串


redis_safeguard

名称:redis_safeguard,类型:bool,级别:G/C/A

防止清除正在运行的 redis 实例?

默认值为 false,如果设置为 true,且 redis 实例正在运行,初始化/移除 playbook 将立即中止。


redis_clean

名称:redis_clean,类型:bool,级别:G/C/A

初始化期间清除现有的 redis?

默认值为 true,这将在 redis 初始化或移除期间移除 redis 服务器。


redis_rmdata

名称:redis_rmdata,类型:bool,级别:G/C/A

清除 redis 服务器时移除 redis 数据?

默认值为 true,这将与 redis 实例一起移除 redis rdb / aof。


redis_mode

名称:redis_mode,类型:enum,级别:C

redis 模式:standalone、cluster、sentinel

默认值:standalone

  • standalone:将 redis 设置为独立(主从)模式
  • cluster:将此 redis 集群设置为 redis 原生集群
  • sentinel:为独立 redis HA 设置 redis 为 sentinel

redis_conf

名称:redis_conf,类型:string,级别:C

redis 配置模板路径,除 sentinel 外

默认值:redis.conf,这是 roles/redis/templates/redis.conf 中的模板文件。

如果您想使用自己的 redis 配置模板,可以将其放在 templates/ 目录中并将此参数设置为模板文件名。

请注意,redis sentinel 使用不同的模板文件,即 roles/redis/templates/redis-sentinel.conf


redis_bind_address

名称:redis_bind_address,类型:ip,级别:C

redis 绑定地址,空字符串将使用清单主机名

默认值:0.0.0.0,这将绑定到此主机上的所有可用 IPv4 地址

请在生产环境中仅绑定到内网 IP,即将此值设置为 ''


redis_max_memory

名称:redis_max_memory,类型:size,级别:C/I

每个 redis 实例使用的最大内存,默认值:1GB


redis_mem_policy

名称:redis_mem_policy,类型:enum,级别:C

redis 内存逐出策略

默认值:allkeys-lru,查看 redis 逐出策略 获取更多详情

  • noeviction:达到内存限制时不保存新值。当数据库使用复制时,这适用于主数据库
  • allkeys-lru:保留最近使用的键;移除最少使用的(LRU)键
  • allkeys-lfu:保留经常使用的键;移除最少经常使用的(LFU)键
  • volatile-lru:移除过期字段设置为 true 的最少使用键。
  • volatile-lfu:移除过期字段设置为 true 的最少经常使用键。
  • allkeys-random:随机移除键以为添加的新数据腾出空间。
  • volatile-random:随机移除过期字段设置为 true 的键。
  • volatile-ttl:移除过期字段设置为 true 且剩余生存时间(TTL)值最短的键。

redis_password

名称:redis_password,类型:password,级别:C/N

redis 密码,空字符串将禁用密码,这是默认行为

请注意,由于 redis_exporter 的实现限制,每个节点只能设置一个 redis_password。这通常不是问题,因为 pigsty 不允许在同一节点上部署两个不同的 redis 集群。

请在生产环境中使用强密码


redis_rdb_save

名称:redis_rdb_save,类型:string[],级别:C

redis rdb 保存指令,使用空列表禁用,查看 redis 持久化 获取详情。

默认值为 ["1200 1"]:如果至少 1 个键发生变化,每 20 分钟将数据集转储到磁盘:


redis_aof_enabled

名称:redis_aof_enabled,类型:bool,级别:C

启用 redis 追加文件?默认值为 false


redis_rename_commands

名称:redis_rename_commands,类型:dict,级别:C

重命名 redis 危险命令,这是一个 k:v old: new 的字典

默认值:{},您可以通过设置此值来隐藏像 FLUSHDBFLUSHALL 这样的危险命令,这是一个示例:

{
  "keys": "op_keys",
  "flushdb": "op_flushdb",
  "flushall": "op_flushall",
  "config": "op_config"
}

redis_cluster_replicas

名称:redis_cluster_replicas,类型:int,级别:C

redis 集群中一个主节点/主要节点的副本数量,默认值:1


redis_sentinel_monitor

名称:redis_sentinel_monitor,类型:master[],级别:C

只有当 redis_mode 设置为 sentinel 时才能使用。

此 sentinel 集群要监控的 redis 主节点列表。每个主节点定义为具有 namehostportpasswordquorum 键的字典。

redis_sentinel_monitor:  # redis sentinel 的主节点列表,使用 cls 作为名称,主节点 ip:port
  - { name: redis-src, host: 10.10.10.45, port: 6379 ,password: redis.src, quorum: 1 }
  - { name: redis-dst, host: 10.10.10.48, port: 6379 ,password: redis.dst, quorum: 1 }

namehost 是必需的,portpasswordquorum 是可选的,quorum 用于为此主节点设置法定人数,通常大于 sentinel 实例的一半。

3 - 管理

运行管理任务

这里是 Redis 的一些常见管理任务。更多详情请查看 FAQ: Redis


初始化 Redis

初始化集群/节点/实例

# 在组 <cluster> 上初始化所有 redis 实例
./redis.yml -l <cluster>      # 初始化 redis 集群

# 初始化 redis 节点
./redis.yml -l 10.10.10.10    # 初始化 redis 节点

# 初始化一个特定的 redis 实例 10.10.10.11:6379
./redis.yml -l 10.10.10.11 -e redis_port=6379 -t redis

您也可以使用包装脚本:

bin/redis-add redis-ms          # 创建 redis 集群 'redis-ms'
bin/redis-add 10.10.10.10       # 创建 redis 节点 '10.10.10.10'
bin/redis-add 10.10.10.10 6379  # 创建 redis 实例 '10.10.10.10:6379'

移除 Redis

移除集群/节点/实例

# 移除集群 `redis-test`
redis-rm.yml -l redis-test

# 移除集群 `redis-test`,并卸载软件包
redis-rm.yml -l redis-test -e redis_uninstall=true

# 移除 redis 节点 10.10.10.13 上的所有实例
redis-rm.yml -l 10.10.10.13

# 移除一个特定的实例 10.10.10.13:6379
redis-rm.yml -l 10.10.10.13 -e redis_port=6379

您也可以使用包装脚本:

bin/redis-rm redis-ms          # 移除 redis 集群 'redis-ms'
bin/redis-rm 10.10.10.10       # 移除 redis 节点 '10.10.10.10'
bin/redis-rm 10.10.10.10 6379  # 移除 redis 实例 '10.10.10.10:6379'

重新加载 Redis

您可以部分运行 redis.yml 任务来重新配置 redis。

./redis.yml -l <cluster> -t redis_config,redis_launch

请注意,redis 无法在线重新加载;您必须重启 redis 才能使配置生效。


使用 Redis CLI

使用 redis-cli 访问 redis 实例:

$ redis-cli -h 10.10.10.10 -p 6379 # <--- 使用主机和端口连接
10.10.10.10:6379> auth redis.ms    # <--- 使用密码验证
OK
10.10.10.10:6379> set a 10         # <--- 设置一个键
OK
10.10.10.10:6379> get a            # <--- 获取一个键
"10"

Redis 还有一个 redis-benchmark,可用于基准测试和在 redis 服务器上生成负载:

redis-benchmark -h 10.10.10.13 -p 6379

复制 Redis

https://redis.io/commands/replicaof/

# 将 redis 实例提升为主节点
> REPLICAOF NO ONE
"OK"

# 使 redis 实例成为另一个实例的副本
> REPLICAOF 127.0.0.1 6799
"OK"

使用 Sentinel 的高可用

您必须使用您的 redis sentinel 手动为 redis 独立主从集群启用 HA。

以 4 节点沙盒为例,redis sentinel 集群 redis-meta 用于管理 redis-ms 独立集群。

# 对于每个 sentinel,使用以下方式将 redis 主节点添加到 sentinel:
$ redis-cli -h 10.10.10.11 -p 26379 -a redis.meta
10.10.10.11:26379> SENTINEL MONITOR redis-ms 10.10.10.10 6379 1
10.10.10.11:26379> SENTINEL SET redis-ms auth-pass redis.ms      # 如果启用了身份验证,必须配置密码

如果您希望从 sentinel 中移除 redis 主节点,请使用 SENTINEL REMOVE <name>

您可以使用 redis_sentinel_monitor 在 sentinel 集群上配置多个 redis 主节点。

redis_sentinel_monitor: # redis sentinel 的主节点列表,使用 cls 作为名称,主节点 ip:port
  - { name: redis-src, host: 10.10.10.45, port: 6379 ,password: redis.src, quorum: 1 }
  - { name: redis-dst, host: 10.10.10.48, port: 6379 ,password: redis.dst, quorum: 1 }

并使用以下方式刷新 sentinel 集群上的主节点列表:

./redis.yml -l redis-meta -t redis-ha   # 如果您的 sentinel 集群有不同的名称,请替换 redis-meta

4 - 剧本

控制原语

redis 有两个剧本:

redis.yml

剧本 redis.yml 将初始化 redis 集群/节点/实例:

redis_node        : init redis node
  - redis_install : install redis & redis_exporter
  - redis_user    : create os user redis
  - redis_dir     : create redis redis fhs
redis_exporter    : config and launch redis_exporter
  - redis_exporter_config  : generate redis_exporter config
  - redis_exporter_launch  : launch redis_exporter
redis_instance    : config and launch redis cluster/node/instance
  - redis_check   : check redis instance existence
  - redis_clean   : purge existing redis instance
  - redis_config  : generate redis instance config
  - redis_launch  : launch redis instance
redis_register    : register redis to prometheus
redis_ha          : setup redis sentinel
redis_join        : join redis cluster

redis-rm.yml

剧本 redis-rm.yml 将移除 redis 集群/节点/实例:

- register       : remove monitor target from prometheus
- redis_exporter : stop and disable redis_exporter
- redis          : stop and disable redis cluster/node/instance
- redis_data     : remove redis data (rdb, aof)
- redis_pkg      : uninstall redis & redis_exporter packages

5 - 监控

Redis 监控仪表板和告警规则

仪表板

REDIS 模块有三个仪表板。

Redis 概览

Redis Overview:所有 Redis 实例的概览

Redis 集群

Redis Cluster:单个 redis 集群的概览

Redis 实例

Redis Instance:单个 redis 实例的概览


告警规则

Redis 有 6 个预定义的告警规则,定义在 files/prometheus/rules/redis.yml 中。

名称 描述 级别
RedisDown Redis 服务器宕机 Critical
RedisRejectConn Redis 实例拒绝连接 Critical
RedisRTHigh Redis 实例响应时间过高 Warning
RedisCPUHigh Redis 实例 CPU 使用率过高 Warning
RedisMemHigh Redis 实例内存使用率过高 Warning
RedisQPSHigh Redis 实例 QPS 过高 Warning
#==============================================================#
#                         Error                                #
#==============================================================#
# redis down triggers a P0 alert
- alert: RedisDown
  expr: redis_up < 1
  for: 1m
  labels: { level: 0, severity: CRIT, category: redis }
  annotations:
    summary: "CRIT RedisDown: {{ $labels.ins }} {{ $labels.instance }} {{ $value }}"
    description: |
      redis_up[ins={{ $labels.ins }}, instance={{ $labels.instance }}] = {{ $value }} == 0
      http://g.pigsty/d/redis-instance?from=now-5m&to=now&var-ins={{$labels.ins}}

# redis reject connection in last 5m
- alert: RedisRejectConn
  expr: redis:ins:conn_reject > 0
  labels: { level: 0, severity: CRIT, category: redis }
  annotations:
    summary: "CRIT RedisRejectConn: {{ $labels.ins }} {{ $labels.instance }} {{ $value }}"
    description: |
      redis:ins:conn_reject[cls={{ $labels.cls }}, ins={{ $labels.ins }}][5m] = {{ $value }} > 0
      http://g.pigsty/d/redis-instance?from=now-10m&to=now&viewPanel=88&fullscreen&var-ins={{ $labels.ins }}



#==============================================================#
#                         Latency                              #
#==============================================================#
# redis avg query response time > 160 µs
- alert: RedisRTHigh
  expr: redis:ins:rt > 0.00016
  for: 1m
  labels: { level: 1, severity: WARN, category: redis }
  annotations:
    summary: "WARN RedisRTHigh: {{ $labels.cls }} {{ $labels.ins }}"
    description: |
      pg:ins:query_rt[cls={{ $labels.cls }}, ins={{ $labels.ins }}] = {{ $value }} > 160µs
      http://g.pigsty/d/redis-instance?from=now-10m&to=now&viewPanel=97&fullscreen&var-ins={{ $labels.ins }}



#==============================================================#
#                        Saturation                            #
#==============================================================#
# redis cpu usage more than 70% for 1m
- alert: RedisCPUHigh
  expr: redis:ins:cpu_usage > 0.70
  for: 1m
  labels: { level: 1, severity: WARN, category: redis }
  annotations:
    summary: "WARN RedisCPUHigh: {{ $labels.cls }} {{ $labels.ins }}"
    description: |
      redis:ins:cpu_all[cls={{ $labels.cls }}, ins={{ $labels.ins }}] = {{ $value }} > 60%
      http://g.pigsty/d/redis-instance?from=now-10m&to=now&viewPanel=43&fullscreen&var-ins={{ $labels.ins }}

# redis mem usage more than 70% for 1m
- alert: RedisMemHigh
  expr: redis:ins:mem_usage > 0.70
  for: 1m
  labels: { level: 1, severity: WARN, category: redis }
  annotations:
    summary: "WARN RedisMemHigh: {{ $labels.cls }} {{ $labels.ins }}"
    description: |
      redis:ins:mem_usage[cls={{ $labels.cls }}, ins={{ $labels.ins }}] = {{ $value }} > 80%
      http://g.pigsty/d/redis-instance?from=now-10m&to=now&viewPanel=7&fullscreen&var-ins={{ $labels.ins }}

#==============================================================#
#                         Traffic                              #
#==============================================================#
# redis qps more than 32000 for 5m
- alert: RedisQPSHigh
  expr: redis:ins:qps > 32000
  for: 5m
  labels: { level: 2, severity: INFO, category: redis }
  annotations:
    summary: "INFO RedisQPSHigh: {{ $labels.cls }} {{ $labels.ins }}"
    description: |
      redis:ins:qps[cls={{ $labels.cls }}, ins={{ $labels.ins }}] = {{ $value }} > 16000
      http://g.pigsty/d/redis-instance?from=now-10m&to=now&viewPanel=96&fullscreen&var-ins={{ $labels.ins }}

6 - FAQ

常见问题

由于现有 redis 实例而中止

使用 redis_clean = trueredis_safeguard = false 强制清理 redis 数据

当您运行 redis.yml 初始化已经运行的 redis 实例,并且 redis_clean 设置为 false 时会发生这种情况。

如果 redis_clean 设置为 true(且 redis_safeguard 也设置为 false),redis.yml playbook 将删除现有的 redis 实例并将其重新初始化为新实例,这使得 redis.yml playbook 完全幂等。


由于启用 redis_safeguard 而中止

当使用 redis_safeguard 设置为 true 移除 redis 实例时会发生这种情况。

您可以禁用 redis_safeguard 来移除 Redis 实例。这就是 redis_safeguard 的作用。


如何在此节点上添加一个新的 redis 实例?

使用 bin/redis-add <ip> <port> 在节点上部署新的 redis 实例。


如何从节点移除单个 redis 实例?

bin/redis-rm <ip> <port> 从节点移除单个 redis 实例