Как организовать отношение NoSQL хранилищ на сервере?
Есть проект, на который планируется высокая нагрузка. Поэтому изначально его архитектура планируется таким образом, чтобы было возможно дальнейшее горизонтальное масштабирование без значительного рефакторинга кода. С этой целью была выбрана NoSQL MongoDB (привлек автошардинг и другие плюшки). Сейчас Все данные хранятся в этой СУБД (включая сессии). Встал вопрос о переносе сессий в другое, более производительное хранилище вместе с другими данными (типа счетчиков посещений и т.п.). Из вариантов (выбрал по бенчмаркам и доступному описанию) рассматриваю memcached и redis. Redis привлекает тем, что данные сбрасываются на диск и при перезагрузке восстанавливаются (для статистики и сессий идеально), имеются транзакции (чего сильно не хватает в mongo), но вроде как по производительности ниже. Memcached — быстрее, но менее надежно (нельзя быть уверенным, то сессия не инвалидируется неожиданно, когда пользователь делает, например, заказ) и все данные необходимо дублировать. Все это планируется делать в виде кластера с использованием консистентного хеша. С одной стороны для сессий и статистики идеально подходит redis, а для кеша данных — memcached, но имеет ли смысл заводить такой зоопарк (mongo, memcached, redis), будет ли какой-то ощутимый выигрыш? Может стоит под кеш данных использовать redis (он вроде умеет все, что и memcached) и в нем же хранить сессии, или наоборот, сессии хранить в memcached вместе с кешем? Или может вообще оставить сессии в mongo, туда же писать статистику, а под кеш использовать memcached? Или может есть какие-то другие решения? Прошу совета.
Также, чтобы не задавать второй вопрос, спрошу здесь. В mongo нет транзакций. Есть две коллекции, с счетчиками. Необходимо атомарно уменьшить счетчик в одной коллекции и увеличить в другой на N. Есть ли какое-то нормальное решение? Пока используем костыли: выставляем флаг блокировки на документы, сохраняем текущее состояние, выполняем операции, снимаем флаги. В случае ошибки — возвращаем старое состояние, снимаем флаги. В целом работает, но выглядит как костыль.
1. Заводить зоопарк — зло, это можно делать только если ты чётко понимаешь зачем и почему, и всё-равно это будет зло. Чем проще система, тем в ней меньше ошибок и она дешевле.
2. Редис(как и мемкэш) — это в первую очередь кэш, во вторую — хранилище. Поэтому и использовать его надо по назначению (сесси и рантайм статистика — хорошо, рассчитывать, что он будет сбрасывать на диск — плохо).
3. Зачем NoSQL? Только ради произодительности и горизонтального масштабирования? Может тогда будет проще использовать PostgreSQL или MySQL как Key-Value? lionet.livejournal.com/98362.html вот тут хорошо написано по этому поводу.
4. Прежде чем на чём-то останавливаться лучше написать тесты, погонять их, и сделать из этого вывод :)
Делая вывод из всего вышесказанного, лучше обдумать получше, потестировать и определиться, что нужно и почему. Чем проще система, тем она лучше.
Накладные расходы SQL интерфейс? PostgreSQL(про MySQL не знаю) поддерживает бинарный протокол, там всё нормально.
Главное — это будет проще и быстрее сделать, а если возникнет реальная необходимость в чем-то более сложном, то мигрируете уже с опытом и понимаем, что и как сделать.
Накладные расходы будут заключатся в том, что ключом будет текстовое поле (чтобы был аналог key-value). Пусть даже мы возьмем хеш-ключ с высокой селективностью. Получим бинарное дерево. А поиск в бинарном дереве имеет скорость O(log2(N)), что в принципе очень хорошо. Пусть сюда же будет хранение кеша (что несомненно увеличивает скорость обработки запроса), но не знаю, как в посгрес, но мускуль обрабатывает запрос прежде чем отдать ответ из кеша, чтобы понять что ответ не изменился. Отсюда следующие накладные расходы: мы храним таблицу на жестком диске, мы храним индекс, мы храним кеш, мы делаем запрос к жесткому диску, если нет в кеше, мы каждый раз обрабатываем sql-запрос, чтобы понять какие данные хотим получить. Для хеш-таблицы (именно такие key-value я рассматриваю) мы имеем скорость выборки O(1), все данные всегда в памяти + если нам необходимо, то сбрасываем дампы на диск. Конечно, есть еще memory хранилища в РСУБД, но я все таки предпочту использовать специализированное решение, чем делать свой велосепед. В целом, я думаю можно настоить мускуль\постгрес на приемлемые скорости работы, но все таки это решение похоже на забивание гвоздей телескопом.