Redis vs SQLite vs PostgreSQL

Решил сравнить производительность указанных БД для нескольких болльших плоских таблиц и простейших запросов (по ключу, по индексу и т.п.). Представил одинаковую предметную область — очередь сообщений: для SQLite и PostgreSQL это одинаковые схемы, для Redis использовались сортированные списки, т.к. другие варианты хранения не подошли для описанной задачи. Запросы: поиск сообщения по ключу, удаление сообщения по ключу из очереди, выборка сообщений старше n минут, выборка и удаление сообщения из начала очереди.

10 млн строк, все базы занимают почти по 2 ГБ (больше к сожалению не было RAM). Результат: если база влазит в память, то скорость выполнения запросов примерна одинакова для разных «СУБД» (простые операции — около 3000 операций в секунду, посложнее — около 600). В чём же тогда прелесть Redis-а? Понимаю, что он подходит для узконаправленных задач, например, только поиск по ключу, т.е. для ограниченных по размеру кешей. В остальном одни минусы: и за памятью следи, чтобы база влезала в RAM (PG же просто замедлиться перейдя к дисковому чтению, Redis же начнёт свопится); и набор команд и типов данных ограничен.

PS: Что вы используете для надёжного перманентного хранения данных и быстрого выполнения простых запросов? Холивар PG vs MySQL можно опустить, разницы между ними практически не будет.
  • Вопрос задан
  • 16087 просмотров
Решения вопроса 1
@Ghostwriter
1. В Redis лучше представлена работа с коллекциями. Простой пример — инкрементальный счётчик. Вы делаете incrby/hincrby для любого ключа, не заботясь о его наличие в хранилище. В Postgres аналогичная функциональность на основе последовательностей (nextval('foo')) подразумевает, что вы уже создали последовательность 'foo' ранее. Это подталкивает вас на написание процедур, которые перед попыткой изменить счётчик, сначала проверяют его наличие, при необходимости создают его и только потом изменяют. Больше ручной работы.

2. Структуры данных в Redis оптимизированы либо под быстрый поик О(1), либо под компактность и приемлемую произволительность O(N), O(log(N)). Практически всегда получается обходиться простыми или вложенными хеш-таблицами с О(1) или О(n). В Postgres вы практически всегда пользуетесь той или иной разновидностью B/R-tree, GiST/GIN индексов со сложностью O(log(N)(+N)). До версии 8.4, индексы типа HASH в Postgres имели практически схожую с B-tree скорость поиска, поэтому их применение не имело никакого смысла. Сейчас, в версии 9.1, смысла стало больше, но не намного — HASH индексы не поддерживают Write-Ahead Log и при сбоях требуют ручной переиндексации:
"Hash index operations are not presently WAL-logged, so hash indexes might need to be rebuilt with REINDEX after a database crash. They are also not replicated over streaming or file-based replication. For these reasons, hash index use is presently discouraged." http://www.postgresql.org/docs/9.1/static/indexes-types.html

У себя в проектах, я использую и Redis, и Postgres. Первый — как эффективную систему для сбора онлайн-статистики (счетчики-лайки, различные метрики), а второй — как хранилище для пользовательских аккаунтов и контента с его мета-информацией. При этом, наметилась тенденция переносить контент на HBase, оставляя для Postgres только задачи по ACID-обслуживанию операций с пользовательскими аккаунтами.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 7
CKOPOBAPKuH
@CKOPOBAPKuH
Молоток vs Кувалда vs Отвёртка

Я решил выяснить, какой из инструментов лучше. Представил одинаковую задачу — ударять себя по большому пальцу ноги. Отвёртку решил держать за ручку и ударять наконечником, так как неудобно держать за наконечник и ударять ручкой. Для молотка и кувалды это одинаковые схемы. Запросы: ударить по большому пальцу и измерить время, сколько болит.

Результат: если ударить больно, то палец болит. В чём же тогда прелесть отвёртки? Понимаю, что она подходит для узконаправленных задач, например, только откручивание или закручивание, т.е. для ограниченных задач. В остальном одни минусы: и держать неудобно, и площадь поражения невелика, и по пальцу я попал только с третьего раза.

PS: Что вы используете для надёжного перманентного отбивания пальцев? Холивар классический русский молоток vs молоток из икеи можно опустить, разницы между ними практически не будет.
Ответ написан
Stdit
@Stdit
Помимо РСУБД, мы используем MongoDB. Замечательная и быстрая штука, которая позволяет хранить коллекции из деревьев любой формы, строить индексы по любым их узлам, легко масштабируется горизонтально, имеет довольно мощную систему запросов на чтение и обновление. Недостаток — отсутствие джойнов, проблемы с агрегацией, они решаются путём предварительной агрегации при изменении данных или переучётом по крону.
Ответ написан
@dborovikov
>для надёжного перманентного хранения данных

Вот здесь берегитесь, на сколько я знаю практически все NoSQL полуперсистентные, то есть не дают 100% гарантий на сохранность. Postgres легко превращяется в некое подобие NoSQL если отключить синхронный коммит — снижаются гарантии сохранности, скорость вырастает где-то на два порядка.

UPDATE — дорогая операция для того же постгра. Видимо in memory базы умеют эту операцию выполнять быстро. Так что для всякого рода счетчиков redis — отличная штука.
Ответ написан
alekciy
@alekciy
Вёбных дел мастер
>В чём же тогда прелесть Redis-а?
Данные всегда в ОЗУ, когда как в РСУБД индекс может быть вытесняться на диск, данные при этом на больших объемах почти всегда на диске. Поэтому и получаем просадку производительности из-за I/O на диске. В Redis это в принципе нет, они сейчас на сколько я помню от виртуальной памяти отказались. Про О(1) Ghostwriter уже сказал. ACID таки вносит свой оверхед.

Ну и из подобной группы ПО его выделяет условная персистентность.
Ответ написан
@HiltoN Автор вопроса
Если можно перефразирую вопрос: подскажите быструю персистентную базу, которая, желательно, целиком может мапиться в память, обеспечивать высокую надёжность в случае краха системы, работать на одной машине, поддерживать мультипоточность, желательна поддержка транзакционности. Остальные фишки не важны.

На мой взгляд все три описанные в сабже системы подходят под определение (если нет — исправляйте). Что ещё можете посоветовать?
Ответ написан
@gro
где тесты?
параллельные запросы тестировали?
Ответ написан
Begetan
@Begetan
1. О каких 3000 запросах в секунду идет речь? На тестовом Intel Atom 1,6 ГГц в скрипте на PHP я получил 12000 запросов в секунду GET/SET

2. Непонятно почему вы не использовали списки (Lists), которые по сути есть готовая реализация очереди?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы