На данный момент работаю над небольшим приложением на Node.js. В приложении используется MySQL (MariaDB) для хранения данных, Redis для кеширования и Express.js. Приложение пока работает на 1 сервере, но возникла необходимость масштабировать приложение и соответственно распределить данные из БД на несколько серверов. Начал разбираться с шардингом и репликацией БД.
На данный момент пришел к решению выбрать горизонтальный шардинг как основной инструмент масштабирования данных в БД. Но так как большого опыта с шардингом у меня нет, то спрашиваю совет здесь. Как разбить данные по шардам и как хранить данные примерно понятно, но остались некоторые вопросы.
1) Как работать из Node.js приложения одновременно с десятками шардов (серверов БД)? Сейчас я работаю только с 1 инстансом БД, а после шардинга придется для одного запроса к API приложения делать несколько соединений к разным шардам БД и несколько запросов?
2) Как осуществлять поиск / извлечение данных из разных шардов? Например, на одной странице необходимо отобразить одновременно 10 юзеров (имя, аватар и т.п.), которые распределены по разным шардам. Что делать в этом случае? Можно также хранить важные данные в кеше (Memcache/Redis), но при этом, чтобы сделать поиск / извлечь данные нужно также как-то объединить кешы в кластер. Можно ли индексировать данные на шардах с помощью ElasticSearch, а потом уже делать поиск?
3) На какие подводные камни стоит обратить внимание на начальном этапе, чтобы избежать проблем в будущем?
Поделитесь, пожалуйста, собственным опытом и советами.
Классический вопрос из серии XY Problem.
Вместо того чтобы писать "я не знаю что мне надо, но вообразил что мне нужен шардинг, поэтому расскажите как им пользоваться" надо писать "масштабирование мне требуется по такой-то причине и с такими-то условиями. подскажите наилучший вариант".
И тогда тебе подскажут ответ, в порядке частоты причин, по которым задают этот вопрос:
1. Нет, бояться миллиона записей не надо. Mysql потянет во много раз больше.
2. Сделать репликацию мастер-слейв, с нужным количеством слейвов.
3. Возможно, под какие-то условия подойдет и шардинг.
> я не знаю что мне надо, но вообразил что мне нужен шардинг, поэтому расскажите как им пользоваться
Я знаю, что мне надо. Мне нужно распределенное хранилище пользовательских данных с возможностью добавления новых серверов (при необходимости).
> Нет, бояться миллиона записей не надо.
Я боюсь не миллиона записей в БД, а того что все пользовательские данные (профили, переписка и т.п.) не поместятся физически на одном сервере и в одной БД. Возможно и поместятся, но все будет ужасно тормозить + нужно будет покупать какой-то супер-навороченный сервер. Кроме того, это будет единственная точка отказа и в этом случае придется делать бекапы на десятки/сотни гигабайт. Сколько времени при этом будет занимать создание индексов?
Что плохого в том, что я хочу добавить возможность распределения данных на несколько серверов? Да, я не понимаю некоторые моменты, поэтому и задал вопрос для более опытных ребят.
Что данные не поместятся бояться не надо. Диски нынче дешевы. Тормозить будет обязательно. Но только не из-за того что все данные на одном сервере, а из-за твоей личной неграмотности и отсутствия базовых знаний. Каковые знания и надо прокачивать, вместо влажных эротических мечтаний про шардинг.
Тут все просто. Научись сначала работать с одной БД, а потом уже думай про шардинг. Если ты на Жигулях не можешь довезти 20 кирпичей на дачу, то покупка второго автотранспортного средства тебе не поможет.
Спасибо за ответ. Не вижу смысла дальше обсуждать все вышесказанное в этом ответе потому, что вместо каких-то конструктивных советов и решений дискуссия переходит в русло личный оскорблений. Поэтому остановлюсь на своей личной неграмотности и влажных эротических мечтаниях про шардинг.
Юноша, конструктивный совет я тебе дал: учись работать с БД. И тогда все запросы будут у тебя летать. Но понятное дело что учиться - это скучно и совсем не так романтично, как загадочный "шардинг". поэтому проще надуться и изображать из себя обиженное дарование.
Что характерно, все любители "конкретных ответов" сами задать конкретный вопрос не в состоянии. Из двух попыток ты не смог дать ни одной конкретной цифры, а только мутные страдания про то что данные не поместятся и все будет ужасно тормозить. Отсюда очевидный вывод, что данных у тебя нет и не предвидится, а есть только липкие подростковые фантазии.
Мне кажется, что у Вас великий талант - гадать на кофейной гуще, высвечивать все в негативном свете и оскорблять. Обычно я очень быстро прекращаю общение с такими людьми, но все же решил ответить.
> Юноша, конструктивный совет я тебе дал: учись работать с БД
Я Вам не "юноша" и "липких подростковых фантазий" у меня нет. Работать с различными базами (MySQL, MongoDB) я умею на достаточном уровне.
> понятное дело что учиться - это скучно и совсем не так романтично
Ну вот я пытаюсь разобраться с тем как правильно распределить пользовательские данные на несколько серверов БД и как делать в этом случае поиск. Вместо каких-то советов / решений меня обвиняют в "личной неграмотности", "влажных эротических мечтаниях" и "подростковых фантазиях". Похоже, что здесь осталось мало адекватных людей.
> любители "конкретных ответов" сами задать конкретный вопрос не в состоянии
Я задал 3 конкретных вопроса, с которыми пока не смог разобраться:
1) Как работать из Node.js приложения одновременно с десятками шардов (серверов БД)?
2) Как осуществлять поиск / извлечение данных из разных шардов?
3) На какие подводные камни стоит обратить внимание на начальном этапе, чтобы избежать проблем в будущем?
> ты не смог дать ни одной конкретной цифры, а только мутные страдания про то что данные не поместятся
Все дело в том, что Вы поспешно делаете выводы и сразу же высвечиваете все в негативном свете.
> данных у тебя нет и не предвидится, а есть только липкие подростковые фантазии
Сейчас у меня примерно 250 000 зарегистрированных пользователей. В приложении есть система личных сообщений между пользователями и уже этого достаточно для того, чтобы понять, что нужно как-то распределить / вынести данные на несколько серверов БД. Вариант мастер-слейв или мастер-мастер репликации я не рассматриваю потому, что это поможет распределить нагрузку только первое время. Бесконечно плодить реплики большой базы особо смысла не вижу. Здесь и ответ на Ваш вопрос - "Попробуй объяснить, хотя бы самому себе, каким боком здесь шардинг свалился".
> Каковые знания и надо прокачивать, вместо влажных эротических мечтаний про шардинг
Спасибо. Вы мне в этом вопросе очень помогли.
Шардинг имеет смысл именно когда данные чаще всего достаются из одного шарда. Картинки, например, или статистика по различным серверам/сервисам. Юзера, как основаная сущность приложения, должны физически лежать в одной базе. И даже теоретически макс возможные 6 млрд пользователей в базе займут пару терабайт, что для мускула не проблема - https://habrahabr.ru/post/64851/
Спасибо за ответ. Да, теоретически 6 млрд пользователей в базе займут пару терабайт, но если в приложении есть еще и другой функционал, то скорее всего это может не поместится в пару терабайт. Например, в системе личных сообщений 6 млрд пользователей будут общаться между собой и генерировать при этом большой объем данных. Кроме того, скорее всего будет сложно делать/восстанавливать бэкапы базы в несколько терабайт.
На данный момент все-таки думаю хранить данные на нескольких шардах MySQL и одновременно работать только с шардом текущего пользователя, а необходимые данные о пользователях с других шардов хранить в каком-то поисковом движке/кеше типа ElasticSearch/Sphinx.
Да все равно шардинг не нужен. Шардинг - последний вариант, когда другие уже не возможны.
Кто мешает вынести сообщения юзеров в отдельную Монгу/Кассандру? В реляционной базе хранить переписку - очень непродуманное решение. Тут или джойнить таблицу юзеров из млн записей к десятку комментов на каждый вывод или кешировать все и везде (и тогда по памяти улетишь).
А если еще и шардинг сверхе привинтить - то вообще сливай воду. "а необходимые данные о пользователях с других шардов хранить в каком-то поисковом движке/кеше типа ElasticSearch/Sphinx." - это тоже архитектурный шедевр. Полная копия базы юзеров (типа шардированной) в эластике, конечно, будет работь ошен быстро.
Не, ну если хочется модное слово в резюме добавить, то дерзай, конечно. Мы же тебе не менеджер/заказчик.
Спасибо за конструктивные советы. Согласен, что в принципе имеет смысл вынести сообщения юзеров в отдельную Монгу/Кассандру.
>Полная копия базы юзеров (типа шардированной) в эластике
здесь я имел в виду не полную базу юзеров, а только самую необходимую информацию о всех юзерах (например, имя, пол, возраст, аватар и т.п.), а переписку 2-х пользователей с разных шардов дублировать одновременно на 2-х шардах.
> Шардинг - последний вариант, когда другие уже не возможны.
Возможно, но именно к шардингу в итоге пришли все более-менее крупные приложения типа Вконтакте, Instagram, различные мессенджеры и т.п. Именно так, судя по их докладам, они хранят данные в реляционной базе типа MySQL и это работает. Мне до них ооооочень далеко, но все же хочется узнать как это делают большие приложения и заложить такую возможность в архитектуру своего приложения на данном этапе (250 000 юзеров), чтобы иметь возможность быстрого роста за счет простого добавления нового сервера (шарда) и избежать проблем в будущем.
Еще раз - никто не шардит данее которые предполагается доставать в одном запросе. Юзеров, категории и т.п. Шардят независимые данные - для разных групп юзеров, языков и т.д.
Вот схема хай-лоад сайта с шардингом (википедия) - https://upload.wikimedia.org/wikipedia/commons/4/4...
юзера лежат в одной базе с репликацией, тексты для разных языков размазана по шардам.
И если возникает вопрос "Например, на одной странице необходимо отобразить одновременно 10 юзеров (имя, аватар и т.п.), которые распределены по разным шардам. " - значит с понятиме шардинга его автор ни хрена не знаком. "счет простого добавления нового сервера (шарда)" - та же херня. Это называется репликация, но никак не шардинг.