scrapy_redis分布式组件Connection源码解读及工作原理-阿里云开发者社区

开发者社区> Python技术进阶> 正文

scrapy_redis分布式组件Connection源码解读及工作原理

简介: 之前已经将主要的scrapy_redis分布式组件源码及其工作原理介绍完成,今天介绍分布式组件的最后一个Connection,这是Redis的连接组件。 《RedisSpider的调度队列实现过程及其源码》 《scrapy中scrapy_redis分布式内置pipeline源码及其工作原理》 ...

之前已经将主要的scrapy_redis分布式组件源码及其工作原理介绍完成,今天介绍分布式组件的最后一个Connection,这是Redis的连接组件。

RedisSpider的调度队列实现过程及其源码

scrapy中scrapy_redis分布式内置pipeline源码及其工作原理

scrapy分布式调度源码及其实现过程

scrapy分布式Spider源码分析及实现过程

scrapy分布式去重组件源码及其实现过程

scrapy_redis中序列化源码及其在程序设计中的应用

Connection组件是用创建Redis的客户端的,其源码如下:

import six

from scrapy.utils.misc import load_object

from . import defaults


# Shortcut maps 'setting name' -> 'parmater name'.
SETTINGS_PARAMS_MAP = {
    'REDIS_URL''url',
    'REDIS_HOST''host',
    'REDIS_PORT''port',
    'REDIS_ENCODING''encoding',
}


def get_redis_from_settings(settings):
    """Returns a redis client instance from given Scrapy settings object.

    This function uses ``get_client`` to instantiate the client and uses
    ``defaults.REDIS_PARAMS`` global as defaults values for the parameters. You
    can override them using the ``REDIS_PARAMS`` setting.

    Parameters
    ----------
    settings : Settings
        A scrapy settings object. See the supported settings below.

    Returns
    -------
    server
        Redis client instance.

    Other Parameters
    ----------------
    REDIS_URL : str, optional
        Server connection URL.
    REDIS_HOST : str, optional
        Server host.
    REDIS_PORT : str, optional
        Server port.
    REDIS_ENCODING : str, optional
        Data encoding.
    REDIS_PARAMS : dict, optional
        Additional client parameters.

    """

    params = defaults.REDIS_PARAMS.copy()
    params.update(settings.getdict('REDIS_PARAMS'))
    XXX: Deprecate REDIS_* settings.
    for source, dest in SETTINGS_PARAMS_MAP.items():
        val = settings.get(source)
        if val:
            params[dest] = val

    # Allow ``redis_cls`` to be a path to a class.
    if isinstance(params.get('redis_cls'), six.string_types):
        params['redis_cls'] = load_object(params['redis_cls'])

    return get_redis(**params)


# Backwards compatible alias.
from_settings = get_redis_from_settings


def get_redis(**kwargs):
    """Returns a redis client instance.

    Parameters
    ----------
    redis_cls : class, optional
        Defaults to ``redis.StrictRedis``.
    url : str, optional
        If given, ``redis_cls.from_url`` is used to instantiate the class.
    **kwargs
        Extra parameters to be passed to the ``redis_cls`` class.

    Returns
    -------
    server
        Redis client instance.

    """

    redis_cls = kwargs.pop('redis_cls', defaults.REDIS_CLS)
    url = kwargs.pop('url'None)
    if url:
        return redis_cls.from_url(url, **kwargs)
    else:
        return redis_cls(**kwargs)


首先是设置了配置文件配置字段和传入参数的键值对SETTINGS_PARAMS_MAP,这个键值对后面会反转。

SETTINGS_PARAMS_MAP = {
    'REDIS_URL''url',
    'REDIS_HOST''host',
    'REDIS_PORT''port',
    'REDIS_ENCODING''encoding',
}


然后读出默认的配置参数给params字段并将setting字段中的Redis配置更新进params字段。

params = defaults.REDIS_PARAMS.copy()
params.update(settings.getdict('REDIS_PARAMS'))


接着开始将配置文件中的配置字段替换成传入参数字段,如:REDIS_URL替换成url,REDIS_HOST替换成host。

    for source, dest in SETTINGS_PARAMS_MAP.items():
        val = settings.get(source)
        if val:
            params[dest] = val


然后是处理实例化Redis客户端的类,根据‘redis_cls’路径返回实例化redis客户端的类load_object(params['redis_cls'])

 if isinstance(params.get('redis_cls'), six.string_types):
        params['redis_cls'] 
= load_object(params['redis_cls'])


然后是调用创建客户端的函数get_redis(),该函数中redis_cls = kwargs.pop('redis_cls', defaults.REDIS_CLS)的作用是在参数列表中弹出实例化客户端的类,如果没有将用默认的类创建

REDIS_CLS = redis.StrictRedis

    

url = kwargs.pop('url', None)弹出url,如果有url弹出那么将选择url连接的方式实例化,反之选择含有账号密码的参数列表实例化。

    redis_cls = kwargs.pop('redis_cls', defaults.REDIS_CLS)
    url = kwargs.pop('url', None)
    if url:
        return redis_cls.from_url(url, **kwargs)
    else:
        return redis_cls(**kwargs)


当然最后就返回了一个连接的redis客户端。

2019-03-18-23_05_15.png


原文链接

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
Python技术进阶
使用钉钉扫一扫加入圈子
+ 订阅

官网链接