Django-session-redis,Django使用redis保存session

自己公司的运维平台项目,考虑到session保存到数据库的性能问题,所以使用redis做为缓存服务,于是在github上选择Django-session-redis 0.6拿来用,但是,有许多坑,也不知道是版本问题还是什么,几乎配置文件都不能生效,里面也充斥这各种bug
下面写出来我遇到的问题,有问题欢迎留言

1.设置

说明里提供了几种模式进行设置
设置IP

SESSION_REDIS = {
    'host': 'localhost'
    'port': 6379
    'db': 0,
    'password': 'password',
    'prefix': 'session',
    'socket_timeout': 1
}

domain socket连接

SESSION_REDIS = {
    'unix_domain_socket_path': '/var/run/redis/redis.sock',
    'db': 0,
    'password': 'password',
    'prefix': 'session',
    'socket_timeout': 1
}

Redis Sentinel

SESSION_REDIS_SENTINEL_LIST = [(host, port), (host, port), (host, port)]
SESSION_REDIS_SENTINEL_MASTER_ALIAS = 'sentinel-master'

Redis Pool (Horizontal partitioning)

SESSION_REDIS = {
    'prefix': 'session',
    'socket_timeout': 1
    'retry_on_timeout': False,
    'pool': [{
        'host': 'localhost3',
        'port': 6379,
        'db': 0,
        'password': None,
        'unix_domain_socket_path': None,
        'url': None,
        'weight': 1
    },
    {
        'host': 'localhost2',
        'port': 6379,
        'db': 0,
        'password': None,
        'unix_domain_socket_path': None,
        'url': None,
        'weight': 1
    },
    {
        'host': 'localhost1',
        'port': 6379,
        'db': 0,
        'password': None,
        'unix_domain_socket_path': None,
        'url': None,
        'weight': 1
    }]
}

我呢,就选择第一种方式,BUT,无论我怎么设置,程序一直包localhost连接不上,只能调试源码,遇到以下几种问题

1.redis_session.settings.py
from django.conf import settings

# SESSION_REDIS - Default
SESSION_REDIS = getattr(settings, 'SESSION_REDIS', {})

SESSION_REDIS_HOST =   getattr(SESSION_REDIS, 'host', '172.17.118.207')
SESSION_REDIS_PORT = getattr(SESSION_REDIS, 'port', 6379)

可以看到我们从django中导入setting设置,然后取出来SESSION_REDIS,使用getattr取他的属性,但是SESSION_REDIS不是一个对象,他是一个字典dict,你无论如何使用getattr是取不出来的

2.redis_session.session.py

假如成功取到了相关配置进入session.py init

    def __init__(self, session_key):
        self.session_key = session_key
        self.connection_key = ''

        if settings.SESSION_REDIS_SENTINEL_LIST is not None:
            self.connection_type = 'sentinel'
        else:
            if settings.SESSION_REDIS_POOL is not None:
                server_key, server = self.get_server(session_key, settings.SESSION_REDIS_POOL)
                self.connection_key = str(server_key)
                settings.SESSION_REDIS_HOST = getattr(server, 'host', '172.17.118.207')
                settings.SESSION_REDIS_PORT = getattr(server, 'port', 6379)
                settings.SESSION_REDIS_DB = getattr(server, 'db', 0)
                settings.SESSION_REDIS_PASSWORD = getattr(server, 'password', None)
                settings.SESSION_REDIS_URL = getattr(server, 'url', None)
                settings.SESSION_REDIS_UNIX_DOMAIN_SOCKET_PATH = getattr(server,'unix_domain_socket_path', None)

            if settings.SESSION_REDIS_URL is not None:
                self.connection_type = 'redis_url'
            elif settings.SESSION_REDIS_HOST is not None:
                self.connection_type = 'redis_host'
            elif settings.SESSION_REDIS_UNIX_DOMAIN_SOCKET_PATH is not None:
                self.connection_type = 'redis_unix_url'

        self.connection_key += self.connection_type

我们设置了HOST

            if settings.SESSION_REDIS_URL is not None:
                self.connection_type = 'redis_url'
            elif settings.SESSION_REDIS_HOST is not None:
                self.connection_type = 'redis_host'
            elif settings.SESSION_REDIS_UNIX_DOMAIN_SOCKET_PATH is not None:
                self.connection_type = 'redis_unix_url'

因此 self.connection_type 的值为’redis_host’

 self.connection_type = 'redis_host'

但是在get的时候,请看代码

        if self.connection_type == 'sentinel':
            from redis.sentinel import Sentinel
            self.__redis[self.connection_key] = Sentinel(
                settings.SESSION_REDIS_SENTINEL_LIST,
                socket_timeout=settings.SESSION_REDIS_SOCKET_TIMEOUT,
                retry_on_timeout=settings.SESSION_REDIS_RETRY_ON_TIMEOUT,
                db=getattr(settings, 'db', 0),
                password=getattr(settings, 'password', None)
            ).master_for(settings.SESSION_REDIS_SENTINEL_MASTER_ALIAS)

        elif self.connection_type == 'redis_url':
            self.__redis[self.connection_key] = redis.StrictRedis.from_url(
                settings.SESSION_REDIS_URL,
                socket_timeout=settings.SESSION_REDIS_SOCKET_TIMEOUT
            )
        elif self.connection_type == 'unix_url':
            self.__redis[self.connection_key] = redis.StrictRedis(
                host=settings.SESSION_REDIS_HOST,
                port=settings.SESSION_REDIS_PORT,
                socket_timeout=settings.SESSION_REDIS_SOCKET_TIMEOUT,
                retry_on_timeout=settings.SESSION_REDIS_RETRY_ON_TIMEOUT,
                db=settings.SESSION_REDIS_DB,
                password=settings.SESSION_REDIS_PASSWORD
            )
        else:
            self.__redis[self.connection_key] = redis.StrictRedis(
                unix_socket_path=settings.SESSION_REDIS_UNIX_DOMAIN_SOCKET_PATH,
                socket_timeout=settings.SESSION_REDIS_SOCKET_TIMEOUT,
                retry_on_timeout=settings.SESSION_REDIS_RETRY_ON_TIMEOUT,
                db=settings.SESSION_REDIS_DB,
                password=settings.SESSION_REDIS_PASSWORD,
            )

第三个elif self.connection_type == ‘unix_url’ 应该是 redis_host,我估计是粗心大意写错了,改成redis_host就可以使用自己配置的地址了

    原文作者:神力无敌_61b6
    原文地址: https://www.jianshu.com/p/45b757b40106
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞