• 为了保证你在浏览本网站时有着更好的体验,建议使用类似Chrome、Firefox之类的浏览器~~
    • 如果你喜欢本站的内容何不Ctrl+D收藏一下呢,与大家一起分享各种编程知识~
    • 本网站研究机器学习、计算机视觉、模式识别~当然不局限于此,生命在于折腾,何不年轻时多折腾一下

redis_py_cluster读取redis遇到too many connections问题

tech admin 5天前 37次浏览 0个评论 扫描二维码

最近项目中需要自己去往 redis 里面写数据,redis 集群读写需要使用到 redis_py_cluster 这个 python 包,这中间遇到不少问题,其中就有数据序列化问题,有人使用 spark 中的 json 序列化方式,与 python 还不兼容,最后是不序列化直接存字符串的方式解决了不同语言之间的兼容问题,但是自己在读写 redis 的时候遇到了 too many connections 的错误,字面上就是建立了太多的连接。

redis 本来不就是频繁的读写操作?这个报连接太多嘛意思,一开始定位可能是 redis 集群版本与 python 包版本不匹配的问题,通过降级方式还是会出现上述现象。
下面是定义连接的方式

from rediscluster import StrictRedisCluster

redis_conn = StrictRedisCluster(startup_nodes=[{'host': '1333', 'port': 829}, {'host': '13334', 'port': 8269}],
                                skip_full_coverage_check=True)

注意上面只是定义连接,其实现在你还没有跟 redis 集群进行任何连接,当你在执行 get 或者 set 的时候才会进行连接。
StrictRedisCluster 定义如下

    def __init__(self, host=None, port=None, startup_nodes=None, max_connections=None, max_connections_per_node=False, init_slot_cache=True,
                 readonly_mode=False, reinitialize_steps=None, skip_full_coverage_check=False, nodemanager_follow_cluster=False,
                 connection_class=None, **kwargs):
        """
        :startup_nodes:
            List of nodes that initial bootstrapping can be done from
        :host:
            Can be used to point to a startup node
        :port:
            Can be used to point to a startup node
        :max_connections:
            Maximum number of connections that should be kept open at one time
        :readonly_mode:
            enable READONLY mode. You can read possibly stale data from slave.
        :skip_full_coverage_check:
            Skips the check of cluster-require-full-coverage config, useful for clusters
            without the CONFIG command (like aws)
        :nodemanager_follow_cluster:
            The node manager will during initialization try the last set of nodes that
            it was operating on. This will allow the client to drift along side the cluster
            if the cluster nodes move around alot.
        :**kwargs:
            Extra arguments that will be sent into StrictRedis instance when created
            (See Official redis-py doc for supported kwargs
            [https://github.com/andymccurdy/redis-py/blob/master/redis/client.py])
            Some kwargs is not supported and will raise RedisClusterException
            - db (Redis do not support database SELECT in cluster mode)
        """
        # Tweaks to StrictRedis client arguments when running in cluster mode
        if "db" in kwargs:
            raise RedisClusterException("Argument 'db' is not possible to use in cluster mode")

        if kwargs.get('ssl', False):
            connection_class = SSLClusterConnection

        if "connection_pool" in kwargs:
            pool = kwargs.pop('connection_pool')
        else:
            startup_nodes = [] if startup_nodes is None else startup_nodes

            # Support host/port as argument
            if host:
                startup_nodes.append({"host": host, "port": port if port else 7000})

            if readonly_mode:
                connection_pool_cls = ClusterReadOnlyConnectionPool
            else:
                connection_pool_cls = ClusterConnectionPool

            pool = connection_pool_cls(
                startup_nodes=startup_nodes,
                init_slot_cache=init_slot_cache,
                max_connections=max_connections,
                reinitialize_steps=reinitialize_steps,
                max_connections_per_node=max_connections_per_node,
                skip_full_coverage_check=skip_full_coverage_check,
                nodemanager_follow_cluster=nodemanager_follow_cluster,
                connection_class=connection_class,
                **kwargs
            )

        super(StrictRedisCluster, self).__init__(connection_pool=pool, **kwargs)

其中有一个 max_connections 最大连接数的参数,这个如果你设置 20,那么在你建立 20 个连接的时候会报错,这个就会出现文章一开始说的问题,这个也是自己折腾好久才发现的点。

你可以这么来定位这个问题,你是哟空上面的定义好之后执行一个 get 操作,在去查看这个变量

redis_conn.connection_pool._available_connections

这个可以打印当前已经建立的连接,你会发现有一条,当你继续读写数据的时候如果建立的连接超过 20 立马就会报错。

那么解决的方法是啥呢,我现在想的是超级简单:max_connnections 参数不指定,因为你不指定,python 会自己指定 2**31 次方
源码定义

       self.max_connections = max_connections or 2 ** 31

这个为什么设置这么大也可以理解,基本上你一次 get 之后很快就会失去连接,redis 不会保持很长的连接,所以自动就会断开,设置这么大其实对 redis 集群没有什么太大的影响,除非你的并发超级大,超过了 redis 默认最大的连接数,那么就会出现问题。


Deeplearn, 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明redis_py_cluster 读取 redis 遇到 too many connections 问题
喜欢 (0)
admin
关于作者:
互联网行业码农一枚/业余铲屎官/数码影音爱好者/二次元

您必须 登录 才能发表评论!