引言

Redis 是一个开源的、内存中的键值数据存储。 其最受欢迎的特性之一是支持复制: 任何 Redis 服务器都可以将其数据复制到任意数量的副本,从而实现高读取可伸缩性和强大的数据冗余。 此外,Redis 的设计允许许多客户机(默认情况下最多可达10000个)连接并与数据交互,使其成为许多用户需要访问相同数据集的情况下的一个很好的选择。

本教程将介绍用于管理 Redis 客户机和副本的命令。

如何使用本指南

本指南是作为包含自包含示例的备忘单编写的。 我们鼓励您跳转到任何与您正在尝试完成的任务相关的部分。

本指南中显示的命令是在运行 Redis 4.0.9版本的 Ubuntu 18.04服务器上测试的。 要建立一个类似的环境,你可以按照我们关于如何在 Ubuntu 18.04上安装和保护 Redis 的指南的第一步。 我们将通过使用 Redis-cli (Redis 命令行界面)运行这些命令来演示它们的行为。 请注意,如果您使用的是不同的 Redis 接口ーー例如 Redli ーー某些命令的确切输出可能会有所不同。

或者,您可以提供一个托管 Redis 数据库实例来测试这些命令,但是请注意,根据您的数据库提供程序所允许的控制级别,本指南中的某些命令可能不能像描述的那样工作。 要提供一个数字数据库管理数据库,请遵循我们的管理数据库产品文档。 然后,必须安装 Redli 或设置 TLS 通道,以便通过 TLS 连接到托管数据库。

注: Redis 项目在其文档和各种命令中使用了术语“ master”和“ slave” ,以确定复制中的不同角色,不过项目贡献者正在采取措施,在不会导致兼容性问题的情况下更改这种语言。 Digitalocean 通常倾向于使用替代术语“ primary”和“ replica”。 本指南将尽可能默认使用“ primary”和“ replica” ,但请注意,在某些情况下不可避免地会出现术语“ master”和“ slave”。

管理副本

Redis 最显著的特点之一是其内置的复制功能。 在使用复制时,Redis 创建主实例的精确副本。 这些辅助实例在其连接中断时重新连接到主实例,并将始终致力于保持主实例的精确副本。

如果您不确定当前连接到的 Redis 实例是主实例还是副本,可以运行 role 命令进行检查:

  • role

如果使用 Redis Sentinel,这个命令将返回 master 或 slave,或者 Sentinel。

若要将 Redis 实例指定为另一个实例的动态副本,请运行命令副本。 这个命令以预期的主服务器的主机名或 IP 地址和端口作为参数:

  • replicaof hostname_or_IP port

如果服务器已经是另一个主服务器的副本,它将停止复制旧服务器,并立即开始与新服务器同步。 它还将放弃旧的数据集。

要将副本提升为主要副本,请运行以下命令副本:

  • replicaof no one

这将阻止实例复制主服务器,但不会放弃已复制的数据集。 这种语法在原始主系统失败的情况下很有用。 在失败的主副本上运行无人副本之后,前一个副本可以用作新的主副本,并拥有自己的副本作为故障保护。

注意: 在5.0.0版本之前,Redis 包含了这个命令的一个版本 slaveof。

管理客户

客户端是连接到服务器以访问服务的任何机器或软件。 Redis 附带了几个命令,可以帮助跟踪和管理客户机连接。

客户端列表命令返回一组关于当前客户端连接的可读信息:

  • client list
Output
"id=18165 addr=[2001:db8:0:0::12]:47460 fd=7 name=jerry age=72756 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ping id=18166 addr=[2001:db8:0:1::12]:47466 fd=8 name= age=72755 idle=5 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=info id=19381 addr=[2001:db8:0:2::12]:54910 fd=9 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=32742 obl=0 oll=0 omem=0 events=r cmd=client "

下面是每个字段的意思:

  • id : a unique 64-bit client ID
  • Name: 客户端连接的名称,由之前的客户端 setname 命令定义
  • 客户端连接的地址和端口
  • Fd: 与客户端连接的套接字对应的文件描述符
  • 年龄: 客户端连接的总持续时间,以秒为单位
  • 标志: 一组或多个单字符标志,提供有关客户端的更详细的信息; 有关详细信息,请参阅客户端列表命令文档
  • Db: 客户端连接的当前数据库 ID 号(可以从0到15)
  • Sub: 客户端订阅的通道数
  • Psub: 客户端模式匹配订阅的数量
  • Mutli: 客户端在事务中排队的命令数量(如果客户端尚未开始事务,将显示 -1; 如果客户端仅仅开始事务,而没有排队任何命令,则显示0)
  • Qbuf: 客户端的查询缓冲区长度,0表示它没有挂起的查询
  • Qbuf-free: 客户端查询缓冲区中的可用空间量,0表示查询缓冲区已满
  • 客户端的输出缓冲区长度
  • Oll: 客户端输出列表的长度,当缓冲区已满时,应答将在该列表中排队
  • 客户端输出缓冲区使用的内存
  • Events: 客户端的文件描述符事件,这些事件可以是 r 表示“可读” ,w 表示“可写” ,或者两者兼有
  • Cmd: 客户机运行的最后一个命令

设置客户端名称对于在任何使用 Redis 的应用程序中调试连接泄漏非常有用。 每个新连接都在没有分配名称的情况下启动,但是客户端设置名称可用于为当前客户端连接创建一个名称。 客户端名称的长度没有限制,尽管 Redis 通常将字符串长度限制为512 MB。 但是请注意,客户端名称不能包含空格:

  • client setname elaine

要检索客户端连接的名称,请使用 client getname 命令:

  • client getname
Output
"elaine"

要检索客户机的连接 ID,请使用客户机 ID 命令:

  • client id
Output
(integer) "19492"

Redis 客户端 id 不会重复,并且是单调增量的。 这意味着,如果一个客户机的 ID 大于另一个客户机,那么它是在以后建立的。

阻塞客户端和关闭客户端连接

复制系统通常被描述为同步或异步的。 在同步复制中,每当客户机添加或更改数据时,它必须从一定数量的副本接收某种确认,以便将更改注册为已提交。 这有助于防止节点发生数据冲突,但代价是延迟,因为客户机必须等待执行另一个操作,直到收到一定数量的副本的回复。

另一方面,在异步复制中,一旦数据写入本地存储,客户机就会看到确认操作已经完成。 然而,这与副本实际写入数据之间可能存在滞后。 如果其中一个副本在写入更改之前失败,那么这个写操作将永远丢失。 因此,虽然异步复制允许客户端继续执行操作而不必等待副本引起的延迟,但它可能会导致节点之间的数据冲突,并可能需要数据库管理员控制中心的额外工作来解决这些冲突。

由于 Redis 侧重于性能和低延迟,因此默认情况下实现了异步复制。 但是,可以使用 wait 命令模拟同步复制。 Wait 会在指定的时间内(以毫秒为单位)阻塞当前客户端连接,直到所有以前的写命令都被成功传输并被指定数量的副本接受。 这个命令使用以下语法:

  • wait number_of_replicas number_of_milliseconds

例如,如果您希望在30毫秒超时内阻塞客户端连接,直到所有以前的写操作都被至少3个副本注册,那么您的等待语法如下:

  • wait 3 30

等待命令返回一个整数,表示确认写命令的副本数量,即使不是每个副本都这样做:

Output
2

要解除之前被阻塞的客户端连接的阻塞,无论是通过 wait、 brpop 还是 xread 命令,您都可以运行一个客户端解除阻塞命令,其语法如下:

  • client unblock client_id

要临时挂起当前连接到 Redis 服务器的所有客户端,可以使用客户端暂停命令。 在需要以受控的方式更改 Redis 设置的情况下,这非常有用。 例如,如果您正在将您的一个副本提升为主实例,您可能会事先暂停每个客户端,以便您可以提升副本,并让客户端连接到它作为新的主实例,而不会在过程中丢失任何写操作。

客户端暂停命令要求您指定要挂起客户端的时间量(以毫秒为单位)。 下面的示例将暂停所有客户机一秒钟:

  • client pause 1000

客户端 kill 语法允许您基于许多不同的过滤器关闭单个连接或一组特定的连接。 语法如下:

  • client kill filter_1 value_1 ... filter_n value_n

在 Redis 2.8.12及以后的版本中,可以使用以下过滤器:

  • Addr: 允许您从指定的 IP 地址和端口关闭客户端连接
  • Client-ID: 允许根据客户机连接的唯一 ID 字段关闭客户机连接
  • 类型: 关闭给定类型的所有客户端,这些客户端可以是普通客户端、主客户端、从客户端或 pubsub 客户端
  • 这个过滤器的值选项是 yes 和 no: 如果指定了 no,那么调用 client kill 命令的客户机将不会被跳过,如果指定了 yes,那么其他过滤器将被应用到这个过滤器,运行该命令的客户机将被跳过,kill 命令将不会对客户机产生影响。 缺省情况下,斯基普总是“是”

总结

本指南详细介绍了用于管理 Redis 客户机和副本的许多命令。 如果还有其他相关的命令、参数或者程序你想在本指南中看到,请在下面的评论中询问或者提出建议。

有关 Redis 命令的更多信息,请参见我们关于如何管理 Redis 数据库的系列教程。