美文网首页
python redis 连接

python redis 连接

作者: 明明就_c565 | 来源:发表于2023-01-31 15:28 被阅读0次

Redis四种模式

这里的模式主要是说的Redis Server的部署模式,有四种:单机模式、主从模式、哨兵模式、集群模式

这四种模式的详细介绍可以参考这篇文章:https://juejin.cn/post/6844904191236767751

主从模式的Redis数据库,单点连接主节点。这种模式主要如果主节点挂掉,从库会切换为主节点,但是主节点IP已经变化,应用服务需要修改IP地址,重新发布。

建议哨兵模式,这种主要连接的是哨兵节点(一个或多个组成),访问redis集群的数据都是通过哨兵集群的,redis集群出现问题,应用服务不用更改访问地址

连接池

ConnectionPool

redis-py 使用 connection pool 来管理对一个 redis server 的所有连接,避免每次建立、释放连接的开销。

默认,每个Redis客户端实例都会维护一个自己的连接池。可以直接建立一个连接池ConnectionPool,然后作为参数初始化Redis,这样就可以实现多个 Redis 实例共享一个连接池。

redis 取出的结果默认是字节,我们可以设定 decode_responses=True 改成字符串。

import redis # 导入redis 模块

pool = redis.ConnectionPool(host='localhost',port=6379,decode_responses=True)

r = redis.Redis(connection_pool=pool)

连接池大小默认是2 ** 31,可以通过设置max_connections来限制连接池大小

import redis # 导入redis 模块

pool = redis.ConnectionPool(host='localhost',port=6379,max_connections=40,decode_responses=True) # 连接池大小设置40

r = redis.Redis(connection_pool=pool)

因为Redis服务器设置的连接数是有限的,在大并发的情况下,可能会导致客户端连接数超过redis server设置的最大连接数,从而会报错

但是也不能设置太小,连接池设置太小会导致在大并发的时候没有可用连接而抛出异常。

报错信息:

BlockingConnectionPool

BlockingConnectionPool和ConnectionPool功能是一样的,但是是线程安全的,在多线程的环境下,建议用BlockingConnectionPool,比如gunicorn使用了多线程的worker。同时,当所有连接都在使用时,获取可用连接不会抛异常,而是可以设置等待时间。

# Block forever.

pool=BlockingConnectionPool(timeout=None)

# Raise a ``ConnectionError`` after five seconds if a connection is

# not available.

pool=BlockingConnectionPool(timeout=5)

from redis import BlockingConnectionPool

from redis.exceptions import ConnectionError, ResponseError

from redis import Redis

pool = BlockingConnectionPool.from_url(redis_url,

                                      max_connections=100,

                                      timeout=10,

                                      socket_timeout=3

                                      socket_connect_timeout=5,

                                      retry_on_timeout=True,

                                      retry_on_error=[ConnectionError, ResponseError],

                                      health_check_interval=10,

                                      decode_responses=True)

r = Redis(connection_pool=pool)

r.get("key")

timeout相关

在初始化连接的时候,可以设置一些超时时间。

socket_timeout

指Redis发出命令接收响应的时间不能超过此参数设置时间. 如果超过了此时间, 将会抛出异常:redis.exceptions.TimeoutError: Timeout reading from socket, 即读取响应超时。

建议设置这个时间,防止程序读取redis数据超时导致服务卡住,同时增加对这个的异常处理。

socket_connect_timeout

指Redis建立连接超时时间. 当设置此参数时, 如果在此时间内没有建立连接, 将会抛出异常redis.exceptions.TimeoutError: Timeout connecting to server。

socket_connect_timeout不设置时,这个值等于socket_timeout。

可以只设置socket_timeout

retry_on_timeout

Boolean类型,建议设置为True

当设置False时, 一个命令超时后, 将会直接抛出timeout异常。

当设置为True时, 命令超时后,将会重试一次, 重试成功则正常返回; 失败则抛出timeout异常。

Sentinel(哨兵)连接

Sentinel一般包含:Sentinel地址列表,master name,redis auth,分别填入下面

Sentinel连接方式和普通连接方式类似,master_for函数会返回一个Redis实例,但是sentinel的连接池不同,连接池类型是SentinelConnectionPool。

里面逻辑主要新增:

connect创建连接时,每次都会先去Sentinel查询一次master的地址。

master宕机发生主从切换时,有两种场景,第一种是原master宕机了,这时候这时候客户端无法连接到master, 会产生ConnectionError或者TimeoutError异常。第二种是原master会变成slave,这样就会返回ReadOnlyError异常,会被转换为ConnectionError。

无论哪种情况,都会在execute_command里调用Connection里的disconnect方法。

这样在下次再使用这个连接时,因为连接断开了,就会再次调用connect创建连接,而connect调用connection_pool的get_master_address方法,这里调用get_master_address获取master的地址,而且都是实时获取的,如果发现master地址变了,就会断开所有的连接,重新连接。

redis-py的Sentinel维持master的地址的方式是每次创建连接时都会去动态获取一次master的地址,而不是每次查询时都去获取一次master。不然的话,每一次请求都实际需要两次请求,吞吐量就下降了不少。而检查到master的异常后,会断开所有连接,然后重连

使用建议

单py文件,无需对redis-py进一步封装,直接用原生的就好,因为本身有连接池,可以直接在py文件中创建对应db的连接,比如使用db 0,创建一个redis_cli_0,其他地方需要用到直接导入即可,单例模式。

相关Redis命令

看Redis当前连接数

127.0.0.1:6379> info clients# Clientsconnected_clients:2# 已连接客户端数client_recent_max_input_buffer:2client_recent_max_output_buffer:0

查看具体连接信息

具体含义可参考:https://www.runoob.com/redis/server-client-list.html

这里的name是指客户端连接的名称,我们可以再创建连接的时候通过client_name设置,低版本不支持这个参数

关闭客户端连接

clientkillip:port

查看Redis最大连接数

127.0.0.1:6379> config get maxclients1)"maxclients"2)"10000"

查看空闲连接多少时间会关闭

默认为0,指redis server永远不会关闭空闲连接

127.0.0.1:6379> config get timeout1)"timeout"2)"0"

参考

原文链接:https://zhuanlan.zhihu.com/p/465487818

文档:https://redis.readthedocs.io/en/stable/connections.html#redis.asyncio.connection.Connection

redis库:https://pypi.org/project/redis/

博客:https://www.cnblogs.com/leijiangtao/p/4668771.html

redis操作:https://blog.51cto.com/xinsz08/4996337

相关文章

网友评论

      本文标题:python redis 连接

      本文链接:https://www.haomeiwen.com/subject/mafbhdtx.html