之前已经将主要的scrapy_redis分布式组件源码及其工作原理介绍完成,今天介绍分布式组件的最后一个Connection,这是Redis的连接组件。
《scrapy中scrapy_redis分布式内置pipeline源码及其工作原理》
《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客户端。