Skip to content

Redis 管理器

PySpigot 包含一个 Redis 管理器,允许你连接并与 Redis 服务器进行交互。在内部,PySpigot 利用 lettuce 与远程 Redis 服务器实例进行交互。RedisManager 提供两种与 Redis 服务器交互的方式:发出命令(例如与 Redis 数据库交互)以及发布和订阅 Redis 的 pub/sub 消息系统。在 PySpigot 中,这些通过 RedisCommandClient 和 RedisPubSubClient 分别实现。此外,PySpigot 还包括一个通用的 ScriptRedisClient,如果你想要处理其他 Redis 方面,比如 Redis 哨兵或 Redis 集群,你可以创建该客户端。

有关如何将 Redis 管理器导入到你的脚本中的说明,请访问通用信息页面。

注意

这并不是一个全面的使用 Redis 的指南。如果有疑问,请寻找适当的教程/信息。

Redis 客户端类型

出于组织目的,根据你的特定用例,有三种不同类型的 Redis 客户端可供选择使用。在通过 Redis 管理器初始化/打开 Redis 客户端时,可以使用 ClientType 参数指定这些客户端类型。可用的客户端类型包括:

  • ClientType.BASIC:这是一个没有内置功能的通用 Redis 客户端。如果其他两种 Redis 客户端类型不太合适你的特定用例,可以使用它。
  • ClientType.COMMAND:这种客户端类型允许在 Redis 服务器上提交和执行命令。
  • ClientType.PUB_SUB:这种客户端允许连接到 Redis 并发布/订阅 Redis pub/sub 消息通道。

根据你的具体使用情况,你会选择使用哪个客户端。例如,如果你想订阅和发布到一个 Redis 的 pub/sub 频道,你应该使用 PUB_SUB 客户端类型。如果你想同时做多件事情,你应该为每种活动类型打开一个新连接。例如,如果你希望同时使用 pub/sub 消息和命令,你应该打开两个连接,一个使用 COMMAND 客户端类型,另一个使用 PUB_SUB 客户端类型。

提示

Lettuce 库包括同步和异步操作功能,在 PySpigot 中也有相应体现。例如,pub/sub 客户端能够同步和异步发布消息。在大多数情况下,你应该以异步方式执行操作。

通用(基本)Redis 客户端

基本的 Redis 客户端提供对底层 RedisClient 的访问,让你可以访问任何你希望的内容。不实现其他功能。与此客户端类型对应的对象是 ScriptRedisClient

可用功能:

  • getRedisURI(): 获取与客户端关联的 RedisURI。
  • getClientOptions(): 获取与客户端关联的 ClientOptions。
  • getRedisClient(): 获取与 ScriptRedisClient 关联的底层 redis 客户端。

欲了解更多信息,请参阅 lettuce 文档的基本用法部分。在下面的代码示例部分查看示例用法。

命令客户端允许在redis服务器上提交和执行命令。Lettuce支持400多个命令;这些命令都可以在本节末尾的lettuce文档链接中查看。对应于此客户端类型的对象是 RedisCommandClient

可用函数:

  • 所有上述通用ScriptRedisClient中的函数,以及:
  • getConnection(): 返回客户端的有状态redis连接。
  • getCommands(): 返回表示客户端连接的RedisCommands API的RedisCommands对象。
  • getAsyncCommands(): 返回表示客户端连接的RedisAsyncCommands API的RedisAsyncCommands对象。

有关更多信息,请参阅lettuce文档的Command Interfaces部分。有关示例用法,请参见下面的示例代码部分。

发布/订阅客户端

发布/订阅客户端允许在redis服务器上订阅和发布消息通道。对应于此客户端类型的对象是 RedisPubSubClient

可用函数:

  • 如上所述,在通用的ScriptRedisClient中的所有功能,以及:
  • registerListener(function, channel): 注册一个新的同步监听器。接受一个函数作为参数,当接收到消息时将调用该函数,以及频道的名称 channel 进行监听。返回一个 ScriptPubSubListener 对象,代表已注册的监听器。
  • registerSyncListener(function, channel): 注册一个新的同步监听器。接受一个函数作为参数,当接收到消息时将调用该函数,以及频道的名称 channel 进行监听。返回一个 ScriptPubSubListener 对象,代表已注册的监听器。
  • registerAsyncListener(function, channel): 注册一个新的异步监听器。接受一个函数作为参数,当接收到消息时将调用该函数,以及频道的名称 channel 进行监听。返回一个 ScriptPubSubListener 对象,代表已注册的监听器。
  • unregisterListener(listener): 取消注册监听器。接受一个要取消注册的 ScriptPubSubListener
  • unregisterListeners(channel): 取消注册所有在提供的频道上正在监听的监听器。
  • publish(channel, message): 同步发布消息到指定的频道。提供要发布到的频道以及要发布的消息作为参数。返回代表接收到消息的客户端数的数字。
  • publishSync(channel, message): 同步发布消息到指定的频道。提供要发布到的频道以及要发布的消息作为参数。返回代表接收到消息的客户端数的数字。
  • publishAsync(channel, message): 异步发布消息到指定的频道。提供要发布到的频道以及要发布的消息作为参数。返回一个 future,当操作完成时将返回一个代表接收到消息的客户端数的数字。

要获取更多信息,请查看 lettuce 文档中的 发布/订阅 部分。 请查看下面的 示例用法 部分。

使用 Redis 管理器

在 redis 管理器中有一些可用的函数,方便您与 redis 服务器进行交互。它们包括:

  • newRedisURI(): 返回一个新的、空的 RedisURI 构建器,方便使用。
  • newClientOptions(): 返回一个新的 ClientOptions 构建器,方便使用。
  • openRedisClient(clientType, ip, port, password): 使用指定的 client 类型,通过指定的 IP、端口和密码打开与远程 redis 服务器的连接。使用默认的 client 选项。
  • openRedisClient(clientType, ip, port, password, clientOptions): 使用指定的 client 类型,通过指定的 IP、端口和密码打开与远程 redis 服务器的连接。使用提供的 client 选项。
  • openRedisClient(clientType, redisURI): 使用指定的 client 类型,通过给定的 RedisURI 连接字符串打开与远程 redis 服务器的连接。使用默认的 client 选项。
  • openRedisClient(clientType, redisURI, clientOptions): 使用指定的 client 类型,通过给定的 RedisURI 连接字符串打开与远程 redis 服务器的连接。使用提供的 client 选项。
  • closeRedisClient(client): 关闭提供的 redis 客户端。
  • closeRedisClientAsync(client): 异步关闭提供的 redis 客户端。
提示

如果你使用完了 Redis 客户端,最好的做法是将其关闭。如果在执行脚本时或脚本终止时有任何未关闭的 Redis 客户端,则这些未关闭的客户端将会自动关闭。如果在事务执行过程中或者待执行事务中关闭 Redis 客户端,客户端将尝试等待挂起的事务完成后再关闭,但无法保证事务将成功完成。

RedisURI

RedisURI 构建器是一个方便的对象,允许你轻松构建用于连接到远程 Redis 服务器的 URI 连接字符串。使用 URI 可能是与远程 Redis 服务器建立连接的最便捷方式,因为你还可以在 URI 中指定连接设置,还可以指定 IP、端口、密码等。有关用法的更多信息,请参阅 lettuce 文档

在 Redis 管理器中提供了一个 newRedisURI() 函数,方便获取一个新的 RedisURI 构建器对象。

Redis ClientOptions

ClientOptions 构建器对象是 lettuce 提供的一个方便对象,允许你更好地控制与连接相关的设置。例如,它允许你设置自动重连、缓冲使用比例和请求队列大小。有关 ClientOptions 的更多信息,请参阅 lettuce 文档

在 Redis 管理器中提供了一个 newClientOptions() 函数,方便获取一个新的 ClientOptions 构建器对象。

代码示例

一般客户端示例

以下示例演示了如何使用基本客户端连接到远程 Redis 服务器。

 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
import pyspigot as ps # (1)!
from dev.magicmq.pyspigot.manager.redis import ClientType # (2)!

# 这里我们导入 PySpigot as `ps` 来使用 Redis 管理器。

# 这里我们引入 `ClientType`,以便稍后使用。

# 获取来自 `ps` 的数据库管理器,并将其设置为 `redis`。
redis = ps.redis_manager() # (3)!

# 在这里,我们以 `BASIC` 客户端类型打开一个新的 Redis 客户端,使用提供的 IP/地址、端口和无密码。我们将连接的客户端赋给 `basic_client`。
basic_client = redis.openRedisClient(ClientType.BASIC, 'localhost', '6379', None) # (4)!

# 从 PySpigot 基础客户端获取底层 Redis 客户端,并将其赋给 `client`。此时,您可以随意处理底层 Redis 客户端。
client = redis_client.getRedisClient() # (5)!

# 在底层 Redis 客户端上执行一些操作...

### 命令客户端示例

以下示例使用命令客户端连接并向远程 Redis 服务器提交命令

``` py linenums="1"
import pyspigot as ps # (1)!
from dev.magicmq.pyspigot.manager.redis import ClientType # (2)!

# 这里我们导入 PySpigot as `ps` 来使用 Redis 管理器。

# 这里我们引入 `ClientType`,以便稍后使用。

# 获取来自 `ps` 的数据库管理器,并将其设置为 `redis`。
redis = ps.redis_manager() # (3)!

# 使用 `COMMAND` 客户端类型,使用提供的 IP/地址、端口和无密码打开一个新的 Redis 客户端。我们将连接的客户端赋给 `command_client`。
command_client = redis.openRedisClient(ClientType.COMMAND, 'localhost', '6379', None) # (4)!

# 获取命令客户端的命令集合,并将其赋给 `commands`。
commands = command_client.getCommands() # (5)!

# 将 'test_record' 设置为 'Helloredis!'。
commands.set('test_record', 'Helloredis!') # (6)!

# 打印 'test_record' 的值。
print(commands.get('test_record')) # (7)!
  1. 在这里,我们从命令客户端获取redis命令,并将其赋值给commands变量。

  2. 在这里,我们提交一个新的命令记录test_record,其值为Helloredis!

  3. 在这里,我们通过从commands获取命令记录并打印其值来验证已提交的命令。

Pub/Sub客户端示例

以下示例利用pub/sub客户端连接到远程redis服务器,并订阅和提交消息到其pub/sub消息系统。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import pyspigot as ps # (1)!
from dev.magicmq.pyspigot.manager.redis import ClientType # (2)!

redis = ps.redis_manager() # (3)!

pub_sub_client = redis.openRedisClient(ClientType.PUB_SUB, 'localhost', '6379', None) # (4)!

def message_received(channel, message): # (5)!
    print(f'在频道 \'{channel}\' 收到消息:{message}')

listener = pub_sub_client.registerAsyncListener(message_received, 'test_channel') # (6)!

num_received = pub_sub_client.publishAsync('test_channel', '这是一条测试消息!') # (7)!

pub_sub_client.unregisterListener(listener) # (8)!
  1. 在这里,我们导入PySpigot并将其命名为ps以使用redis管理器。

  2. 在这里,我们导入ClientType以便稍后使用。

  3. 在这里,我们从ps获取数据库管理器并将其设置为redis

  4. 在这里,我们使用提供的IP地址、端口和无密码打开一个新的redis客户端,其中client_typePUB_SUB,并将连接的客户端赋值给pub_sub_client

  5. 在这里,我们定义一个名为message_received的新函数,接受两个参数:channel(一个字符串)和message(也是一个字符串)。在函数内部,我们打印一个包含channelmessage的消息。

  6. 在这里,我们注册一个新的异步监听器,传入先前定义的函数message_received,以及我们想要监听的通道(在此例中是test_channel)。我们将注册的监听器分配给listener,以便稍后可以取消注册。

  7. 在这里,我们异步发布一条消息到通道test_channel,内容为这是一条测试消息!。所有发布消息到通道的函数(同步和异步)都会返回一个值,表示接收消息的客户端数量。我们将这个值赋给num_received

  8. 在这里,我们通过将listener传递给unregisterListener函数来取消先前注册的监听器。

Note

当在test_channel通道收到消息时,message_received函数会被自动调用,并将传递通道的名称(channel参数,在此例中为test_channel)以及消息的内容(message参数)。

Note

请注意,由于消息是异步发布的,num_received是一个RedisFuture对象。需要额外的代码(此处未显示)来从该对象中获取值。如果需要帮助,请在Discord上询问。

Warning

如前所述,函数包括以同步和异步方式执行redis操作。一般而言,最好以异步方式执行操作,以避免服务器挂起和延迟(因为大多数这些函数执行与远程redis服务器的交互,这些都是I/O操作,因此完成速度相对较慢)。

摘要

  • RedisManager允许您连接和与远程Redis服务器交互。
  • 有三种可用的客户端类型: ClientType.BASICClientType.COMMANDClientType.PUB_SUB。您应该根据您的具体用例选择使用哪一种。
  • 使用openRedisClient函数(根据您的具体情况,还可以使用客户端类型和其他提供的选项)来连接到Redis服务器。
  • 连接到Redis服务器时,openRedisClient函数会返回一个Redis客户端对象(将是ScriptRedisClientRedisCommandClientRedisPubSubClient中的一个,取决于指定的客户端类型),然后用它与 Redis 进行交互。
  • 与Redis进行交互是一种 I/O操作 。除非在非常有限的情况下,应该使用异步函数而不是同步函数。例如,如果使用RedisPubSubClient,应该使用publishAsync而不是publishpublishSync
  • 在脚本停止时,Redis客户端会自动关闭。在其他任何时间,如果您完成了对Redis客户端的使用,应通过从Redis管理器调用closeRedisClientcloseRedisClientAsync来关闭它。closeRedisClient/closeRedisClientAsync函数需要打开客户端时返回的Redis客户端对象。