На что сменить MongoDB

Сейчас на сервере (2хE5-2630, 128Гб RAM, SAS) стоит MongoDB 2.4.1
В ней две коллекции (в разных бд):
— Коллекция-1: 70 млн. записей (120 insert/s, 60 find/s, база с индексами ~ 9 Гб).
— Коллекция-2: 40 млн. записей (50 insert/s, 40 find/s, база с индексами ~ 11 Гб).

Цифры вроде не большие для данного железа. Вообще-то, запросов на чтение приходит на порядок больше, но по остальным информация берется из кэша (Redis). До монго доходит только в случае кэш промаха.

Проблема в том, что постоянно несколько операций find выполняются по 180 — 600 мс. Судя по отчетам профайлера и логам они ожидают, пока не освободится writing lock.
Sun Apr 14 13:40:44.859 [conn3581] query db1.coll1 query: { _id: "14638g27189a6a957c6a792151df31b7" } ntoreturn:1 idhack:1 keyUpdates:0 locks(micros) r:188697 reslen:105 188ms

К базе вообще делаю только findOne или insert. Объем данных в insert не превышает 120 байт.

iostat -x
rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
0,01 5,55 0,57 27,60 35,60 1531,59 111,28 0,41 14,46 8,01 14,60 1,61 4,53

Вопрос: что делать? В дальнейшем объем данных вырастет до 500 — 1000 млн записей. И количество обращений на чтение до 10 тыс/сек.
Мне нужна БД с очень низкой латентностью для чтения по ключу. Никаких сложных выборок. Нужен backend для кэша. А монго со своим per-database write lock все портит.

Еще вариант, читать только со slave ноды. А писать на master. Но боюсь столкнуться с задержками при репликации данных, и, как следствие, с неконсистентными данными.

Что посоветуете? HBase, Hypertable? Нужно уложиться в максимум 2-5 мс при чтении из БД.
  • Вопрос задан
  • 14154 просмотра
Пригласить эксперта
Ответы на вопрос 18
@Slader Автор вопроса
Потому что 1 миллиард ключей — это уже 166 гигабайт. Вполне нормально для сервера с 256Гб.
Но если по каждому ключу еще и данные хранить, то уже не впишемся по объему. У нас максимум 512Гб можно установить на мать.
Можно, конечно, делать user-level sharding для redis или использовать memcached. Думаем теперь и над этим.

С другой стороны, весь миллиард хранить в памяти не надо совсем. Из него активных — 100 млн. максимум. А остальное все же хотелось бы хранить в бд. И если вдруг потребуется — быстро вычитать и положить в кэш.

Возможно, нам стоит перейти на другой тип БД? Нам нужна отложенная запись (только insert) и быстрое (не более 2 мс) чтение. SSD готовы поставить, лишь бы помогло.
Ведь insert делается сначала в кэш. И все ноды забирают данные из кэша. Так что не особо важно, через сколько БД запишет данные.
А вот минимальная задержка при кэш промахе очень важна.
Ответ написан
amakhnach
@amakhnach
смотрите в сторону Cassandra DB
Ответ написан
BlessMaster
@BlessMaster
Не пробовали «играться» с fsync?
Ответ написан
dizballanze
@dizballanze
Software developer at Yandex
Почему бы полностью не перейти на Redis? Память сейчас дешёвая.
Ответ написан
Комментировать
necromant2005
@necromant2005
Глобальная проблема опарий щаписи в том что каждая вставка заставляет перестраивать индексы.
Поэтому единстенная возможно решить проблему кардинально — это бить на части базу(шардинг), что приводит к тому что опареции записи распределяются за все шарды (желательно развномеррно, зависит от алгоритма выбора ключей) и как результат:
количество_записей_на_1_ноду = общее_количество_записей/количество_нод
Тоесть для 10000к в секунду и 100 нод — 10000/100 = 100 операйций записи в секунду.

Как бы других путей маштабирования записи — нет.
opium — правильно предложил, самый простой вариант шардинг внутри самой монги (это приведет к блокировке только части)
Cassadra / Riak возможно были бы более подходящими, но все опять же кластерные решения: больше нод — выше производительность.

Ну и в качестве странности: жить на одном сервере — с пробелмами записи не получится.
Ответ написан
Emmaseven
@Emmaseven
Мега производительное хранилище Ключ => Значение fallabs.com/kyototycoon/
Ответ написан
Комментировать
@boodda
При таком железе, почему бы не использовать MySQL или Postgre c секционированием данных блоками по 1М-10М, сделав ID инкрементарный BIGINT первичным ключом и поле данных, фиксированного размера(fixed), тогда поиск будет сводиться по сути к выбору нужной секции по iD и выбору нужной записи по формуле id*row_len. Это будет работать очень быстро даже с диска при условии, что файлы таблицы не будет фрагментированы физически на диске, ну а если из памяти не думаю что будет чем то уступать Mongo. Но естественно надо тестить

Постоянные коннекты тут будут обязательны я думаю.
Ответ написан
Комментировать
flyaway
@flyaway
www.tokutek.com/products/tokumx-for-mongodb/
Ужимает бд примерно втрое, намного лучше на запись, намного лучше работает mongos
Ответ написан
Комментировать
@meeshaeel

Попробуй Aerospike http://www.aerospike.com
Желательно иметь машины с болшим количеством ОП и SSD
Community edition ограничивает размер базы до 200Гб

Ответ написан
Комментировать
@Slader Автор вопроса
Может кто Berkley DB пользовался на SSD? Расскажите тогда, как оно?
Find и insert нужны. Delete — вообще нет
Ответ написан
Комментировать
@realduke
Может на PostgreSQL посмотрите, с другой стороны, особенно учитывая то, что у вас всего один сервер.

Есть такая презенташка — wiki.postgresql.org/images/b/b4/Pg-as-nosql-pgday-fosdem-2013.pdf. Конечно тесты решают, но всё же.

Лично мне MongoDB всегда казалась костыльным решением. Красивый API, достаточно возможностей. Но вот как доходит дело до эксплуатации, постоянно вылазит куча недоработок. Знакомые отзывались, что и админить геморрой.

Лучше уж Riak + Redis, когда много нод нужно, ну и соотвественно имеете все плюсы и минусы dynamo-style хранилища.
Ответ написан
@sowich
Возможно orientDB покажет неплохой результат.
Ответ написан
Комментировать
opium
@opium
Просто люблю качественно работать
Может вам find делать через какой нибудь sphinxsearch?
Ответ написан
Iliapan
@Iliapan
не знаю точно, почему тормоза в монго, но в мускуле ваша задача решается через бд с движком archive. На такой системе он спокойно переварит вашу нагрузку и даже под десяток виртуалок памяти останется. Вы сильно промахнулись с платформой, пошли за модой, теперь расплачивайтесь :)
Ответ написан
Tenkoff
@Tenkoff
LevelDB
Ответ написан
Комментировать
FuN_ViT
@FuN_ViT
веб-разработчик
Имхо у вас не верное архитектурное решение. Просто добавте реплику в ReadOnly и операции чтения - только с нее. И прощай write lock...
Ответ написан
Комментировать
Adam_Ether
@Adam_Ether
Java Developer
Мне, кажется что вам нужно смотреть в сторону Riak (класс dynamodb и подобные).
Но, как правильно уже заметили выше, их преимущество можно почувствовать только при использовании в кластере, а использовать один instance -- это как стрелять из пушки по воробьям.
see more
Вот неплохой ответ как это можно все мигрировать, например на AWS DynamoDB
www.masonzhang.com/2013/07/lean7-migrate-from-mong...
news.dice.com/2013/02/21/why-my-team-went-with-dyn...
blog.cloudthat.in/5-reasons-why-dynamodb-is-better...
Ответ написан
Комментировать
@kolofut
Посмотрите на ElasticSearch, он хоть и позиционируется, в основном, как полнотектовый поисковик, прекрасно себя чуствует в роли NoSQL DB. Мы его уже так используем, очень довольны. Вот пример такого использования, хабра перевод. Особенно удобно то что для запросов в эластик используется JSON, после монго будет привычно (а еще и удобно)
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы