Redis 系列教程导航

  1. 如何在 Ubuntu 18.04 上安装和保护 Redis
  2. 如何连接到 Redis 数据库
  3. 如何管理 Redis 数据库和 Keys
  4. 如何在 Redis 中管理副本和客户端
  5. 如何在 Redis 中管理字符串
  6. 如何在 Redis 中管理 List
  7. 如何在 Redis 中管理 Hashes
  8. 如何在 Redis 中管理 Sets
  9. 如何在 Redis 中管理 Sorted Sets
  10. 如何在 Redis 中运行事务
  11. 如何使 Redis 中的 Key 失效
  12. 如何解决 Redis 中的故障
  13. 如何从命令行更改 Redis 的配置
  14. Redis 数据类型简介

介绍

Redis 是一个开源的内存键值存储系统。它最受欢迎的功能之一是对复制(Replication)的支持:任何 Redis 服务器都可以将其数据复制到任意数量的副本中,从而实现高读取可伸缩性和强大的数据冗余性。此外,Redis 设计允许许多客户端(默认情况下最多 10,000 个)连接数据并与之交互,因此对于许多用户需要访问同一数据集的情况而言,它是一个不错的选择。

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

如何使用本指南

本指南以备有完整示例的速查表(Cheatsheet)形式编写。我们鼓励您跳至与您要完成的任务相关的任何部分。

本指南中显示的命令已在运行 Redis 版本 4.0.9 的 Ubuntu 18.04 服务器上进行了测试。要设置类似的环境,您可以按照我们的指南 如何在 Ubuntu 18.04 上安装和保护 Redis步骤 1 进行操作。我们将通过使用 Redis 命令行界面 redis-cli 运行它们来演示这些命令的行为。请注意,如果您使用其他 Redis 界面(例如 Redli),则某些命令的确切输出可能会有所不同。

另外,您可以提供一个托管的 Redis 数据库实例来测试这些命令,但是请注意,根据数据库提供者所允许的控制级别,本指南中的某些命令可能无法按所述方式工作。要配置 DigitalOcean 托管数据库,请遵循我们的 托管数据库产品文档。然后,您必须 安装 Redli 设置 TLS 隧道 才能通过 TLS 连接到托管数据库。

注意: Redis 项目在其文档和各种命令中使用术语“主(Master)”和“从(Slave)”来标识复制中的不同角色,尽管该项目的参与者 正在采取措施 在不引起兼容性问题的情况下 更改此语言。DigitalOcean 通常更喜欢使用替代术语“主要(Primary)”和“副本(Replica)”。

本指南将在可能的情况下默认设置为“主要”和“副本”,但请注意,在某些情况下不可避免地会出现“主”和“从”这两个术语。

管理副本

Redis 最具特色的功能之一是其 内置的复制功能。使用复制时,Redis 创建主实例的精确副本。这些辅助实例在其连接断开时会随时重新连接至主要实例,并且始终旨在保持主要实例的精确副本。

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

role

如果您使用 Redis Sentinel,则此命令将返回 masterslave,或者可能返回 sentinel

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

replicaof hostname_or_IP port

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

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

replicaof no one

这将阻止实例复制主服务器,但不会丢弃已复制的数据集。在原始主数据库失败的情况下,此语法很有用。在 replicaof no one 发生故障的主数据库的副本上运行之后,以前的副本可以用作新的主数据库,并拥有自己的副本作为故障保护。

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

管理客户端

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

client list 命令返回一组有关当前客户端连接的可读信息:

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唯一的 64 位客户端 ID
name客户端连接的名称,由先前的 client setname 命令定义
addr客户端连接的地址和端口
fd与客户端所连接的套接字相对应的 文件描述符
age客户端连接的总时长,以秒为单位
flags一组一个或多个单字符标志,可提供有关客户端的更详细的信息;有关更多详细信息,请参见 client list 命令文档
db客户端连接到的当前数据库 ID 号(可以从 015
sub客户端订阅的频道数
psub客户端的模式匹配订阅数
multi客户端已在 事务中 排队的命令数(将显示 -1 客户端是否尚未开始事务或 0 是否仅已开始事务且未排队任何命令)
qbuf客户端的查询缓冲区长度,0 这意味着它没有待处理的查询
qbuf-free客户端查询缓冲区中的可用空间量,0 表示查询缓冲区已满
obl客户端的输出缓冲区长度
oll客户端的输出列表的长度,当客户端的缓冲区已满时,将在其中排队答复
omem客户端的输出缓冲区使用的内存
events客户端的文件描述符事件,可以是 r“可读”,w“可写”或两者兼有
cmd客户端运行的最后一条命令

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

client setname elaine

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

client getname
Output
"elaine"

要获取客户端的连接 ID,请使用以下 client id 命令:

client id
"19492"

Redis 客户端 ID 永远不会重复,并且会单调递增。这意味着,如果一个客户端的 ID 大于另一个客户端,则它是在以后的时间建立的。

阻止客户端并关闭客户端连接

复制系统通常被描述为 同步 或 _异步_。

  • 同步复制:每当客户端添加或更改数据时,客户端都必须从一定数量的副本中收到某种确认,以使更改注册为已提交。这有助于防止节点发生数据冲突,但是这会增加延迟,因为客户端必须等待执行另一项操作,直到从一定数量的副本中收到回音为止。
  • 异步复制:一旦将数据写入本地存储,客户端就会看到确认操作已完成的确认。但是,这与副本实际写入数据的时间之间可能会有滞后。如果其中一个副本在写入更改之前失败,则该写入将永远丢失。因此,尽管异步复制允许客户端继续执行操作而没有等待副本引起的延迟,但它可能导致节点之间的数据冲突,并且可能需要数据库管理员方面的额外工作来解决这些冲突。

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

wait number_of_replicas number_of_milliseconds

例如,如果要在 30 毫秒的超时时间内至少 3 个副本注册所有先前的写入操作之前阻止客户端连接,则 wait 语法应如下所示:

wait 3 30

wait 命令返回一个整数,该整数表示已确认写入命令的副本数,即使并非每个副本都这样做:

2

要解除阻止以前通过 waitbrpop,或 xread)命令阻止的客户端连接,可以 client unblock 使用以下语法运行命令:

client unblock client_id

要暂时挂起当前连接到 Redis 服务器的每个客户端,可以使用以下 client pause 命令。这在需要以受控方式更改 Redis 设置的情况下很有用。例如,如果要将一个副本提升为主实例,则可以事先暂停每个客户端,以便升级副本并使客户端作为新的主实例连接到该副本,而不会丢失任何写操作。

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

client pause 1000

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

client kill filter_1 value_1 ... filter_n value_n

在 Redis 2.8.12 和更高版本中,可以使用以下过滤器:

  • addr:允许您从指定的 IP 地址和端口关闭客户端连接
  • client-id:允许您根据其唯一 ID 字段关闭客户端连接
  • type:关闭一个给定类型,它可以是每一个客户端 normalmasterslave,或 pubsub
  • skipme:此过滤器的值选项为 yesno

    • 如果 no 指定了,则调用该 client kill 命令的客户端不会被跳过,并且如果其他过滤器应用到该客户端,它将被杀死
    • 如果 yes 指定,则将跳过运行该命令的客户端,而 kill 命令将对该客户端无效。skipme 始终 yes 默认为

结论

本指南详细介绍了用于管理 Redis 客户端和副本的许多命令。如果您想在本指南中概述其他相关的命令、参数或过程,请在下面的评论中提出疑问或提出建议。

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


说明: 本文内容基于 Redis 4.0.9 版本及 Ubuntu 18.04 环境测试。请注意,Redis 5.0.0 及以上版本在复制命令上有所变更(如 slaveof 变更为 replicaof),部分命令行为在新版本中可能有所不同。