Comments 48
Давайте начнем с того что в java нет особых проблем с тредами. И на этом можно и закончить.
Давайте начнем с того, что однопоточный NodeJS
может лопатить тысячи запросов в секунду не отжирая гигабайты памяти. а в джава подход — зачем нам думать о памяти и производительности, нафигачим тысячи потоков и разрастемся на десятки ЕС2 инстансов.
Вы вот сейчас рассказываете феерический бред. Во первых nodejs течет причем довольно сильно. И да сколько там у вас nodejs жрет? Давайте начнем с этого. В java если вы нормально написали приложение у вас вытекания памяти не будет. У меня было приложение которое работало nonstop несколько лет и не текло. В nodejs это вообще реально?
Мне нравится ваш подход — возьмем кривое nodejs приложение и будем сравнивать с хорошо написанным джавовским :))) Речь то не об утекании памяти в кривых приложениях, а о том что вы не понимаете зачем нужен async non-blocking подход. Вы считаете что thread-per-request это лучшая практика и что создание тысячи тредов это нормальная ситуация. Готов с вами поспорить на ящик octomore 6.3 что вы пишете свое стандартное потоковое приложение с хождением в редис и постгрес, а я свое и потом мы запускаем все в докере с жесткими ограничениями типа 512 на CPU и 512Mb памяти на контейнер. И долбим к примеру 1000 конкурентных юзеров на это все — а дальше смотрим latency и error rate.
А можно дурацкий вопрос? А сколько у нас будет ядер этой машине? Если больше двух то боюсь для вашего nodejs приложения это плохие новости. Вы надеюсь помните что не блокирующийся nodejs не умеет больше одного потока? А java умеет. И даже современный бюджетный процессор умеет запускать более двух потоков кода. И java это умеет ооочень давно.
Вы походу читаете через строку.
ограничениями типа 512 на CPU и 512Mb памяти на контейнер.
и писать я буду на джаве — какой нить springboot(чтобы пожирнее было :))) ), lettuce и vertx-pg-client. Но могу и на Ноде если вам так сильно хочется.
Там про количество ядер ни слова. Вы отлично должны понимать что в java проблем с многопоточностью нет, причем очень давно, так-как это основная ниша где она применяется. И в случае nodejs вам придется просто запускать пачку nodejs приложений и иметь блокировки на уровне СУБД. Получим в лучшем случае шило на мыло.
512 CPU units это пол ядра :)
И без обид но вы вообще не в курсе что такое async non-blocking. Почитайте про epoll, что такое Netty и тд. Мне не надо стопяцот потоков чтобы читать/писать с сокетов. Я обойдусь всего парочкой — тк в IO bound задач нет проблем с ЦПУ тк основное время это записать-подождать-прочитать какую либо ИО задачу. Все ваши потоки будут просто стоять и ждать и кушать память. При 1000 конкуретных юзерах и thread-per-request у вас по дефолту отожрется 1Гб памяти только для хттп потоков.
Я вообще-то в курсе и более того пишу под это. И настраивал все это еще в apache. По этому знаю ограничения. В случае если у вас внезапно больше одного ядра, то async non-blocking может не утилизировать весь процессор и сеть. И если не использовать простую модель one request one process, то гибридная модель будет легко натягивать async non-blocking Хороший пример гибридной модели nginx.
Каша какая то — что такое гибридная модель? Это когда на каждое ядро запускаем event loop? а не на одном все делаем? Так это все равно как был async non-blocking так и остался. И чтобы закончить эту демагогию — готовы ли вы доказать преимущества тысячи потоков перед парочкой.
Я беру springboot reactive, lettuce, vertx-pg-client. Вы springboot, Jedis и PG JDBC — и смотрим на 512 юнитах цпу, 512Мб памяти контейнера(не хипа). Выигрывает кто больше обработает запросов за 5 минут на 1000 конкурентных юзерах.
Каша какая то — что такое гибридная модель? Это когда на каждое ядро запускаем event loop? а не на одном все делаем? Так это все равно как был async non-blocking так и остался.
Никакой каши. Проблема у вас в случае event loop будет возникать в том что в случае утилизации множества ядер потребуется как-то балансировать нагрузку. И в случае классического java модели и сервлета это проблемы особо не представляет, а вот в случае non-blocking есть определенные проблемы.
И чтобы закончить эту демагогию — готовы ли вы доказать преимущества тысячи потоков перед парочкой.
На нормальной машине где более одного потока исполнения, про что я сразу сказал. А не на куцем полпроцессора. Где обычно java и используется.
А если же будет 512 юнита цпу и 512Мб памяти то лучше взять вообще openresty с lapis фреймворк на lua. Жрать всего будет меньше В том числе и памяти. И да там тоже есть неблокирующие вызовы postgresql. А ну да и nginx я могу воспользоваться его моделью распределяющей нагрузку.
Дополнительно все сильно зависит от используемой загрузки. К примеру если вы начнете тянуть под миллион записей, у вас async non-blocking тоже может сливать, потому что банально оно однопоточный.
non-blocking не панацея, как и многопоточная модель. Если у вас много мелких запросов и много клиентов, он может быть лучше. А может и не быть. В случае многопоточной модели, производительность могут убивать медленные клиенты. Но в случае non-blocking они же будут жрать память.
Не будет у меня возникать тк джавовские имплементации обычно делают два евент лупа на ядро. А в ноде запускают несколько процессов.
Проблема у вас в случае event loop будет возникать в том что в случае утилизации множества ядер потребуется как-то балансировать нагрузку.
А вы платите за эту нормальную машину из своего кармана? Представляете бывают проекты где инстансов микро-сервисов пару тысяч и вот таким горе программистам на каждый инстанс надо подавать по 16 ядер и 64Гб оперативки иначе в их понимании джава не взлетает.
На нормальной машине где более одного потока исполнения, про что я сразу сказал. А не на куцем полпроцессора. Где обычно java и используется.
А в Кафку как будем ходить? Или данные читать с какого нить AWS S3? Джава или Нода тем и хороши что много разработчиков и много различных библиотек доступны.
А если же будет 512 юнита цпу и 512Мб памяти то лучше взять вообще openresty с lapis фреймворк на lua. Жрать всего будет меньше
О неужели снизошло озарение, что программы разные бывают и по разному их надо реализовывать.
Дополнительно все сильно зависит от используемой загрузки.
Если тянуть по миллиону и одновременно куча клиентов то первее умрет Постгрес. и никакие потоки и ивент лупы тут вообще не спасут.
К примеру если вы начнете тянуть под миллион записей, у вас async non-blocking тоже может сливать, потому что банально оно однопоточный.
А кроме вас никто и не утверждал что есть серебряная пуля.
Помините фразу вашу — Давайте начнем с того что в java нет особых проблем с тредами. И на этом можно и закончить.
non-blocking не панацея, как и многопоточная модель.
Те вы будет ок про наш спор если мы оставляем 512Мб памяти и читерим до 2048 ЦПУ юнитов?
Но в случае non-blocking они же будут жрать память.
А вы платите за эту нормальную машину из своего кармана? Представляете бывают проекты где инстансов микро-сервисов пару тысяч и вот таким горе программистам на каждый инстанс надо подавать по 16 ядер и 64Гб оперативки иначе в их понимании джава не взлетает.
Если у меня есть ограничения про процессору и памяти, я бы сначала подумал зачем мне там вообще java.
О неужели снизошло озарение, что программы разные бывают и по разному их надо реализовывать.
Как обычно не читай сразу отвечай. Еще раз я сейчас пишу как раз под non-blocking со всеми вытекающими оттуда проблемами.
Те вы будет ок про наш спор если мы оставляем 512Мб памяти и читерим до 2048 ЦПУ юнитов?
Вполне норм. Имплементацию можете и сами набросать в том же spring она переключается банально заменой библиотек. Заодно и померять. Дополнительно стоит померять при 50% медленных клиентов. В том же jmeter есть. Вполне интересно в чем будет разница.
А у вас все проекты вида тратьте денег мульоны, нам пофиг на расходы? Или понять что хорошо когда бэкенд на одном языке написан и людей можно перекидывать с проекта на проект?
Если у меня есть ограничения про процессору и памяти, я бы сначала подумал зачем мне там вообще java.
Смотрите свое самое первое сообщение и думайте.
Как обычно не читай сразу отвечай. Еще раз я сейчас пишу как раз под non-blocking со всеми вытекающими оттуда проблемами.
Не, никто за вас свою часть не будет делать и тем более за интерес. А то накинуть на вентилятор это вы можете и писать кучу комментариев время есть. А как сделать так пусть другие?
Вполне интересно в чем будет разница.
А у вас все проекты вида тратьте денег мульоны, нам пофиг на расходы? Или понять что хорошо когда бэкенд на одном языке написан и людей можно перекидывать с проекта на проект?
Мне просто без разницы на чем писать. На чем надо на том и напишу. Если не писал до этого нуу окей, просто будет более долгий старт.
Не, никто за вас свою часть не будет делать и тем более за интерес.
Для сравнения нужно, чтобы реализации делали одно и то же. Если хотите чтобы я написал ну окей, я могу набросать, но вопрос упирается что надо?
Ага — удачи в бизнесе с таким подходом. А давайте это забахаем на Расте, а это на Скале, вот этот кусок ради интереса сделаем на Хаскеле.
Мне просто без разницы на чем писать. На чем надо на том и напишу. Если не писал до этого нуу окей, просто будет более долгий старт.
Делаем два ендпоинта
- в один случайным образом постим число 1..100 — оно записывается в Постгрес где ид это число, а второе поле текущий таймстемп, а так же эти же данные кладем в редис с ттл в 1 сек
- вычитываем записи по случайному числу 1..100 — если есть то вовращаем данные с редиса, если там нет то с постгреса.
Для сравнения нужно, чтобы реализации делали одно и то же. Если хотите чтобы я написал ну окей, я могу набросать, но вопрос упирается что надо?
Ага — удачи в бизнесе с таким подходом. А давайте это забахаем на Расте, а это на Скале, вот этот кусок ради интереса сделаем на Хаскеле.
Прямо сейчас у меня основные языки это lua и js. Ну js еще ладно. Но первый так получилось :)
Делаем два ендпоинта
Уже сделали
https://medium.com/@filia.aleks/r2dbc-vs-jdbc-19ac3c99fafa
Но там надо еще две статьи что я выше привел добавить для получения целостной картины.
Хотя вообще говоря я сделал проще. Я погуглил
Нашел три статьи
https://medium.com/@filia.aleks/r2dbc-vs-jdbc-19ac3c99fafa
https://technology.amis.nl/2020/03/27/performance-of-relational-database-drivers-r2dbc-vs-jdbc/
https://technology.amis.nl/2020/04/10/spring-blocking-vs-non-blocking-r2dbc-vs-jdbc-and-webflux-vs-web-mvc/
https://github.com/spring-projects/spring-data-r2dbc/issues/203
Если кратко, скомпилировать. То на машине с малым количеством CPU и памяти будет лучше reactive. На большей машине с большим количеством CPU будет лучше JDBC.
Это касается R2DBC про который я не раз говорил в комментариях к схожим статьям, что он медленный и авторы этого не скрывают. И в продакшене его еще рано использовать.
Так же в этой статье была приведена ссылка на производительность verxt client'a — https://www.techempower.com/benchmarks/#section=data-r18&hw=ph&test=db
так же мы с вами говорим вообще за подход когда вся система реативная или когда поток потоком погоняет.
Тут вопрос больше в том как будет происходить масштабирование системы. Если масштабирование идет плодим кучу мелких машин и как-то между этим всем балансируем закладывая это в архитектуру, то nonblocking можно. Если же масштабирование "классическое", просто берем машину побольше, тот там в случае java работает лучше стандартные сервлеты, просто за счет того что там так сложилось и уже все грабли по этой теме собраны.
Но опять же если уж реактивщину использовать и хочется использовать jvm, я бы scala или clojure. Хотя конечно для второго народ программировать будет сложновато :)
Вы на ходу сами себе придумываете что-то, то классическое маштабирование которое ничем не отличается от плодим кучу мелких машин
Наш спор ограничивается одним инстансом с указанными параметрами.
Ну почему же “закончить“? Наличие хорошего способа сделать что-то не означает, что все остальное — плохо.
Если не ошибаюсь, то это vertx, рассмотренный в статье. Возможно, немного модифицированный.
По сути предлагаемые решения есть именно те самые велосипеды, которые в данном случае стоит сделать самим. Потому что — всё очень жёстко заточено под конкретное видение автора велосипеда. Значит придётся изголяться и тратить много лишнего времени на получение нужного функционала через узкое отверстие, оставленное автором как обычно — сзади. А альтернатив нет (кроме собственного велосипеда). Ну и Oracle не поддерживает.
Хотя может у приведённых примеров решений есть какие-то значимые плюсы? Но я в статье их не увидел.
все просто — возможности нет
Если у вас Хибернейт то вам уже производительность по определению не приоритет :)
Но когда R2DBC будет готово для продакшена то к нему есть Спринг Дата
Можно попробовать просто генерить SQL с jOOQ и скармливать его Vert.x
В общем-то мой изначальный вопрос как раз о таком опыте. Пусть даже это будет просто генерация SQL при помощи jOOQ с последующей отправкой в какой-нибудь Vert.x Reactive PostgreSQL client.
Хочется узнать, как другие решают эту задачу (если вообще решают), увидеть примеры…
Совсем недавно на Хабре статья была: https://habr.com/ru/post/500446/
Думаю неплохо было бы упомянуть и написать про цели своей: например раскрыть подробнее ...
Игнорируется отсутствие встроенного кэша в R2DBC, а применение Spring Cache позволяет кэшировать только тип Mono, а коллекции как Mono<List<T>>. В реактивном стиле возможен вызов одного источника из разных цепочек, но что может привести к взаимной блокировке в одной транзакции, т.к. R2DBC помечает все запросы как FOR UPDATE.
Две альтернативы JDBC