Начиная знакомство с nosql-базой Redis, практически в каждой статье ей посвященной, мы встречаем утверждение о том, что эта база невероятно быстро работает. Скорость работы действительно потрясающая, благодаря хранению данных в оперативной памяти.
Но представим ситуацию, когда Redis надрывается от нагрузки. Эта ситуация не редка. Что же в таком случае делать?
Replication
Первое что приходит в голову – добавить еще одну базу, создав связку master-slave, и операции чтения перенаправить на нее.
Плюсы:
Добавить базу и настроить реплицирование можно быстро. Устанавливаем Redis, выполняем несколько команд, ждем, когда данные синхронизируются и используем реплику.
Количество операции чтения увеличивается пропорционально количеству slave-баз.
Минусы:
Необходимо дорабатывать код — создавать прокси-класс для распределения операций чтения/записи на нужные базы.
Количество операции записи останется неизменным. С slave-баз мы можем только читать. Операции записи можно проводить только на master-базе. Если Redis надрывался от слишком большого количества команд на запись, то никакого ускорения работы мы не получим.
Cluster
Второе очевидное решение – создать кластер из Redis-баз.
Плюсы кластера:
Количество операций чтения и записи увеличивается пропорционально количеству баз в кластере.
Кластер легко настраивается для новой базы.
Можно достаточно легко добавить репликацию для Redis-баз входящих в кластер. Тем самым увеличив максимальное количество операций чтения.
Размер базы существенно больше. Согласитесь, что 8 серверов по 32 Гб памяти гораздо лучше, чем один.
В случае необходимости размер базы просто увеличить. Замена 8 серверов с 32 Гб памяти на 8 серверов по 64 Гб сразу увеличит максимальный размер базы на 128 Гб (Не забываем, что для быстрой работы Redis объем оперативной памяти должен быть минимум в 2 раза больше размера базы). Это гораздо лучше, чем замена одного сервера на другой с большим количеством оперативки.
Минусы кластера:
Необходимо дорабатывать код – создавать прокси-класс для распределения операций чтения/записи между узлами кластера.
Если такое решение внедряется на существующую базу, то необходимо осуществить миграцию данных на базы, входящие в кластер. Это задача нетривиальная и требующая много сил и времени. В каждой переносимой базе своя логика и поэтому для каждого случая придется создавать индивидуальное решение. Проще всего изначально создать кластер из баз и использовать его в работе, чем готовую базу переносить на кластер.
Я уже два года использую Redis в качестве основной базы данных на высоконагруженных проектах. (Игры для мобильных устройств). Все это время создатели Redis обещают, что они вот-вот выпустят кластерное решение для Redis. Обещанного три года ждут, а те, кто не ждет, пишут свои решения и я в том числе.
Собственный кластер создать у меня получилось. Надеюсь, что мои опыт будет полезен людям, стремящимся увеличить производительность Redis в своих проектах. Скажу сразу что использую 8 нод по-умолчанию. Если производительности 1 redis-базы не хватало, то полностью нагрузить 8 redis-баз еще не удалось.
Два года работы кластера под нагрузками в нескольких проектах показали его состоятельность.
Заинтересовавшиеся могут скачать и использовать пример кода с гитхаба – github.com/dfer/myredis
P.S.
Два года назад, когда я думал, как решить проблему с производительностью базы Redis и создать redis-кластер, мне помогли следующие 2 статьи:
oldblog.antirez.com/post/redis-presharding.html
blog.zawodny.com/2011/02/26/redis-sharding-at-craigslist/
Надеюсь, что мое решение и статьи, указанные выше, могут быть полезны людям, столкнувшимся с низкой производительностью Redis в своих проектах.
Автор: AlexeiZhuravlev