Как стать автором
Обновить

Как мы начали использовать виртуальные потоки Java 21 и на раз-два получили дедлок в TPC-C для PostgreSQL

Уровень сложностиСредний
Время на прочтение9 мин
Количество просмотров21K
Всего голосов 17: ↑16 и ↓1+19
Комментарии31

Комментарии 31

Проблема в том, что код с synchronized может находится глубоко внутри используемых библиотек


Асинхронные библиотеки плохо работают в связке с синхронными. Например асинхронный веб сервер будет так-себе, если использовать синхронный клиент внутри.

В Java, во имя обратной совместимости, порой реализовывают интерфейсы через одно место. Например объект типа List созданный черезunmodifiableList имеет метод add, который бросает рантайм исключение.

Ну и комбо асинхронный объект в интерфейсе Thread. При малом количестве задач, это часто будет просто неэффективный код, который гоняет event loop, но по факту гоняте всё синхронно на ThreadPool. Ну а если задач много, то всё подвиснет, как в статье.

Асинхронность это очень крутой инструмент, но кроме производительности он открывает бездны возможностей сделать всё еще медленней.

Асинхронные библиотеки плохо работают в связке с синхронными

В примере не вижу, чтобы использовались асинхронные библиотеки в связке с синхронными. Виртуальные потоки придуманы как раз для того, чтобы писать привычный синхронный код, а вся "асинхронность" уйдет в недра JVM. И авторы project loom везде предупреждают, что с synchronized блоками и native это работать не будет (в лучшем случае не будет никакого полезного эффекта), о чем и написано в конце статьи. Такое вот ограничение, которое тут и стреляет. Проблема в том, что еще много где продолжают использоваться synchronized блоки, даже внутри классов самой JVM, не говоря уже о куче сторонних библиотек. Но, надеюсь, со временем все это допилится.

В Java, во имя обратной совместимости, порой реализовывают интерфейсы через одно место.

Обратная совместимость это одна из сильных сторон Java. И идея, что можно по щелчку превратить все потоки в виртуальные в уже написанном коде без его переписывания, мне кажется очень крутой. Даже не смотря на то, что при столкновении с реальностью всплывает много разных нюансов.

В примере не вижу, чтобы использовались асинхронные библиотеки в связке с синхронными.


Пул потоков в данном случае не асинхронный.

Виртуальные потоки придуманы как раз для того, чтобы писать привычный синхронный код, а вся "асинхронность" уйдет в недра JVM. И авторы project loom везде предупреждают, что с synchronized блоками и native это работать не будет (в лучшем случае не будет никакого полезного эффекта), о чем и написано в конце статьи.

Задумка хороша, просто пока надо знать много деталей реализации, чтобы это приносило пользу.

Пул потоков в данном случае не асинхронный.

Тик а что тут вообще асинхронное?

просто пока надо знать много деталей реализации

Пока это все сыровато, то да. Потом как раз думать не надо будет об этом

100 конекшенов к базе, но почему бы не юзать их в 100000 потоков.

Голдратт, да? Если узкое место БД, то извращения в жаве тебя не спасут.

Ладно тупой вопрос: работать быстрее стало?))

100 конекшенов к базе, но почему бы не юзать их в 100000 потоков.

Проблема, которую мы решали, как раз обусловлена тем, что в отличие от виртуальных крайне проблематично запустить 100K физических потоков.

Если узкое место БД, то извращения в жаве тебя не спасут.

Речь в первую очередь о клиенте (бенчмарке), а не какой-либо БД.

Ладно тупой вопрос: работать быстрее стало?))

Да, благодаря переходу на виртуальные потоки мы теперь можем запускать на одном сервере десятки и даже сотни тысяч терминалов TPC-C. А до этого приходилось запускать на нескольких серверах. Изначально мы стали оптимизировать бенчмарк по очень простой причине: чтобы нагрузить кластер YDB из 3 серверов (по 128 ядер и 512 GB RAM), требовалось 3-5 таких же серверов для запуска TPC-C. А что если мы хотим нагрузить кластер из 100 серверов? :) В этой презентации я подробно рассказал об этой и некоторых других проблемах производительности бенчмарков, которые нам пришлось решить.

"Метрика производительности, представленная в TPC-C, - это "бизнес-производительность", измеряющая количество обработанных заказов в минуту." -

Короче строили самую быструю тачку, построили которая жрёт мало бенза.

Ээ.. Цель достигнута?

Да, благодаря переходу на виртуальные потоки мы теперь можем запускать на одном сервере десятки и даже сотни тысяч терминалов TPC-C

В статье очень не хватает результатов работы, а также кода как именно поправили с семафором

В статье очень не хватает результатов работы

В самом начале есть ссылка на наш предыдущий пост о TPC-C, где все результаты: https://habr.com/ru/companies/ydb/articles/763938/

а также кода как именно поправили с семафором

В тексте есть ссылка на коммит с этим исправлением: https://github.com/ydb-platform/tpcc/commit/175f0c03d9c16652c85a6103331fec473017797e

Сильное исправление, которое ломает весь остальной код кроме конкретного бенчмарка

Сильное исправление, которое ломает весь остальной код кроме конкретного бенчмарка

Benchbase - фреймворк для написание бенчмарков и добавления СУБД. Мы оттуда используем только TPC-C. Но несложно добавить returnConnection() в другие бенчмарки, если потребуется.

А можно для тупых?

У вас есть жава, которая тупо прикидывает запросы в БД. У вас 700 ядер и 2,5 терабайта ram держат этакий аналог nginx.

100к запросов, это 100ГБ RAM для жавы, вы упёрлись в количество потоков, не буду врать в реальной жизни такого никогда не было, поэтому интересно конечно как это делать.

Но какая то надуманная ситуация, что жавочный передаст жрет столько же ресурсов сколько бд

У вас 700 ядер и 2,5 терабайта ram держат этакий аналог nginx.

Про nginx не понял, что имеете в виду. У нас есть СУБД (YDB и PostgreSQL). Нам нужен бенчмарк, чтобы оценить производительность. TPC-C как раз очень популярный бенчмарк для OLTP систем. Проблема оказалось в том, что общедоступная реализация TPC-C потребляет слишком много ресурсов и нам пришлось решать эту проблему, т.к. в нашем случае (YDB) речь идёт о сотнях серверов под СУБД и не вариант заводить дополнительно сотни серверов под запуск бенчмарка. Самый свежий пример: вчера один из клиентов попросил результаты TPC-C для YDB, работающей на 18 серверах (каждый 128 ядер, 1 TB RAM и 6 NVMe дисков). Без улучшений TPC-C нам бы потребовалось как минимум ещё 18 таких серверов, а с улучшениями должно хватить двух.

Я прочитал tpc-c. Не до конца понял.

Вам нужно нагрузить БД?

Жава- это обвязка для нагрузки, вы там в цикле фигачите транзакции и в какой-то момент жава посыпалась потому что условный линух падает при 100000 потоках?

Если так, то рост потоков вызван перегрузкой БД, это она не тащит и подвисает. Или я не понял?

Или TpC-c ещё включает рест в себя?

Да, нам нужно нагрузить БД. Для этого мы используем бенчмарк TPC-C, который написан на Java. Большое число потоков обусловлено тем, как реализован бенчмарк и совсем не связано с БД.

Я к тому, что БД тупит, жава потоки не закрывает и копит их.

Эта обвязка из жавы не вами сделана? Вы взяли какую то испытательную жава проект, а из-за того что она сломалась, вы её подшаманили слегка?

Ну если вы не нарушили условий испытаний, то ништяк наверно.

Я так понял это код нарузочных тестов от компании автора статьи.

База как раз не тупит, а со старой версией тестов, могла переварить все на что способна машина которая теститрует. Машину упирался в предел потоков и приходилось использовать несколько машин.

Да, шаблон порвался.

Я привык, что БД всегда медленней, соответсвеено она всегда рухнет быстрей, чем жава.

Тут автор рассказывает как порешать с помощью виртуальных потоков, крайне редкий специфичный случай,когда жава не делает нифига кроме как в цикле фигачит новые бесконечные потоки, которые в итоге кладут линух, потому что напротив сверхмощная БД.

Ясно, понятно. Не понятно, как применить в реальной жизни. Программирование бенчмарков(это такая испытательная программа) редкая специфичная вещь.

Не понятно, как применить в реальной жизни

Виртуальные потоки придумали как раз для реальной жизни. Смотрите, в большинстве бэкенд-приложений на Java (кроме реактивных) каждый запрос обрабатывается в отдельном потоке и на это время поток по сути блокируется. В мире микросервисов очень часто бывает, что при обработке запроса сервис внутри отправляет запросы в пачку других сервисов, по сути ничего не делая и ожидая от них ответ. Поток в это время просто висит и ждет. Потоки ОС, как выше уже писали, достаточно тяжелые для выделения, переключения и т.д., кроме этого есть ограничения на их количество. Вот для таких случаев и нужны виртуальные потоки, они позволяют лучше масштабироваться и эффективнее утилизировать железо.

Это не про виртуальные потоки статья.

Это про дедлоки БД в tpc-c.

Нет, maxzh83 Вам выше очень верно описал суть. TPC-C это бенчмарк, дедлоки возникли именно в нём. СУБД здесь не при чём.

Виртуальные потоки придумали как раз для реальной жизни.


Звучит немного громко. Это всего лишь еще одна реализация асинхронности. Идее уже не один десяток лет и асинхронные код можно было писать и раньше.

Придумали тут только новую обертку для этого. Со своими плюсами и минусами.

Звучит немного громко. Это всего лишь еще одна реализация асинхронности

Так и асинхронность изобрели для реальной жизни, а не от скуки)

В любом случае есть две конкурентные (concurrent) задачи: ожидание приложением ответа

Довольно расточительно блокировать интерфейс, ожидая окончания фоновой задачи.

Довольно расточительно блокировать интерфейс, ожидая окончания фоновой задачи.

В этом суть горутин: сделать возможным делать это максимально дёшево. И virtual threads идет к той же цели.

Я конечно понимаю, что нужен какой-то "авторитетный" результат, и потому использовано "одобренное" решение. Но если уж вы взялись его использовать, то почему вы не подумали о смысле действий в "одобренном" решении?

Смысл там такой - "авторитеты" почему-то считают важным, что бы каждый клиент обязательно долго ждал перед отправкой новой транзакции. Вы же, своим исправлением в соответствующем тесте, это ожидание исключили. То есть натянули штамп "одобрено" на ваши результаты. Хотя одобрявшие набор тестовых операций не одобрили бы ваше нововведение.

Ну и очевидное следствие - все те, кому вы будете демонстрировать свои результаты, будут введены в заблуждение из-за наличия отклонения от рекомендаций авторитетов в вашей реализации.

Хотя обычно все те, кому вы будете впаривать, давно знают, что все вокруг стремятся именно впарить, а потому не придадут особого значения вашим результатам. И таким образом круг "купи слона, он мытый, зуб даю!" обязательно завершится как полагается - куплю дарагой, куплю! Но помой его при мне ещё раз.

ЗЫ. Проще надо быть, тесты бы легче писать было. А впаривают пусть специально обученные люди. И если они не справляются, то ваши неумелые усилия на этом поприще уже никому не помогут. Так что писать надо было что-то простое, а впариватели бы далее сумели (должны!) это всё продать.

Вы задались важным вопросом, как могут повлиять наши изменения на результаты бенчмарка. Наверное, стоило проговорить это более явно в самом начале поста. Наши изменения абсолютно никак не влияют на результаты. Времена всех задержек прописаны в стандарте TPC-C, они используются в оригинальном benchbase и сохранены в нашем форке. Более того, мы в процессе доработки pull request в benchbase и уже прошли ревью изменений. Что же тогда делают наши изменения? Они позволяют запустить бенчмарк на меньшем количестве железа, что позволяет снизить расходы на исследование производительности СУБД.

Повторюсь, что нам следовало разобрать более подробно некоторые базовые моменты, чтобы у Вас не возникло ощущение того, что Вам что-то впаривают. Мне кажется, что неплохим доказательством нашей добропорядочности является то, что английская версия поста сейчас на главной странице hacker news, а запостили её туда наши прямые конкуренты YugabyteDB, которые тоже используют Benchbase. Мы очень активно сотрудничаем как с ними, так и с другими конкурентами, чтобы получить честное сравнение наших баз. И именно поэтому активно вкладываемся в бенчмарки.

Конечно, вы стараетесь показать себя с лучшей стороны. Но сам факт допиливания тестов говорит об одном - вы внесли изменения. Дальше можно спорить, на сколько они важны, но само по себе внесение изменений - факт неоспоримый. Именно про него я и сообщил. Ну а оправдания, будь то меньше железа или ещё что, это же вторично в сравнении с отходом от методики, разве нет?

С другой стороны, понимаю, что ваш маркетинг решил давить на результаты тестов, ну и поэтому вы обязаны их здесь защищать. Плюс, видимо, какие-то ваши личные убеждения в качестве лично ваших усилий могли пострадать. Только это всё опять же вторичные факторы на фоне восприятия информации читателями. Подумайте лучше, как подать информацию так, что бы читатели даже не задумались бы о мелочах, или о ваших исправлениях тестов.

Вообще, сам подход типа "мы выполнили кучу действий по инструкции" мало кому интересен. Ну да, при этом вы вышли на факт использования не адаптированного к новым API вызова в выбранной вами библиотеке, но это же ваш косяк - вы решили использовать новое не проверив совместимость со старым. Так что такую особенность выполнения действий по инструкции тоже нельзя признать захватывающей внимание читателей. Хотя кому-то знакомому с темой вы могли подсказать про synchronized и native, но их ведь очень мало в сравнении с остальными читателями.

Правда пока не могу ткнуть пальцем в личный пример "как надо", но наверное я это как-нибудь сделаю.

Мне очень жаль, что Вы остались при своём мнении и, судя по всему, не ознакомились ни с пул реквестом, ссылку на который я дал и где есть комментарии авторов Benchbase, ни со стандартом TPC-C и сутью того, чем мы вообще занимаемся.

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

А почему именно нельзя чтобы виртуальный поток открепился от физического в syncronized блоке?

А почему именно нельзя чтобы виртуальный поток открепился от физического в syncronized блоке?

Это текущая особенность реализации. Как я понимаю, они хотят это исправить, но в чём заключается сложность я, к сожалению, не знаю.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий