Redis副本与客户端管理:高效运维实践指南

简介

Redis是一种开源的内存键值数据存储系统。其最受欢迎的功能之一是其支持数据复制。任何Redis服务器都可以将其数据复制到任意数量的副本中,从而实现高度的读扩展性和强大的数据冗余。此外,Redis被设计为允许许多客户端(默认情况下最多10,000个)连接并与数据交互,使其成为在许多用户需要访问相同数据集的情况下的良好选择。

本教程将概述用于管理Redis客户端和副本的命令。

如何使用本指南

本指南是一个包含自成体系示例的速查表。我们鼓励您直接跳转到与您正在完成的任务相关的任何部分。

本指南中显示的命令已在运行Redis版本6.0.16的Ubuntu 22.04服务器上进行了测试。要设置类似的环境,您可以按照我们在《如何在Ubuntu 22.04上安装和保护Redis》指南的第一步进行操作。我们将通过使用Redis命令行接口redis-cli来运行这些命令,演示它们的行为。如果您使用不同的Redis接口,例如Redli,某些命令的确切输出可能会有所不同。

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

注意

请注意:Redis项目在其文档和各种命令中使用术语“master”来标识复制中的不同角色,尽管项目的贡献者正在采取措施在不影响兼容性的情况下更改这种语言。Silicon Cloud通常更倾向于使用另一种术语“primary”和“replica”。本指南在可能的情况下默认使用“primary”和“replica”,但请注意,仍然有一些情况下不可避免地会出现术语“master”。

管理副本

Redis的一个最显著特点就是其内建的复制功能。在使用复制时,Redis会创建主实例的完全副本。这些副本实例在连接中断时会重新连接到主实例,并始终力求保持与主实例完全一致的状态。

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

  1. 127.0.0.1:6379> role

 

这条命令将返回主节点或从节点,或者如果你使用Redis Sentinel,还有可能返回哨兵节点。

为了将一个 Redis 实例即时指定为另一个实例的副本,运行 replicaof 命令。该命令通过指定主要服务器的主机名或 IP 地址以及端口作为参数来实现。

  1. 127.0.0.1:6379> replicaof hostname_or_IP port

 

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

要将一个副本重新提升为主节点,请运行以下的replicaof命令:

  1. 127.0.0.1:6379> replicaof no one

 

这将阻止实例复制主服务器,但不会丢弃它已经复制的数据集。这种语法在原始主服务器出现故障的情况下非常有用。在运行了 “replicaof no one” 命令后,原来的副本可以作为新的主服务器使用,并且拥有自己的副本作为备用。

处理客户端

客户端是指任何连接到服务器以访问服务的设备或软件。Redis提供了几个命令来帮助追踪和管理客户端连接。

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

  1. 127.0.0.1:6379> client list

 

输出

这是文章《如何管理Redis中的副本和客户端》的第2部分(共3部分)。

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号。范围从0到15
  • sub: 客户端订阅的频道数量
  • psub: 客户端的模式匹配订阅数量
  • multi: 客户端在事务中排队的命令数量。如果客户端尚未开始事务,则显示-1;如果已开始事务但未排队任何命令,则显示0
  • qbuf: 客户端的查询缓冲区长度,0表示没有待处理的查询
  • qbuf-free: 客户端查询缓冲区中的可用空间量,0表示查询缓冲区已满
  • obl: 客户端的输出缓冲区长度
  • oll: 客户端输出列表的长度,当其缓冲区已满时,回复会在此处排队
  • omem: 客户端输出缓冲区使用的内存
  • events: 客户端的文件描述符事件。可以是“r”表示“可读”,“w”表示“可写”,或两者兼有
  • cmd: 客户端运行的最后一个命令

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

  1. client setname elaine

使用客户端的getname命令来获取客户端连接的名称。

  1. client getname
输出
"elaine"

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

  1. client id
输出
(integer) "19492"

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

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

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

在异步复制中,一旦数据被写入本地存储,客户端会收到操作完成的确认。然而,在实际复制数据之前,可能存在一个延迟。如果其中一个副本在写入更改之前发生故障,那么该写入将永远丢失。因此,尽管异步复制允许客户端继续执行操作而无需等待副本的延迟,但它可能导致节点之间的数据冲突,并可能需要数据库管理员额外的工作来解决这些冲突。

由于Redis专注于性能和低延迟,它默认实现了异步复制。然而,你可以通过WAIT命令模拟同步复制。WAIT命令会阻塞当前客户端连接,直到所有先前的写入命令成功传输并被指定数量的副本接受。此命令的语法如下:

  1. wait number_of_replicas number_of_milliseconds

例如,如果您想要在30毫秒的超时时间内,等待直到所有先前的写入至少被3个副本注册完毕,您可以使用以下等待语法。

  1. wait 3 30

即使不是每个副本都确认写入命令,WAIT命令仍然返回一个表示确认写入的副本数量的整数。

输出

这是文章《如何管理Redis中的副本和客户端》的第3部分(共3部分)。

要解除先前被阻塞的客户端连接,无论是从等待、BRPOP或XREAD命令,你可以运行CLIENT UNBLOCK命令,语法如下:

127.0.0.1:6379> CLIENT UNBLOCK <client_id>

为了暂时暂停当前连接到Redis服务器上的每个客户端,您可以使用CLIENT PAUSE命令。在需要以可控的方式更改Redis设置的情况下,这非常有用。例如,如果你要将其中一个Redis副本升级为主实例,你可以在此之前暂停每个客户端,这样你就可以升级副本并使客户端连接到它作为新的主实例,而在此过程中不会丢失任何写操作。

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

127.0.0.1:6379> CLIENT PAUSE 1000

CLIENT KILL语法允许您关闭单个连接或基于多个不同过滤器的特定连接集合。该语法的书写格式如下:

127.0.0.1:6379> CLIENT KILL <filter_1> <value_1> ... <filter_n> <value_n>

以下过滤器可用:

  • addr: 允许您关闭来自指定IP地址和端口的客户端连接。
  • client-id: 允许您根据客户端的唯一ID字段关闭连接。
  • type: 关闭给定类型的所有客户端,类型可以是normal(普通)、master(主节点)、replica(副本)或pubsub(发布/订阅)。
  • skipme: 此过滤器的值选项为yesno
    • 如果指定no,则调用CLIENT KILL命令的客户端不会被跳过,如果其他过滤器适用于它,它将被终止。
    • 如果指定yes,则运行该命令的客户端将被跳过,并且KILL命令对其没有影响。skipme默认始终为yes

结论

本指南详细介绍了用于管理Redis客户端和副本的一系列命令。如果您对本指南中的其他相关命令、参数或操作有任何问题或建议,请在评论中提出。

若想获取更多有关Redis命令的信息,请查看我们的教程系列《如何管理Redis数据库》。

bannerAds