— node.js: vm неспособна утилизировать больше одного ядра, их надо запускать несколько штук и кластеризовать, единствьенный способ решать проблемы: «а, убъем и перезапустим, это быстро», большое количество сырых библиотек непонятного качества, асинхронные коллбэки — это хорошо, пока не начинается достаточного размера система, которую надо как-то отлаживать
— mongodb: настраивать, настраивать, и еще раз настраивать. Про проблемы MongoDB под нагрузкой, про проблемы с репликацией, локами и т.п. в инете не писал только ленивый
— ну и поверх всего этого езе и redis, который надо примирять со всем вышесуществующим (то есть +еще одна технология, которую надо интегрировать)
Что имеется в итоге? «мы истекали кровью на всем протяжении разработки» Неудивительно
> Мне гораздо интереснее что есть сейчас, а не то что было тогда.
Да и сейчас с Монго не все в порядке. Сейчас, к сожалению уже не найду :( Но где-то месяц назад была серия статей разных компаний о проблемах с Монго (срочно переходили на что угодно — от редиса до mysql)
Быстрый гуглинг находит, например, www.zopyx.de/blog/goodbye-mongodb Там описаны основные проблемы, многие из которых есть до сих пор
Использую монго как хранилище для горячих данных: около 30Мб, которые очень быстро обновляются. Оно умудряется время от времени создавать серьезную нагрузку на диск и совершенно не ясно как это регулировать.
Вот взять Postgres: есть частые обновления/запись — включаем delayed_commit небольшой; нагрузка возросла — увеличиваем задержку; совсем уж не справляется — делаем репликацию и отключаем fsync.
много запросов на чтение — загоняем всю базу в shared_buffers.
В монго ничего такого нет. Есть mmap файл и хз как с ним обращаться. Разве что в последних версиях прикрутили журналирование. Но и журналирование не синхронное — остается возможность потерять часть данных. Если использовать getLastEror, то производительность станет ничем не лучше того же Postgres и красивых бенчмарков уже не получится.
да, она не может больше одного ядра и нужен кластер. так он ис каропки есть, в чем проблема-то?
да, много сырых либ странного вида — в чем проблема переписать то, что вас смущает?
да, асинхронные коллбеки — тот еще ад, но есть масса способов решить вопрос, как async ko, так и message passing-ом, типа обсерверов всяких
но она очень простая, быстро разворачивается и стабильно живет + под ноду можно писать на CoffeeScript — самом человечном из языков :)
> В том, что это — костыль. «Масштабируемая мегасуперсистема», которая неспособна использовать более одного ядра? В топку.
У Вас пруф отклеился :) Смысли какая фик разница как она это делает? Кроме ощущения фатального недостатка?
> И сколько времени займет переписывание?
Ну, вы же не школьник, можете сами прикинуть время разработки :)
> Ни один из которых не является стандартным или обкатанным в деле, да еще в комбинации с вышеупомянутой кластеризацией.
Эрлангерам расскажите, вот они удивятся :) И еще тем типам, которые книжки пишут. По паттерны программирования и всякое такое. Вы на ноде писали чего-нить? Маны читали?
> Аргументы школьников
Да я на большее и не претендую, ИМХО лучше писать на приятном языке стройные алгоритмы в понятных программах, чем пехепешить на перле, потому что «риальному спицу сирано на каком языке быдлокодить», а в результате ад и израиль — экспорт переменных, везде глобали, ре-юз кода копипастой и ифы с пролетом на триста-четыреста строк :)
> Иииии, «это фатальный недостаток, потому что...»? Что? Общественность в моем лице ждет ломающихся новостей :)
Действительно, зачем использовать больше одного ядра, если они есть в системе? Обойдемся одним
Действительно, зачем VM возможность оптимизировать исполнение, раскидывая работу по нескольким ядрам
Действительно зачем избегать копирования данных при передачи их с одной VM на другую при работе на одной и той же машине?
Действительно, зачем избегать cache miss, переключения контекстов исполнения, и прочей мишуры связанной с ограничениями на один процессор и необходимостью запускать несколько VM?
Ведь «истинно масштабируемой системе» это все не надо, так ведь?
> и эрленгер недоволен чистой смертью процесса, потому что жизнь того дешевле медяка?
Школота неспособна понять, что я писал не об этом?
> Все приемы работы с асинхронностью — по сути дела синтаксический сахар над коллбековым адом, если по сути.
Нет
> И какой-же паттерн не может быть применен в ноде?
> Действительно, зачем использовать больше одного ядра, если они есть в системе? Обойдемся одним
> Действительно, зачем VM возможность оптимизировать исполнение, раскидывая работу по нескольким ядрам
Запустите кластер. Я даже и не знаю как вам это еще донести.
> Действительно зачем избегать копирования данных при передачи их с одной VM на другую при работе на одной и той же машине?
> Действительно, зачем избегать cache miss, переключения контекстов исполнения, и прочей мишуры связанной с ограничениями на один процессор и необходимостью запускать несколько VM?
Мы все еще о ноде и JavaScript говорим? Вы не в состоянии сделать первое (во всяком случае разумными методами) и не в состоянии контролировать второе, пусть у VM голова и болит, что и как делать.
> Школота неспособна понять, что я писал не об этом?
> Вы не в состоянии сделать первое (во всяком случае разумными методами) и не в состоянии контролировать второе, пусть у VM голова и болит, что и как делать.
Вы не способны понять, что VM неспособна сделать все, о чем я говорил
> А я спрашивал — какой конкретный паттерн проектирования не может быть реализован в ноде.
Школоло. Паттерны программирования не ограничиваются паттернами объектно-ориентированного программирования.
В общем, прекращаю этот разговор в одностороннем порядке. Мне не платят за то, чтобы обучать школьников.
Давайте я вам помогу дочитать, а то вы все время вырываете цитату из контекста — «мы истекали кровью на всем протяжении разработки, но я не никогда не видел команды, делающей интересное приложение, без кровопролития, связанного с инструментами и компонентами».
По поводу многопроцессорности, так в JS совсем недавно появилась поддержка потоков (воркеров), и люди начали ее понимать. Почему бы не сделать по такой же схеме многопроцессорное распределение? Да, печалько, что оно не шарит память, но возможности для машстабирования предусматривают не только наращивание процессоров, а и серверов и вы сможете легко и безболезненно перейти к выполнению скриптов на другом сервере (потому что память у вас не шарится и вы общаетесь только сообщениями).
А вот что меня действительно пугает, так это популярность forever. Это как бы признание того, что быстроподнятное упавшим не считается.
> а то вы все время вырываете цитату из контекста — «мы истекали кровью на всем протяжении разработки, но я не никогда не видел команды, делающей интересное приложение, без кровопролития, связанного с инструментами и компонентами».
Люде не говорят «истекали кровью», а «было сложно», «мы столкнулись с такими-то и такими-то трудностями» и т.п.
> в JS совсем недавно появилась поддержка потоков (воркеров), и люди начали ее понимать. Почему бы не сделать по такой же схеме многопроцессорное распределение?
Ну попытайтесь его сделать в VM/фреймворке, который не поддерживает многопроцессорность и является однопоточной по определению.
> Да, печалько, что оно не шарит память, но возможности для машстабирования предусматривают не только наращивание процессоров, а и серверов и вы сможете легко и безболезненно перейти к выполнению скриптов на другом сервере
Тогда нет никакой разницы между node.js и, скажем, php-fpm. Но я понимаю, хайп, да. Не говоря о том, что возможность использовать несколько ядер не отменяет возможности масштабирования на несколько серверов, и наоборот.
> Это как бы признание того, что быстроподнятное упавшим не считается.
Ситуация с node.js вообще напомниает ранние Rails, в которых тоже все падало, глючило, все было дико сырое, но все делали хорошую мину при плохой игре. И только пару лет спустя DHH, автор Rails, сказал: это было такое говно, что мы его по скрипту прибивали и перезапускали раз в нцать минут. Точно такие же детские проблемы сейчас переживает и node.
Нода так же умеет работать — точно теми же механизмами вроде передачи открытого сокета — nodejs.org/api/cluster.html или вас смущает название кластер — ну термин такой.
P.S. Признайтесь, что пофигу что там нода — важно, что не ваш любимый ерланг?
Вы читали комментарий по ссылке, что я привел? Видимо, не читали. Понять, что там написано, вы тоже не в состоянии.
Дам только домашнее задание.
Дано: обработка данных.
В случае, если VM одна, и она способна перекидывать задания самостоятельно между CPU, такая VM способна распределить нагрузку между ядрами самостоятельно. При этом той же VM доступна простейшая оптимизация: так как VM одна, то данные туда-сюда копировать не надо, достаточно передавать указатель.
В случае, если VM несколько? А ничего. Любые данные между этими VM будут копироваться при каждой попытке передать данные туда-сюда. Это, безусловно, архитектурно правильное и мегаудобное решение, ага.
Про то, что VM, знающая, что такое multicore, способна грамотно управлять процессами и структурами данных, чтобы минимизировать прочие накладные расходы, я умолчу, для вас это будет высшая математика. Радуйтесь, что вы переизобрели nginx + php-fpm под другим, более хайповым названием.
Эрланг не использует передачу сокетов между процессами ОС.
В эрланге для SMP используются потоки а не процессы, так что передавать сокеты (как и любые другие данные) по пайпам нет необходимости.
Вот вам пример задачки, которую я не уверен что можно в NodeJS + cluster решить:
Есть сервер с 12 ядрами. На нём запущено 12 копий NodeJS. Они обслуживают, например, 20000 клиентов.
Есть сервер с БД.
NodeJS нужно иногда к этому серверу обращаться. Чтобы не создавать на каждую сессию новое подключение к БД, нужно поддерживать пул подключений.
Как мне сделать общий пул подключений для всех 12-ти воркеров? Или скажете держать отдельный маленький пул для каждого воркера?
наверняка есть другие варианты, у меня задачи такой не стояло, так что не в курсе как это на самом деле решается.
но сейчас под ноду много нового обвязочного кода пишется, черта лысого можно найти.
так, оффтопом — мерялись Perl, Twiggy and Redis VS CoffeeScript, Node and Redis — на разных платформах\конфигах результаты немного разные, но нода как минимум НЕ медленнее, а местами на 30% привозит. на примере простого url-shortener
так что можно спокойно писать, хуже уже не будет.
Ну ок, если вы так считаете, ещё несколько примеров, с которыми я лично имел дело, помимо пула подключений к БД:
http клиент с поддержкой keep-alive (должен где-то хранить пул подключенных сокетов);
шейпер, ограничивающий максимальную скорость обработки запросов на всю систему (в Mongo/Redis хранить счетчики?)
Плюс, когда переписывал эту систему с Python + gevent на Erlang, сумел ПОЛНОСТЬЮ отказаться от MongoDB, заменив её на хранилище в локальной памяти.
HTTP клиент с поддержкой keep-alive должен хранить открытые keep-alive сокеты.
Например, нам нужно послать 100 тыс запросов к example.com в 500 потоков. example.com выставляет keep-alive в 2 минуты.
Один поток сделал запрос, получил результат и начал его обрабатывать. Вернул открытый сокет в пул. Пока поток обрабатывает полученные данные, какой-то другой поток может взять уже открытый сокет из пула и сделать запрос через него.
По сути то же, что и пул подключений к бд. Да, можно держать локальные пулы для каждого процесса. Но так накапливается — пул для редиса, пул для монги пул для Postgres, пул keep-alive.
Понимаю, что для БД и HTTP пулы разные. Просто говорю, что на машине с 24 ядрами в Node cluster будет 24 маленьких пула для БД, 24 маленьких пула для HTTP 24 маленьких чего-то ещё для чего то ещё.
Хотя, по хорошему, для оптимальной утилизации ресурсов должен быть один пул для бд на всех, один пул keep-alive на всех (или не одно но, по крайней мере, контролируемое, а не навязываемое количество).
Ну так это и не оптимизация. Просто пишешь наиболее естественным способом, а оно само собой получается оптимизированным. Уж не знаю почему вам это так не нравится, но если можно оптимизировать что-то не прилагая никаких усилий, то почему нет?
Выходит, что если работа с HTTP везде одинаковая, то какая вообще разница на чем писать?
Примеры с пулом коннектов к БД, шейпером и keep-alive кешем привел как самые простые.
Но тот же отказ от Mongo в пользу хранения данных в Erlang процессе в локальной памяти уже дал заметный прирост, т.к. не нужно делать по несколько сотен мелких запросов к БД в секунду.
Очередной пример (не из моего проекта, но похожая задача) — рекурсивный веб-граббер. Скачал страничку — на ней 1500 ссылок. Нужно выяснить какие мы уже посетили, какие нет.
Что лучше — сериализовать и прогнать туда-обратно по TCP к Mongo/redis или проверить в локальной памяти?
Не спорю, что отсутствие в Node Cluster удобной общей памяти не всем мешает. Но если необходимость возникает, начинают лепить заплатки в виде хранения данных во внешних хранилищах и пр.
А представьте, что вы разрабатываете «отчуждаемое решение», вроде Erlyvideo (или Jabber сервера или базы данных какой то) и для того, чтобы оно завелось, требуется поставить монго/редис?
> Но я ж не бегаю по этому поводу срать кирпичами в эрланговский блог, как товарисч из первого поста.
Товарищ из первого поста внятно и аргументировал свою позицию, в отличие от школоты на ноде, у которой единственные «аргументы»:
— зато удобно писать
— кофескрипт — это удобно
и не забыть
— зато удобно писать
Было бы от чего быть батхерту. Батхерт на протяжении всего этого топика (и любого другого про ноду) у нодежсников. Еще бы его у них не было. Им впарили аналог nginx+php-fpm, а они рады. Вот и приходится делать невероятные усилия, чтобы не обращать на этот факт внимания. От этого и попоболь.
Почему-то большенство, кто пишет или начинает писать на nodeJs, используют MongoDB. Нет, я ничего не имею против, но пока не понимаю, почему так мало решений в связке nodejs + mysql.
Создаётся впечатление, что существует какое-то табу: если php, то только mysql, если nodejs, то nosql.
В силу специфики проектов, в которых учавствую, использую именно mysql и не вижу никаких проблем в принципе. node-mysql — это кто не знает вдруг.
У PHP так повелось со знаменитой связки LAMP (Linux Apache MySql PHP). Не в обиду будет сказано, но на Ruby и Python процент школьников заметно меньше, люди более серьезнее что ли подходят к разработке продуктов. Не хочу развивать тут холивар, но мне непонятен выбор MySql в качестве СУБД для проектов, учитывая что хранимые процедуры в ней появились вроде как только с 5 версии. На мой взгляд в PostgreSQL есть все что нужно для работы на проектах любого уровня.
Тоже не хочу развивать дискуссию по поводу баз данных. Просто любопытно ваше мнение. Вчера в одном из камментов на хабре кто-то высказался, что хранимые процедуры в бд создают vendor-lock и повышают стоимость и сложность переезда на другие бд.
У нас был тяжёлый путь от Java + MySQL и Java + Oracle к менее традиционным Java + Postgresql и Java + DB2/zOS. MySQL неплохая СУБД для маленьких и лёгких проектов, но при росте базы выше 20 ГБайт в нём открывается портал в ад. Проблема усиливалась тем, что на момент начала проекта InnoDB существовал только в зародыше и масса production environment была запущена и крутилась на MyISAM.
Кто использует Node.js: Trello (Часть 2)