Pull to refresh

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. Хотя конечно для второго народ программировать будет сложновато :)

Вы на ходу сами себе придумываете что-то, то классическое маштабирование которое ничем не отличается от плодим кучу мелких машин
Наш спор ограничивается одним инстансом с указанными параметрами.

Наш спор ограничивается одним инстансом с указанными параметрами.

На указанном инстансе с 512 CPU и 512 RAM будет быстрее non-blocking в общем случае. Но nginx я бы перед ним все же поставил.

ну хоть что то :)))) рад что объективность восторжествовала. и он будет быстрее и на 8 ядрах и 64Гб памяти

Да на 16 ядрах уже можно писать на джаве, а все остальное это мелочь и не достойна этого славного языка. Пусть го-писатели мучаются в докере и считают каждый доллар.

Ну почему же “закончить“? Наличие хорошего способа сделать что-то не означает, что все остальное — плохо.

На java пишут все же больше стандартные большие и скучные "опердени" для кровавого интерпрайза. Там чем стандартнее тем лучше. Плюс классическое масштабирование применяется чаще.

Если не ошибаюсь, то это vertx, рассмотренный в статье. Возможно, немного модифицированный.

нет — Кваркус это просто прослойка под вертексом. С ним из коробки не особо удобно работать на всех его колбеках. А кваркус это все причесывает и делает аля спринг бут :)

Речь о драйвере баз данных, а не о фреймворка в целом

Про поддержку в БД. А зачем ждать у моря погоды? В смысле Oracle не поддерживает фичу, значит enterprise массово не будет её использовать, а потому ждать незачем и если есть нужда — можно сделать довольно простой эмулятор, обеспечивающий аналогичный функционал без завязки на конкретную СУБД.

По сути предлагаемые решения есть именно те самые велосипеды, которые в данном случае стоит сделать самим. Потому что — всё очень жёстко заточено под конкретное видение автора велосипеда. Значит придётся изголяться и тратить много лишнего времени на получение нужного функционала через узкое отверстие, оставленное автором как обычно — сзади. А альтернатив нет (кроме собственного велосипеда). Ну и Oracle не поддерживает.

Хотя может у приведённых примеров решений есть какие-то значимые плюсы? Но я в статье их не увидел.

Данные велосипеды делаются под эгидой Eclipse и Spring, что внушает некоторое доверие.

Вообще не сильно понятно зачем. Для запуска в контейнере где мало ресурсов и один поток исполнения?

ОНО ЖЕ НЕБЛОКИРУЮЩЕЕСЯ!111. Хотя постойте это java это там не так уж и важно.

Я вас удивлю, но на Java тоже можно в неблокирующиеся игрушки играть.

Я знаю что умеет. И более того поддержка тянется аж с tomcat 6 версии nio под него есть.

Было бы очень интересно узнать о возможности (и опыте если такой есть) подружить асинхронные драйверы с такими озвученными инструментами, как JOOQ и Hibernate.

все просто — возможности нет

Если у вас Хибернейт то вам уже производительность по определению не приоритет :)
Но когда R2DBC будет готово для продакшена то к нему есть Спринг Дата

У нас jOOQ и Vert.x. Поэтому вопрос весьма актуален — сейчас приходится городить свои пулы.

Можно попробовать просто генерить SQL с jOOQ и скармливать его Vert.x

Можно, но это такая полумера все же. Хотелось бы полноценной работы с record'ами и custom типами.
В общем-то мой изначальный вопрос как раз о таком опыте. Пусть даже это будет просто генерация SQL при помощи jOOQ с последующей отправкой в какой-нибудь Vert.x Reactive PostgreSQL client.
Хочется узнать, как другие решают эту задачу (если вообще решают), увидеть примеры…

Я делал один запрос в котором много возможных вариантов через jOOQ и сгенерить SQL, но большинство запросов просто руками писаные в Repository объекте сидят. У меня специфика, что много микросервисов и схемы простые — не больше 10 таблиц в схеме.

Игнорируется отсутствие встроенного кэша в R2DBC, а применение Spring Cache позволяет кэшировать только тип Mono, а коллекции как Mono<List<T>>. В реактивном стиле возможен вызов одного источника из разных цепочек, но что может привести к взаимной блокировке в одной транзакции, т.к. R2DBC помечает все запросы как FOR UPDATE.

Sign up to leave a comment.

Articles