当前位置:首页>python>Python 连接 Redis Cluster

Python 连接 Redis Cluster

  • 2026-02-07 01:01:25
Python 连接 Redis Cluster

redis-py 现已支持集群模式,并为 Redis 集群提供客户端支持。该集群客户端基于 Grokzen 的 redis-py-cluster 实现,在修复若干缺陷后现已取代原有库。

连接集群

redis-py 连接到 Redis 集群实例时,至少需要一个节点用于集群发现。创建集群实例有多种方式:

1.使用 host 和 ip 参数

>>> from redis.cluster import RedisCluster as Redis>>> rc = Redis(host='192.168.137.3', port=6379,password="pw")>>> print(rc.get_nodes())[[host=127.0.0.1,port=6379,name=127.0.0.1:6379,server_type=primary,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f9bcdc60fd0>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f9bcdc49fd0>>,credential_provider=None,protocol=2,host=127.0.0.1,port=6379,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>], [host=192.168.137.4,port=6380,name=192.168.137.4:6380,server_type=replica,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f9bcdae5700>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f9bcdc49fd0>>,credential_provider=None,protocol=2,host=192.168.137.4,port=6380,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>], [host=192.168.137.5,port=6379,name=192.168.137.5:6379,server_type=primary,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f9bcdae5df0>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f9bcdc49fd0>>,credential_provider=None,protocol=2,host=192.168.137.5,port=6379,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>], [host=127.0.0.1,port=6380,name=127.0.0.1:6380,server_type=replica,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f9bcdaee520>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f9bcdc49fd0>>,credential_provider=None,protocol=2,host=127.0.0.1,port=6380,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>], [host=192.168.137.4,port=6379,name=192.168.137.4:6379,server_type=primary,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f9bcdaeec10>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f9bcdc49fd0>>,credential_provider=None,protocol=2,host=192.168.137.4,port=6379,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>], [host=192.168.137.5,port=6380,name=192.168.137.5:6380,server_type=replica,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f9bcdafa340>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f9bcdc49fd0>>,credential_provider=None,protocol=2,host=192.168.137.5,port=6380,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>]]>>> 

如果使用从节点呢?也是同样的效果

>>> from redis.cluster import RedisCluster as Redis>>> rc = Redis(host='192.168.137.3', port=6380,password="pw")>>> print(rc.get_nodes())[[host=127.0.0.1,port=6379,name=127.0.0.1:6379,server_type=primary,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f0cbfd1cfd0>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f0cbfd05fd0>>,credential_provider=None,protocol=2,host=127.0.0.1,port=6379,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>], [host=192.168.137.4,port=6380,name=192.168.137.4:6380,server_type=replica,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f0cbfba1700>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f0cbfd05fd0>>,credential_provider=None,protocol=2,host=192.168.137.4,port=6380,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>], [host=192.168.137.5,port=6379,name=192.168.137.5:6379,server_type=primary,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f0cbfba1df0>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f0cbfd05fd0>>,credential_provider=None,protocol=2,host=192.168.137.5,port=6379,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>], [host=192.168.137.3,port=6380,name=192.168.137.3:6380,server_type=replica,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f0cbfbaa520>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f0cbfd05fd0>>,credential_provider=None,protocol=2,host=192.168.137.3,port=6380,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>], [host=192.168.137.4,port=6379,name=192.168.137.4:6379,server_type=primary,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f0cbfbaac10>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f0cbfd05fd0>>,credential_provider=None,protocol=2,host=192.168.137.4,port=6379,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>], [host=192.168.137.5,port=6380,name=192.168.137.5:6380,server_type=replica,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f0cbfbb6340>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f0cbfd05fd0>>,credential_provider=None,protocol=2,host=192.168.137.5,port=6380,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>]]>>> 

2.使用 Redis URL 说明

>>> from redis.cluster import RedisCluster as Redis>>> rc1 = Redis.from_url("redis://:pw@localhost:6379/0")>>> print(rc1.get_nodes())[[host=192.168.137.3,port=6379,name=192.168.137.3:6379,server_type=primary,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(password=pw,db=0,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7fb5f7c8ae20>>,host=192.168.137.3,port=6379,retry=<redis.retry.Retry object at 0x7fb5f7c368e0>)>)>)>], [host=192.168.137.4,port=6380,name=192.168.137.4:6380,server_type=replica,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(password=pw,db=0,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7fb5f7c8ae20>>,host=192.168.137.4,port=6380,retry=<redis.retry.Retry object at 0x7fb5f7c62520>)>)>)>], [host=192.168.137.5,port=6379,name=192.168.137.5:6379,server_type=primary,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(password=pw,db=0,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7fb5f7c8ae20>>,host=192.168.137.5,port=6379,retry=<redis.retry.Retry object at 0x7fb5f7c58bb0>)>)>)>], [host=192.168.137.3,port=6380,name=192.168.137.3:6380,server_type=replica,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(password=pw,db=0,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7fb5f7c8ae20>>,host=192.168.137.3,port=6380,retry=<redis.retry.Retry object at 0x7fb5f7be6340>)>)>)>], [host=192.168.137.4,port=6379,name=192.168.137.4:6379,server_type=primary,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(password=pw,db=0,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7fb5f7c8ae20>>,host=192.168.137.4,port=6379,retry=<redis.retry.Retry object at 0x7fb5f7be8610>)>)>)>], [host=192.168.137.5,port=6380,name=192.168.137.5:6380,server_type=replica,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(password=pw,db=0,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7fb5f7c8ae20>>,host=192.168.137.5,port=6380,retry=<redis.retry.Retry object at 0x7fb5f7aa2670>)>)>)>]]>>> 

3.直接通过 ClusterNode 类

>>> from redis.cluster import RedisCluster as Redis>>> from redis.cluster import ClusterNode>>> nodes = [ClusterNode('localhost'6379), ClusterNode('localhost'6380)]>>> rc = Redis(startup_nodes=nodes, password='pw')>>> print(rc.get_nodes())[[host=127.0.0.1,port=6379,name=127.0.0.1:6379,server_type=primary,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f24c02a1f40>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f24c100a340>>,credential_provider=None,protocol=2,host=127.0.0.1,port=6379,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>], [host=192.168.137.4,port=6380,name=192.168.137.4:6380,server_type=replica,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f24c0108670>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f24c100a340>>,credential_provider=None,protocol=2,host=192.168.137.4,port=6380,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>], [host=192.168.137.5,port=6379,name=192.168.137.5:6379,server_type=primary,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f24c0108d60>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f24c100a340>>,credential_provider=None,protocol=2,host=192.168.137.5,port=6379,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>], [host=127.0.0.1,port=6380,name=127.0.0.1:6380,server_type=replica,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f24c0110490>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f24c100a340>>,credential_provider=None,protocol=2,host=127.0.0.1,port=6380,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>], [host=192.168.137.4,port=6379,name=192.168.137.4:6379,server_type=primary,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f24c0110b80>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f24c100a340>>,credential_provider=None,protocol=2,host=192.168.137.4,port=6379,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>], [host=192.168.137.5,port=6380,name=192.168.137.5:6380,server_type=replica,redis_connection=<redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(db=0,username=None,password=pw,socket_timeout=None,encoding=utf-8,encoding_errors=strict,decode_responses=False,retry_on_error=[],retry=<redis.retry.Retry object at 0x7f24c011c2b0>,health_check_interval=0,client_name=None,lib_name=redis-py,lib_version=7.0.1,redis_connect_func=<bound method RedisCluster.on_connect of <redis.cluster.RedisCluster object at 0x7f24c100a340>>,credential_provider=None,protocol=2,host=192.168.137.5,port=6380,socket_connect_timeout=None,socket_keepalive=None,socket_keepalive_options=None)>)>)>]]>>> 

创建 RedisCluster 实例时,首先尝试连接提供的启动节点的其中一个。若所有启动节点均不可达,则抛出 "RedisClusterException" 异常。成功连接集群节点后,RedisCluster 实例将通过以下 3 个缓存完成初始化:

·槽位缓存,将16384个槽位分别映射至负责处理的节点;

·节点缓存,包含集群所有节点的 ClusterNode 对象(含名称、主机、端口及 Redis 连接信息);

·命令缓存,存储通过 Redis 'COMMAND' 输出获取的所有服务器支持命令。

RedisCluster 实例可直接用于执行 Redis 命令。当通过集群实例执行命令时,将在内部自动确定目标节点。使用基于键的命令时,目标节点即为持有该键槽位的节点。集群管理命令及其他非基于键的命令有一个名为 "target_nodes" 的参数,可用于指定命令的执行节点。若未指定 target_nodes,命令将默认在集群默认节点上执行。集群实例初始化时,默认节点会从集群主节点中随机选取,并在重新初始化时更新。可通过 r.get_default_node() 获取集群默认节点,或使用 "set_default_node" 方法进行修改。

>>> # target-nodes: the node that holds 'foo1's key slot>>> rc.set('foo1''bar1')>>> # target-nodes: the node that holds 'foo2's key slot>>> rc.set('foo2''bar2')>>> # target-nodes: the node that holds 'foo1's key slot>>> print(rc.get('foo1'))b'bar'>>> # target-node: default-node>>> print(rc.keys())[b'foo1']>>> # target-node: default-node>>> rc.ping()

指定目标节点

如上所述,所有非基于键的 RedisCluster 命令均接受可选参数 target_nodes,用于指定应执行命令的目标节点。最佳实践是使用 RedisCluster 类的节点标志来指定目标节点:PRIMARIES(主节点)、REPLICAS(副本节点)、ALL_NODES(所有节点)、RANDOM(随机节点)。当节点标志与命令一同传递时,系统会内部解析为相关节点。若命令执行期间集群节点拓扑发生变化,客户端将根据新拓扑重新解析节点标志并尝试重试命令执行。

>>> from redis.cluster import RedisCluster as Redis>>> rc = Redis(host='localhost', port=6379,password="pw")>>> rc.cluster_meet('127.0.0.1'6379, target_nodes=Redis.ALL_NODES){'127.0.0.1:6379'True'192.168.137.4:6380'True'192.168.137.5:6379'True'127.0.0.1:6380'True'192.168.137.4:6379'True'192.168.137.5:6380'True}>>> # ping all replicas>>> rc.ping(target_nodes=Redis.REPLICAS)True>>> # ping a random node>>> rc.ping(target_nodes=Redis.RANDOM)True>>> # get the keys from all cluster nodes>>> rc.keys(target_nodes=Redis.ALL_NODES)[]>>> # execute bgsave in all primaries>>> rc.bgsave(Redis.PRIMARIES)True>>> 

若需在特定节点/节点组上执行命令(该节点组未被 nodes 标志覆盖),也可直接传递 ClusterNodes。但需注意:若因集群拓扑变更导致命令执行失败,系统将不会重试,因为传递的目标节点可能已失效,此时将返回相应的集群或连接错误。

>>> node = rc.get_node('localhost'6379)>>> # Get the keys only for that specific node>>> rc.keys(target_nodes=node)>>> # get Redis info from a subset of primaries>>> subset_primaries = [node for node in rc.get_primaries() if node.port > 6378]>>> rc.info(target_nodes=subset_primaries)

此外,RedisCluster实例可查询特定节点的Redis实例,并直接在该节点上执行命令。但Redis客户端不处理集群故障和重试机制。

>>> cluster_node = rc.get_node(host='localhost', port=6379)>>> print(cluster_node)[host=127.0.0.1,port=6379,name=127.0.0.1:6379,server_type=primary,redis_connection=Redis<ConnectionPool<Connection<host=127.0.0.1,port=6379,db=0>>>]>>> r = cluster_node.redis_connection>>> r.client_list()[{'id''276''addr''127.0.0.1:64108''fd''16''name''''age''0''idle''0''flags''N''db''0''sub''0''psub''0''multi''-1''qbuf''26''qbuf-free''32742''argv-mem''10''obl''0''oll''0''omem''0''tot-mem''54298''events''r''cmd''client''user''default'}]>>> # Get the keys only for that specific node>>> r.keys()[b'foo1']

多键命令

在集群模式下,Redis支持多键命令,例如集合类型的并集或交集操作、mset和mget命令,前提是所有键都哈希到同一槽位。通过 RedisCluster 客户端,可使用已知函数(如 mget、mset)执行原子性多键操作。但必须确保所有键映射到相同槽位,否则将抛出 RedisClusterException 异常。Redis 集群实现了哈希标签机制,可强制特定键存储于同一哈希槽位。对于部分多键操作,也可使用非原子模式,并传递未映射至相同槽位的键。此时客户端会将键映射至相关槽位,并将命令发送至槽位节点所有者。非原子操作会根据哈希值对键进行分批处理,然后将每批键分别发送至对应槽位的所有者。

# Atomic operations can be used when all keys are mapped to the same slot>>> rc.mset({'{foo}1''bar1''{foo}2''bar2'})>>> rc.mget('{foo}1''{foo}2')[b'bar1'b'bar2']# Non-atomic multi-key operations splits the keys into different slots>>> rc.mset_nonatomic({'foo''value1''bar''value2''zzz''value3')>>> rc.mget_nonatomic('foo''bar''zzz')[b'value1'b'value2'b'value3']

集群发布订阅

当创建ClusterPubSub实例时若未指定节点,系统将在首次命令执行时自动为PubSub连接选择单个节点。节点选择机制如下:

1. 对请求中的通道名称进行哈希运算以获取其键槽位置

2. 选择处理该键槽的节点:若read_from_replicas设置为true或提供了load_balancing_strategy参数,则可选择副本节点。

PubSub 限制

由于键槽机制,模式订阅和发布功能目前无法正常工作。若对 fo* 模式进行哈希处理,将获得该字符串的键槽,但基于此模式的channel名称存在无限可能——无法预先确定。该功能未被禁用,但当前不建议使用相关命令。

>>> p1 = rc.pubsub()p1 connection will be set to the node that holds 'foo' keyslot>>> p1.subscribe('foo')p2 connection will be set to node 'localhost:6379'>>> p2 = rc.pubsub(rc.get_node('localhost', 6379))

只读模式

默认情况下,访问副本节点时Redis集群始终返回MOVE重定向响应。可通过开启 READONLY 模式来突破此限制并扩展读取命令。

启用 READONLY 模式需向 RedisCluster 构造函数传递 read_from_replicas=True 参数,或定义load_balancing_strategy 策略。当 read_from_replicas 设为true时,读取命令将以轮询方式分配给主节点及其副本。通过load_balancing_strategy可自定义读取命令分配策略,将命令分配至副本节点和主节点。

运行时可通过调用 readonly() 方法并传入 target_nodes='replicas' 参数设置只读模式,调用readwrite() 方法即可恢复读写访问权限。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-02-07 12:15:48 HTTP/2.0 GET : https://f.mffb.com.cn/a/470041.html
  2. 运行时间 : 0.277979s [ 吞吐率:3.60req/s ] 内存消耗:4,730.14kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=180bdea4e0ef9cee21ab99863463e6f6
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000849s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001626s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.004774s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.007833s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001801s ]
  6. SELECT * FROM `set` [ RunTime:0.006371s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001523s ]
  8. SELECT * FROM `article` WHERE `id` = 470041 LIMIT 1 [ RunTime:0.019539s ]
  9. UPDATE `article` SET `lasttime` = 1770437748 WHERE `id` = 470041 [ RunTime:0.002122s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.004758s ]
  11. SELECT * FROM `article` WHERE `id` < 470041 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001161s ]
  12. SELECT * FROM `article` WHERE `id` > 470041 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.007022s ]
  13. SELECT * FROM `article` WHERE `id` < 470041 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.040556s ]
  14. SELECT * FROM `article` WHERE `id` < 470041 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.034092s ]
  15. SELECT * FROM `article` WHERE `id` < 470041 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.063225s ]
0.279666s