自己公司的运维平台项目,考虑到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就可以使用自己配置的地址了