Використання Redis в якості засобу для зберігання сесій і кешу в Django

7 хв. читання

Redis - засіб для зберігання даних в оперативній пам'яті у форматі ключ-значення, чимось схожий на Memcached. Оскільки зберігання даних відбувається в оперативній пам'яті, читання і запис відбувається дуже швидко, тому це відмінне рішення для зберігання недовговічної інформації, наприклад, кешу вмісту сторінок або даних про активні користувальницькі сесії. Це звільняє вашу базу даних від виконання зайвих операцій запису і зчитування і, очевидно, підвищує швидкість роботи вашого сайту.

Передумови

У цій статті передбачається, що у вас є власний Django додаток на supervisor'і, запущений на сервері Debian. Якщо це не так, то ви можете дізнатися, як все налаштувати і встановити в цьому пості.

Redis

На Debian Redis встановлюється командою apt-get. Якщо ж ваша система заснована на RPM, то ви можете скористатися еквівалентною yum-командою.

Встановлення Redis

$ sudo apt-get install redis-server
$ redis-server --version
Redis server version 2.4.14 (00000000:0)

Налаштування для підключення по сокету

Підключитися до локально запущеного Redis можна або через мережевий шар (від TCP до інтерфейсу зворотнього зв'язку) або ж за допомогою сокет-файлу unix. Для того, щоб уникнути зайвих перевантажень TCP, дозволимо приймання прямих сокет-підключень. Для цього відкриємо файл /etc/redis/redis.conf, закоментуємо директиви bind та port і розкоментуємо - unixsocket:

# Accept connections on the specified port, default is 6379.
# If port 0 is specified Redis will not listen on a TCP socket.
# port 6379

# If you want you can bind a single interface, if the bind option is not
# specified all the interfaces will listen for incoming connections.
#
# bind 127.0.0.1

# Specify the path for the unix socket that will be used to listen for
# incoming connections. There is no default, so Redis will not listen
# on a unix socket when not specified.
#
unixsocket /var/run/redis/redis.sock
unixsocketperm 700

Для того, щоб зміни прийшли в силуу, потрібно перезавантажити Redis:

$ sudo service redis-server restart

Тепер можна виконати перевірку:

$ redis-cli ping
PONG

Дозволи сокет-підключень

На Debian стандартні настройки дозволів в Redis дуже обмежені і дозволяють тільки користувачеві з ім'ям redis підключатися по сокету. Їх можна послабити і дозволити підключення для кожного локального користувача, для цього потрібно підправити директиву unixsocketperm у файлі redis.conf:

unixsocketperm 777

Не забувайте перезавантажитися, щоб зміни прийшли в силу:

$ sudo service redis-server restart

З міркувань безпеки може знадобитися не обмежувати доступ тільки групі користувачів. За допомогою цієї команди ви можете вибрати користувачів, яким надаватимуться дозволи як для користувача redis:

$ sudo usermod -a -G redis django_username

Після цього необхідно змінити директиву unixsocketperm у файлі redis.conf таким чином:

unixsocketperm 770

Групи визначаються при запуску, тому якщо ваш додаток було запущено і ви щось змінили, необхідно його перезавантажити. Наприклад, якщо у вас запущено програму hello за допомогою supervisor, перезавантажити його можна наступною командою:

$ sudo supervisorctl restart hello

Більше інформації про те, як почати роботу з Redis, можна прочитати в документації.

Прив'язки Python для Redis

Якщо ви плануєте використовувати Redis з python-додатком, наприклад Django, вам необхідно встановити модуль прив'язки інтерфейсу Python-Redis. Встановити його в віртуальне оточення можна за допомогою команди pip:

$ source bin/activate
(hello_django) $ pip install redis

Redis в якості бекенду кешування в Django

Для того, щоб використовувати Redis для зберігання кешу вашого додатку потрібен модуль django-redis-cache. Установка django-redis-cache в віртуальне оточення:

(hello_django) $ pip install django-redis-cache 

Після цього необхідно додати в файл settings.py наступне:

CACHES = {
    'default': {
        'BACKEND': 'redis_cache.RedisCache',
        'LOCATION': '/var/run/redis/redis.sock',
    },
}

Після перезавантаження вашої програми за організацію роботи з кешем тепер відповідатиме Redis.

Використання кешу Django у вашому додатку

Фреймворк для роботи з кешем в Django дуже гнучкий і дозволяє вам гнучко налаштовувати кешування як усього сайту, так і окремих видів. Контроль за кешуванням здійснюється декоратором cache_page. Наприклад, для того, щоб закешувати результат виконання my_view на 15 хвилин, необхідно скористатися кодом:

from django.views.decorators.cache import cache_page

@cache_page(60 * 15)
def my_view(request):
    ...

Якщо у вас ще не налаштоване кешування в middleware, зробити це можна, додавши другий і шостий рядки зі сніппету, який показаний нижче, в MIDDLEWARE_CLASSES, що у файлі settings.py

MIDDLEWARE_CLASSES = (
    'django.middleware.cache.UpdateCacheMiddleware',    # This must be first on the list
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    (...)
    'django.middleware.cache.FetchFromCacheMiddleware', # This must be last

Більше інформації про використання кеша Django.

Робота з кешем в ваших функціях

Ви також можете працювати з кешем в ваших функціях, для зберігання довільних даних та їх подальшого швидкого отримання:

# Імпортуємо кеш:
from django.core.cache import cache

# Зберігання даних за унікальним ключем:
cache.set('a-unique-key', 'this is a string which will be cached')

# Пізніше ви можете отримати дані в іншій функції:
cache.get('a-unique-key') # Поверне None якщо ключ не знайдено в кеші.

# Ви можете визначити значення за замовчанням:
cache.get('another-unique-key', 'default value')

# Ви можете зберігати декілька значень:
cache.set_many({'a': 1, 'b': 2, 'c': 3})

# І отримувати їх:
cache.get_many(['a', 'b', 'c']) # поверне {'a': 1, 'b': 2, 'c': 3}

# Ви можете зберігати складні типи в кеші:
cache.set('a-unique-key', {
    'string'    : 'this is a string',
    'int'       : 42,
    'list'      : [1, 2, 3, 4],
    'tuple'     : (1, 2, 3, 4),
    'dict'      : {'A': 1, 'B' : 2},
})

Комплексні значення будуть впорядковані і зберігатимуться в одному ключі. Перш ніж ви зможете подивитися значення в структурі, вони повинні бути виключені з кеша та десеріалізовані. Звісно, це позначається на швидкості і вона виявляється менше, ніж при зберіганні простих значень. Більш детально: Django's cache API.

Redis в якості бекенду роботи з даними сесії

Якщо ви використовуєте django-redis-cache так, як показано вище в статті, ви також можете налаштувати його на роботу з сесіями Django, додавши наступне у файлі setting.py:

SESSION_ENGINE = 'django.contrib.sessions.backends.cache'

Також ви можете зберігати інформацію про сесії в базі даних і тільки завантажувати їх за допомогою кешу:

SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'

Це гарантує, що дані про сесії збережені і будуть доступними після перезавантаження

Робота з сесіями за допомогою Redis без django-redis-cache

Ви також можете використовувати Redis виключно для роботи з сесіями. Для цього необхідно встановити модуль django-redis-sessions. Встановлення django-redis-sessions в віртуальному оточенні:

(hello_django) $ pip install django-redis-sessions

Тепер треба конфігурувати redis_sessions.session в якості рушія для роботи з сесіями у файлі setting.py. До того ж, так як ми використовуємо сокет підключення, нам необхідно вказати до шлях до файлу сокета:

SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_UNIX_DOMAIN_SOCKET_PATH = '/var/run/redis/redis.sock'

Ось і все. Після перезавантаження дані про сесії будуть зберігатися в Redis замість бази даних.

Redis та кілька додатків

Врахуйте, що все що описано в статті, розглянуто в контексті одного django додатку. Якщо ж вам потрібно організувати роботу з Redis для декількох додатків, можете спробувати розділити їх простори імен за допомогою префіксів, або ж використовувати різні чисельні бази даних для кожної програми. Однак я не рекомендую подібні рішення. Більш правильно буде використання декількох інстанцій Redis для кожного додатку. Більш докладно про це можете прочитати у блозі Chris Laskey.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.7K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація