Re[4]: WA: 3 млн tcp соединений на одном сервере
От: Pzz Россия https://github.com/alexpevzner
Дата: 02.08.20 02:39
Оценка: +5 :))) :)))
Здравствуйте, SkyDance, Вы писали:

SD>

SD>Any sufficiently complicated concurrent program in another language contains an ad hoc informally-specified bug-ridden slow implementation of half of Erlang.


Надо же. А еще про Lisp то же самое говорят: https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule

Похоже, что любая достаточно замысловатая программа состоит наполовину из Лиспа, и наполовину из Ерланга потому она такая и замысловатая
Re: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 28.07.20 15:34
Оценка: 16 (4) +1
Здравствуйте, Sharov, Вы писали:

S>Вот тут человек не может понять как это возможно на одном сервере -- https://youtu.be/vQ5o4wPvUXg


S>Понятно, что это erlang+elixir. Но все же при физическом ограничении в ~60т. сокетов как это возможно?


Такого ограничения нет и никогда не было.
Если вы про TCP, все сокеты установленных соединений, созданных коннектом к серверу, имеют один и тот же номер порта с серверной стороны. Ядро их различает по комбинации всех 4 параметров — 2 адреса хоста и 2 порта двух сторон.

Для IPv4 таким образом предел это около 2^79 таких сокетов

Erlang по части держания коннектов и производительности ничуть не лучше, а почти всегда хуже, компилируемых аналогов (разве что они сделали свой JIT). Единственное чем он тут способен побить — это встроенной системой автообновления без рестарта.

S>Т.е. я понимаю про non-blocking IO, c10k и т.д., но с10М как? Как возможно наплодить такое кол-во сокетов на одной машине?


Таки перечитайте теорию, тут всё банально.
The God is real, unless declared integer.
Re: WA: 3 млн tcp соединений на одном сервере
От: Reset  
Дата: 29.07.20 08:13
Оценка: 26 (2) :)
S>Вот тут человек не может понять как это возможно на одном сервере -- https://youtu.be/vQ5o4wPvUXg

Т.е. это ты не для себя спрашиваешь, а для друга. Ясно-понятно.

Ну, про количество IP:port с одной и другой стороны тебе уже рассказали (у пользователей могут быть разные IP и у сервера тоже много IP на одном интерфейсе, с портами аналогично), про int вместимостью в 31 бит тоже.

Однако, про IPv6 чё-та совсем и не упомянули, а там каждому клиенту полагается сеть /64 (в стандарте так написано, но правда, даже хостеры стандарты не читают и умудряются на клиента выдавать IPv6 адреса в штуках, откусывая их от своей сети /48 или сколько там дают провайдеру по умолчанию). Впрочем, с таким провайдером я бы не пытался держать 10M сокетов на одной машине.

Также от себя добавлю, что для таких масштабов вполне могут использовать какой-нибудь DPDK, где между приложением и сетевушкой никакого ядра и нет вовсе (драйвер сетевухи со всем сетевым стеком находится прямо в userspace). Там и трафик (количество пакетов) можно сделать больше, и количество соединений держи сколько в память влезет.

Еще полезно отключить, все что мешается — огнестенку, например, с conntrack, да и просто фильтр там будет тормозить. Впрочем, с DPDK, это, наверняка, не актуально, а если сокеты держит ядро, то файрвол, однозначно, будет мешать, даже без conntrack. Фильтровать придется через eBPF (каждый школьник уже может осилить).
Отредактировано 29.07.2020 9:45 Reset . Предыдущая версия . Еще …
Отредактировано 29.07.2020 9:45 Reset . Предыдущая версия .
Re[3]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 28.07.20 19:41
Оценка: 15 (3)
N>>Erlang по части держания коннектов и производительности ничуть не лучше, а почти всегда хуже, компилируемых аналогов (разве что они сделали свой JIT). Единственное чем он тут способен побить — это встроенной системой автообновления без рестарта.

S>Подождем Skydance'а. Он как раз performance engineer в wa.


По совместительству еще и один из директоров Erlang Ecosystem Foundation. Занятно, что в данный момент я как раз исправляю часть, которая связана с поддержкой сетевых соединений.

Что именно интересует? Просто открыть 3 млн соединений проблем нет почти на любой языке.

Преимущество Эрланга (и вообще BEAM languages) в том, что:
1. Сделать такое можно буквально в десяток строк кода — сам язык хорошо заточен под подобное использование.
2. Программисту гораздо сложнее выстрелить себе в ногу. Но, конечено, чем более сеньором себя программист считает, тем чаще стреляет даже в Эрланге — от умного дурака защититься сложнее, чем от глупого.

JIT для BEAM пока существует только в экспериментальном проекте, хорошо если через год будет продакшн. Hot code load — да, ценная и важная фича, но не единственное, что важно.
А вот что важно, так это фреймворк, который заставляет программиста думать асинхронно. Все то самое "reactive programming", только очень-очень взрослое по сравнению со смешными поделками, которые сейчас массово вылезают в виде разных react.js и прочего. Все-таки, за 30 лет Эрланг и BEAM повзрослели. Там уже заложены все те концепции, до которых сейчас только думают дорасти очередные итерации "серебряных пуль". Начиная от supervision, и заканчивая immutable releases.

Лучше всего про Эрланг сказал один из его авторов, Роберт Вирдинг:

Virding's First Rule of Programming
After reading the blogs about how good Erlang's concurrency model is and how we just just made a super implementation of it in XXX I have been led to formulate Virding's First Rule of Programming:

Any sufficiently complicated concurrent program in another language contains an ad hoc informally-specified bug-ridden slow implementation of half of Erlang.

With all respect to Greenspun.

Re[11]: WA: 3 млн tcp соединений на одном сервере
От: std.denis Россия  
Дата: 05.08.20 20:06
Оценка: +3
SD>И тогда получается WhatsApp
хм.. как-будто вацап это что-то хорошее, а не кусок говна, который даже нельзя на нескольких машинах использовать ¯\_(ツ)_/¯
Re[9]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 05.08.20 15:43
Оценка: 117 (1) +1
Здравствуйте, SkyDance, Вы писали:

N>>Про перекодировку я ни слова вообще-то не сказал, это уже ваши... мнээээ... догадки я говорил про посылку.

SD>Вы прямо заявили: "при неустранимой динамической типизации Erlang и очень слабой JIT компиляции (где она вообще есть) Erlang не может быть быстрым."

Да.

SD>Для типичных коммуникационных задач Эрланг более чем быстр. В отличие от number crunching и подобных задач, включая ту самую перекодировку.


Ну то есть вы хотите сказать, что при I/O bound задачах его тормоза обычно незаметны. OK, в такой постановке — согласен. С уточнением для этого "обычно", что банально впасть (как было у нас) именно в тот вариант использования, когда они из незаметных превращаются в фатальные.

N>>Ну да, вместо OTP с супервизорами и рестартами — будет какой-то закат солнца вручную, пригодный для местных условий. И обмен сообщениями будет перенесен на какой-то свой движок, который может работать даже поверх мьютексов и условных переменных. А где-то его и не будут использовать, если удобнее без него.


SD>^^^ иными словами, "Any sufficiently complicated concurrent program in another language contains an ad hoc informally-specified bug-ridden slow implementation of half of Erlang."

SD>Вот ровно так и есть. До того как я начал пользоваться Эрлангом, у меня тоже были закаты солнца вручную, "свои движки" и подобное. Да, оно работало побыстрее, чем аналогичный софт на Эрланге (просто в силу близости к железу), но багов, увы, там было немало.

Баги — исправляются. А вот принципиальная тормознутость рантайма — с ней сильно сложнее.
Или таки скоро завезут сильный JIT (а не убогий HiPE)?

SD>Короче говоря, можно переизобрести этот велосипед (эрланг) еще 10 раз. Например, akka streams есть не что иное как. И Orleans тоже. И go, и вообще практически весь современный concurrency-oriented софт.


Да. Только надо перестать смотреть на это как на "переизобретение эрланга". Даже если Erlang был одно время образцом, то все эти реализации уже давно ушли дальше.

SD>Просто чтобы это понять, нужно потратить очень много времени на изучение сложившейся ситуации. На то, чтобы научиться пользоваться всеми этими инструментами, и иметь возможность их сравнить. У меня такая возможность была. Надо понимать, что Erlang — очень, очень-очень взрослый язык. Даже, пожалуй, старый — поэтому мы и обновляем его (не только виртуальную машину, но и язык тоже).


OK, когда будут множественные входные очереди на процесс?

SD> И вот эта самая взрослость — maturity — и позволяет увидеть простую истину: ничто не ново под луной. Новомодним технологиями еще только предстоит тот путь, который Эрланг уже прошел.


А им просто не надо его проходить. У них другая специфика, и повторять ошибки Эрланга им не с руки.

SD>Смешались в кучу кони, люди... чем rebar-то помешал? Как раз он-то прекрасно подходит для генерации релизов, и relup-ов. Я как-то даже урок для своих делал, показывающий, как оно работает.


С какой версии это стало нормально работать? Я после 2015 не смотрел, до этого коллеги пробовали — не работало.

N>>Основной наш проект был роскошным, но в результате я не хочу на Erlang больше ничего делать.

SD>Что ж это вы такое начали, что не смогли закончить? Впрочем, ладно, я лучше у Франческо спрошу, раз уж такое дело у него может быть другой взгляд на совместные проекты.

Основное было системой мониторинга кластера "Ломоносов". Её у нас забрали прямо в процессе затыкания этих проблем, так что я после 2013 там не участвую аж никак. Франческо вряд ли в курсе, с ESL мы не подружились независимо от того проекта.

SD>Реальная проблема у Эрланга только одна. Он не для обезьян. Надо понимать, что делаешь, если хочешь написать что-то серьезное.


Это роскошная отмазка для любого... мнэээ... некачественного продукта, но проблема в том, что она настолько заезжена, что сейчас одно её упоминание обычно сразу снижает восприятие качества обсуждаемой вещи
А тут она ещё и грубо неверна. Когда проект начинался, мы взяли в контору группу военных админов(!) и они успешно за срок менее месяца переключились на проектирование и написание (при том, что часть ещё и не имела опыта программирования кроме одноэкранных скриптов баша) — и всё шло замечательно до тех пор, пока под реальной нагрузкой не начались уже характерно эрланговые проблемы, как минимум:
1) Переполнение входных очередей без возможности адекватного взаимодействия с пострадавшими процессами; лечилось грубыми хаками типа просовывания управляющих команд через ETS с соседним процессом;
2) Страшно тормозной global, с синхронизацией, страдающей при перегрузке (попросту кластер рассыпался — и это при несчастных ~30 узлах); сейчас, по слухам, есть настройка "межкластерные данные идут по другим каналам, чем heartbeats", я не успел это сделать — выдернули на живую.
Были и другие, поменьше, но облом вспоминать (попросишь — подниму архивы).

Эти проблемы я обсуждал с Валкиным, Лапшиным, Димандтом, с теми ребятами, которые делали Erlang как Xen guest (не помню фамилий) — узок наш круг и все согласны с их наличием, но они просто обошли те задачи, на которых эти проблемы давали максимальный эффект, а наша фирма встретилась с ними по полной.

Понимаешь, почему мне теперь твои рассказы про "надо уметь готовить" вызывают просто ржач? Меня не надо учить его готовить, я его пять лет готовил, и командой рулил. И именно поэтому я знаю, что есть проблемы, которые элементарно бы решились (расширив его области применения в разы), но из-за дуболомства разработчиков языка они тупо отвергнуты. Множественные входные очереди — для меня сейчас ключевой критерий, лакмусовая бумажка. И главное, сделать-то их банально (с их силами) — надо только признать реальность. Поэтому: сделают их — начну смотреть и всерьёз предполагать применение хотя бы в тех областях, где мне что-то подобное нужно. Не сделают — к чёрту старперов, есть много других современных альтернатив без таких диверсий, а Erlang будет продолжать уверенно терять позиции.

(Ну а по современному состоянию ситуация ещё хуже: линейный рост мощности процессоров почти остановился, паралельность у программистов до сих пор зачаточная, RAM не дешевеет с 2012, аппетиты растут... средство, которое не умеет эффективно компилироваться, скоро пойдёт на обочину даже в тех областях, где Erlang был силён. Сейчас я для проекта из его типовой ниши скорее выберу Go, если пересилю тошноту. Ну или ещё альтернатив регулярно подвозят.)

SD> Или, если говорить в терминах менеджмента, "there are staffing issues". Как пример, десяток инженеров могут сделать WhatsApp — потому что это сильные инженеры. Но если брать среднестатистическое, то... даже у сотни не получится. Проще на PHP.


Ну вот пока вы так будете думать — у вас и будет 1-2 потребителя из тех, кто смог набрать "сильных инженеров", которые к тому почему-то согласились работать с намеренно самосостарившимся средством. Хотите развития — делайте, чтобы написать и запустить мог простой школьник. Даже если 1 из 1000 потом заинтересуется — уже приток сил. Впрочем, как хотите, мне уже пофиг
The God is real, unless declared integer.
Re[3]: WA: 3 млн tcp соединений на одном сервере
От: Mystic Artifact  
Дата: 28.07.20 18:15
Оценка: 10 (1) +1
Здравствуйте, Sharov, Вы писали:

S>Вы это мне уже объясняли, было дело. Математика с ув. netch80 не бьется -- под внешней парой понимается адрес:порт? Тогда всего (грубо) 2^32 адресов на 2^16 портов (это все клиент) и на 2^16 портов на сервере, т.е. всего 2^64 возможных соединений. Откуда 2^79?

netch80 говорит, что внутренняя пара так же учитывается. Ты же из внутренней пары считаешь только номера портов, полагая что у сервера только один сетевой интерфейс, но ничего не мешает иметь больше одного.
Re[14]: WA: 3 млн tcp соединений на одном сервере
От: Слава  
Дата: 06.08.20 11:57
Оценка: 10 (1) +1
Здравствуйте, std.denis, Вы писали:

SD>просто не смог пройти, когда в очередном сообщении увидел ещё раз кичливое "мы тут настоящие инженеры и создали чудо инженерной мысли" и всю эту "обезьянью" демагогию


Я с огромным интересом читаю тред, и жду очередного ответа SkyDance. А про демагогию — ну для начала тут у нас КЫВТ, да и никакой демагогии в его словах я не заметил.

Слушайте, где ещё вы сможете пообщаться с человеком на подобной должности? Тут надо аккуратно спрашивать и не докапываться до слов.
Re[9]: WA: 3 млн tcp соединений на одном сервере
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 05.08.20 00:26
Оценка: :))
Здравствуйте, SkyDance, Вы писали:

SD>Реальная проблема у Эрланга только одна. Он не для обезьян. Надо понимать, что делаешь, если хочешь написать что-то серьезное. Или, если говорить в терминах менеджмента, "there are staffing issues". Как пример, десяток инженеров могут сделать WhatsApp — потому что это сильные инженеры. Но если брать среднестатистическое, то... даже у сотни не получится. Проще на PHP.


Ну ну, сам себя не похвалишь... но на деле Erlang как раз позволяет понизить требования к разработчикам и при этом получить стабильное но тормознутое сетевое приложение. И таки реальная проблема в динамической сути языка и большой нерасторопности, хотя надо признать, что стабильность решения в купе с понижением требований к инженерам того стоит в 99% случаев.
Отредактировано 05.08.2020 0:28 kaa.python . Предыдущая версия .
Re[16]: WA: 3 млн tcp соединений на одном сервере
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.08.20 14:29
Оценка: 117 (1)
Здравствуйте, Sharov, Вы писали:

S>Скорее менеджеры, и скорее как средство борьбы с постоянными модификациями и изменениями. Причем для разных клиентов. Ядро трогать не надо, но поведение адаптировать как-то надо. Вот и прикручивают скрипты.


Это не менеджеры, это такая жизненная позиция, называется программирование не для людей, а для компьютеров.

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

Менеджер предложит систему, в которой фотки котиков сохраняются на компьютере в форматах PNG или JPEG, приаттачиваются к электронным письмам и отправляются по системе e-mail. Количество проблем у пользователя сразу увеличилось: надо как-то извлечь фотографии в нужных форматах, у барышень должен быть компьютер, все участники должны обзавестись программами для e-mail и адресами, и научиться как-то всем этим хозяйством пользоваться. Зато бизнесу стало хорошо: все участники заплатили по 5 баксов за интернет, а некоторые еще и купили книжку на 500 страниц "как научиться пользоваться е-мейлом за 15 простых шагов".

Программист систему реализует, и в картине мира появятся дополнительные сущности, такие, как Mail Transfer Agent, DNS, PPP authentication, network packet routing и т.п. К счастью для себя, ни пользователь ни барышни про эти дополнительные сущности почти ничего не узнают, кроме иногда появляющихся на экране непонятных для них сообщений об ошибках внутри этих самых сущностей ("mail delivery failed: DNS lookup timed out"). Все попытки объяснить пользователю, где у котика находится DNS, уткнутся в глухую стену непонимания, и в конце концов пользователь смирится с тем, что компьютеры постоянно глючат, но метод try again/reboot and try again/reinstall windows and try again обычно помогает.

А потом придет WatsApp, и сделает все для людей (воспользовавшись уже накопленной к этому моменту инфраструктурой): фотка котика будет браться прямо из камеры телефона и отправляться к барышне. И всем станет хорошо.

Реально, создание платформы, на которой какую-то жизненную проблему можно решить — это примерно 10% работы, необходимой для решения проблемы. Жизненная позиция заключается в том, что всем нравится создавать платформы, а не решать проблемы.
Re[13]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 09.08.20 19:00
Оценка: 22 (1)
Здравствуйте, Mystic Artifact, Вы писали:

N>>Слово "синидиотически" не находится. Опечатка или что?

MA> Там одна большая опечатка... и не только в орфографии но и по смыслу.
MA> Имелось ввиду, что больше нравятся языки и платформы общего назначения, на которых строятся конкретные решения (аля библиотеки). Не вижу плохого в других подходах (а иногда вижу и плюсы), но узколобая душонка их не любит и требует сделки с дьяволом.

Ну да, этот подход вообще больше распространён сразу по нескольким причинам — единый язык, универсальность поддержки и отладки (не нужно строить бутербродов, для диагностики в которых требуются супер-скиллы) и прочая и прочая... И вот что характерно — именно набравшись разнообразного опыта и дойдя до высот профессии, начинаешь понимать, насколько ценна экономия умственных усилий даже в достаточно простых вещах. Так что это не "сделка с дьяволом", это как раз достижение разумного оптимума. Всякие штуки типа облегчения работы с персоналом (банально, меньше потребность в суперспецах) это уже приятное следствие. А работы всё равно хватит на всех
The God is real, unless declared integer.
Re[7]: Дублирую вопрос.
От: SkyDance Земля  
Дата: 08.08.20 03:45
Оценка: 15 (1)
S>>>Ну вот индус спрашивает про rp\lb. Это что-то свое самописное или используете известные вещи типа nginx? Если известные, то что? Если не NDA.
S>reverse proxy

До 2019 были самые простые решения, и самые надежные. Никаких rp/lb. Эрланг напрямую торчал в Интернет, банальнейшим TCP socket. Весь "load balancing" делался в DNS.

Сейчас все работает через инфраструктуру Facebook. Там не используется nginx, и вообще все свое. Рассказать не могу, извините. То, о чем можно рассказывать, уже есть в интернете, ключевые слова "facebook software load balancer L4".
Re[13]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 06.08.20 09:07
Оценка: 11 (1)
Здравствуйте, Mystic Artifact, Вы писали:

MA> От души могу добавить только то,что любому человеку который скажет что в каждой ... программе есть часть лиспа — готов не только плюнуть в рожу, но и больно ударить в нос. Потому что это бредятина сивой кобыли и слезные мечтания.


MA> Я ваш лисп наблюдал в ныне процветающих CAD системах и ничего кроме как сказать, что это полное уебище — просто невозможно.


MA> Но конечно, всегда найдутся альтернатмвно мыслящие которые найдут в этом хоть каплю хорошего. А что долдно быть им не ведомо.


Я таки чуть вступлюсь за него (заранее прикрыв нос)
Что собственно хотел сказать тут Гринспун, это следующее:

1. Толстая система (будем говорить так) достаточно быстро дорастает до состояния, когда её надо тюнить по куче параметров, причём (если это десктопное приложение) индивидуально и часто ещё и параметризованно.
2. Толстая система должна поддерживать скриптование — как хуки на события, так и просто автоматизацию (по кнопке).
3. Язык этих скриптов должен быть достаточно гибким, чтобы быть, грубо говоря, эквивалентным машине Тьюринга.
4. Язык этих скриптов должен позволять средства метапрограммирования, включая генерацию кода на ходу (даже если от неё требуется примитив уровня make_adder).

По состоянию на сейчас этому соответствуют несколько языков, сюда годятся JavaScript, Python, Ruby, Lua и с два десятка ещё других менее известных. Но:

1. На 1993, широко известным таким языком был, пожалуй, только LISP. Остальные были в зачаточном состоянии (Python, Ruby) или вообще ещё не родились. Может, были какие-то сейчас забытые (наверняка даже были), но тоже малопопулярные.
2. LISP, в отличие от остальных, обладает гомоиконичным метапрограммированием, то есть в нём код и данные представлены идентично, любые данные могут быть отданы на исполнение как код. Код можно реформировать, оптимизировать и т.д. обычными средствами работы с данными. (Как пример, это делается внутри GCC: его GIMPLE это специализация LISP.) У остальных надо как минимум конвертировать между исполнимым и обрабатываемым представлениями.

Ну и Common LISP был на тот момент развитой отработанной реализацией.

Это всё не значит, что сейчас надо всегда использовать LISP, тем более тяжеловатый Common LISP. GNU в основном использует свою реализацию, близкую к Scheme. Гугл использует JavaScript (например, вы можете даже на стандартном акаунте нарисовать скрипт, который будет что-то делать с документами на Google Drive, и сказать запускать его периодически или по триггеру). В небольшой программе на C/C++ можно собрать код на ходу через libjit, в более толстой — подключить LLVM. Важно понимать стоящий за этим принцип.

В задаче реализации распределённого сервиса с устойчивостью к локальным проблемам, сетевым проблемам, невидимым обновлением на ходу и т.д. — Erlang показывает аналогичный образец, тут Вирдинг в заметной мере прав. Эрланг старается держать марку идеала такой ниши; там, естественно, есть 100500 вопросов к отдельным моментам реализации, но как образец он сохраняет силу и сейчас.
Другой вопрос, что уже появились неплохие конкуренты (вроде Go)...

Ну и проблемы у LISP с Erlang в заметной мере одинаковые из-за, например, функционального подхода (хоть и самого примитивного, по сравнению с группой ML, хаскеллоидами и так далее) — если 99% программистов пишут императивно, то в фаворе будут императивные средства.

И спасибо за комплимент

MA> А я вот знаю точно — ни лиспу ни эрлангу в современном мире места нет. Доживают, не иначе.


MA> Add: А если ты не GP язык — то заявить как бы и нечего. И дело даже не в обезьянах... Просто, каждый язык и область требует своего погружения. Где-то рядом в темах мне наверное не верят, что люди выжимают из выровненных указателей. На кой оно надо? Где это вообще возможно? Зачем? Но, я вот нашел ответы для себя на эти вопросы. Зачем ерланг, раст, го или еще какая люси — мне неведомо. Да, список просто наугад взят. Вся популярность раста растет не из за его ебанутой прости господи модели, а то что серво+мозилла. Так то он язычок был и есть так себе. Тоже самое с го без гугла — никто б и не взглянул. Так и ты с эрлангом, но это просто нишевое решение.


Не путай таки, кто раскручивает изначально, и есть ли в принципе заметный смысл. Что раскрутить язык сейчас требует заметных ресурсов — факт, поэтому идут на это только крупными коллективами и от безысходности. Поддержка — тоже (подсчитаем-ка затраты на развитие GCC и Clang). Но дальше, набрав силу, он может существовать и без начального толкателя.
На сейчас, мне кажется, Rust и Go достигли того уровня, который позволяет существовать без первосоздателя — его роль кто-то точно подхватит. А вот для Erlang это откровенно сомнительно. Ну разве что тот же фейсбук с WhatsApp подхватит... но популярности ему это не добавит.

MA> За пределами своей ниши обитают только обезьяны, и хотя это видимо должно многим людям быть обидно, просвященный человек в 2020 году знает что теория эволюции Дарвина относительно человека весьма туманна, а большинство находок начала прошлого столетия — подделки. Шило в мешке не утоишь.


The God is real, unless declared integer.
Re: WA: 3 млн tcp соединений на одном сервере
От: Pzz Россия https://github.com/alexpevzner
Дата: 28.07.20 16:33
Оценка: 10 (1)
Здравствуйте, Sharov, Вы писали:

S>Понятно, что это erlang+elixir. Но все же при физическом ограничении в ~60т. сокетов как это возможно?

S>Т.е. я понимаю про non-blocking IO, c10k и т.д., но с10М как? Как возможно наплодить такое кол-во сокетов на одной машине?

Я без особых проблем держал на Си ~300K сокетов, и держал бы и больше, если бы больше ко мне приходило

Никакого ограничения в 60К сокетов нет. Есть ограничение в 60K портов. Но TCP-соединение идеинтифицируется сочетанием адресов/портов на обеих сторонах, так что если у тебя внешние адреса разные, то внутренний порт может быть хоть один на всех.

Кстати, я количество внутренних портов принудительно ограничивал. Иначе оно имеет тенденцию занимать их все, и другим программам начинает не хватать.
Re[3]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 28.07.20 19:02
Оценка: 5 (1)
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, Pzz, Вы писали:


Pzz>>Я без особых проблем держал на Си ~300K сокетов, и держал бы и больше, если бы больше ко мне приходило


S>


Pzz>>Никакого ограничения в 60К сокетов нет. Есть ограничение в 60K портов. Но TCP-соединение идеинтифицируется сочетанием адресов/портов на обеих сторонах, так что если у тебя внешние адреса разные, то внутренний порт может быть хоть один на всех.


S>Вы это мне уже объясняли, было дело. Математика с ув. netch80 не бьется -- под внешней парой понимается адрес:порт? Тогда всего (грубо) 2^32 адресов на 2^16 портов (это все клиент) и на 2^16 портов на сервере, т.е. всего 2^64 возможных соединений. Откуда 2^79?


Я считал, разумеется, и возможность назначить локальной машине сколько угодно адресов.
Исключить 1/8 адресного пространства на всякие мультикасты и класс E и предположить, что сервер сам к себе обычно не ходит...
The God is real, unless declared integer.
Re[13]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 06.08.20 13:33
Оценка: 5 (1)
Здравствуйте, Pzz, Вы писали:

Pzz>А что, у ерланга вынимание из очереди пробегается по всей памяти очереди? Потому что иначе трудно понять, почему временное достижение очередью размера кэша настолько замедляет разгребание очереди, причем делает это "навсегда", что программа уже не восстанавливается.


У него это выглядит так: оператор receive может получать шаблон или нет.
Если шаблона нет, просто хватается сообщение из головы очереди.
Если шаблон есть, идёт перебор начиная с головы пока не встретится сообщение, соответствующее шаблону. Точнее, шаблонов может быть несколько, они проверяются по приоритетам.
Если такого сообщения (не соответствующего ни одному из предложенных шаблонов) в очереди нет, то процесс переходит в спячку, а при поступлении новых пробуждается на проверку поступивших. У спячки может быть задан таймаут.
Можно посмотреть, например, здесь.

Нормальный цикл процесса выглядит примерно так: я переписываю для ясности на C-подобный синтаксис:

work() {
  Message = receive(); // из головы очереди, вариантов нет
  if (Message LIKE первый шаблон) { ... }
  else if (Message LIKE второй шаблон) { ... }
  ...
  work(); // циклов в коде нет, всё пишется через рекурсию, интерпретатор умеет хвостовую рекурсию
}


в этом варианте всё ещё относительно шустро (с поправкой на динамику).

Проблемы начинаются, если делается синхронный вызов. Каждый такой вызов это:

1. Клиент заворачивает свой запрос — далее Request — в кортеж с тегом "это синхронное сообщение от меня"; в его синтаксисе это, чуть упрощая, Message переводится в {'$call', pid(), Request, make_ref()} и это отправляется серверу. make_ref() это функция генерации уникального значения (считай GUIDʼом, но конструируется иначе).

2. Сервер, получив нечто соответствующее такому шаблону {'$call', Client, Request, Ref}, исполняет запрос и отдаёт свой ответ, посылая процессу Client сообщение {'$reply', Ref, Reply}, где Reply — его ответ.

3. Клиент в это время находится в ожидании ответа, выполняя код типа

Ref = make_ref();
send(ServerPid, {'$call', pid(), Request, Ref});
Resp = receive(       //  <-- вот тут сидим в ожидании ответа
  {'$reply', Ref, *}, //  <-- это шаблон для поиска в очереди
  5000);              //  <-- таймаут, по умолчанию это 5 секунд, пишется в миллисекундах


И вот тут начинаются проблемы. Представим себе, что в очереди 10000 сообщений. receive() всегда работает одинаково: начинает перебирать с головы очереди. Как-то ему сказать, что сейчас ещё точно ответа нет? Не положено. Значит, послали запрос и начинаем перебирать эти 10000 сообщений... хотя твёрдо известно, что в этом нет смысла.
В худшем случае, если делается один синхронный вызов на каждое входящее сообщение, время работы становится O от квадрата длины очереди — что мы и наблюдали в полный рост.

В общем случае это решается несколькими вариантами:

1. Перед посылкой запроса узнать позицию хвоста очереди, а в receive() передать её, чтобы итерирование в поиске ответа начиналось с этой позиции.
Это оптимизация на частный случай, и она сделана, кажется, в 14-м релизе, но она 1) завязана на получение этого самого Ref, а поэтому не работает, например, при отправке в TCP порт (это то, что как раз обходится залезанием в потроха в RabbitMQ), и вообще для всех случаев за пределами стандартного вызова стиля gen_call; 2) делается не программистом, а компилятором на анализе кода, и поэтому отклонение от идеального шаблона make_ref() — send() — receive() сразу ломает логику и выключает оптимизацию. Дать возможность программисту управлять этим они отказались.

2. Сделать таки хотя бы 2 очереди, честные FIFO, и пусть обычный send() отправляет в 0, а спецпосылки и ответы на синхронные запросы — в 1; пусть синтаксис receive не менять, но чтобы очередь 1 всегда проверялась первой. Это даст универсальное решение для таких ожиданий и не только; я писал в предыдущем, что у нас при такой перегрузке даже нормальный call() тормозил и выбивался по таймауту из-за перегрузки входа (обычный разбор идёт строго последовательно).

N>>2) Если ему хоть иногда надо делать синхронные вызовы (gen_server:call) и соответственно сразу ждать отвёт — всё, суши вёсла: из накопления входной очереди выше 10-20K сообщений он не способен уже выйти. Граница неточная, но, похоже, связана с размером кэша процессора. Временное переполнение, безвредное в других условиях, становится фатальным (надо только рубить процесс).


Pzz>Вот по таким оговоркам сразу видно профессионала. Любителю такая гипотеза в голову не придет (это искренний комплимент, а не скрытая ирония).


Спасибо на самом деле я уже за давностью не помню, это я предположил или кто-то из команды, но я запомнил и оно, по экспериментам, подтвердилось.
При такой квадратичной зависимости от длины очереди дополнительный рывок торможения в 10-15 раз за счёт вылета из кэша оказался смертельным для задачи.
The God is real, unless declared integer.
Re[7]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 04.08.20 05:04
Оценка: 2 (1)
Здравствуйте, SkyDance, Вы писали:

N>>С другой стороны, я тут с ним не согласен хотя бы потому, что при неустранимой динамической типизации Erlang и очень слабой JIT компиляции (где она вообще есть) Erlang не может быть быстрым.


SD>Довольно много сильных заявлений, но все из них верны лишь отчасти (и про типизацию, и про JIT, и про "быстрым").

SD>Эрланг предназначен для concurrency at scale. Он не должен быть быстрым с точки зрения "перекодировки видео". Его задача в другом — дирижировать всеми этими перекодировщиками.

Про перекодировку я ни слова вообще-то не сказал, это уже ваши... мнээээ... догадки я говорил про посылку.
Но при наличии рядом уже заметного количества достойных конкурентов, которые способны обеспечить то же самое по результату, при этом минимально требуя бутербродизации — чем тут Erlang будет сильно лучше?
Ну да, вместо OTP с супервизорами и рестартами — будет какой-то закат солнца вручную, пригодный для местных условий. И обмен сообщениями будет перенесен на какой-то свой движок, который может работать даже поверх мьютексов и условных переменных. А где-то его и не будут использовать, если удобнее без него.

И обратите внимание, что с массовым переходом на rebar/mad (а кто сейчас пакует без них?) успешно похерена самая главная вкусность — обновление на ходу, и всем пофиг — задача перенесена выше, на уровень контейнеров, докеры-шмокеры-куберы.

SD>Рекомендую все того же Роберта Вирдинга (австрал, кстати — из Мельбурна) и его "Pilgrims progress to the promised land", слайды — https://www.slideshare.net/nashjain/pilgrims-progress-to-the-promised-land-by-robert-virding — но еще лучше найти видео.


Когда я работал в Massive Solutions, мы и с ESL общались плотно, и с Вирдингом я лично разговаривал. Не думаю, что он меня помнит, но ESL должны помнить про попытки старта совместных проектов.
Основной наш проект был роскошным, но в результате я не хочу на Erlang больше ничего делать.
The God is real, unless declared integer.
Re[2]: WA: 3 млн tcp соединений на одном сервере
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 28.07.20 17:59
Оценка: +1
Здравствуйте, Pzz, Вы писали:

Pzz>Никакого ограничения в 60К сокетов нет. Есть ограничение в 60K портов. Но TCP-соединение идеинтифицируется сочетанием адресов/портов на обеих сторонах, так что если у тебя внешние адреса разные, то внутренний порт может быть хоть один на всех.

Имеется ввиду максимальное количество дескрипторов сокета который вроде как int от 0 до max_int которое можно открыть и их ~60к.
Sic luceat lux!
Re[4]: WA: 3 млн tcp соединений на одном сервере
От: Sharov Россия  
Дата: 28.07.20 19:32
Оценка: +1
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, Sharov, Вы писали:


S>>Гугл выдал:

S>>

S>>Maximum number of sockets. For most socket interfaces, the maximum number of sockets allowed per each connection between an application and the TCP/IP sockets interface is 65535.


N>Эээ

N>ссылку можно?
N>А то я такой текст нашёл только для z/OS — вы в курсе, что это не Unix, не Windows, не Mac-что-угодно, и вообще настолько далёкая от типовых решений индустрии, что у них всё иначе и называется иначе?
N>)

да-да, я вбил "maximum number of sockets" в гугол и он мне, в рамочке, выдал это определение. Но вообще, я это помню из книжек\вуза, что есть некое ограничение на сокет в виде 2^16. Я это ограничение запомнил на кол-во сокетов в системе (ОС).
Кодом людям нужно помогать!
Re[11]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 05.08.20 19:44
Оценка: +1
Здравствуйте, SkyDance, Вы писали:

SD>Прям-таки классика жанра! Когда я написал "нельзя набрать обезьян" — я ровно это и имел в виду. Дело в том, что синтаксис и "первые шаги" на Эрланге до одури просты. И потому возникает ощущение "мы все поняли и все умеем". Но когда дело доходит до написания реального софта, оказывается, что кроме синтаксиса нужно еще... понять, что такое OTP, и как на самом деле надо пользоваться языком. Вы, однако, так и не поняли. Посему и проблемы, перечисленые ниже. Как раз отражение непонимания, как должна работать система.


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

А сейчас я настаиваю, чтобы вы извинились за оскорбление в их адрес. Только после этого будет возможна какая-то дискуссия по сути, а пока этого нет — я буду считать, что и все ваши (якобы) технические аргументы — не стоят рассмотрения по причине вашего верхоглядства.
The God is real, unless declared integer.
Re[12]: WA: 3 млн tcp соединений на одном сервере
От: Mystic Artifact  
Дата: 05.08.20 22:50
Оценка: :)
Здравствуйте, SkyDance, Вы писали:

SD>Ровно что я и написал. Мой наивный код на С всегда был быстрее аналогичного на эрланге.

SD>Просто потому, что код... наивный. И попросту не делает все то, что еще за него делает OTP (не сам эрланг, а платформа).

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

netch80 пишет несколько иное, и я как бы склоняюсь на его сторону, не сколько потому что ему сверх сильно доверяю (хотя этот человек, в отличии от меня херни не пишет) — просто, для себя не вижу в нем смысла (в эрланге, в netch80 смысл то как раз есть, кто еще разъяснит такие вещи о которых и не подумаешь?).

Тут же на этом форуме, были и весьма смешанные отзывы об этом всем, хотя и не плохие. Я б позвал человека, вы все его знаете, но он вроде вышел из форума не так давно.

От души могу добавить только то,что любому человеку который скажет что в каждой ... программе есть часть лиспа — готов не только плюнуть в рожу, но и больно ударить в нос. Потому что это бредятина сивой кобыли и слезные мечтания.

Я ваш лисп наблюдал в ныне процветающих CAD системах и ничего кроме как сказать, что это полное уебище — просто невозможно.

Но конечно, всегда найдутся альтернатмвно мыслящие которые найдут в этом хоть каплю хорошего. А что долдно быть им не ведомо.

А я вот знаю точно — ни лиспу ни эрлангу в современном мире места нет. Доживают, не иначе.

Add: А если ты не GP язык — то заявить как бы и нечего. И дело даже не в обезьянах... Просто, каждый язык и область требует своего погружения. Где-то рядом в темах мне наверное не верят, что люди выжимают из выровненных указателей. На кой оно надо? Где это вообще возможно? Зачем? Но, я вот нашел ответы для себя на эти вопросы. Зачем ерланг, раст, го или еще какая люси — мне неведомо. Да, список просто наугад взят. Вся популярность раста растет не из за его ебанутой прости господи модели, а то что серво+мозилла. Так то он язычок был и есть так себе. Тоже самое с го без гугла — никто б и не взглянул. Так и ты с эрлангом, но это просто нишевое решение. За пределами своей ниши обитают только обезьяны, и хотя это видимо должно многим людям быть обидно, просвященный человек в 2020 году знает что теория эволюции Дарвина относительно человека весьма туманна, а большинство находок начала прошлого столетия — подделки. Шило в мешке не утоишь.
Отредактировано 05.08.2020 23:04 Mystic Artifact . Предыдущая версия .
Re[13]: WA: 3 млн tcp соединений на одном сервере
От: std.denis Россия  
Дата: 06.08.20 11:27
Оценка: +1
SD>>>И тогда получается WhatsApp
SD>>хм.. как-будто вацап это что-то хорошее, а не кусок говна, который даже нельзя на нескольких машинах использовать ¯\_(ツ)_/¯
Pzz>Ну это ж придирка не к имплементации, а к Т.З. Его-то (Т.З.) вряд ли на Ерланге писали

ну тут сложно сказать со стороны – это может быть как административным ограничением, так и технической неспособностью реализации

просто не смог пройти, когда в очередном сообщении увидел ещё раз кичливое "мы тут настоящие инженеры и создали чудо инженерной мысли" и всю эту "обезьянью" демагогию 🙈
Re[13]: WA: 3 млн tcp соединений на одном сервере
От: lpd Черногория  
Дата: 06.08.20 11:41
Оценка: +1
Здравствуйте, Pzz, Вы писали:

Pzz>Ну это ж придирка не к имплементации, а к Т.З. Его-то (Т.З.) вряд ли на Ерланге писали


Дизайн и маркетинг у whatsapp на уровне. Но технически сверх сложного ничего нет, даже с учетом большого числа пользователей. Обычный мессенджер, не более.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Re[21]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 09.08.20 20:30
Оценка: :)
NB>потому что людям нужно решать реальные задачи, а не бороться с языком из-за того что твоя задача не вписывается в стандартные шаблоны.

А, стало быть, опять "трясти надо" (С) анекдот.
Вот пока вы "решаете реальные задачи", другие пишут WhatsApp.
WA: 3 млн tcp соединений на одном сервере
От: Sharov Россия  
Дата: 28.07.20 15:16
Оценка:
Здравствуйте.

Вот тут человек не может понять как это возможно на одном сервере -- https://youtu.be/vQ5o4wPvUXg

Понятно, что это erlang+elixir. Но все же при физическом ограничении в ~60т. сокетов как это возможно?
Т.е. я понимаю про non-blocking IO, c10k и т.д., но с10М как? Как возможно наплодить такое кол-во сокетов на одной машине?
Кодом людям нужно помогать!
Re: WA: 3 млн tcp соединений на одном сервере
От: Слава  
Дата: 28.07.20 15:22
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Понятно, что это erlang+elixir. Но все же при физическом ограничении в ~60т. сокетов как это возможно?

S>Т.е. я понимаю про non-blocking IO, c10k и т.д., но с10М как? Как возможно наплодить такое кол-во сокетов на одной машине?

Откуда берётся ограничение в 60т. сокетов? Значение подозрительно похоже на максимальное для двухбайтового значения.

Взяли и написали патч для ядра. Или даже не патч, а просто изменили параметр, это же FreeBSD, а не линукс.
Re: WA: 3 млн tcp соединений на одном сервере
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 28.07.20 15:32
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте.


S>Вот тут человек не может понять как это возможно на одном сервере -- https://youtu.be/vQ5o4wPvUXg


S>Понятно, что это erlang+elixir. Но все же при физическом ограничении в ~60т. сокетов как это возможно?

S>Т.е. я понимаю про non-blocking IO, c10k и т.д., но с10М как? Как возможно наплодить такое кол-во сокетов на одной машине?

BEAM реально творит чудеса в вопросах разработки сетевых приложений.
Re[2]: WA: 3 млн tcp соединений на одном сервере
От: Sharov Россия  
Дата: 28.07.20 16:14
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, Sharov, Вы писали:


S>>Вот тут человек не может понять как это возможно на одном сервере -- https://youtu.be/vQ5o4wPvUXg


S>>Понятно, что это erlang+elixir. Но все же при физическом ограничении в ~60т. сокетов как это возможно?


N>Такого ограничения нет и никогда не было.

N>Если вы про TCP, все сокеты установленных соединений, созданных коннектом к серверу, имеют один и тот же номер порта с серверной стороны. Ядро их различает по комбинации всех 4 параметров — 2 адреса хоста и 2 порта двух сторон.8

N>Для IPv4 таким образом предел это около 2^79 таких сокетов


Гугл выдал:

Maximum number of sockets. For most socket interfaces, the maximum number of sockets allowed per each connection between an application and the TCP/IP sockets interface is 65535.


N>Erlang по части держания коннектов и производительности ничуть не лучше, а почти всегда хуже, компилируемых аналогов (разве что они сделали свой JIT). Единственное чем он тут способен побить — это встроенной системой автообновления без рестарта.


Подождем Skydance'а. Он как раз performance engineer в wa.
Кодом людям нужно помогать!
Re[2]: WA: 3 млн tcp соединений на одном сервере
От: Sharov Россия  
Дата: 28.07.20 17:37
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Я без особых проблем держал на Си ~300K сокетов, и держал бы и больше, если бы больше ко мне приходило




Pzz>Никакого ограничения в 60К сокетов нет. Есть ограничение в 60K портов. Но TCP-соединение идеинтифицируется сочетанием адресов/портов на обеих сторонах, так что если у тебя внешние адреса разные, то внутренний порт может быть хоть один на всех.


Вы это мне уже объясняли, было дело. Математика с ув. netch80 не бьется -- под внешней парой понимается адрес:порт? Тогда всего (грубо) 2^32 адресов на 2^16 портов (это все клиент) и на 2^16 портов на сервере, т.е. всего 2^64 возможных соединений. Откуда 2^79?
Кодом людям нужно помогать!
Re[3]: WA: 3 млн tcp соединений на одном сервере
От: Pzz Россия https://github.com/alexpevzner
Дата: 28.07.20 18:35
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Вы это мне уже объясняли, было дело. Математика с ув. netch80 не бьется -- под внешней парой понимается адрес:порт? Тогда всего (грубо) 2^32 адресов на 2^16 портов (это все клиент) и на 2^16 портов на сервере, т.е. всего 2^64 возможных соединений. Откуда 2^79?


Ну, видимо Валентин решил, что локальных IP-адресов тоже может быть много.
Re[3]: WA: 3 млн tcp соединений на одном сервере
От: Pzz Россия https://github.com/alexpevzner
Дата: 28.07.20 18:38
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Имеется ввиду максимальное количество дескрипторов сокета который вроде как int от 0 до max_int которое можно открыть и их ~60к.


Они уж сто лет в обед, как 32-битные.
Re: WA: 3 млн tcp соединений на одном сервере
От: Bill Baklushi СССР  
Дата: 28.07.20 18:46
Оценка:
Sharov:

S>Вот тут человек не может понять как это возможно на одном сервере -- https://youtu.be/vQ5o4wPvUXg


S>Понятно, что это erlang+elixir. Но все же при физическом ограничении в ~60т. сокетов как это возможно?

S>Т.е. я понимаю про non-blocking IO, c10k и т.д., но с10М как? Как возможно наплодить такое кол-во сокетов на одной машине?

И главное — зачем?

Не смотрел, но осуждаю.
Есть же UDP, RTP, групповые адреса и пр. страшные слова, чтобы не хранить дофига миллионов состояний каждого соединения...
Модератор-националист Kerk преследует оппонентов по политическим мотивам.
Re[3]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 28.07.20 19:00
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Гугл выдал:

S>

S>Maximum number of sockets. For most socket interfaces, the maximum number of sockets allowed per each connection between an application and the TCP/IP sockets interface is 65535.


Эээ
ссылку можно?
А то я такой текст нашёл только для z/OS — вы в курсе, что это не Unix, не Windows, не Mac-что-угодно, и вообще настолько далёкая от типовых решений индустрии, что у них всё иначе и называется иначе?
The God is real, unless declared integer.
Re[2]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 28.07.20 19:02
Оценка:
Здравствуйте, Bill Baklushi, Вы писали:

BB>И главное — зачем?


BB>Не смотрел, но осуждаю.

BB>Есть же UDP, RTP, групповые адреса и пр. страшные слова, чтобы не хранить дофига миллионов состояний каждого соединения...

Почему бы не хранить, если мощность сервера позволяет это?
The God is real, unless declared integer.
Re[2]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 28.07.20 19:42
Оценка:
KP>BEAM реально творит чудеса в вопросах разработки сетевых приложений.

никаких чудес, просто грамотное использование kqueue/epoll. Но да, читать этот код ох непросто, и вот сейчас как раз epoll-related баг выносит мне мозг капитально.
Re[5]: WA: 3 млн tcp соединений на одном сервере
От: Mystic Artifact  
Дата: 29.07.20 15:31
Оценка:
Здравствуйте, Sharov, Вы писали:

S>да-да, я вбил "maximum number of sockets" в гугол и он мне, в рамочке, выдал это определение. Но вообще, я это помню из книжек\вуза, что есть некое ограничение на сокет в виде 2^16. Я это ограничение запомнил на кол-во сокетов в системе (ОС).


У меня было точно такое же интуитивное понятие на ограничение числа коннектов на порты. Не знаю даже откуда... А потом столкнулся поближе с темой (нет нет, кучи коннектов не нужно было, наверное скорее делал poor-man in-process "файерволл", что бы это ни было), и пришло озарение, что это не так. А потом даже смешно немного стало, ведь если присмотреться что творится со списком коннектов, то можно когда и никогда разглядеть несогласовааность этой интуитивной теории с реальным миром.
Re[4]: WA: 3 млн tcp соединений на одном сервере
От: Sharov Россия  
Дата: 29.07.20 22:39
Оценка:
Здравствуйте, SkyDance, Вы писали:

SD>Что именно интересует? Просто открыть 3 млн соединений проблем нет почти на любой языке.


Ну вот индус спрашивает про rp\lb. Это что-то свое самописное или используете известные вещи типа nginx? Если известные, то что?
Кодом людям нужно помогать!
Re[5]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 02.08.20 07:56
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, SkyDance, Вы писали:


SD>>

SD>>Any sufficiently complicated concurrent program in another language contains an ad hoc informally-specified bug-ridden slow implementation of half of Erlang.


Pzz>Надо же. А еще про Lisp то же самое говорят: https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule


Так Вирдинг же прямо и сослался на Гринспуна.

С другой стороны, я тут с ним не согласен хотя бы потому, что при неустранимой динамической типизации Erlang и очень слабой JIT компиляции (где она вообще есть) Erlang не может быть быстрым.
Из ближайших — Go его побивает на слегка похожем подходе уже в разы даже с учётом его откровенно тухлого кодогенератора.
Ну и единственная входная очередь + head-of-line blocking вносят непредсказуемые задержки, из-за чего я от него везде отказался.

Но если кому эти проблемы не существенны, переполнений входа нет и можно отдавать данные крупными порциями — получается действительно шустро и надёжно, как пример — erlyvideo.
The God is real, unless declared integer.
Re[2]: WA: 3 млн tcp соединений на одном сервере
От: Mr.Delphist  
Дата: 03.08.20 10:04
Оценка:
Здравствуйте, Bill Baklushi, Вы писали:

BB>Есть же UDP, RTP, групповые адреса и пр. страшные слова, чтобы не хранить дофига миллионов состояний каждого соединения...


UDP — далеко не всякую схему взаимодействия можно представить в connectionless-модели (а если и можно, то путём переноса этой части сложности с транспортного уровня на прикладной)
RTP — прикладной протокол на основе UDP
групповые адреса — тоже не существуют в вакууме, а требуют исполнения определённых протоколов, плюс нет гарантии на преодоление границ подсетей
Re[5]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 04.08.20 00:33
Оценка:
Pzz>Надо же. А еще про Lisp то же самое говорят: https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule

Более того, первая виртуальная машина Эрланга была Вирдингом написана на Лиспе. И он же в одно лицо поддерживает (до сих пор!) LFE, Lisp-Flavoured Erlang.
Могучий человечище, очень с ним приятно пообщаться. Не так давно я как раз организовал встречу с ним, отлично прошло.
Re[6]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 04.08.20 00:37
Оценка:
N>С другой стороны, я тут с ним не согласен хотя бы потому, что при неустранимой динамической типизации Erlang и очень слабой JIT компиляции (где она вообще есть) Erlang не может быть быстрым.

Довольно много сильных заявлений, но все из них верны лишь отчасти (и про типизацию, и про JIT, и про "быстрым").
Эрланг предназначен для concurrency at scale. Он не должен быть быстрым с точки зрения "перекодировки видео". Его задача в другом — дирижировать всеми этими перекодировщиками.

Рекомендую все того же Роберта Вирдинга (австрал, кстати — из Мельбурна) и его "Pilgrims progress to the promised land", слайды — https://www.slideshare.net/nashjain/pilgrims-progress-to-the-promised-land-by-robert-virding — но еще лучше найти видео.
Re[8]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 04.08.20 20:52
Оценка:
N>Про перекодировку я ни слова вообще-то не сказал, это уже ваши... мнээээ... догадки я говорил про посылку.

Вы прямо заявили: "при неустранимой динамической типизации Erlang и очень слабой JIT компиляции (где она вообще есть) Erlang не может быть быстрым."

Для типичных коммуникационных задач Эрланг более чем быстр. В отличие от number crunching и подобных задач, включая ту самую перекодировку.

N>Но при наличии рядом уже заметного количества достойных конкурентов, которые способны обеспечить то же самое по результату, при этом минимально требуя бутербродизации — чем тут Erlang будет сильно лучше?


А вот тем самым, что вы и описали ниже:

N>Ну да, вместо OTP с супервизорами и рестартами — будет какой-то закат солнца вручную, пригодный для местных условий. И обмен сообщениями будет перенесен на какой-то свой движок, который может работать даже поверх мьютексов и условных переменных. А где-то его и не будут использовать, если удобнее без него.


^^^ иными словами, "Any sufficiently complicated concurrent program in another language contains an ad hoc informally-specified bug-ridden slow implementation of half of Erlang."
Вот ровно так и есть. До того как я начал пользоваться Эрлангом, у меня тоже были закаты солнца вручную, "свои движки" и подобное. Да, оно работало побыстрее, чем аналогичный софт на Эрланге (просто в силу близости к железу), но багов, увы, там было немало.

Короче говоря, можно переизобрести этот велосипед (эрланг) еще 10 раз. Например, akka streams есть не что иное как. И Orleans тоже. И go, и вообще практически весь современный concurrency-oriented софт.
Просто чтобы это понять, нужно потратить очень много времени на изучение сложившейся ситуации. На то, чтобы научиться пользоваться всеми этими инструментами, и иметь возможность их сравнить. У меня такая возможность была. Надо понимать, что Erlang — очень, очень-очень взрослый язык. Даже, пожалуй, старый — поэтому мы и обновляем его (не только виртуальную машину, но и язык тоже). И вот эта самая взрослость — maturity — и позволяет увидеть простую истину: ничто не ново под луной. Новомодним технологиями еще только предстоит тот путь, который Эрланг уже прошел.

N>И обратите внимание, что с массовым переходом на rebar/mad (а кто сейчас пакует без них?) успешно похерена самая главная вкусность — обновление на ходу, и всем пофиг — задача перенесена выше, на уровень контейнеров, докеры-шмокеры-куберы.


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


N>Когда я работал в Massive Solutions, мы и с ESL общались плотно, и с Вирдингом я лично разговаривал. Не думаю, что он меня помнит, но ESL должны помнить про попытки старта совместных проектов.

N>Основной наш проект был роскошным, но в результате я не хочу на Erlang больше ничего делать.

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

Реальная проблема у Эрланга только одна. Он не для обезьян. Надо понимать, что делаешь, если хочешь написать что-то серьезное. Или, если говорить в терминах менеджмента, "there are staffing issues". Как пример, десяток инженеров могут сделать WhatsApp — потому что это сильные инженеры. Но если брать среднестатистическое, то... даже у сотни не получится. Проще на PHP.
Re[10]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 05.08.20 00:47
Оценка:
KP>Ну ну, сам себя не похвалишь... но на деле Erlang как раз позволяет понизить требования к разработчикам и при этом получить стабильное но тормознутое сетевое приложение. И таки реальная проблема в динамической сути языка и большой нерасторопности, хотя надо признать, что стабильность решения в купе с понижением требований к инженерам того стоит в 99% случаев.

Думаю, на этом стоит остановить дискуссию, ибо мы явно подходим к проблеме с разных сторон. У меня статистика на большом количестве разработчиков, которые по среднемировым стандартам весьма сильны. А также очень хорошая видимость во множество других компаний. Иными словами, я хорошо знаю ситуацию, и те проблемы, с которыми сталкиваются реальные проекты.
Поэтому я отлично вижу, что процитированные выше заявления далеки от реальности. И про тормознутость, и про стабильность, и про динамическую типизацию, и про нерасторопность. Но чтобы обсудить это предметно, следует рассмотреть конкретные применения, а не общие высказывания про "сетевые приложения".
Re[11]: WA: 3 млн tcp соединений на одном сервере
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 05.08.20 01:43
Оценка:
Здравствуйте, SkyDance, Вы писали:

SD>Думаю, на этом стоит остановить дискуссию, ибо мы явно подходим к проблеме с разных сторон. У меня статистика на большом количестве разработчиков, которые по среднемировым стандартам весьма сильны. А также очень хорошая видимость во множество других компаний. Иными словами, я хорошо знаю ситуацию, и те проблемы, с которыми сталкиваются реальные проекты.


Очень спорное утверждение, так как принципы отбора в компании типа FB давно известны, там не самые сильные, а самые упорные. Ну а если говорить про видимость использования в других компаниях то видишь ты исключительно BEAM-решения и явно у тех, у кого они хорошо взлетели, т.к. остальные просто отказались в пользу чего-то еще и ты с ними даже не пересекался.

SD>Поэтому я отлично вижу, что процитированные выше заявления далеки от реальности. И про тормознутость, и про стабильность, и про динамическую типизацию, и про нерасторопность. Но чтобы обсудить это предметно, следует рассмотреть конкретные применения, а не общие высказывания про "сетевые приложения".


Складывается ощущение, что ты видишь исключительно то, что хочешь видеть. При этом я вроде выше сказал, что BEAM — это круто очень для подавляющего большинства сетевых серверных приложений.
Re[10]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 05.08.20 18:03
Оценка:
N>Баги — исправляются. А вот принципиальная тормознутость рантайма — с ней сильно сложнее.

Я так понимаю, "принципиальная тормознутость" рассматривается ниже (с конкретными проблемами). Или есть еще что-то еще? Кроме заявлений про "тормознутость", чтобы было нечто осмысленное. А то я вижу, что "тормознутость" — это 50.000 юзеров на машину в кластере (средней руки мессенджер на жаве) и 500.000 на такую же машину (на Эрланге).

N>Да. Только надо перестать смотреть на это как на "переизобретение эрланга". Даже если Erlang был одно время образцом, то все эти реализации уже давно ушли дальше.


Это и есть переизобретение эрланга. "Эти реализации" ушли не дальше, а в болото. Как туда уходит любой мейнстрим, см. Жава, С++.

N>OK, когда будут множественные входные очереди на процесс?


Сначала нужно объяснить, зачем. Один из патчей, который я сделал, как раз подобная поддержка (в слегка упрощенном виде, т.н. prepend send, послать сообщение в голову очереди). Но чем больше я занимаюсь архитектурой и более серьезным пониманием происходящих процессов, тем больше я понимаю, как был неправ. Просто на тот момент, когда я это сделал, у меня не было достаточно знаний. Сейчас эти знания есть, и я понимаю, что и prepend send, и "множественные очереди", и priority queues — это ошибочные направления. Но, повторюсь, чтобы это понять, нужно действительно провести много времени за изучением этих проблем.

N>А им просто не надо его проходить. У них другая специфика, и повторять ошибки Эрланга им не с руки.


Ошибка эрланга в том, что он очень долго был внутренним продуктом эрикссон. Его следовало опен-сорснуть лет на 15 раньше.

N>С какой версии это стало нормально работать? Я после 2015 не смотрел, до этого коллеги пробовали — не работало.


В следующий раз посоветуй коллегам разобраться. Оно работало всегда. Могло не хватать каких-то инструментов для удобства. Но systools были еще с 90х годов.

N>Основное было системой мониторинга кластера "Ломоносов". Её у нас забрали прямо в процессе затыкания этих проблем


Вот в это я могу поверить — что в силу политических причин ("забрали проект") у кого-то образовалось неприятие к инструментам, которыми попросту не научились пользоваться.

N>А тут она ещё и грубо неверна. Когда проект начинался, мы взяли в контору группу военных админов(!) и они успешно за срок менее месяца переключились на проектирование и написание (при том, что часть ещё и не имела опыта программирования кроме одноэкранных скриптов баша) — и всё шло замечательно до тех пор, пока под реальной нагрузкой не начались уже характерно эрланговые проблемы, как минимум:


Прям-таки классика жанра! Когда я написал "нельзя набрать обезьян" — я ровно это и имел в виду. Дело в том, что синтаксис и "первые шаги" на Эрланге до одури просты. И потому возникает ощущение "мы все поняли и все умеем". Но когда дело доходит до написания реального софта, оказывается, что кроме синтаксиса нужно еще... понять, что такое OTP, и как на самом деле надо пользоваться языком. Вы, однако, так и не поняли. Посему и проблемы, перечисленые ниже. Как раз отражение непонимания, как должна работать система.

N>1) Переполнение входных очередей без возможности адекватного взаимодействия с пострадавшими процессами; лечилось грубыми хаками типа просовывания управляющих команд через ETS с соседним процессом;


Иными словами, не смогли правильно реализовать backpressure. Справедливости ради, это действительно holy grail асинхронного программирования, и по сути нормально нигде и не реализовано. Да, есть теоретические измышления (SEDA та же) и кое-какие реализации (а ля GenStage), но чтоб серьезно к этому делу подойти, — пока руки не дошли. На данный момент все в стадии написания whitepaper.

N>2) Страшно тормозной global, с синхронизацией, страдающей при перегрузке (попросту кластер рассыпался — и это при несчастных ~30 узлах); сейчас, по слухам, есть настройка "межкластерные данные идут по другим каналам, чем heartbeats", я не успел это сделать — выдернули на живую.


Сейчас global попросту не нужен (как он не был нужен и раньше). Если нужны process groups, они уже есть (и нет, не pg2, которые работали поверх global). В общем, то, что вы не смогли кластер из 30+ машин поднять, так я про то и пишу — надо было разработчиков высокой квалификации брать. Тогда и 20.000 машин в кластере не были бы проблемой, и даже 30.000 (больше просто пока не требовалось).

N>Были и другие, поменьше, но облом вспоминать (попросишь — подниму архивы).


Нет смысла. Я уже понимаю, что не тот уровень знаний.

N>Эти проблемы я обсуждал с Валкиным, Лапшиным, Димандтом


А надо было обсуждать с Lukas Larsson, Kenneth Lundin, Rickard Green, Sverker Eriksson, Kjell Winnblad. Круг, действительно, узок, и он не включает ни одной из указанных выше фамилий.

N>Понимаешь, почему мне теперь твои рассказы про "надо уметь готовить" вызывают просто ржач? Меня не надо учить его готовить, я его пять лет готовил, и командой рулил.


Понимаешь теперь, что его действительно нужно просто уметь готовить? И тогда получается WhatsApp. Где я как раз его и готовлю. И рулю не одной командой.
Re[10]: WA: 3 млн tcp соединений на одном сервере
От: Mystic Artifact  
Дата: 05.08.20 21:30
Оценка:
Здравствуйте, netch80, Вы писали:

N>Баги — исправляются. А вот принципиальная тормознутость рантайма — с ней сильно сложнее.

N>Или таки скоро завезут сильный JIT (а не убогий HiPE)?

Имхо, нормальный JIT нигде не завезли и никуда не завезут. Все успешные рантаймы идут на дикие компромисы, при чем стратегию "долго запрягаем — быстро едем" — они не только не способны обеспечить, но и часто искусственно отвергают.

Add: Прошу прощения, за то что ворвался. Ну просто такое вот наблюдение по жизни. В добавок из того очень малого, что я воочию видел в erlang — это то,что он мог очень хорошо распарралелить задачу (под это написанную), но выхлоп... эх. Мой наивный код сделал его раза так в 4, на весьма скромном железе. Да, я понимаю,что лумать так не правильно, но я с тех пор считаю вот его ущербцем. Для клеевых целей возможно он и годиться, но античеловечный язык, имхо, — это двести камней против и никакие JIT нп помогут. Именно, что называется — нишевой. Это не плохо, но... нишевые GP решениянравятся как-то больше тупо синидиотически.
Отредактировано 05.08.2020 21:50 Mystic Artifact . Предыдущая версия .
Re[3]: WA: 3 млн tcp соединений на одном сервере
От: zubr Россия  
Дата: 05.08.20 21:58
Оценка:
Здравствуйте, SkyDance, Вы писали:

KP>>BEAM реально творит чудеса в вопросах разработки сетевых приложений.


SD>никаких чудес, просто грамотное использование kqueue/epoll. Но да, читать этот код ох непросто, и вот сейчас как раз epoll-related баг выносит мне мозг капитально.


время io_uring
Re[12]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 05.08.20 22:27
Оценка:
N>Это просто потрясающе, насколько вы сделали выводы безо всякой на то причины. Начнём просто с факта, что именно эти коллеги, которых вы тут походя назвали обезьянами, делали много полезных вещей, но именно к описанным проблемам они имеют минимальное отношение.

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

Однако продолжаю утверждать, что из-за очень простого синтаксиса начальная стадия изучения Эрланга ведет к совершенно неверному понимаю сути языка и проблем, которые он решает. Иными словами, кажется, что "уже вот все понял и освоил". Многие начинают после этого писать очередной "worker pool" или что-то еще подобное на эрланге, и, конечно, встречаются с озвученными вами выше проблемами. Но происходит все это лишь оттого, что реального понимания языка и его предметной области нет совсем. Кривая обучения очень нелинейна: понять синтаксис легко, но дальше кажется что "все неправильно". Потому что очень непривычно, нужно ломать стереотипы и представления о том, как и что должно работать. Вот через вторую стадию большинство, по моему опыту, пройти не могут. И они пытаются продолжать переизобретать С++ на эрланге. После чего, естественно, у них и язык виноват, и медленный он, и вообще все не так.
Re[11]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 05.08.20 22:30
Оценка:
MA> Мой наивный код сделал его раза так в 4, на весьма скромном железе.

Ровно что я и написал. Мой наивный код на С всегда был быстрее аналогичного на эрланге.
Просто потому, что код... наивный. И попросту не делает все то, что еще за него делает OTP (не сам эрланг, а платформа).
Re[11]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 06.08.20 04:18
Оценка:
Здравствуйте, Mystic Artifact, Вы писали:

N>>Баги — исправляются. А вот принципиальная тормознутость рантайма — с ней сильно сложнее.

N>>Или таки скоро завезут сильный JIT (а не убогий HiPE)?

MA> Имхо, нормальный JIT нигде не завезли и никуда не завезут. Все успешные рантаймы идут на дикие компромисы, при чем стратегию "долго запрягаем — быстро едем" — они не только не способны обеспечить, но и часто искусственно отвергают.


Ну всё зависит таки от уровней ожидания. У меня сейчас один тяжело нагруженный компонент на Python (переход на что-то иное... ну планируется, а когда реально делать?) Даже странный зверь PyPy (который, если кто не знает, JITит код промежуточного интерпретатора, а не финальный код) даёт ускорение в разы. Но для этого надо его, да, прогреть (считаем, 50000 проходов по коду).

В условиях Erlang, HiPE давал нашему коду ну процентов 5. Если какой-то JIT ускорит его вдвое — это уже очень хороший показатель. А там можно думать и об интеграции с чем-то типа C, где может быть полезно (хотя нам не помогло бы).

MA> Add: Прошу прощения, за то что ворвался. Ну просто такое вот наблюдение по жизни. В добавок из того очень малого, что я воочию видел в erlang — это то,что он мог очень хорошо распарралелить задачу (под это написанную), но выхлоп... эх. Мой наивный код сделал его раза так в 4, на весьма скромном железе.


Ну тут от задачи зависит. Я свою могу вполне осветить в деталях, и там действительно на I/O был местами основной упор... но не весь, не весь.

MA> Да, я понимаю,что лумать так не правильно, но я с тех пор считаю вот его ущербцем. Для клеевых целей возможно он и годиться, но античеловечный язык, имхо, — это двести камней против и никакие JIT нп помогут. Именно, что называется — нишевой. Это не плохо, но... нишевые GP решениянравятся как-то больше тупо синидиотически.


Слово "синидиотически" не находится. Опечатка или что?
The God is real, unless declared integer.
Re[13]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 06.08.20 04:19
Оценка:
Здравствуйте, SkyDance, Вы писали:

N>>Это просто потрясающе, насколько вы сделали выводы безо всякой на то причины. Начнём просто с факта, что именно эти коллеги, которых вы тут походя назвали обезьянами, делали много полезных вещей, но именно к описанным проблемам они имеют минимальное отношение.


SD>Признаю, что потерял навыки обращения с языком, и сформулировал утверждение в очень кривой форме. Ни в коем разе не хотел назвать ваших коллег обезьянами.


OK, принято. Отвечу по предыдущему сообщению.
The God is real, unless declared integer.
Re[12]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 06.08.20 04:20
Оценка:
Здравствуйте, std.denis, Вы писали:

SD>>И тогда получается WhatsApp

SD>хм.. как-будто вацап это что-то хорошее, а не кусок говна, который даже нельзя на нескольких машинах использовать ¯\_(ツ)_/¯

Это уже, думаю, ортогональный вопрос. Коллега SkyDance наверняка не влияет на маркетинг или команду клиентской части.
The God is real, unless declared integer.
Re[11]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 06.08.20 05:43
Оценка:
Здравствуйте, SkyDance, Вы писали:

N>>Баги — исправляются. А вот принципиальная тормознутость рантайма — с ней сильно сложнее.

SD>Я так понимаю, "принципиальная тормознутость" рассматривается ниже (с конкретными проблемами). Или есть еще что-то еще? Кроме заявлений про "тормознутость", чтобы было нечто осмысленное. А то я вижу, что "тормознутость" — это 50.000 юзеров на машину в кластере (средней руки мессенджер на жаве) и 500.000 на такую же машину (на Эрланге).

В случае Java, я думаю, сделано просто какого-то явно лишнего кода. Или в условиях очень коротких сработок на один клиентский запрос с длительными ожиданиями между ними — сделана какая-нибудь глупость типа персональной нити на каждого клиента. Иначе бы такой суровой разницы не было.
Но это надо смотреть реализацию в деталях: что делается и как.

N>>Да. Только надо перестать смотреть на это как на "переизобретение эрланга". Даже если Erlang был одно время образцом, то все эти реализации уже давно ушли дальше.

SD>Это и есть переизобретение эрланга. "Эти реализации" ушли не дальше, а в болото. Как туда уходит любой мейнстрим, см. Жава, С++.

Вы можете считать это болотом, но эта кочка зрения (tm) не выглядит обоснованной. Мейнстрим уходит в обеспечение значительно более широкого набора потребностей, чем нишевый продукт, в более разнообразных условиях. Но это никак не означает невозможность качественной специализации под конкретную реализацию.

N>>OK, когда будут множественные входные очереди на процесс?

SD>Сначала нужно объяснить, зачем. Один из патчей, который я сделал, как раз подобная поддержка (в слегка упрощенном виде, т.н. prepend send, послать сообщение в голову очереди). Но чем больше я занимаюсь архитектурой и более серьезным пониманием происходящих процессов, тем больше я понимаю, как был неправ. Просто на тот момент, когда я это сделал, у меня не было достаточно знаний. Сейчас эти знания есть, и я понимаю, что и prepend send, и "множественные очереди", и priority queues — это ошибочные направления. Но, повторюсь, чтобы это понять, нужно действительно провести много времени за изучением этих проблем.

Ну в таком случае выдайте на-гора, пожалуйста, хоть немного этой мудрости (в хорошем смысле), почему это "ошибочное направление". А то то, что я вижу, пока что подтверждает важность подхода.

Вот например RabbitMQ борется с такой проблемой:

  цитата
%% gen_tcp:send/2 does a selective receive of {inet_reply, Sock,
%% Status} to obtain the result. That is bad when it is called from
%% the writer since it requires scanning of the writers possibly quite
%% large message queue.
%%
%% So instead we lift the code from prim_inet:send/2, which is what
%% gen_tcp:send/2 calls, do the first half here and then just process
%% the result code in handle_message/2 as and when it arrives.
%%
%% This means we may end up happily sending data down a closed/broken
%% socket, but that's ok since a) data in the buffers will be lost in
%% any case (so qualitatively we are no worse off than if we used
%% gen_tcp:send/2), and b) we do detect the changed socket status
%% eventually, i.e. when we get round to handling the result code.
%%
%% Also note that the port has bounded buffers and port_command blocks
%% when these are full. So the fact that we process the result
%% asynchronously does not impact flow control.
port_cmd(Sock, Data) ->
    true = try rabbit_net:port_command(Sock, Data)
           catch error:Error -> exit({writer, send_failed, Error})
           end,
    ok.

(там где-то есть ещё и игнорирование этих tcp reply, не буду искать сейчас)


Опишите, пожалуйста, вашу точку зрения на их решение, одним из следующих вариантов (допустимы мелкие поправки):

1. Да, ребята молодцы, что для решения проблемы они полезли в обход аж двух слоёв стандартной библиотеки (gen_tcp и prim_inet), рискуя несовместимостью с будущими реализациями, так и надо. MQ много, OTP одна. Пусть страдают при переходе, не наше дело.

2. Нет, надо было искать чудо и делать, чтобы очередь никогда не превышала K сообщений, где K < N. Как это делать — да хоть через ETS, которую наполняет другой процесс. Публичная ETS (потому что удаляет другой процесс, чем добавляет) не страшна, все свои.

3. Надо было сидеть и страдать. Нефиг тут неуправляемые входные потоки принимать на процесс. TCP приёмник нормально контролирует, а заторы возникают по дороге? Пофиг, у меня всё работает (tm).

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

5. Иное (интересно, что?)

N>>С какой версии это стало нормально работать? Я после 2015 не смотрел, до этого коллеги пробовали — не работало.

SD>В следующий раз посоветуй коллегам разобраться. Оно работало всегда. Могло не хватать каких-то инструментов для удобства. Но systools были еще с 90х годов.

Я именно про rebar. Где-то с 2012 вместо прежних подходов, когда народ достаточно любовно настраивал обстановку и был готов к тому, что система должна работать 24*365, пошли новые подходы типа
1) Пакуем всё в один тарболл вместе с рантаймом, зависимостями и рабочим кодом
2) Всей задачи девопам — развернуть на сервере и запустить
3) Прерывание сервиса? Если волнует, переедут на соседние узлы, если нет — и так пофиг
4) Завернём это ещё и в докер, нефиг тратить время на тюнинг внешних компонентов
5) failover, takeover, relup? Дядя, ты с кем сейчас разговаривал? У нас свои средства кластеризации и надёжности в кластере (90% — просто общая SQL база).

и именно к этому подходу rebar подошёл идеально и стал основным инструментом.

И на него тогда даже смотрели "а он сможет обеспечить нормальный relup на месте, без рестарта, при своей паковке?" и на версиях тех времён однозначно не сложилось.

N>>Основное было системой мониторинга кластера "Ломоносов". Её у нас забрали прямо в процессе затыкания этих проблем


SD>Вот в это я могу поверить — что в силу политических причин ("забрали проект") у кого-то образовалось неприятие к инструментам, которыми попросту не научились пользоваться.


Нет, для себя мы её решили — костылями различной кривости. На продуктин оно не ушло — или ушло, не знаем — но это уже стало не нашей заботой.

N>>А тут она ещё и грубо неверна. Когда проект начинался, мы взяли в контору группу военных админов(!) и они успешно за срок менее месяца переключились на проектирование и написание (при том, что часть ещё и не имела опыта программирования кроме одноэкранных скриптов баша) — и всё шло замечательно до тех пор, пока под реальной нагрузкой не начались уже характерно эрланговые проблемы, как минимум:


SD>Прям-таки классика жанра! Когда я написал "нельзя набрать обезьян" — я ровно это и имел в виду. Дело в том, что синтаксис и "первые шаги" на Эрланге до одури просты. И потому возникает ощущение "мы все поняли и все умеем". Но когда дело доходит до написания реального софта, оказывается, что кроме синтаксиса нужно еще... понять, что такое OTP, и как на самом деле надо пользоваться языком. Вы, однако, так и не поняли. Посему и проблемы, перечисленые ниже. Как раз отражение непонимания, как должна работать система.


Спасибо за извинения за "обезьян" (в соседнем сообщении), повторюсь, что именно эта группа не имеет отношения к проблемам перегрузки. Проблемы же возникали в следующей обстановке:

1. Приложение NA принимает входной поток (его плотность... ну давайте для простоты остановимся на цифре 10K сообщений в секунду) из толпы разных источников (можно распределять между экземплярами приложения на разных узлах). Но сообщение групповое, содержит ~50 вложенных других, и реально обрабатывается 500K. При первичной обработке поток сокращается в ~5 раз, получается 100K mps. Одно сообщение со всеми деталями это, насколько помню, около 200 байт. Вроде бы поток небольшой.

2. Поток выходных сообщений из NA отправляется на несколько приёмников, для простоты скажем про 2: генератор первичных логических выводов (NMU) и логгер. Реально между ними сидит ещё приложение шины (приняло и перепостило подписчикам).

3. NMU делает первичные выводы и посылает их на шину 2. Там свои логгер и групповая логика.

4. Приложение групповой логики (GL) делает выводы уже финальные — типа "стойка 123 недопустимо перегрета, надо выключать оборудование".

В спокойной обстановке на участке NMU — GL поток сообщений в десятки раз меньше входного потока NMU (то есть тысячи, если не сотни, в секунду, уровня "тут всё спокойно, тангаж, крен, рысканье в норме, температура 36.6"), при проблемах — может подскакивать до равного потока (считаем, те же 100K mps). Работа при пиковой нагрузке, соответственно, критична (должно быть всё гладко-линейно и должен ещё быть запас производительности).

Реально частично работало горизонтальное деление — NC, NMU, часть GL просто горизонтально масштабировалась. Но уже участок — вершина GL, и всё, что за ним — регистратор алармов, логгеры этой части, генератор команд по выводам GL (типа, уже надо грубо выключать ток) — не масштабируются. У получателя, типа регистратора, один отправитель. Не 100500 отдельных мелких, каждый из которых послал какое-нибудь "GET /zuka HTTP/1.1", а один, и он не ждёт — посылает следующие.

И вот тут начинается, что любой из процессов — приёмников потока:

1) Если он делает только обработку входящих сообщений и асинхронные посылки другим — живёт. (На самом деле чуть сложнее — иногда получалось, что и в этом случае начиналось торможение. Но этот вопрос на потом.)
2) Если ему хоть иногда надо делать синхронные вызовы (gen_server:call) и соответственно сразу ждать отвёт — всё, суши вёсла: из накопления входной очереди выше 10-20K сообщений он не способен уже выйти. Граница неточная, но, похоже, связана с размером кэша процессора. Временное переполнение, безвредное в других условиях, становится фатальным (надо только рубить процесс).
3) Даже если он сам не делает синхронные вызовы, задача оперативно получить состояние, не блокируя запрашивающего на недопустимый срок (1 секунда уже предел), не выполняется — пока прорабатываются остальные, {'$call',запрос} стоит в конце очереди.

Вот теперь я хочу послушать Ваши предложения по исправлению этих проблем в пределах текущих возможностей Erlang.

N>>1) Переполнение входных очередей без возможности адекватного взаимодействия с пострадавшими процессами; лечилось грубыми хаками типа просовывания управляющих команд через ETS с соседним процессом;


SD>Иными словами, не смогли правильно реализовать backpressure.


Нет. Backpressure вообще недопустим на участке как минимум после NMU. Есть некоторый уровень нагрузки, который в ламинарном состоянии это весьма мелкая доля от того, что может осилить железо и рантайм. Но это в ламинарном. Как только где-то перегрузка, Erlang не даёт восстановиться.

В том решении, которое было испытано локально, но не дошло до целевой эксплуатации, было сделано, что при детекте перегрузки NMU приостанавливает отдачу разрешений посылки сообщений исходным агентам. (Ну и темп регулировался, понятно, общими настройками.) Но даже это пришлось решать немного хакерски, ну и сама постановка вопроса означала, что система не справляется с задачей — состояние должно сниматься не реже раза в секунду, и не теряться.

SD> Справедливости ради, это действительно holy grail асинхронного программирования, и по сути нормально нигде и не реализовано. Да, есть теоретические измышления (SEDA та же) и кое-какие реализации (а ля GenStage), но чтоб серьезно к этому делу подойти, — пока руки не дошли. На данный момент все в стадии написания whitepaper.


Меня тут не интересуют дискуссии о теоретических основах. Остановить агентов мы были в состоянии. Реально они сами останавливались, не получив команды "даю разрешение на 5 отчётов". Меня интересует именно устойчивость реакции на перегрузку. В идеале, пока нет других проблем типа переполнения по памяти, ему должна была быть пофиг длина очереди, хоть миллиард.

N>>2) Страшно тормозной global, с синхронизацией, страдающей при перегрузке (попросту кластер рассыпался — и это при несчастных ~30 узлах); сейчас, по слухам, есть настройка "межкластерные данные идут по другим каналам, чем heartbeats", я не успел это сделать — выдернули на живую.

SD>Сейчас global попросту не нужен (как он не был нужен и раньше). Если нужны process groups, они уже есть (и нет, не pg2, которые работали поверх global). В общем, то, что вы не смогли кластер из 30+ машин поднять, так я про то и пишу — надо было разработчиков высокой квалификации брать. Тогда и 20.000 машин в кластере не были бы проблемой, и даже 30.000 (больше просто пока не требовалось).

И снова домыслы и критика "обезьян". Но это я отложу на следующий заход.

N>>Были и другие, поменьше, но облом вспоминать (попросишь — подниму архивы).

SD>Нет смысла. Я уже понимаю, что не тот уровень знаний.

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

N>>Эти проблемы я обсуждал с Валкиным, Лапшиным, Димандтом

SD>А надо было обсуждать с Lukas Larsson, Kenneth Lundin, Rickard Green, Sverker Eriksson, Kjell Winnblad. Круг, действительно, узок, и он не включает ни одной из указанных выше фамилий.

Общением с кем-то из core team занимались другие коллеги. Успеха не добились.
The God is real, unless declared integer.
Отредактировано 06.08.2020 5:55 netch80 . Предыдущая версия .
Re[9]: WA: 3 млн tcp соединений на одном сервере
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.08.20 09:08
Оценка:
Здравствуйте, SkyDance, Вы писали:

SD>Короче говоря, можно переизобрести этот велосипед (эрланг) еще 10 раз. Например, akka streams есть не что иное как. И Orleans тоже. И go, и вообще практически весь современный concurrency-oriented софт.


Тут сказывается непонимание. У Go достаточно древние корни: Go->Alef->Newsqueak->Squeak. Так что непонятно еще, кто первоначальный изобретатель этого велосипада. Но скорее всего, там мысль двигалась параллельно у разных людей.

P.S. И что интересно, и Go и Erlang пришли из телефонной индустрии
Re[12]: WA: 3 млн tcp соединений на одном сервере
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.08.20 09:22
Оценка:
Здравствуйте, std.denis, Вы писали:

SD>>И тогда получается WhatsApp

SD>хм.. как-будто вацап это что-то хорошее, а не кусок говна, который даже нельзя на нескольких машинах использовать ¯\_(ツ)_/¯

Ну это ж придирка не к имплементации, а к Т.З. Его-то (Т.З.) вряд ли на Ерланге писали
Re[12]: WA: 3 млн tcp соединений на одном сервере
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.08.20 09:49
Оценка:
Здравствуйте, netch80, Вы писали:

N>2) Если ему хоть иногда надо делать синхронные вызовы (gen_server:call) и соответственно сразу ждать отвёт — всё, суши вёсла: из накопления входной очереди выше 10-20K сообщений он не способен уже выйти. Граница неточная, но, похоже, связана с размером кэша процессора. Временное переполнение, безвредное в других условиях, становится фатальным (надо только рубить процесс).


Вот по таким оговоркам сразу видно профессионала. Любителю такая гипотеза в голову не придет (это искренний комплимент, а не скрытая ирония).

А что, у ерланга вынимание из очереди пробегается по всей памяти очереди? Потому что иначе трудно понять, почему временное достижение очередью размера кэша настолько замедляет разгребание очереди, причем делает это "навсегда", что программа уже не восстанавливается.
Re[14]: WA: 3 млн tcp соединений на одном сервере
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.08.20 10:35
Оценка:
Здравствуйте, netch80, Вы писали:

N>Я таки чуть вступлюсь за него (заранее прикрыв нос)

N>Что собственно хотел сказать тут Гринспун, это следующее:

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

Сравни, например, подход sendmail, который по сути представляет собой этакий тьюринг-полный rewrite engine, с сетевыми сокетами и спулером (правда, не с лиспом, а с рефалом внутри, видимо для разнообразия) с более современными мейлерами, типа postfix/exim, написанными, когда уже стало понятно, чего MTA должен делать, а потому у них конфигурация описывается уже в предметных терминах, и в тьюринговской полноте не нуждается.

N>На сейчас, мне кажется, Rust и Go достигли того уровня, который позволяет существовать без первосоздателя — его роль кто-то точно подхватит


Мне кажется, критерием достижения такого уровня является появление независимых компиляторов. Go достигнет этого уровня, когда и если LLVM Go наконец доведут до ума (gccgo не считается, это те же самые люди).
Re[15]: WA: 3 млн tcp соединений на одном сервере
От: Sharov Россия  
Дата: 06.08.20 13:41
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Мне кажется, это происходит от того, что разработчики системы, толком не понимая, что она должна делать, сваливают свой технический долг на голову специалистов по эксплуатации. Отсуда и возникает потребность в тьюринг-полных конфигурационных скриптах.


Скорее менеджеры, и скорее как средство борьбы с постоянными модификациями и изменениями. Причем для разных клиентов. Ядро трогать не надо, но поведение адаптировать как-то надо. Вот и прикручивают скрипты.
Кодом людям нужно помогать!
Re[4]: Дублирую вопрос.
От: Sharov Россия  
Дата: 06.08.20 13:56
Оценка:
Здравствуйте, SkyDance, Вы писали:

SD>Что именно интересует? Просто открыть 3 млн соединений проблем нет почти на любой языке.


Ну вот индус спрашивает про rp\lb. Это что-то свое самописное или используете известные вещи типа nginx? Если известные, то что? Если не NDA.
Кодом людям нужно помогать!
Re[14]: WA: 3 млн tcp соединений на одном сервере
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.08.20 14:03
Оценка:
Здравствуйте, netch80, Вы писали:

N>Проблемы начинаются, если делается синхронный вызов. Каждый такой вызов это:


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

Ужос.

При такой архитектуре напрашивается мысль, что использование синхронных вызовов во всех промежуточных процессах — непозволительная роскошь. Т.е., процесс должен получить сообщение, что-то с ним сделать, куда-то переслать дальше, если сам не может обработать, и забыть навсегда. Отправка ответа изначальному инициатору запроса всегда должна быть заботой того процесса, который окончательно разрешил вопрос (самого последнего процесса в цепочке).

Хуже всего получаецца, если цепочка исполнения запроса разветвляется, и "последних" процессов несколько. Тогда кто-то должен свести результат воедино. Наверняка в ерланге есть какая-то идеома на этот счет, такая потребность должна возникать постоянно.

N>Спасибо на самом деле я уже за давностью не помню, это я предположил или кто-то из команды, но я запомнил и оно, по экспериментам, подтвердилось.


Не скромничай, кто бы ни предположил, понять такую гипотезу тоже не всякий может
Re[15]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 06.08.20 14:16
Оценка:
Здравствуйте, Pzz, Вы писали:

N>>Проблемы начинаются, если делается синхронный вызов. Каждый такой вызов это:


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


Да, именно так. Ну см. поправку на оптимизацию частного случая, в который ещё надо попасть.

Pzz>Ужос.


Ну а я о чём говорю весь тред
Причём пролечить это — чуть сложнее чем совсем тривиально (добавить параметр в десяток похожих вызовов), но — не хотят. Первый известный мне плач относится к 2008 или 2009 году, а наверняка были и раньше.

Pzz>При такой архитектуре напрашивается мысль, что использование синхронных вызовов во всех промежуточных процессах — непозволительная роскошь. Т.е., процесс должен получить сообщение, что-то с ним сделать, куда-то переслать дальше, если сам не может обработать, и забыть навсегда. Отправка ответа изначальному инициатору запроса всегда должна быть заботой того процесса, который окончательно разрешил вопрос (самого последнего процесса в цепочке).


Это ещё один вариант залезания в потроха (формально, даже описанные мной форматы сообщений это внутренняя кухня модуля gen_server, а не публичное API), и/или заката солнца полностью вручную (самому отрабатывать все сообщения, включая служебные сообщения OTP).

Pzz>Хуже всего получаецца, если цепочка исполнения запроса разветвляется, и "последних" процессов несколько. Тогда кто-то должен свести результат воедино. Наверняка в ерланге есть какая-то идеома на этот счет, такая потребность должна возникать постоянно.


Именно такого, по-моему, нет. Обычный API даёт только синхронные вызовы или асинхронные передачи, остальное — делайте сами.

N>>Спасибо на самом деле я уже за давностью не помню, это я предположил или кто-то из команды, но я запомнил и оно, по экспериментам, подтвердилось.


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


ok
The God is real, unless declared integer.
Re[15]: WA: 3 млн tcp соединений на одном сервере
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.08.20 14:33
Оценка:
Здравствуйте, Слава, Вы писали:

С>Слушайте, где ещё вы сможете пообщаться с человеком на подобной должности? Тут надо аккуратно спрашивать и не докапываться до слов.


Интернет сделал мир плоским. В том смысле, что он теперь невысокий и широкий. В этом новом электрическом мире с кем угодно можно перекинуться парой писем
Re[15]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 06.08.20 14:34
Оценка:
Здравствуйте, Pzz, Вы писали:

N>>Я таки чуть вступлюсь за него (заранее прикрыв нос)

N>>Что собственно хотел сказать тут Гринспун, это следующее:

Pzz>Мне кажется, это происходит от того, что разработчики системы, толком не понимая, что она должна делать, сваливают свой технический долг на голову специалистов по эксплуатации. Отсуда и возникает потребность в тьюринг-полных конфигурационных скриптах.


Pzz>Сравни, например, подход sendmail, который по сути представляет собой этакий тьюринг-полный rewrite engine, с сетевыми сокетами и спулером (правда, не с лиспом, а с рефалом внутри, видимо для разнообразия) с более современными мейлерами, типа postfix/exim, написанными, когда уже стало понятно, чего MTA должен делать, а потому у них конфигурация описывается уже в предметных терминах, и в тьюринговской полноте не нуждается.


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

Возьми даже майкрософтовский офис. Что ему на скрипты навешивают? Вполне может быть, что нажатие кнопки на экселевском листе вызывает цепочку реакций вплоть до открытия ворот, посылки робота на склад или подрыва пиропатрона. И как ты такую реакцию запишешь в готовый код?

Или более программистский пример. Есть пачка тикетниц (JIRA, Youtrack, RT, Redmine, ORTS...), серверов репозиториев (Gitlab, Gerrit...), CI серверов (Jenkins, Travis... ничего не путаю?)
И что, просить для каждого из них плагин у авторов?

Можно требовать писания плагинов, а можно — скриптов, если у них есть достаточный доступ внутри и снаружи. Скрипт будет плагином, просто не компилируемым в целевой язык.

И такие плагины не единственная задача скриптования. Даже просто автоматизировать последовательность своих действий или вызвать её по внешнему сигналу — уже задача достойная введения какого-то внутреннего языка.

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

Про sendmail история отдельная. Фактически его популярность вызвана тем, что он был в базовой поставке BSD систем, а туда попал потому, что разработчик был "свой" из своей тусовки. В то же время был, например, zmailer, у которого был свой скриптовый язык стиля шелла. Но кто сейчас помнит про zmailer, кроме совсем уж ветеранов типа меня?
И у exim, если ты не видел, есть Perl map. Через который включается любое внешнее скриптование в пределах, как можно что-то сделать вызовом мапы

N>>На сейчас, мне кажется, Rust и Go достигли того уровня, который позволяет существовать без первосоздателя — его роль кто-то точно подхватит

Pzz>Мне кажется, критерием достижения такого уровня является появление независимых компиляторов. Go достигнет этого уровня, когда и если LLVM Go наконец доведут до ума (gccgo не считается, это те же самые люди).

У Go уже давно свой компилятор и собственный бутстраппинг. Хотя стиль и качество выходного кода у него, мягко говоря, своеобразно.
The God is real, unless declared integer.
Re[16]: WA: 3 млн tcp соединений на одном сервере
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.08.20 14:42
Оценка:
Здравствуйте, netch80, Вы писали:

N>Про sendmail история отдельная. Фактически его популярность вызвана тем, что он был в базовой поставке BSD систем, а туда попал потому, что разработчик был "свой" из своей тусовки. В то же время был, например, zmailer, у которого был свой скриптовый язык стиля шелла. Но кто сейчас помнит про zmailer, кроме совсем уж ветеранов типа меня?


Я его как-то даже себе поставил zmailer, когда осознал, что sendmail я один раз настроить могу, а вот поддерживать его, не будучи профессионально этим озабочен (т.е., залезая в его настройки раз в полгода) не могу. Запускаю я его, все вроде как работает, только компьютер раз в несколько секунд диском похрюкивает. Оказалось, что я что-то недоделал, тестовое письмо куда-то не дошло, и он написал отлуп. Который тоже не дошел, и на него тоже написался отлуп. Так он сам с собой и переписывался, пока я это случайно не заметил. Накопившаяся к тому времени история переписки была уже вполне впечатляющего размера. Но что характерно, систему почти не грузила, как и обещали.

N>И у exim, если ты не видел, есть Perl map. Через который включается любое внешнее скриптование в пределах, как можно что-то сделать вызовом мапы


Я обычно использую exim.

N>У Go уже давно свой компилятор и собственный бутстраппинг. Хотя стиль и качество выходного кода у него, мягко говоря, своеобразно.


Я имею ввиду, должно быть хотя бы два независимых компилятора. Их наличие показывает, что язык готовы поддерживать не только его авторы, и что если авторов дружно переедет трамвай, язык от этого не умрет.
Re[16]: WA: 3 млн tcp соединений на одном сервере
От: Pzz Россия https://github.com/alexpevzner
Дата: 06.08.20 14:44
Оценка:
Здравствуйте, netch80, Вы писали:

N>Именно такого, по-моему, нет. Обычный API даёт только синхронные вызовы или асинхронные передачи, остальное — делайте сами.


Ну да, делаешь асинхронные передачи по цепочке. Потом где-то сводишь результат. Обещанная при этом простота куда-то вдруг волшебным образом рассасывается
Re[17]: WA: 3 млн tcp соединений на одном сервере
От: Sharov Россия  
Дата: 06.08.20 20:22
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Реально, создание платформы, на которой какую-то жизненную проблему можно решить — это примерно 10% работы, необходимой для решения проблемы. Жизненная позиция заключается в том, что всем нравится создавать платформы, а не решать проблемы.


А причем здесь здесь 10%? Речь про требования, которые постоянно и по-разному меняются. Программисты и пишут решения проблемы, а потом выясняется,
что решений много или для каждому заказчику нужно свое решение. Программисты и начинают писать платформу. Ну или добавляют скриптование или DSL, что
сам код ядра не трогать.

ЗЫ: может эту ветку в менеджмент снесете?
Кодом людям нужно помогать!
Re[12]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 07.08.20 01:34
Оценка:
N>В условиях Erlang, HiPE давал нашему коду ну процентов 5.

Это хороший показатель HiPE вообще был по сути исследовательским проектом.
Если что, его поддержку удалили из ОТР (буквально вот сейчас). JIT будет. Но вдвое — разве что только на очень специфичных задачах.
Равно как и статическая типизация, тоже будет.

А вот интеграция с С уже есть, и очень даже хороша — не понимаю, как вы могли упустить NIF. Особенно сейчас, в dirty CPU NIF & dirty IO NIF, и всем вокруг этого.
Re[12]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 07.08.20 03:07
Оценка:
ЗN>В случае Java, я думаю, сделано просто какого-то явно лишнего кода. Или в условиях очень коротких сработок на один клиентский запрос с длительными ожиданиями между ними — сделана какая-нибудь глупость типа персональной нити на каждого клиента. Иначе бы такой суровой разницы не было.

Именно в том и дело, что в Java/C++ и прочих "закатах солнца вручную" очень легко выстрелить себе в ногу. Вот в самом деле, персональная нить на клиента — это же, черт подери, удобно, и очень правильно! И, собственно, так и должно быть (более того, должно быть две нити на клиента, одна на вход, другая на выход, in/out pipes). Потому что это точно воспроизводит всю коммуникационную специфику. Неспроста же это решение возникло в телекоме. Обмен сообщениями. Просто, понятно, гениально.

N>Но это надо смотреть реализацию в деталях: что делается и как.


Как обычно. Дьявол в деталях. И в уровне разработчиков. То, что десяток профессионалов сделют на Эрланге, может быть недоступно сотне "обычных порошков". Для меня, кстати, это совсем недавнее открытие. Раньше я как-то и представить не мог, что один разработчик может быть на порядок более производителен, чем другой. То есть, раньше, в моем понимании, команда из пятерых человек по определению сделает больше, чем один гений. Вынужден признать, что глубоко заблуждался.

N>Вот например RabbitMQ борется с такой проблемой:


Как обычно, у любой проблемы есть варианты решений. Хотя для начала надо понять, почему у них эта проблема существует вообще.
1. Почему у writer'а длинная очередь?
2. Почему selective receive optimisation не работает для их случая?
3. Почему они вообще используют gen_tcp?

Могу лишь предположить, что:
а) переписывать старый код дорого
б) им нужно поддерживать старые версии OTP, или неподходящие для их софта ОС (ту же Windows)
в) нет большой нужды что-то улучшать в этом коде

Ибо если б нужна была, достаточно было бы просто перебраться на socket API, который выполнен в виде NIF и не страдает от указанных недостатков.

Я бы еще понял, если бы они страдали от странностей реализации TLS. Вот там да, мягко говоря, все очень и очень грустно, по куче разных причин. Что уж там, 3 последних PR я делал как раз вокруг TLS, ибо там и баги, и тормоза, и вообще — так делать не следовало с самого начала. Но "переписать с нуля" было бы еще менее осмысленным шагом, ибо это была бы уже четвертая реализация

N>1. Да, ребята молодцы, что для решения проблемы они полезли в обход аж двух слоёв стандартной библиотеки


Думаю, здесь было бы куда более логичным описать проблему более предметно. И вместо "обхода двух слоев" добавить нужную фунцкиональность. Но для этого им бы сначала пришлось разобраться в существующей. А вот это всегда и для всех было проблемой. Что уж там, сколько лет я пытаюсь подвинуть процесс интервью в направлении "проверять как кандидат умеет _читать_ код", но воз, увы, стоит на месте — все так же требует _писать_ код (который писать не нужно).

N>2. Нет, надо было искать чудо и делать, чтобы очередь никогда не превышала K сообщений, где K < N. Как это делать — да хоть через ETS, которую наполняет другой процесс. Публичная ETS (потому что удаляет другой процесс, чем добавляет) не страшна, все свои.


За такие "архите-крутные" решения вынесу порицание. И вообще, к моему страху и ужасу, кроме Вирдинга да еще пары человек понмания какие ужасы несут нам ETS, почти ни у кого нет. Как тут не вспомнить Хаскел, где усилие было приложено в нужном направлении, и ETS попросту нет (в том виде как они есть в Эрланге).

N>3. Надо было сидеть и страдать. Нефиг тут неуправляемые входные потоки принимать на процесс. TCP приёмник нормально контролирует, а заторы возникают по дороге? Пофиг, у меня всё работает (tm).


Этот вариант я не понял. Что именно предлагается? Разделить на два процесса, где у одного очередь и flow control, а второй непосредственно пишет в сокет? Да, так делают, да, нормально работает, но да, костыль. Но вообще эти страдания не совсем логичны. Впрочем, хорошо уже то, что у них таки есть разделение на r/w. Потому как куда более суровы страдания тех, кто в одном процессе все это делает, а потом жалуется, что gen_tcp:send() не возвращает управление пока данные не уйдут хотя бы в kernel send buffer.

N>4. Вы неверно понимаете задачу и вообще у вас плохой дзен, становитесь ёжиками. Детали не интересуют, я стратегию разрабатываю.

N>5. Иное (интересно, что?)

Пожалуй, что "иное" — просто используйте socket. Если его нет в вашей версии, — портируйте. Вполне нормальная практика backport'ить что-то из старших версий, скажем, мы в древние времена бэкпортили crypto, чтобы работало с аппаратным ускорением (через УМЗ), а не как в R16B.

N>1) Пакуем всё в один тарболл вместе с рантаймом, зависимостями и рабочим кодом


Так ведь это и есть release (он же target system). Где-то еще так с начала 90х

N>5) failover, takeover, relup? Дядя, ты с кем сейчас разговаривал? У нас свои средства кластеризации и надёжности в кластере (90% — просто общая SQL база).


Традиционная проблема же, "нам некогда учиться, нам надо вчера", в итоге велосипедостроение в полный рост, tech debt, и — свой вариант, но очень незрелый, того что есть в ОТР.
Классика жанра. Очень немногие способны разобраться, понять как сделано, как надо, какие грабли были. Нет, вместо этого надо скорее делать, чтобы потом просто совершить еще один круг, еще один прыжок на месте, сделать свой Эрланг, с блекджеком и женщинами.

N>И на него тогда даже смотрели "а он сможет обеспечить нормальный relup на месте, без рестарта, при своей паковке?" и на версиях тех времён однозначно не сложилось.


Может быть. Я в 2012 этим не занимался. Но были уже тогда systools. Но да, неудобные — и правильным вариантом было бы просто исправить. Ибо ведь open source. Это и есть подход, который я исповедую. Сначала разберись, потом пойми, потом осознай, почему так, — потом исправь и сделай мир лучше. Дай другим результаты твоего труда. Используй синергию этого процесса, объедини усилия.
Но да, это требует усилий.

N>Нет, для себя мы её решили — костылями различной кривости.


Может, в этом причина недовольства?

N>В спокойной обстановке на участке NMU — GL поток сообщений в десятки раз меньше входного потока NMU (то есть тысячи, если не сотни, в секунду, уровня "тут всё спокойно, тангаж, крен, рысканье в норме, температура 36.6"), при проблемах — может подскакивать до равного потока (считаем, те же 100K mps). Работа при пиковой нагрузке, соответственно, критична (должно быть всё гладко-линейно и должен ещё быть запас производительности).


Это же невозможно по определению. Или вы должны быть overprovisioned, чтобы соблюдать гарантии, или должна быть load shedding логика для защиты от перегрузки, или — backpressure.
"Все уже украдено до нас": https://ferd.ca/handling-overload.html

N>2) Если ему хоть иногда надо делать синхронные вызовы (gen_server:call) и соответственно сразу ждать отвёт — всё, суши вёсла


Хаха, как знакомо, все с тем же Вирдингом общались на тему "кто же это придумал gen_server:call и какие кары ждут его в аду"
Все правильно: как только нарушается стройная концепция ("процессы обмениваются сообщениями") и приходит императивный девелопер "нам нужно сделать RPC", как все сразу начинает работать не так, как задумано. Embrace concurrency, adopd asynchronicity, и так далее. Пока это не случится, будут все те же одинаковые проблемы с блокировкой процесса там, где не следует.

N>: из накопления входной очереди выше 10-20K сообщений он не способен уже выйти. Граница неточная, но, похоже, связана с размером кэша процессора.


Прочитав еще пару комментариев ниже, и увидев, как другие участники восхищаются скоростью постановки диагноза, просто обязан прокомментировать. Во-первых, отослать к моему выступлению на прошлой code MESH, — как раз на тему "in god we trust, all others must bring data".

Во-вторых, конечно же, у меня есть куда более простое, логичное и понятное объяснение, почему это происходит, ибо — я в теме разобрался чуть менее поверхностно. Допускаю, что у вас на тот момент не было никого, что мог бы просто воспользоваться gdb/perf/fprof/eprof/cprof, и понять, что дело не в кэше, а в том, как работает GC. Но да, что занятно, Rick Reed в свое время тоже наступил на сию граблю, но на то он и Rick Reed, чтобы разобраться. Я тогда еще и рядом не стоял. Могу лишь гордится тем, что учился у таких людей.

Так вот, возвращаясь к вопросу, — возможно в древних версиях, которыми вы пользовались, еще не было off-heap message queues, поэтому и случалась death spiral, когда с ростом количества сообщений в очереди GC становился все более и более дорогим, что вело к еще более быстрому наполнению очереди, что вело к еще более медленному GC, и так далее.

N> Временное переполнение, безвредное в других условиях, становится фатальным (надо только рубить процесс).


Кто хочет, ищет причины. Кто хочет — решения. Мы нашли решения: во-первых, добавили патч для flush message queue, во-вторых, допилили GC для более удачной работы с длинными очередями, в-третьих, когда доделали off-heap mq, просто перелезли на них.

N>Вот теперь я хочу послушать Ваши предложения по исправлению этих проблем в пределах текущих возможностей Erlang.


Надеюсь, я ответил. No fate but the one we make. Если что-то сейчас в Эрланге не так, как нужно, это либо просто не было нужно до вас (и тогда — просто сделайте PR), либо... вам это не нужно, просто нужно разобраться, как оно на самом деле должно быть.

N>Нет. Backpressure вообще недопустим <...> Остановить агентов мы были в состоянии. Реально они сами останавливались, не получив команды "даю разрешение на 5 отчётов".


Или я чего-то не понимаю, или... это как раз и есть backpressure (в самом простом и классическом варианте, т.е. credit control. Странно, что это вы считаете "хаком". Это вполне легальный, и один из самых простых в реализации, способов. В конце концов, Ulf Wiger еще в 2010 (на деле, в 2005, но опубликовали позже) с теоретической стороны это рассмотрел. Позже, в том же Elixir, Jose Valim сделал аналогичный GenStage. Да что там, реализаций немало.

И. Справедливости ради, это же и есть holy grail. SEDA, и все эти akka streams, и все это reactive programming, — все аналогичные data flow pipelines, все это отнюдь не ново! Все уже было, и whitepapers более чем навалом, и реализаций. Если уж вы работали над "Ломоносовым", это ведь в МГУ, как могло так получиться, что вы не были знакомы со всеми работами в этом направлении? Уж на что моя должность прикладного характера, но даже я с ними знаком. Ибо без такого знакомства я был бы обречен написать очередной worker pool.


N>И снова домыслы и критика "обезьян". Но это я отложу на следующий заход.


Давайте, очень жду. Чем же так был нужен global, чтобы вот без него никак.

SD>>А надо было обсуждать с Lukas Larsson, Kenneth Lundin, Rickard Green, Sverker Eriksson, Kjell Winnblad. Круг, действительно, узок, и он не включает ни одной из указанных выше фамилий.

N>Общением с кем-то из core team занимались другие коллеги. Успеха не добились.

Что такое core team?
OTP team, у них нет "core", есть VM, есть PS, и есть еще один человек сбоку. И так уже лет... пятнадцать. И вот это, да, проблема, слишком мало драйверов роста.

Не знаю, почему не удалось добиться успеха. У нас отлично получается.
Re[10]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 07.08.20 03:09
Оценка:
Pzz>Тут сказывается непонимание. У Go достаточно древние корни: Go->Alef->Newsqueak->Squeak. Так что непонятно еще, кто первоначальный изобретатель этого велосипада. Но скорее всего, там мысль двигалась параллельно у разных людей.

Erlang родом из 70х. Это и хорошо, и одновременно плохо — хорошо тем, что очень взрослый язык. Плохо тем, что слишком поздно он вышел из лаборатории, в 1998 году, на 15 лет позже чем стоило бы. Момент был упущен.

Pzz>P.S. И что интересно, и Go и Erlang пришли из телефонной индустрии


Такая уж предметная область (массивная параллельная обработка). По сути ведь это был язык для телефонных свитчей. Самых надежных в мире.
Re[14]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 07.08.20 03:16
Оценка:
N>Проблемы начинаются, если делается синхронный вызов. Каждый такой вызов это:

Правильно. В первоначальном варианте языка никаких "синхронных вызовов" не предусматривалось (и правильно, по делу).

N>Это оптимизация на частный случай, и она сделана, кажется, в 14-м релизе


А сейчас на дворе 23.
И оптимизации сделаны чуть иначе, с чуть большими возможностями. Но, да, только под конкретный шаблон (тот самый gen_server:call).
Странно еще что вы не совершили традиционный "удар ниже пояса" на тему monitor()/demonitor() — ведь это еще пара злобных поглотителей времени (и да, конечно, уже тоже давно не относится к реальности, примерно с R21, где было добавлено то самое, о чем вы просили — "две очереди", даже, скажем так три, но не для пользователя).

Pzz>>Вот по таким оговоркам сразу видно профессионала. Любителю такая гипотеза в голову не придет (это искренний комплимент, а не скрытая ирония).


N>Спасибо на самом деле я уже за давностью не помню, это я предположил или кто-то из команды, но я запомнил и оно, по экспериментам, подтвердилось.


Вот именно это меня особенно смущает, "подтверждение экспериментами". Нет бы просто прочитать код и разобраться. Как это сделали мы.
Re[5]: Дублирую вопрос.
От: SkyDance Земля  
Дата: 07.08.20 03:18
Оценка:
S>Ну вот индус спрашивает про rp\lb. Это что-то свое самописное или используете известные вещи типа nginx? Если известные, то что? Если не NDA.

не совсем понимаю вопрос. Что есть rp? lb — load balancing?
Re[17]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 07.08.20 03:43
Оценка:
Pzz>Ну да, делаешь асинхронные передачи по цепочке. Потом где-то сводишь результат. Обещанная при этом простота куда-то вдруг волшебным образом рассасывается

Это и есть простота.
Надо научиться думать асинхронно. Понять и принять это. Осознать, что именно так и работает наш мир. Мы, существа, actors, — просто посылаем сообщения. Наш мозг так работает. Он посылает сообщения. И он не блокируется в ожидании ответа, как это делает анти-паттерн "call".

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

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

Ладно, можно на этом закругляться. Все равно общение слегка бессмысленное. Мир идет по кругу, или по спирали, если смотреть сбоку, но суть от того не меняется. Все в итоге суета сует. Буду честным — сделать можно какой угодно софт, на какой угодно платформе, на любом языке.
Дело лишь в профессионализме тех, кто будет этим заниматься, и в свойствах полученной системы. У меня хватает примерно увидеть то, на что способны несколько талантливых людей. И увидеть то, как на место десятка нанимается сотня, с результатами куда более печальными.

Такова жизнь. Мы рождаемся, взрослеем, стареем, умираем.
И мы несем это в софт. Он тоже рождается, взрослеет, стареет, умирает. Порой долго и мучительно, см. КОБОЛ, порой с феерверками. Иногда оставляет восхитительное послевкусие, см. common lisp — я до сих пор считаю модель разработки CL куда более удобной, чем то, что происходит в С++, жаве и многом еще. Благодаря одному чертовски важному свойству, тому, что я зову instant signal, — когда сигнал от сделанного изменения виден немедленно. Это holy grail of development productivity. И он достижим на Erlang'е. Сложнее, но также и на Java, PHP, Python, еще языкам. На С++, хм, нуу... не знаю, может, стар я стал, но до того медленны нынче компиляторы, что не то что signal, а даже build, и тот не instant.
Re[13]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 07.08.20 04:32
Оценка:
Здравствуйте, SkyDance, Вы писали:

SD>А вот интеграция с С уже есть, и очень даже хороша — не понимаю, как вы могли упустить NIF. Особенно сейчас, в dirty CPU NIF & dirty IO NIF, и всем вокруг этого.


99% работы продукта это манипуляция структурами данных.
Объём работы по переносу их на C через NIF был бы такой, что точно проще было бы "задвинуть" целиком C/C++.
The God is real, unless declared integer.
Re[12]: WA: 3 млн tcp соединений на одном сервере
От: Mystic Artifact  
Дата: 07.08.20 05:09
Оценка:
Здравствуйте, netch80, Вы писали:

N>Слово "синидиотически" не находится. Опечатка или что?


Там одна большая опечатка... и не только в орфографии но и по смыслу.

Имелось ввиду, что больше нравятся языки и платформы общего назначения, на которых строятся конкретные решения (аля библиотеки). Не вижу плохого в других подходах (а иногда вижу и плюсы), но узколобая душонка их не любит и требует сделки с дьяволом.
Re[6]: Дублирую вопрос.
От: Sharov Россия  
Дата: 07.08.20 06:44
Оценка:
Здравствуйте, SkyDance, Вы писали:

S>>Ну вот индус спрашивает про rp\lb. Это что-то свое самописное или используете известные вещи типа nginx? Если известные, то что? Если не NDA.


SD>не совсем понимаю вопрос. Что есть rp?


reverse proxy

SD>lb — load balancing?


Да.
Кодом людям нужно помогать!
Re[13]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 07.08.20 10:46
Оценка:
Здравствуйте, SkyDance, Вы писали:

N>>Вот например RabbitMQ борется с такой проблемой:


SD>Как обычно, у любой проблемы есть варианты решений. Хотя для начала надо понять, почему у них эта проблема существует вообще.

SD>1. Почему у writer'а длинная очередь?

Потому что туда поступили сообщения из внутренней обработки, и их надо отправить. Терять нельзя.

SD>2. Почему selective receive optimisation не работает для их случая?


Потому что не подходит под тот единственный шаблон, на котором настаивали авторы этого костыля.

SD>3. Почему они вообще используют gen_tcp?

SD>Ибо если б нужна была, достаточно было бы просто перебраться на socket API, который выполнен в виде NIF и не страдает от указанных недостатков.

Гениально, Ватсон!

>> Module socket was introduced in OTP 22.0.


Спасибо, что снизошли до нас, простых смертных. А все предыдущие ~15+ лет нам что делать было?
Мы начинали на R11, кажется.

N>>1. Да, ребята молодцы, что для решения проблемы они полезли в обход аж двух слоёв стандартной библиотеки

SD>Думаю, здесь было бы куда более логичным описать проблему более предметно.

Проблема очевидна: есть задача обрабатывать поток сообщений, не теряя их и адекватно реагируя на нагрузку (со стоимостью не выше линейной, в идеале — ниже).

Это проблема и MQ-движков, и нашего мониторинга.

SD> И вместо "обхода двух слоев" добавить нужную фунцкиональность. Но для этого им бы сначала пришлось разобраться в существующей. А вот это всегда и для всех было проблемой. Что уж там, сколько лет я пытаюсь подвинуть процесс интервью в направлении "проверять как кандидат умеет _читать_ код", но воз, увы, стоит на месте — все так же требует _писать_ код (который писать не нужно).


Опять "мышки, станьте ёжиками". У меня совершенно конкретный вопрос: как вы предлагаете писать, чтобы не получать квадратичную зависимость затрат CPU (хотя бы) от скорости потока, в условиях подобных неоптимизируемых синхронных вызовов (которые неизбежны хоть изредка)?

Хотя бы самую общую идею, как это сделать, но чтобы было реализуемо в пределах Erlang.

N>>2. Нет, надо было искать чудо и делать, чтобы очередь никогда не превышала K сообщений, где K < N. Как это делать — да хоть через ETS, которую наполняет другой процесс. Публичная ETS (потому что удаляет другой процесс, чем добавляет) не страшна, все свои.


SD>За такие "архите-крутные" решения вынесу порицание. И вообще, к моему страху и ужасу, кроме Вирдинга да еще пары человек понмания какие ужасы несут нам ETS, почти ни у кого нет. Как тут не вспомнить Хаскел, где усилие было приложено в нужном направлении, и ETS попросту нет (в том виде как они есть в Эрланге).


Роскошно. Повторю вопрос: как вы будете решать иначе?
ETS был тут совсем не от хорошей жизни.

N>>3. Надо было сидеть и страдать. Нефиг тут неуправляемые входные потоки принимать на процесс. TCP приёмник нормально контролирует, а заторы возникают по дороге? Пофиг, у меня всё работает (tm).


SD>Этот вариант я не понял. Что именно предлагается? Разделить на два процесса, где у одного очередь и flow control, а второй непосредственно пишет в сокет? Да, так делают, да, нормально работает, но да, костыль.


Мнэээ... вы хоть попробовали действительно детально расписать, как вы предполагаете реализацию этого?

Ну-ка попробую ("давно не брал я в руки шашек", но основы помню). Итак, процесс A получает входные сообщения, процесс B отправляет пусть штатным образом через gen_tcp:send (напоминаю, socket API нам ещё не доступен). Мы защищаемся от слишком длинной очереди процесса B, передавая эту обязанность на A.

Очевидно, что если B передаёт каким-то образом "а ну дай следующие данные на передачу", их надо собрать одним сообщением. Проблема в receive именно в количестве сообщений, а если я все передаваемые пакеты набью в одно, оно будет тяжёлым (объём данных никуда не девается), но одним. Потом процесс будет разбирать его и отправлять по кусочкам.
И чтобы не ожидать синхронизации с A, B всегда просит запас на сколько-то сообщений, если есть. Он передаёт в сторону A сообщения типа "у меня сейчас <N готовых на отправку, давай следующие" (XON) или "у меня сейчас >=N, копи у себя" (XOFF). (Пока не думаем, как он именно это передаёт в A. Можно рассматривать на грубых мерах уровня XON/XOFF, а не более тонких типа "скинь мне ещё 200 сообщений", покамест это неважно.)
Теперь: B должен же как-то реагировать на внешний мир, пока это происходит? Значит, надо разбирать поступившее относительно мелкими порциями, давая в промежутках управляющей системе что-то сделать. Может, она пошлёт стандартное OTP сообщение "расскажи, чем ты занят" (не помню, как выглядит), может, скажет проапгрейдиться, а может, скажет потухнуть. Значит, один раз на K сообщений надо отдать управление основному циклу (мы ж считаем, что он не самопальный? значит, берём gen_server, вряд ли что-то иное). А себе тогда надо послать сообщение типа "работай дальше".

Вроде с B утвердили. В нормальной обстановке у него безумной очереди нет: в произвольный момент там будут только какие-то из набора: 1) порция данных от A, <=1 сообщение; 2) самому себе про про продолжение разбора, <=1 сообщение; 3) какое-то разумное количество '$call', если спрашивают; 4) что-то управляющее от системы, <=1 сообщение.

Теперь переходим к A. Он накапливает входную очередь в своё состояние и сбрасывает его по заказу от B. Теперь пусть последний сигнал от B — "XOFF, копи у себя". В очереди опять ~20000 сообщений, источники не могут группировать. B передаёт A: XON. Теперь этот XON становится в хвост этих 20000 сообщений... B давно всё отправил и ждёт нового поступления, а A накапливает сообщения, раздуваясь, хотя давно мог бы скинуть порцию для B.

Вот это как раз тот случай, когда мы применили ETS, что вам так не нравится. В нём B выставлял этот флажок XON/XOFF, а A в обработке своего handle_cast (или handle_info, не помню) раз на 100 отработанных сообщений проверял его и смотрел, может он отправлять на B. Некошерно, зато мгновенно.

Итак, оно типа работает (хотя и потребовало заметного усложнения обоих процессов). Теперь: у этой системы есть свой мониторинг мониторинга. Каждый процесс должен отвечать подробностями своего состояния. Делаем это на сообщениях? Опять, пока "покажи личико" стоит в хвосте очереди, A прорабатывает свой входной набор.

Да, мы это обошли — и снова через ваш нелюбимый ETS! В приложении процесс listener отрабатывает длинный вход и рапортует своё состояние через ETS процессу manager, а заодно проверяя там — опять же каждые пусть 100 сообщений, или по таймеру — запросы от manager по ETS. А manager не получает длинную очередь, и отрабатывает все управляющие команды. И так в каждом приложении.

А теперь как это было бы на более разумно спроектированном средстве: никаких множественных процессов, никаких сложных буферизаций, никаких нечестных каналов мгновенного взаимодействия. Просто: пусть у нас 3 очереди. 0 — входной поток (cast + info), 1 — синхронные запросы (call + служебные OTP), 2 — ответы на наши синхронные запросы. Даже если receive читает, пусть по шаблону, в порядке приоритета: 2, 1, 0 (но пока копается в 0, всё равно реагирует на поступление в очередь 2) — то всё решено, реакция своевременная и адекватная, поведение устойчивое и линейное, и одного процесса хватает с головой. Ещё лучше, конечно, ограничить, что ответы на call читаются только из 2, но это следующий шаг.

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

Ну теперь хочу послушать ваши предложения. Только в технической конкретике, иначе спор неравный, и без фокусов типа socket API, который недоступен (машины времени, простите, нет), по уровню 2010 года (когда вопрос про очереди уже был поднят и получил отказ), максимум 2012. Потом можно перейти к 2020, вдруг что изменилось.

SD> Но вообще эти страдания не совсем логичны. Впрочем, хорошо уже то, что у них таки есть разделение на r/w. Потому как куда более суровы страдания тех, кто в одном процессе все это делает, а потом жалуется, что gen_tcp:send() не возвращает управление пока данные не уйдут хотя бы в kernel send buffer.


Это как раз более понятная проблема и решаемая: 1) просто распараллелить отправщиков (считаем, TCP соединения разные), 2) задержка линейна, а не квадратична.

SD>Пожалуй, что "иное" — просто используйте socket. Если его нет в вашей версии, — портируйте. Вполне нормальная практика backport'ить что-то из старших версий, скажем, мы в древние времена бэкпортили crypto, чтобы работало с аппаратным ускорением (через УМЗ), а не как в R16B.


Этой "старшей версии" ещё в 2011 просто нет, бэкпортить нечего. Надо писать самому. Лезть на сишный уровень в сложный чужой код...
Понимаете, почему я во втором проекте всё это выбросил, и просто перегнал на другой язык? И взлетело за 3 дня.

N>>Нет, для себя мы её решили — костылями различной кривости.

SD>Может, в этом причина недовольства?

Не-а

N>>В спокойной обстановке на участке NMU — GL поток сообщений в десятки раз меньше входного потока NMU (то есть тысячи, если не сотни, в секунду, уровня "тут всё спокойно, тангаж, крен, рысканье в норме, температура 36.6"), при проблемах — может подскакивать до равного потока (считаем, те же 100K mps). Работа при пиковой нагрузке, соответственно, критична (должно быть всё гладко-линейно и должен ещё быть запас производительности).

SD>Это же невозможно по определению. Или вы должны быть overprovisioned, чтобы соблюдать гарантии, или должна быть load shedding логика для защиты от перегрузки, или — backpressure.
SD>"Все уже украдено до нас": https://ferd.ca/handling-overload.html

И снова вы не хотите читать, что вам пишут.
У нас не было проблемы переполнения именно такого рода, как тут пишут, не было причины выставлять какие-то произвольные лимиты на основании представления, что это предел, и всё такое.
Если бы система адекватно (то есть с зависимостью не выше линейной) реагировала на нагрузку, пусть там ждёт 100000, 1000000 сообщений — всё пофиг; мы их просто обрабатываем.
Да, это именно что overprovisioned, и в данной ситуации это намеренно. Пусть каждый узел будет нагружен даже в самом тяжёлом случае на 50%, на 30% — всё отлично, нас это устроило бы, задача не просто допускает такой overprovisioning, она косвенно это требует.

Но квадратичность зависимости от текущей длины очереди:
1. Не даёт возможность создать никакого запаса нагрузки.
2. Не допускает устойчивого поведения: в отличие от линейной реакции, где любой локальный перекос просто чуть удлиняет очереди и спокойно разгребается вслед — тут подскок приводит к тому, что времени разгребать уже нет, надо дропать без обработки или дохнуть.

N>>2) Если ему хоть иногда надо делать синхронные вызовы (gen_server:call) и соответственно сразу ждать отвёт — всё, суши вёсла


SD>Хаха, как знакомо, все с тем же Вирдингом общались на тему "кто же это придумал gen_server:call и какие кары ждут его в аду"

SD>Все правильно: как только нарушается стройная концепция ("процессы обмениваются сообщениями") и приходит императивный девелопер "нам нужно сделать RPC", как все сразу начинает работать не так, как задумано. Embrace concurrency, adopd asynchronicity, и так далее. Пока это не случится, будут все те же одинаковые проблемы с блокировкой процесса там, где не следует.

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

И от синхронных вызовов отказаться как-то нереально. Хотя сократить их долю, да, можно.

N>>: из накопления входной очереди выше 10-20K сообщений он не способен уже выйти. Граница неточная, но, похоже, связана с размером кэша процессора.

SD>Прочитав еще пару комментариев ниже, и увидев, как другие участники восхищаются скоростью постановки диагноза, просто обязан прокомментировать. Во-первых, отослать к моему выступлению на прошлой code MESH, — как раз на тему "in god we trust, all others must bring data".

Если бы кто-то нормально отреагировал на эти вопросы в 2011-м или около того, у него были бы не просто данные, у него была бы живая установка на самому пощупать во всех аспектах. А сейчас, извините, поезд ушёл. Но повторение проблемы через пару лет на другом проекте с независимым кодом — для меня достаточно, чтобы сделать вывод (о квадрате, не о кэше).

SD>Во-вторых, конечно же, у меня есть куда более простое, логичное и понятное объяснение, почему это происходит, ибо — я в теме разобрался чуть менее поверхностно. Допускаю, что у вас на тот момент не было никого, что мог бы просто воспользоваться gdb/perf/fprof/eprof/cprof, и понять, что дело не в кэше, а в том, как работает GC. Но да, что занятно, Rick Reed в свое время тоже наступил на сию граблю, но на то он и Rick Reed, чтобы разобраться. Я тогда еще и рядом не стоял. Могу лишь гордится тем, что учился у таких людей.


Мне на самом деле нет принципиальной разницы тут: кэш, GC или стая ворон. Это только дополнительный триггер, который приводил к более резкой границе срабатывания. Мы могли бы выдержать торможение и в 10 раз на переходе границы, но — фиксированное. Вот пусть ровно в 12.4 раза, но не больше.
Реально же измерения на тесте типа "заполняем входную очередь до заданного количества, потом начинаем разбирать" показали, что время растёт с характеристикой, близкой к квадрату количества сообщений.

SD>Так вот, возвращаясь к вопросу, — возможно в древних версиях, которыми вы пользовались, еще не было off-heap message queues, поэтому и случалась death spiral, когда с ростом количества сообщений в очереди GC становился все более и более дорогим, что вело к еще более быстрому наполнению очереди, что вело к еще более медленному GC, и так далее.


Там есть функции пощупать, чем занят сейчас процесс (без вопроса ему самому) — собственно, process_info() с соответствующими параметрами. Если бы вы были правы, там оно показывало бы GC. Но оно не показывало GC. Так что этот фактор если и влиял, то далеко не главным.

(Ну или показометр врал. Кто знает... но тогда это опять же проблема Erlang.)

N>> Временное переполнение, безвредное в других условиях, становится фатальным (надо только рубить процесс).

SD>Кто хочет, ищет причины. Кто хочет — решения. Мы нашли решения: во-первых, добавили патч для flush message queue, во-вторых, допилили GC для более удачной работы с длинными очередями, в-третьих, когда доделали off-heap mq, просто перелезли на них.

Вот именно, что ищет решения. Нашим решением для второго проекта был уход от Erlang. И не пожалели.

N>>Нет. Backpressure вообще недопустим <...> Остановить агентов мы были в состоянии. Реально они сами останавливались, не получив команды "даю разрешение на 5 отчётов".


SD>Или я чего-то не понимаю, или... это как раз и есть backpressure (в самом простом и классическом варианте, т.е. credit control. Странно, что это вы считаете "хаком". Это вполне легальный, и один из самых простых в реализации, способов. В конце концов, Ulf Wiger еще в 2010 (на деле, в 2005, но опубликовали позже) с теоретической стороны это рассмотрел. Позже, в том же Elixir, Jose Valim сделал аналогичный GenStage. Да что там, реализаций немало.


Супер статья, да:

>> For lack of a better analysis,we called them “monster waves” (see Figure 5) although we do notyet know exactly what causes it.


Ну хоть по вашему мнению, вы победили эти monster waves, или нет? )

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

SD>И. Справедливости ради, это же и есть holy grail. SEDA, и все эти akka streams, и все это reactive programming, — все аналогичные data flow pipelines, все это отнюдь не ново! Все уже было, и whitepapers более чем навалом, и реализаций. Если уж вы работали над "Ломоносовым", это ведь в МГУ, как могло так получиться, что вы не были знакомы со всеми работами в этом направлении? Уж на что моя должность прикладного характера, но даже я с ними знаком. Ибо без такого знакомства я был бы обречен написать очередной worker pool.


А кто вам сказал, что не были знакомы? Мне сейчас не доступна история внутренних событий тех времён, но раскопки шли, и какие-то работы рассматривались. Имя Wigerʼа я помню с тех времён.
Тем не менее, их не хватило.

Поставьте сами эксперимент такого же рода. Какое-то современное железо (не менее Corei3 или Ryzen3, если x86), незагруженный узел. Сделайте процесс, который принимает поток сообщений с отдельного узла (какая-нибудь структурка в кортеже байт на 200) и обрабатывает их с участием синхронного вызова (пусть в трёх вариантах: сначала типа оптимизированного gen_server:call, потом gen_tcp:send и наконец чего-то своего) хотя бы один раз на 100 сообщений. И ещё один, который периодически мониторит этот процесс вызовами, на которые тот должен в handle_call отвечать своим состоянием. И начните его грузить, равномерным потоком, под потолок 50% нагрузочной способности на текущем железе. Потом сделайте внешнее вмешательство: просто заставьте заснуть процесс на 2-3 секунды (годится call с сообщением, которое зовёт sleep)... а потом смотрите, как он выкарабкивается из этой ситуации.
Потом возьмите от того пикового ламинарного потока — 95%, 90%, 85%... и каждый раз приостанавливайте процесс и смотрите, восстановится или нет.
Критерий восстановления: если остановить входной поток, через 6 секунд (дадим запас, хотя 4 секунд должно было хватить) очередь процесса исчерпывается полностью.
Потом повторить на R12-R13 и на железе того времени (пусть будут Nehalem всех видов).
Основная цифра, которая меня интересует по результату: пусть RL — пиковый рейт для устойчивого ламинарного состояния (сообщений в секунду). Пусть RX — пиковый рейт для режима "пригрузив, остановить процесс на 2 секунды, запустить снова, и чтобы он восстановился после этого" (повторюсь, восстановление — это когда через 4-6 секунд все входные сообщения проработаны, и процесс спит в ожидании). Чему равно RL/RX, и как она зависит от железа, версии Erlang и варианта синхронного вызова?
И если RL/RX более 2 (дадим запас, хотя я бы смотрел на случай >1.4), что именно тормозит восстановление?

SD>>>А надо было обсуждать с Lukas Larsson, Kenneth Lundin, Rickard Green, Sverker Eriksson, Kjell Winnblad. Круг, действительно, узок, и он не включает ни одной из указанных выше фамилий.

N>>Общением с кем-то из core team занимались другие коллеги. Успеха не добились.

SD>Что такое core team?

SD>OTP team, у них нет "core", есть VM, есть PS, и есть еще один человек сбоку.

Core team — это общее понятие. Мне пофиг, как оно называется в конкретном случае — core team, cardinal crew, steering committee или как-то ещё.

SD>И так уже лет... пятнадцать. И вот это, да, проблема, слишком мало драйверов роста.


Ну если вы будете вместо того, чтобы помогать пусть даже на среднего качества разработке добиваться успехов, требовать высочайшего качества подготовки программистов/архитекторов/etc. — не удивляйтесь, что у вас "слишком мало драйверов роста", их больше и не будет — наоборот, будет только меньше.

SD>Именно в том и дело, что в Java/C++ и прочих "закатах солнца вручную" очень легко выстрелить себе в ногу. Вот в самом деле, персональная нить на клиента — это же, черт подери, удобно, и очень правильно! И, собственно, так и должно быть (более того, должно быть две нити на клиента, одна на вход, другая на выход, in/out pipes). Потому что это точно воспроизводит всю коммуникационную специфику. Неспроста же это решение возникло в телекоме. Обмен сообщениями. Просто, понятно, гениально.


Спасибо, посмеялся.

N>>Но это надо смотреть реализацию в деталях: что делается и как.


SD>Как обычно. Дьявол в деталях. И в уровне разработчиков. То, что десяток профессионалов сделют на Эрланге, может быть недоступно сотне "обычных порошков". Для меня, кстати, это совсем недавнее открытие. Раньше я как-то и представить не мог, что один разработчик может быть на порядок более производителен, чем другой. То есть, раньше, в моем понимании, команда из пятерых человек по определению сделает больше, чем один гений. Вынужден признать, что глубоко заблуждался.


У меня такого заблуждения никогда не было. Но вы вместо обсуждения технических деталей опять впали в философию, где святой дух гения помогает Эрлангу, но не помогает Джаве.
The God is real, unless declared integer.
Re[15]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 07.08.20 10:53
Оценка:
Здравствуйте, SkyDance, Вы писали:

N>>Проблемы начинаются, если делается синхронный вызов. Каждый такой вызов это:

SD>Правильно. В первоначальном варианте языка никаких "синхронных вызовов" не предусматривалось (и правильно, по делу).

Ну и где этот "правильный вариант", если сейчас без gen_call OTP в принципе не будет работать — слишком много на него завязано?
Может, вместо того, чтобы его ругать, просто набраться сил и признаться, что синхронные вызовы неизбежны и надо с ними справляться?

N>>Это оптимизация на частный случай, и она сделана, кажется, в 14-м релизе


SD>А сейчас на дворе 23.

SD>И оптимизации сделаны чуть иначе, с чуть большими возможностями. Но, да, только под конкретный шаблон (тот самый gen_server:call).

Вот в этом и загвоздка.

SD>Странно еще что вы не совершили традиционный "удар ниже пояса" на тему monitor()/demonitor() — ведь это еще пара злобных поглотителей времени (и да, конечно, уже тоже давно не относится к реальности, примерно с R21, где было добавлено то самое, о чем вы просили — "две очереди", даже, скажем так три, но не для пользователя).


Потому что monitor/demonitor был ближе к константной затрате на каждый вызов (хотя при перегруженных линках и он мог давать сверхлинейные затраты по времени, но этого я уже тупо не помню).

SD>Вот именно это меня особенно смущает, "подтверждение экспериментами". Нет бы просто прочитать код и разобраться. Как это сделали мы.


Как чтение кода давало бы понять, упёрлись в кэширование или нет? Не заговаривайтесь.
The God is real, unless declared integer.
Re[18]: WA: 3 млн tcp соединений на одном сервере
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.08.20 12:03
Оценка:
Здравствуйте, SkyDance, Вы писали:

SD>Это и есть простота.

SD>Надо научиться думать асинхронно. Понять и принять это. Осознать, что именно так и работает наш мир. Мы, существа, actors, — просто посылаем сообщения. Наш мозг так работает. Он посылает сообщения. И он не блокируется в ожидании ответа, как это делает анти-паттерн "call".

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

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

И да, это стоит потери производительности по сравнению с "голым железом". Мне, как человеку, прошедшему путь от самодельного компьютера на 8080 (и это был не Радио-86РК с интерпретатором бейсика, шестнадцетиричные коды которого публиковались в журнале) до того, что мы имеем сейчас, близка и понятна боль от потерянных на высокоуровневые абстракции тактов процессора и килобайтов памяти. Но тем не менее, если мы не готовы переступить через эту боль, то мы потеряем контроль над собственным софтварием, уж больно сложным он станет, не помещающимся в голове.

В общем, я считаю, что ты изнасиловал себя. Вероятно, ты достаточно талантлив, и в этом изнасиловании себя изрядно преуспел. Но это не отменяет факта изнасилования

Подход Go, с его идеей, "заводите поток на каждый чих, компилятор разберется" мне представляется более человечным. Эти ребята, конечно, врут, что потоки Go ничего не стоят. Между прочим, они уже один раз проделывали такой трюк, когда в 60-е — 70-е считалось, что настоящие операционные системы пишут на настоящем языке программирования, на ассемблере, а они написали свой UNIX на C и ходили, всем рассказывали, что ихний Сишный компилятор почти и не уступает ассемблеру — и тоже врали, он уступал по скорости раза в два, а по памяти даже и не знаю. Но результат нам известен, сейчас все операционные системы пишутся на Си.

Go, кстати, чертовски сложный под капотом, видно, что настоящий хакер старой школы писал. Но наружу эта сложность практически не вылазит.

SD>Учили бы асинхронному мышлению.


Этому в цирковом училище учат, на отделении акробатики

SD>Учили бы разбираться в сути вещей... все было бы иначе.


А этому — в ПТУ

SD>Ладно, можно на этом закругляться. Все равно общение слегка бессмысленное. Мир идет по кругу, или по спирали, если смотреть сбоку, но суть от того не меняется. Все в итоге суета сует. Буду честным — сделать можно какой угодно софт, на какой угодно платформе, на любом языке.


Ну ОК, разговор все равно состоялся приятный.

SD>Дело лишь в профессионализме тех, кто будет этим заниматься, и в свойствах полученной системы. У меня хватает примерно увидеть то, на что способны несколько талантливых людей. И увидеть то, как на место десятка нанимается сотня, с результатами куда более печальными.


Вот это — чертова проблема. Я отношусь к тем людям, которые впятером могут гору свернуть, а потом аккуратно поставить ее на место, а жить приходится в мире, рассчитанном на массовое трудоустройство альтернативно умственно одаренных людей.

SD>И мы несем это в софт. Он тоже рождается, взрослеет, стареет, умирает. Порой долго и мучительно, см. КОБОЛ, порой с феерверками. Иногда оставляет восхитительное послевкусие, см. common lisp — я до сих пор считаю модель разработки CL куда более удобной, чем то, что происходит в С++, жаве и многом еще. Благодаря одному чертовски важному свойству, тому, что я зову instant signal, — когда сигнал от сделанного изменения виден немедленно. Это holy grail of development productivity. И он достижим на Erlang'е. Сложнее, но также и на Java, PHP, Python, еще языкам. На С++, хм, нуу... не знаю, может, стар я стал, но до того медленны нынче компиляторы, что не то что signal, а даже build, и тот не instant.


Этого я просто не понял, объясни, что ты имел ввиду. Про instant signal, а не про КОБОЛ.
Re[18]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 07.08.20 13:02
Оценка:
Здравствуйте, SkyDance, Вы писали:

SD>Это и есть простота.

SD>Надо научиться думать асинхронно. Понять и принять это. Осознать, что именно так и работает наш мир. Мы, существа, actors, — просто посылаем сообщения. Наш мозг так работает. Он посылает сообщения. И он не блокируется в ожидании ответа, как это делает анти-паттерн "call".

Если call — антипаттерн, то процесс — антипаттерн втройне. У нас нет отдельных процессов (а то, что есть — значительно сложнее). Перестаньте плодить процессы на каждый чих — это будет честно.

Но с каких это пор устройство компьютера должно следовать устройству мозга?

SD>Но как до этого просветления добраться, как довести — не знаю. Знаю лишь, что проблема лежит глубоко. В самом нашем образовательном процессе, когда с младых лет детей учат императивному стилю, синхронному программированию и т.п..


Просто потому, что оно проще.
Точно так же, как в математике стараются всё свести к линейным уравнениям, потому что нелинейные мы не умеем решать (а где решаем — сводим к линейным).
А проще — значит, подъёмнее, меньше требуется и уровня, и ресурсов. И это хорошо. Сложным надо делать только то, где это неизбежно.

SD>Учили бы в школе функциональному подходу.

SD>Учили бы асинхронному мышлению.
SD>Учили бы разбираться в сути вещей... все было бы иначе.

От "асинхронного мышления" до "разбираться в сути вещей" — "дистанции огромного размера".
А "асинхронное мышление" вон сейчас у каждого первого фронтэндера, потому что асинхронный JS асинхронно грузит асинхронные скрипты.

SD>Такова жизнь. Мы рождаемся, взрослеем, стареем, умираем.

SD>И мы несем это в софт. Он тоже рождается, взрослеет, стареет, умирает. Порой долго и мучительно, см. КОБОЛ, порой с феерверками. Иногда оставляет восхитительное послевкусие, см. common lisp — я до сих пор считаю модель разработки CL куда более удобной, чем то, что происходит в С++, жаве и многом еще. Благодаря одному чертовски важному свойству, тому, что я зову instant signal, — когда сигнал от сделанного изменения виден немедленно. Это holy grail of development productivity. И он достижим на Erlang'е. Сложнее, но также и на Java, PHP, Python, еще языкам. На С++, хм, нуу... не знаю, может, стар я стал, но до того медленны нынче компиляторы, что не то что signal, а даже build, и тот не instant.

Плюсовик сказал бы, что тот, кто залагается на немедленный результат, не научен думать и предсказывать результаты своих действий
И я частично согласен. REPL и аналоги — плодят лень. Полноценные данные собираются за такие периоды, на которых та компиляция это просто ничто.
Но это уже совсем в оффтопик.
The God is real, unless declared integer.
Re[14]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 08.08.20 00:24
Оценка:
N>Потому что туда поступили сообщения из внутренней обработки, и их надо отправить. Терять нельзя.

Напоминает проблему reliable exactly once delivery в distributed environment, а также все ту же handling overload статью.
Что значит "терять нельзя"? В случае перегрузки либо load shedding, либо backpressure, третьего не дано (или по крайней мере мне неизвестно).

N>Спасибо, что снизошли до нас, простых смертных. А все предыдущие ~15+ лет нам что делать было?


Решать конкретную проблему, попутно улучшая инструменты. Заодно — учиться.

N>Опять "мышки, станьте ёжиками". У меня совершенно конкретный вопрос: как вы предлагаете писать, чтобы не получать квадратичную зависимость затрат CPU (хотя бы) от скорости потока, в условиях подобных неоптимизируемых синхронных вызовов (которые неизбежны хоть изредка)?


Как обычно, есть варианты:
а) научиться мыслить асинхронно, и более не вспоминать про неизбежность
б) внести необходимые изменения в инструмент, сделав его доступным всем (contribute to open source)
в) научиться работать с тем, что есть

N>Роскошно. Повторю вопрос: как вы будете решать иначе?


Я уже объяснил. Можно было написать NIF-based socket, можно было реализовать backpressure, можно было разобраться и поднастроить GC. Можно было подумать про архитектуру и ее огранчиения: почему у вас строго одна выходная "труба"? Ведь это single point of failure. Это по определению ненадежно.

N>Ну-ка попробую ("давно не брал я в руки шашек", но основы помню). Итак, процесс A получает входные сообщения, процесс B отправляет пусть штатным образом через gen_tcp:send (напоминаю, socket API нам ещё не доступен). Мы защищаемся от слишком длинной очереди процесса B, передавая эту обязанность на A.


N>Очевидно, что если B передаёт каким-то образом "а ну дай следующие данные на передачу", их надо собрать одним сообщением.


Пока логично. Процесс "А" просто выгребает приходящее и складывает в iolist, или, как вариант, накапливает длинный binary (unbounded, судя по условию вашей задачи, когда "ничего терять нельзя").

N> Проблема в receive именно в количестве сообщений, а если я все передаваемые пакеты набью в одно, оно будет тяжёлым (объём данных никуда не девается), но одним. Потом процесс будет разбирать его и отправлять по кусочкам.


На этом месте следовало бы остановиться и посмотреть, как именно сделан message passing для тяжелых сообщений (точнее, binaries внутри). Само сообщение будет крошечным, и будет содержать только ref-counter pointer на binary (который лежит вообще в отдельном аллокаторе).
Иными словами, процесс "А" является ровно тем, чего вы от него и хотите — буфером. Все, что он делает, это выгребает приходящие сообщения и сериализует в большой binary. Когда процесс "В", который вызывает (потенциально блокирующийся) вызов gen_tcp:send готов что-то еще отправить, он запрашивает у "А" все, что тот успел накопить.

Позвольте мне пропустить дальнейшее описание рукопашного flow control protocol, ибо сама необходимость водружать столь сложный механизм была основна на заведомо неверном предположении. Ох неспроста "The Art of Challenging Assumptions" по статистике Whova App набрал максимум посещаемости из всех выступлений на той конференции

N>Вот это как раз тот случай, когда мы применили ETS, что вам так не нравится.


Ну, в моей практике встречались и еще более странные применения ETS. Равно как и еще более необычные side channels — скажем, вместо ETS можно было бы завести отдельный процесс (условно назовем его locker) который бы отвечал на вопрос "уже можно или еще нет". Способов организвать flow control — не счесть. И не только на Эрланге, на Java/C++/Python есть ничуть не меньше разных забавных конструкций на эту тему. Скажем, проверять глобальные флажки. А что, отличный вопрос для собеседования — поговорить о семантике volatile переменных
В общем, можно построить очень много ненужных велосипедов, если с самого начала не разобраться в задаче как следует.

Но. Хочу отдать должное, даже в самых простых решениях вроде этого самого binary buffer можно очень легко сделать ошибку. Вот пример. Прям один-в-один ваш случай, включая gen_tcp:send, и middleman-process. Неспроста я про TLS и ужасы говорил


N>Теперь: у этой системы есть свой мониторинг мониторинга.


Каждый такой пример "системы мониторинга" зачастую следствие неумения организовать supervision tree. Эта тема мне уже очень набила оскомину. Более двух лет я и лекции читаю, и мастер-классы провожу, и дизайн ревью, и code review, но, видимо, сказывается отсутствие этой темы в фундаментальном образовании программистов. Корректная организация supervision порой требует познаний в архитектуре. Выделить failure domains, договориться об SLA, о том, какие ошибки считать transient, какие permanent, и на каком периоде времени/частоте — этому всему нужно учиться. Ни в школе, ни в курсев "девелопер на РНР за 21 день" про это не рассказывают. И, кстати, зря — тема не такая и сложная, просто требует развернуть мозги, чтобы те заработали в нужном направлении. Тогда многое щелкнет и станет ясно, как именно (и, главное — ДЛЯ ЧЕГО) нужно организовать мониторинг.

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

N>Просто: пусть у нас 3 очереди


Нет, это не просто. Это как раз сложно. Просто — это когда у вас 3 процесса, и у каждого своя очередь.

N>И, что крайне важно, это всё не помешало бы всему остальному, что вы тут пишете про "правильный дизайн".


Думаю, что ваша точка зрения не имеет достаточной научной базы. Понимаю, что у вас есть вполне конкретный случай, конкретная проблема, но вот что неверно в ваших рассуждениях, вы пытаетесь решить ее не на том уровне. Не скажу что вы одиноки в таком подходе Уж сколько в моей практике приходилось рубить патчей на тему "вот у нас там проблема, но разбиратсья нам лень, но мы видимо что тремя уровнями ниже можно сделать подпорку, и плевать, что этой подпоркой мы испортим стройную модель".

N>Понимаете, почему я во втором проекте всё это выбросил, и просто перегнал на другой язык? И взлетело за 3 дня.


Понимаю, конечно. Я ровно про то и писал в стартовом сообщений этого суб-треда. Кривая обучения нелинейна — вы научились базовому синтаксису, а потом ударились о резкий рост сложности концепций. Повторяю, вы не одиноки — это действительно cliff, на который, когда заберешься, начинаешь понимать, _ПОЧЕМУ_ система получилась столь стройной и красивой.

Есть простая аналогия. Лопата и экскаватор. Кто-то с самого начала сел в экскаватор, и оказалось очень удобно в нем сидеть! Но совершенно непонятно, как этим ковшом копать. Тяжелый, неудобный. В общем, потыркаться, а потом взять лопату и за три дня выкопать канаву. Это явно быстрее, чем месяц осваивать экскаватор.
Учиться в целом очень сложная задача. Мало кто в состоянии. Это надо иметь к тому склонность.

N>И от синхронных вызовов отказаться как-то нереально. Хотя сократить их долю, да, можно.


Представляете, что было бы, если бы ваш мозг мог синхронно зависнуть, ожидая ack'а от сердечной мышцы?

N>Там есть функции пощупать, чем занят сейчас процесс (без вопроса ему самому) — собственно, process_info() с соответствующими параметрами. Если бы вы были правы, там оно показывало бы GC. Но оно не показывало GC. Так что этот фактор если и влиял, то далеко не главным.


Куда именно выс смотрели? Что именно показывали erlang:system_monitor(long_gc) ?

N>Вот именно, что ищет решения. Нашим решением для второго проекта был уход от Erlang. И не пожалели.


Очень разумный подход. Если задача в том, чтобы "быстрее сделать", выбирать надо тот инструмент, в котором разбираешься лучше всего. А если таких инструментов много, то — тот, который лучше подходит к предметной области.
Иными словами, если у вас есть программист на С++, и нужно сделать что-то небольшое и быстро, заставлять его учить Эрланг не было бы разумным подходом. Вы попытались, не осилили, вернулись к знакомым инструментам. По мне так, вполне правильный процесс, fail fast, fail early.

N>А кто вам сказал, что не были знакомы?


Могу судить только по тому, что вы тут пишете. Поскольку упоминаний научных работ не было, я (ошибочно?) предположил, что в те времена вы не изучили наработки в этой области.

N>Поставьте сами эксперимент такого же рода.


Вы описали один из test cases для off-heap message queue. В 2010 ее не было (появилась в OTP 19, то есть 5 лет назад).

N>Потом повторить на R12-R13 и на железе того времени (пусть будут Nehalem всех видов).


Нет смысла, я и так знаю, что произойдет (gc death spiral, можно найти слайды от Rick Reed'a где про это вкратце рассказывается).

Поймите важность root cause analysis. Кстати, да, тоже одна из тем, кажется, в 2019 на code BEAM SF я рассказывал про troubleshooting process и RCA. Не следует делать поспешных выводов на тему "ограничено размером кэша" и т.п.. Следует разобраться в проблеме — прочитав source code, например. И тогда уже оперировать знанием, а не ощущениями.

N>Core team — это общее понятие. Мне пофиг, как оно называется в конкретном случае — core team, cardinal crew, steering committee или как-то ещё.


Нет таких "общих понятий". И не было.

N>Ну если вы будете вместо того, чтобы помогать пусть даже на среднего качества разработке добиваться успехов, требовать высочайшего качества подготовки программистов/архитекторов/etc. — не удивляйтесь, что у вас "слишком мало драйверов роста", их больше и не будет — наоборот, будет только меньше.


К делу не относится, но здесь мне хочется поддержать Pzz,

Вот это — чертова проблема. Я отношусь к тем людям, которые впятером могут гору свернуть, а потом аккуратно поставить ее на место, а жить приходится в мире, рассчитанном на массовое трудоустройство альтернативно умственно одаренных людей.


N>У меня такого заблуждения никогда не было. Но вы вместо обсуждения технических деталей опять впали в философию, где святой дух гения помогает Эрлангу, но не помогает Джаве.


Это ваши личные домыслы. Я лишь утверждаю, что вне зависимости от языка или парадигмы, разработчик, который в состоянии challenge assumptions, который может провести root cause analysis, а затем решить проблему, на порядок более производителен "среднего качества разработчика".

Отдельный котел в аду хотелось бы приготовить для тех, кто решает проблему наворачиванием очередного слоя поверх существующих. Причем слои почти всегда leaky, без соответствующей модели, и почти никогда не в состоянии выдержать property-based testing.
Re[19]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 08.08.20 04:12
Оценка:
Pzz>Я бы поспорил. Я думаю, нам для того и нужны хитроумные инструменты, потому что наши мозги по-другому думают, чем компьютеру было бы удобно.

Разница между мозгом и компьютером в том, что мозг — гибкий.
Не у всех, конечно, а у тех, кто мозг тренировал быть гибким (см. flexible vs rigid thinking). Это хорошая тема для обсуждения Но опять ведь обвинят в уходе в философию. Конечно, все философия — до тех пор, пока не начинаешь решать реальную задачу, и работать над одной проблемой в составе команды.

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


Прекрасно сказано! Эрланг, кстати, один из примеров такого инструмента.
Но сложность в том, что к этому инструменту приходят люди, долгое время (как бы даже не всю жизнь) работавшие только с императивным подходом. И зачастую еще и с полным непониманием асинхронности мира и задач, которые требуется решить. И виноват тут не инструмент. могу рекомендовать выступление Simon Peyton Jones — про новую программу CS в британских школах. Вот это, "The revolution of computing in schools" — нашел запись здесь. То, что он делает, — если взлетит — может ощутимо изменить ландшафт софтостроения.

Pzz> Мне, как человеку, прошедшему путь от самодельного компьютера на 8080 (и это был не Радио-86РК с интерпретатором бейсика, шестнадцетиричные коды которого публиковались в журнале)


Калькулятор МК-61. Ага, от розетки который работал (но мог и пару часов протянуть на трех батарейках, только батарейки было не достать в ту пору).
На другом конце кластеры из десятков тысяч машин, работу которых может разладить единственная неудачная команда.

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

Pzz>Go, кстати, чертовски сложный под капотом, видно, что настоящий хакер старой школы писал. Но наружу эта сложность практически не вылазит.


Да-да, это уже пол-эрланга, надо еще подождать, и будет полный.

Pzz>Ну ОК, разговор все равно состоялся приятный.




Pzz>Вот это — чертова проблема. Я отношусь к тем людям, которые впятером могут гору свернуть, а потом аккуратно поставить ее на место, а жить приходится в мире, рассчитанном на массовое трудоустройство альтернативно умственно одаренных людей.


Вы только не говорите этого в какой-нибудь большой компании с глубокой иерархией. Да-да, Google, Apple, Facebook и т.п.. Нельзя вот так брать и резать правду-матку, или придется участвовать в обсуждениях про "токсичных девелоперов".

Pzz>Этого я просто не понял, объясни, что ты имел ввиду. Про instant signal, а не про КОБОЛ.


Попытаюсь в двух словах.
Суть в том, чтобы разработчик не раздражался по таким пустякам как бессмысленное ожидание.
1. Build (compile/assemble/link/...) должен быть мгновенным (200 мс и меньше). Иными словами, как только я закончил редактировать код/тест/конфиг, я не должен жать никаких кнопок, ждать 5 секунд пока взлетит компилятор, еще 10 секунд на разворачивание разных там докеров, инстанцирование чего-то еще, или запросов "а не компилировал ли кто-то где-то в интернете точно такой же код" (привет bazel).
2. Signal — подразумевается весь полезный сигнал от инструментария разработчика. То есть, lint, format, smoke tests (естественно, с test selection в соответствии с code coverage).
3. Интеграция инструментария (т.е. lint не отдельно где-то там, а прямо в IDE/vim/emacs).
4. Отсутствие любой необходимости (или полная прозрачность) "рестарта системы". Скажем, в том же эрланге, поддержка hot code load сделана по уму (а не как в java, где значительная часть попросту не работает).

И так далее. Все задачи должны выполняться за незначительное время. Чтобы потребность выпить чашечку чая возникало не потому, что "я запустил build", а потому, что чаю захотелось.
Не надо заставлять девелоперов ждать. И уж точно нельзя делать инструменты, которые заставляют человека уходить и менять контекст. Это софт пусть работает в асинхронхронном режиме. А вот процесс его разработки должен быть таким, чтобы имитировать самую что ни на есть синхронность.
Re[15]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 08.08.20 06:40
Оценка:
Здравствуйте, SkyDance, Вы писали:

N>>Потому что туда поступили сообщения из внутренней обработки, и их надо отправить. Терять нельзя.


SD>Напоминает проблему reliable exactly once delivery в distributed environment, а также все ту же handling overload статью.

SD>Что значит "терять нельзя"? В случае перегрузки либо load shedding, либо backpressure, третьего не дано (или по крайней мере мне неизвестно).

Да, тут лучше уточнить. В случае нормальной перегрузки и нормальной реакции на неё — да, управление потоком через backpressure, и его, естественно, делали. В том и дело, что проблема в случае ненормальной реакции из-за свойств рантайма, когда любая реакция на перегрузку в точке её детекта будет заведомо опоздавшей. Это вы в данной дискуссии систематически игнорируете, заменяя абстрактными словами, которые сводятся к "у нас тут своя атмосфера" и "учиться, учиться и учиться", а также "вложите 100500 человеко-часов, это пойдёт всем на пользу" (на самом деле ещё фиг его знает, и очень вероятно, что нет).

N>>Роскошно. Повторю вопрос: как вы будете решать иначе?

SD>Я уже объяснил. Можно было написать NIF-based socket,

Объём работы. Проблема поддержки этого всего.

Вы, мысля масштаба WhatsApp и Facebook, не понимаете, что при маленькой команде (а она никогда не выходила за 10 человек, из которых собственно проблемы транспорта понимали максимум 3, а ведь есть и другие задачи) постановка в духе "написать NIF-based socket" означает серьёзное увеличение затрат на разработку, поддержку и сопровождение; кроме того, она означает, что инструмент не справился с теми задачами, для которых он и был, согласно рассказам авторов, рассчитан.

Так как сочетание NIF-сокета с остальным Erlang означает, кроме того, что этот сокет должен кто-то написать и поддерживать (ладно, я бы написал, у меня "экспертизы" хватает, а дальше кто этим займётся?), ещё и отладку бутерброда и Erlang+C (а то, что отладка будет нужна — к гадалке не ходи). Это проблема всех бутербродных построений, и выигрывают те средства, в которых они не нужны как минимум для 99% базовой функциональности (вспоминаем Java, C#, Python...)

SD> можно было реализовать backpressure, можно было разобраться и поднастроить GC. Можно было подумать про архитектуру и ее огранчиения: почему у вас строго одна выходная "труба"? Ведь это single point of failure. Это по определению ненадежно.


Да вы уже, похоже, цепляетесь за всё подряд. Во втором проекте (я тут везде его так называл, пусть остаётся) единственность выходной трубы это условия вписывания во внешние условия задачи, их менять нельзя. Но даже если бы этого не было, абсолютно не вопрос надёжности, одна тут "труба" или нет: в случае любой потери надо перепосылать с точки обрыва, выкапывая первое недоставленное сообщение. И общей проблемой, наверно, 99% взаимодействий является то, что если сообщение потеряно, то его надо перепосылать. Множественные "трубы" тут ничего не дадут.

N>> Проблема в receive именно в количестве сообщений, а если я все передаваемые пакеты набью в одно, оно будет тяжёлым (объём данных никуда не девается), но одним. Потом процесс будет разбирать его и отправлять по кусочкам.


SD>На этом месте следовало бы остановиться и посмотреть, как именно сделан message passing для тяжелых сообщений (точнее, binaries внутри). Само сообщение будет крошечным, и будет содержать только ref-counter pointer на binary (который лежит вообще в отдельном аллокаторе).


Ага, то есть хорошо было бы ещё и в binary их перепаковывать, причём размера не меньше сколько-то (с какого размера там включается оптимизация)? И это на внутреннем взаимодействии (внутри одной ноды)? Вам не кажется, что это слишком большие требования для простой задачи?

SD>Позвольте мне пропустить дальнейшее описание рукопашного flow control protocol, ибо сама необходимость водружать столь сложный механизм была основна на заведомо неверном предположении. Ох неспроста "The Art of Challenging Assumptions" по статистике Whova App набрал максимум посещаемости из всех выступлений на той конференции


Я посмотрел, спасибо. Великолепный английский как для родного русского — завидую... остальное — или подробности Erlang-решений, или вода. Любой грамотный разработчик с опытом скажет то же самое, пусть и не столь красиво, но во всём этом нет ответа на главное: мы в принципе все свои действия основываем на предположениях на основании существующего опыта, и их подавляющее большинство на самом деле ничему не мешает, и менять их нереально и бессмысленно; но, после того, как надо просто выделить ресурсы на измерения и проверки того, что казалось очевидным (а ресурсы тут важны всегда, и сурово критичны — почти всегда) — остаётся определить, с чего именно начинать измерения и проверки, а это получается только с опытом в теме.
В сумме, доклад — красивый пиар вас лично и фирмы. Полагаю, что вы таки достигли поставленных для этого пиара целей.

И чем же тут было "заведомо неверное" предположение — вы не объяснили, так что ответа нет. Ответ в духе "вы предположили, что можно обойтись первыми приходящими в голову средствами и не подумать вызвать X, Y, Z, чёрта лысого, подключить библиотеку WWW243972" это не ответ, это издевательство.

N>>Вот это как раз тот случай, когда мы применили ETS, что вам так не нравится.


SD>Ну, в моей практике встречались и еще более странные применения ETS. Равно как и еще более необычные side channels — скажем, вместо ETS можно было бы завести отдельный процесс (условно назовем его locker) который бы отвечал на вопрос "уже можно или еще нет".


Дададад. "Отвечал". То есть шло бы обратно сообщение, которое вставало бы в конец очереди. Вы это серьёзно?

SD> Способов организвать flow control — не счесть. И не только на Эрланге, на Java/C++/Python есть ничуть не меньше разных забавных конструкций на эту тему. Скажем, проверять глобальные флажки. А что, отличный вопрос для собеседования — поговорить о семантике volatile переменных


И вы тут то ли намеренно ёрничаете, то ли явно не в курсе про volatile в многонитевом окружении?

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


SD>Но. Хочу отдать должное, даже в самых простых решениях вроде этого самого binary buffer можно очень легко сделать ошибку. Вот пример. Прям один-в-один ваш случай, включая gen_tcp:send, и middleman-process. Неспроста я про TLS и ужасы говорил


Перескажите словами, что происходит, если хотите понимания. Я-то ещё разберу происходящее за пару часов (TLS на Erlang никогда не заводил), но если кто ещё читает — то точно не поймёт.

N>>Теперь: у этой системы есть свой мониторинг мониторинга.


SD>Каждый такой пример "системы мониторинга" зачастую следствие неумения организовать supervision tree.


Как вы через супервизоры будете снимать набор количественных показателей работы приложения (текущие уровни, счётчики, и всё такое)? Или вы под словом "мониторинг" тут понимаете только

>> какие ошибки считать transient, какие permanent, и на каком периоде времени/частоте


?

Ню ню (tm)

Или опять ETS, который вы хотели бы устранить?

SD>Можно обсудить эти вопросы более предметно, но уж шибко много печатать придется. В общем и целом, я всегда буду задавать один и тот же вопрос — "для чего", и "какие действия принимаются на основе полученных фактов".


Я думаю, последние 20 лет вопрос "какие действия принимаются..." на основе счётчиков событий (банально, полученных/посланных сообщений по выбранной классификации, и всё такое) — просто не должен озвучиваться. Вопрос должен быть — делаются ли эти действия вообще и правильные ли они.

N>>Просто: пусть у нас 3 очереди

SD>Нет, это не просто. Это как раз сложно. Просто — это когда у вас 3 процесса, и у каждого своя очередь.

Докажите. Я объяснил, что именно достигается несколькими очередями и как оно стабилизирует работу системы. Теперь хочу послушать, каким образом вы этими 3 раздельными процессами добьётесь аналогичного результата. На всякий случай приведу ещё раз базовые условия, хотя бы в таком наборе:
1) Речь идёт об управлении конкретным процессом и его контроле через единственный, по вашим же правилам, разрешённый интерфейс в виде асинхронно поступающих сообщений. Канал через ETS не разрешаем.
2) Надо управлять этим процессом, включая регулирование параметров (оперативное! ждать секунды, пока он прочтёт сообщение, нельзя).
3) Увы, gen_call иногда (а может, и всегда) нужен из-за того, что на нём работает некоторый интерфейс, который мы менять не можем.

Если вы скажете, что надо заставлять источники группировать сообщения в большие бинарные пакеты, как выше — то это не подходит потому, что в этом случае тем более нафиг не нужно 3 процесса.

N>>И, что крайне важно, это всё не помешало бы всему остальному, что вы тут пишете про "правильный дизайн".


SD>Думаю, что ваша точка зрения не имеет достаточной научной базы.


О том, что не помешало бы? То есть у вас есть очень себе "challenging" предположение о том, что чем-то помешало бы? Хочу послушать предпосылки к этому предположению, это становится интересным А также научную базу, как от этого попортилось бы что-то

SD>Понимаю, что у вас есть вполне конкретный случай, конкретная проблема, но вот что неверно в ваших рассуждениях, вы пытаетесь решить ее не на том уровне. Не скажу что вы одиноки в таком подходе Уж сколько в моей практике приходилось рубить патчей на тему "вот у нас там проблема, но разбиратсья нам лень, но мы видимо что тремя уровнями ниже можно сделать подпорку, и плевать, что этой подпоркой мы испортим стройную модель".


И снова от вас никакой конкретики, только "стройная модель" (стройность которой на самом деле ничуть не испортит введение нескольких очередей) и ссылка на какие-то посторонние случаи, про которые ничего не известно.

N>>И от синхронных вызовов отказаться как-то нереально. Хотя сократить их долю, да, можно.

SD>Представляете, что было бы, если бы ваш мозг мог синхронно зависнуть, ожидая ack'а от сердечной мышцы?

Плохая аналогия подобна котёнку с дверцей (tm).
Ваша аналогия с организмом, повторюсь, неадекватна хотя бы потому, что в сердце и мозгу нет "процессов", аналогичных Erlangʼовым, там всё иначе. Но если вы уж начали обсуждать такими аналогиями, почитайте про основные проблемы анестезии и почему является проблемой, что регулировка дыхания мозгом неадекватна и в какой-то момент начинает работать против своей цели.

N>>Вот именно, что ищет решения. Нашим решением для второго проекта был уход от Erlang. И не пожалели.


SD>Очень разумный подход.

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

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

Ну раз вы сами подтвердили твёрдую позицию команды разработчиков и спутников, как вы — значит, ничего хорошего ожидать от инструмента далее не приходится. Остаток сообщения это подтверждает.

SD>Вы описали один из test cases для off-heap message queue. В 2010 ее не было (появилась в OTP 19, то есть 5 лет назад).


То есть пробовать не хотите? Спасибо, Ч.Т.Д.

SD>К делу не относится, но здесь мне хочется поддержать Pzz,

SD>

SD>Вот это — чертова проблема. Я отношусь к тем людям, которые впятером могут гору свернуть, а потом аккуратно поставить ее на место, а жить приходится в мире, рассчитанном на массовое трудоустройство альтернативно умственно одаренных людей.


Ну поддерживайте себе дальше. Мне уже скорее пофиг, я понял, что от Erlang тут толку не добиться, по крайней мере, пока основной состав разработчиков и управляющих (как бы вы их ни называли) не сменится. Но это, увы, типовая судьба любых проектов — их доводят до ума самые упёртые, а не отличающиеся широтой и глубиной взглядов.
А для практического применения я буду выбирать средства с максимально пологой кривой обучения (будем уже держаться в рамках этого термина), потому что полученные продукты будут выживать даже при полной смене команды.

Ну и у меня, по своему опыту, далеко не такие мрачные выводы о качестве людей (по крайней мере программистов). Может, потому, что я никогда не работал в аутсорсе.

SD>Это ваши личные домыслы. Я лишь утверждаю, что вне зависимости от языка или парадигмы, разработчик, который в состоянии challenge assumptions, который может провести root cause analysis, а затем решить проблему, на порядок более производителен "среднего качества разработчика".


Ну вот пока вы считаете "средним качеством" тех, кто не может и даже не хочет... ok, ваше дело.
The God is real, unless declared integer.
Отредактировано 08.08.2020 7:03 netch80 . Предыдущая версия .
Re[16]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 09.08.20 16:18
Оценка:
N>Вы, мысля масштаба WhatsApp и Facebook, не понимаете, что при маленькой команде (а она никогда не выходила за 10 человек, из которых собственно проблемы транспорта понимали максимум 3, а ведь есть и другие задачи)

Вы, вероятно, не поверите, но в масштабе WhatsApp "проблемами транспорта" занимается 1.5 человека. Эти же 1.5 занимаются еще и системой сборки, и багами в BEAM'е, и еще много чем кроме.

N> И общей проблемой, наверно, 99% взаимодействий является то, что если сообщение потеряно, то его надо перепосылать. Множественные "трубы" тут ничего не дадут.


Возвращемся к exactly once delivery, а также множественным реализациям tcp over tcp. Ох сколько их я видел

N>Ага, то есть хорошо было бы ещё и в binary их перепаковывать, причём размера не меньше сколько-то (с какого размера там включается оптимизация)? И это на внутреннем взаимодействии (внутри одной ноды)? Вам не кажется, что это слишком большие требования для простой задачи?


По условию задачи, вы пользуетесь gen_tcp:send(). Он на вход принимает binary(). То есть вы совершенно точно уже пакуете ваши структуры в binary(). Именно это (и только это) я и предлагаю делать в отдельном процессе, задача которого — заниматься сериализацией, и ничем более.
Вы можете честно признаться, что такое решение не пробовали?

Добавлю, что такие решения начинают появляться только после осознания аналогии между экземпляром класса в С++ и процессом в Эрланге. Равно как класс "труба" не занимается сериализацией, так и в эрланге, процесс "труба" занимается только трубой.

N>Я посмотрел, спасибо. Великолепный английский как для родного русского — завидую...


Спасибо. К сожалению, цена — некоторая потеря умения писать и говорить по-русски.

N> остаётся определить, с чего именно начинать измерения и проверки, а это получается только с опытом в теме.


И об этом я тоже говорю. Начинать надо с вопросов "зачем" (почему). До тех пор, пока не достигнем корня проблемы. К сожалению, подобные выступления всегда очень ограничены по времени, поэтому я лишь очень вскользь прошелся по critical thinking (думаю, упоминал critical thinking cards, fallacies и т.п.). Конечно, опыт важен, но еще важнее умение думать. Зрить в корень.

N>Дададад. "Отвечал". То есть шло бы обратно сообщение, которое вставало бы в конец очереди. Вы это серьёзно?


Я же говорю, что видел и более странные side channel, — не значит, что они работали как ожидалось авторами. Но, однако, из-за selective receive optimisation, — иногда и работало.

N>И вы тут то ли намеренно ёрничаете, то ли явно не в курсе про volatile в многонитевом окружении?


Я же даже поставил большой зеленый смайл. Возможно, стоило вставить смайл с "сарказмом".

N>Перескажите словами, что происходит, если хотите понимания.


Классика жанра, которую так же легко воспроизвести для вашего случая (один процесс накапливает binary buffer, второй шлет данные). Там сделана оптимизация, что процесс "трубы" перед тем как отправить данные в трубу спрашивает у сериализующего процесса "а не пришли ли еще данные". Когда данные идут непрерывно, получается бесконечный цикл, рано или поздно выедающий всю память.

N>Как вы через супервизоры будете снимать набор количественных показателей работы приложения (текущие уровни, счётчики, и всё такое)? Или вы под словом "мониторинг" тут понимаете только


См. выше, про "зрить в корень". Уровни, счетчики, "все такое" — каким это образом используется? Какие решения принимаются?

N>Или опять ETS, который вы хотели бы устранить?


Для простых счетчиков ETS уже не модно. Современные реализации обычно что-то вроде ecount, или вовсе telemetry (open telemetry)

N>Я думаю, последние 20 лет вопрос "какие действия принимаются..." на основе счётчиков событий (банально, полученных/посланных сообщений по выбранной классификации, и всё такое) — просто не должен озвучиваться. Вопрос должен быть — делаются ли эти действия вообще и правильные ли они.


Не соглашусь. Это как раз самый что ни на есть важный вопрос — "как мы используем собираемые данные". Понимаю, что дальше будет вопрос "а что нам это стоит" и "с таким ценником, а стоит ли".

N>1) Речь идёт об управлении конкретным процессом и его контроле через единственный, по вашим же правилам, разрешённый интерфейс в виде асинхронно поступающих сообщений. Канал через ETS не разрешаем.

N>2) Надо управлять этим процессом, включая регулирование параметров (оперативное! ждать секунды, пока он прочтёт сообщение, нельзя).
N>3) Увы, gen_call иногда (а может, и всегда) нужен из-за того, что на нём работает некоторый интерфейс, который мы менять не можем.

Здесь я не могу привести ничего другого, кроме как притчи:

Мастера боевых искусств спросили, как он поступит, если переходя узкий подвесной мост над пропастью, заметит засаду спереди и сзади? Мастер несколько раз сказал, что он не понимает заданного вопроса. В конце концов ученики потеряли терпение:
— Что тут непонятного? Ты на мосту, ты не можешь идти вперед, ты не можешь вернуться, ты не можешь убежать, ты не сможешь справиться с таким большим числом врагов!
— Я не понимаю, как я смогу оказаться в таком положении? — был ответ.


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

N>И снова от вас никакой конкретики, только "стройная модель" (стройность которой на самом деле ничуть не испортит введение нескольких очередей) и ссылка на какие-то посторонние случаи, про которые ничего не известно.


Потому что ваш вопрос не является вопросом, а явлется тем самым "спереди вражеские воины, и сзади, а вы на подвесном мосту". Вы сами ставите такие условия, а потом запрещаете ровно то, о чем я так давно уже говорю — "challenge your assumptions".

N>А почти все задачи начинаются с "быстрее сделать", построить MVP или какой там будет его аналог. И вот тут становится критичным, что люди, которые не разбираются во всех тонкостях, должны поднять и сопровождать проект на начальной стадии.


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

Еще раз сетую на недостатки существующей системы образования. Это заколдованный круг, когда кто-то уже научившийся императивному программированию с идиомой "call" думает, что так легче научить других. Нет, не потому, что так легче, а потому что он уже так научился. Это для него, кто уже с детства был так научен. И что он делает дальше, просто продолжает делать то, чему его научили. Тот самый fixed mindset. Который так мешает многим.

N>То есть пробовать не хотите? Спасибо, Ч.Т.Д.


Мне не нужно пробовать. Я уже объяснил, что знаю, как оно устроено и как работает. Это ключевые умения разработчиков — не просто "пробовать" и говорить "что-то где-то как-то не так", а разбираться в том, *ПОЧЕМУ* оно так.

N>А для практического применения я буду выбирать средства с максимально пологой кривой обучения (будем уже держаться в рамках этого термина), потому что полученные продукты будут выживать даже при полной смене команды.


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

Могу лишь отметить, — кто не рискует, тот не пьет шампанское
Re[17]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 09.08.20 18:43
Оценка:
Здравствуйте, SkyDance, Вы писали:

SD>— Я не понимаю, как я смогу оказаться в таком положении? — был ответ.


SD>Вы можете снова обвинить меня в философствовании, и в том, что не отвечаю на очень конкретно поставленный вопрос. Но попробуйте еще раз перечитать притчу.


Да, роскошная притча. И она показывает, что, так как вопрос "попасть в засаду с обеих сторон" это всего лишь вопрос затрат и качества сил, организованных против такого мастера, то есть по сути только один вариант положительного решения: просто не допускать ситуации, когда это возможно. В переложении на нашу обстановку — не пытаться решать задачи, которые данным средством не решаются, перекладывая их на другие средства. А как именно не допускать (не ходить самому в места, где могут быть такие засады; иметь возможность убежать; успокоить всех врагов) — уже по обстановке.

Ну вот это и совпадает с моим выводом из личного опыта, а также с тем, что говорили упомянутые в прошлых сообщениях коллеги: что Erlang не подходил изначально под эти задачи. Мне только слегка обидно, что для того, чтобы он подошёл, требовалось совсем немного изменить, но в корне... значит, не судьба.

Не вижу смысла тратиться на остаток сообщения, я его сохраню себе на память, но отвечать было бы очередным перепевом уже сказанного, так что закруглюсь. Хотя если у кого-то будут конкретные вопросы по отдельным аспектам — отвечу по мере сил и настроения.

SD>Вероятно, risk/reward у вас сдвинут в сторону меньшего риска.

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

Ну вот мы его и пили — но не с Erlang
The God is real, unless declared integer.
Re[18]: WA: 3 млн tcp соединений на одном сервере
От: night beast СССР  
Дата: 09.08.20 19:22
Оценка:
Здравствуйте, netch80, Вы писали:

N>Ну вот мы его и пили — но не с Erlang


спасибо за познавательный диалог.
стало понятно, почему эрланг не выстрелил.
Re[18]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 09.08.20 19:43
Оценка:
N>Ну вот это и совпадает с моим выводом из личного опыта, а также с тем, что говорили упомянутые в прошлых сообщениях коллеги: что Erlang не подходил изначально под эти задачи. Мне только слегка обидно, что для того, чтобы он подошёл, требовалось совсем немного изменить, но в корне... значит, не судьба.

Erlang-то подходил отлично. Просто у вас не было знаний о том, как его использовать. Простейшее решение с binary buffer, пишется за 3 часа (из которых 2 на написание автотестов, и 0.5 на документацию). Как вариант, за пару дней (но тогда уже с серьезным тестированием через property-based testing).
Поскольку нужной квалификации в 2010 у вас не было, вы приняли правильное решение делать так, как умеете.

И по нашему разговору не совсем ясно, изменилось ли что-то с 2010. Вероятно, вы остались в плену парадигм 90х.
Re[19]: WA: 3 млн tcp соединений на одном сервере
От: SkyDance Земля  
Дата: 09.08.20 19:44
Оценка:
NB>стало понятно, почему эрланг не выстрелил.

Для тех, кому не стало понятно, хотелось бы узнать, почему. Кроме очевидного "за 3 дня мы не научились, а больше времени не было".
Re[20]: WA: 3 млн tcp соединений на одном сервере
От: night beast СССР  
Дата: 09.08.20 19:55
Оценка:
Здравствуйте, SkyDance, Вы писали:

NB>>стало понятно, почему эрланг не выстрелил.


SD>Для тех, кому не стало понятно, хотелось бы узнать, почему. Кроме очевидного "за 3 дня мы не научились, а больше времени не было".


потому что людям нужно решать реальные задачи, а не бороться с языком из-за того что твоя задача не вписывается в стандартные шаблоны.
Re[19]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 09.08.20 20:21
Оценка:
Здравствуйте, SkyDance, Вы писали:

SD>Erlang-то подходил отлично. Просто у вас не было знаний о том, как его использовать. Простейшее решение с binary buffer, пишется за 3 часа (из которых 2 на написание автотестов, и 0.5 на документацию). Как вариант, за пару дней (но тогда уже с серьезным тестированием через property-based testing).


Это не "простейшее". Это костыли на обход заведомых недостатков рантайма. Те самые сложные решения, о уходе от которых вы так красиво тут расписываете.

(Блин, собирался же закрыть тему... ладно, ещё немного попрыгаем.)

SD>Поскольку нужной квалификации в 2010 у вас не было, вы приняли правильное решение делать так, как умеете.


Спасибо на этом.

SD>И по нашему разговору не совсем ясно, изменилось ли что-то с 2010. Вероятно, вы остались в плену парадигм 90х.


Наоборот, мы от них ушли
The God is real, unless declared integer.
Re[22]: WA: 3 млн tcp соединений на одном сервере
От: night beast СССР  
Дата: 09.08.20 20:41
Оценка:
Здравствуйте, SkyDance, Вы писали:

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


SD>А, стало быть, опять "трясти надо" (С) анекдот.


не, тут бы еще какая-нибудь притча лучше подошла...

SD>Вот пока вы "решаете реальные задачи", другие пишут WhatsApp.


смотри, как бы не пришлось в один прекрасный день писать WhatsApp в одно лицо.
Re[3]: WA: 3 млн tcp соединений на одном сервере
От: elmal  
Дата: 09.08.20 21:29
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Подождем Skydance'а. Он как раз performance engineer в wa.

А какое отношение имеет максимальное количество сокетов к соединениям? Если что, сейчас
в моде (и это больше 5 лет точно как мода) держать на одном сокете до хрена соединений. У каждого запроса свой UUID. каждый сокет работает как event loop, там нет никаких синхронных операций, он отдает ответ мгновенно (почти, там из ресурсоемкого только зачастую поиск в хеш мапе). Да, сами обработчики могут занимать значительное время, причем на один запрос могут тратиться даже не минуты, а часы и даже дни. Но за счет асинхронного API время работы обработчика по существу пофиг, его состояние нужно только держать в памяти, зачастую персистентной, чтоб если ноде киржык другая нода подняла и ничего снаружи не было бы заметно.
Re[4]: WA: 3 млн tcp соединений на одном сервере
От: Sharov Россия  
Дата: 09.08.20 22:33
Оценка:
Здравствуйте, elmal, Вы писали:

E> в моде (и это больше 5 лет точно как мода) держать на одном сокете до хрена соединений.


И как это возможно на одном сокете логически демультипликсировать запросы разных пользователей? Сколько запросов, столько сокетов.
И каким образом API сокета знает про UUID? Т.е. речь идет об http, и как сокет будет собирать для каждого отельного http-запроса пакеты?
Т.е. этот пакет для UUID такого, этот для такого... Как это возможно с одним сокетом?
Кодом людям нужно помогать!
Re[4]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 10.08.20 04:23
Оценка:
Здравствуйте, elmal, Вы писали:

E>А какое отношение имеет максимальное количество сокетов к соединениям? Если что, сейчас

E> в моде (и это больше 5 лет точно как мода) держать на одном сокете до хрена соединений. У каждого запроса свой UUID. каждый сокет работает как event loop, там нет никаких синхронных операций,

Это уже вы что-то очень странное пишете. Начнём с того, что термин "соединение" (connection) применяется к TCP, но не к UDP, где принято "ассоциация" (association). Но на TCP, со стандартным BSD sockets API (которое повторено в Linux, в Windows с поправкой на WSA*, и пр.), для установленного соединения вам насильно выдадут отдельный сокет. Объединять несколько соединений в одном сокете там невозможно. А другого API пока что не завезли (а если вспоминать считаем вымерший XTI, то и там было по endpointʼу на соединение).

Для UDP, да, похоже на то, что вы описываете. Но и ограничения от этого соответствующие: например, вы не можете, не поменяв порт (и соответственно сокет) со своей стороны, распределить нагрузку между несколькими слушателями без хитрых примочек уже уровня ОС по тому, на какой сокет (одного порта) пойдут запросы от конкретного IP. Это проблема, например, с QUIC.

И "свой UUID у каждого запроса" это специфика небольшого количества особых протоколов. Например, DNS, SIP, с поправкой на то, что такое UUID для конкретного случая. Уже QUIC сюда слабо подходит.

E>он отдает ответ мгновенно (почти, там из ресурсоемкого только зачастую поиск в хеш мапе). Да, сами обработчики могут занимать значительное время, причем на один запрос могут тратиться даже не минуты, а часы и даже дни. Но за счет асинхронного API время работы обработчика по существу пофиг, его состояние нужно только держать в памяти, зачастую персистентной, чтоб если ноде киржык другая нода подняла и ничего снаружи не было бы заметно.


И это тоже какая-то очень странная специфика, которая не повторяется практически нигде. Если вы не в курсе, то сейчас >95% (если не >99%, не помню точно цифры) это потоки медии и HTTP всех видов, как веб напрямую, так и API+RPC поверх HTTP транспорта. А там запросы длительностью в часы и дни тупо нереальны.

В общем, немного интересно, где вы нашли такую дикую комбинацию свойств местности, но это никак даже не третий по типичности вариант
The God is real, unless declared integer.
Re[5]: WA: 3 млн tcp соединений на одном сервере
От: elmal  
Дата: 10.08.20 04:59
Оценка:
Здравствуйте, netch80, Вы писали:

N>В общем, немного интересно, где вы нашли такую дикую комбинацию свойств местности, но это никак даже не третий по типичности вариант

Ну, относительно соединений — в геймдеве соединение как минимум иногда считается так, как я сказал. Как минимум для мобильных или браузерных гриндилок, для танчиков там другой механизм. Никакой сокет не блокируется, игрок быстренько отдал данные, быстро получил. Все API stateless. В запросе передается UUID игрока, ну и дополнителько контрольная сумма пакета по хитрому ключу, на сервере, чтоб игроки не читили, если контрольная сумма не совпадает, игрок автоматом отправляется в бан.
Re[6]: WA: 3 млн tcp соединений на одном сервере
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 10.08.20 05:10
Оценка:
Здравствуйте, elmal, Вы писали:

E>Здравствуйте, netch80, Вы писали:


N>>В общем, немного интересно, где вы нашли такую дикую комбинацию свойств местности, но это никак даже не третий по типичности вариант

E>Ну, относительно соединений — в геймдеве соединение как минимум иногда считается так, как я сказал. Как минимум для мобильных или браузерных гриндилок, для танчиков там другой механизм. Никакой сокет не блокируется, игрок быстренько отдал данные, быстро получил. Все API stateless.

Тогда это, скорее всего, UDP.

E> В запросе передается UUID игрока, ну и дополнителько контрольная сумма пакета по хитрому ключу, на сервере, чтоб игроки не читили, если контрольная сумма не совпадает, игрок автоматом отправляется в бан.


Ну там точно нет многосуточных запросов
The God is real, unless declared integer.
Re[7]: WA: 3 млн tcp соединений на одном сервере
От: elmal  
Дата: 10.08.20 05:26
Оценка:
Здравствуйте, netch80, Вы писали:

N>Ну там точно нет многосуточных запросов

Там могут быть тяжелые фоновые задачи вроде полного пересчета статистики. При этом запрос на получение статистики отрабатывает мгновенно, только не возвращает локальную статистику, а результат полного пересчета будет виден сильно позднее, там будет возвращаться предыдущее значение.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.