Email or username:

Password:

Forgot your password?
Aleksei � Matiushkin

Just out of curiosity, how do you architect a sticky singleton across cluster in your language of choice?

E. g. the only one simultaneous connection to the external source is allowed, but to handle data we need several nodes. How do we ensure there is the only one connection (downtime is not allowed.)

Thanks in advance. Most wanted solutions: java, go, node.

30 comments
Aleksei � Matiushkin

@3draven был бы очень признателен за ссылку / объяснение, как это принято делать на джаве

s1dul

@mudasobwa @3draven мне кажется, либо я не понимаю условий, либо задача шатает cap теорему.

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

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

kurator88

@s1dul @mudasobwa @3draven мне кажется что на akka концептуально легче всего будет такое сделать, она вроде из коробки сама умеет в кластер и разные ноды. Правда akka на java очень коряво пишется, лучше на scala. На go вообще быстро в голову ничего не приходит.

Aleksei � Matiushkin

@kurator88

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

Меня интересовало архитектурное решение, и акка, к сожалению, решает кластерный синглтон очень плохо.

@s1dul @3draven

s1dul

@mudasobwa @kurator88 @3draven как делал бы я:
Завести легкрвесный контейнер в одном инстансе и рассчитывать, что рестартоваться будет за приемлемое время.

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

Aleksei � Matiushkin

@s1dul у меня BEAM, я могу без локфайла напрямую спросить, жив ли процесс, у соседней ноды.

Но часто-часто долбиться куда-либо — это за гранью, я лично разворачиваю PR не глядя, если там есть вызов sleep, хочется все-таки один раз получить входящее сообщение «теперь ты главный».

@kurator88 @3draven

Aleksei � Matiushkin

@s1dul я понимаю, что если выключится электричество во всех датацентрах, или норвежские строители опять переебут атлантический кабель экскаватором, как в 1997, все будет плохо.

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

Про синглтон в акка я читал, там все плохо.

@3draven

Roman

@mudasobwa Слишком краткое описание. Непонятно, что значит "простои не допускаются". Простои кого именно? Источника данных? Кластера обработки? Или каждой ноде в кластре нельзя ждать освобождения источника?

Но в целом я бы просто посмотрел на Spark или Hadoop, либо на Zookeeper (или аналоги) и не проектировал их работу сам. Решать задачи выбора лидера дело непростое и делать это в сотый раз думаю смысла нет, уже делали. Ну или если надо "почти сам" akka.

Aleksei � Matiushkin

@3draven источник шлет нам стопиццот сообщений в секунду через вебсокет; хочется пропустить в случае факапа как можно меньше сообщений.

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

Спасибо!

Узнать бы еще , как там гошники это решают :)

Roman

@mudasobwa Джава это готовые решения. Очень надо большое обоснование что бы пилить свое решение. Что уж тут, таков путь :)

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

Aleksei � Matiushkin

@3draven заворачиватель потока в кафку не может навернуться?

Aleksei � Matiushkin

@3draven спарк тоже не очень понятно, как поможет переконнектиться, если упадет то, что прицеплено в вебсокету

Roman

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

Aleksei � Matiushkin

@3draven вебсокет один, потому что второй будет стоить еще 15К в месяц, провайдер данных фактически монополист.

Клиент упал, по какой-то причине. Кто его перезапустит? Причем тут вообще кафка?

Roman

@mudasobwa обычно кубер перезапускает, да это не та задача о которой я подумал. До дела бы дошло я бы еще сто раз потестил и подумал, но скорее всего это был бы редис в кубере, распределеная блокировка спринговая, он их умеет (и поверх постгри вроде) и несколько подов, что ее ждут наготове что бы не ждать перезапусков. Я такое не делал, просто первое, что подумалось.

Kirill

@mudasobwa

Либо я не понял вопрос, либо по FLP такое сделать нельзя. (консенсус эквивалентен детектору сбоев)

Aleksei � Matiushkin

@kirillgrachoff ну, не вообще нельзя ни на микросекунду потерять соединение, но переконнектиться надо в пределах миллисекунд, если нода померла

Kirill

@mudasobwa
Решения лучше чем "возьмём консенсус и подтюним heartbeat'ы до 10ms" придумать не могу. Если в каждый момент времени нужно не более 1 процесса (нельзя разъезжаться по состоянию), то без консенсуса/leader election тут не обойтись. По FLP возможен live lock, так что может быть такое (в теории), что сервиса не будет очень долго.

Aleksei � Matiushkin

@kirillgrachoff

> Если […] не более 1 процесса […] без консенсуса/leader election тут не обойтись

Вот уж воистину, во многой мудрости — много печали. Консенсус тут не нужен, как следствие — FLP impossibility вообще ни при чем.

Мне не нужно ни о чем договариваться. Нода №1 померла — нода №2 это увидела и начала сосать данные вместо нее, а в дороге сообщила нодам №№3–N, что теперь она главная.

Алгоритм «кто-первый-встал-того-и-тапки» — не нуждается в консенсусе и потому FLP не подвержен.

Kirill

@mudasobwa
В таком случае возможно 2 лидера (точнее, 2 процесса, каждый из которых считает себя лидером и принимает операции на запись). Если это подходит, то ладно, FLP и консенсус реально не нужны.

Aleksei � Matiushkin

@kirillgrachoff нет, невозможно; только в условиях сплита сети, но там и консенсус облажается, и в ECS обычно сплитов все-таки не бывает.

Kirill

@mudasobwa
В случае сплита сети консенсус не облажается: majority будет в одной половине. Да, если сплит будет каким-то жёстким, консенсус встанет.

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

Возможно, я что-то не понимаю. Для меня пока модель выглядит так:
1. Нода понимает, что лидер лёг.
2. Нода бежит рассказывать всем, что она лидер.

1. Действительно правильный failure detector эквивалентен консенсусу. Если хватит просто какого-то приближения, то хватит и heartbeat'ов.
2. Если нода бежит рассказывать близнецам, что она лидер, то мы переизобретаем консенсус. Не надо это делать. Есть single decree Paxos (надеюсь, не ошибся в названии). Если же она идёт в какой-то внешний сервис, то в этом внешнем сервисе консенсус.

В общем, возможно и невозможно сделать быстрый leader election без погружения в недра системы.

@mudasobwa
В случае сплита сети консенсус не облажается: majority будет в одной половине. Да, если сплит будет каким-то жёстким, консенсус встанет.

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

Возможно, я что-то не понимаю. Для меня пока модель выглядит так:
1. Нода понимает, что лидер лёг.
2. Нода бежит рассказывать всем, что она лидер.

Kirill

@mudasobwa
А где будет записано, что "первым встал" процесс №2?

Aleksei � Matiushkin

@kirillgrachoff конкретно в моем случае — BEAM cluster — нигде экплицитно это записано не будет, просто я запускаю на всех нодах процесс с именем `{:global, Consumer}` и первый запустится и вернет `pid`, а все последующие попытки получат обратно `{:error, {:already_started, pid}}` и всё.

Тут за меня BEAM все сам сделает, проблема только в мониторинге.

github.com/am-kantox/solo/blob

Kirill

@mudasobwa
Значит, в BEAM написан консенсус (либо у них есть точка роста, и можно им нанести там пользу). Тогда где-нибудь в BEAM Cookbook (не знаю, есть ли такая) написано, как следить за тем, что процесс не упал.

(у меня 0 знаний, кроме тех, что BEAM - это что-то про Erlang и поднятие акторов)

Aleksei � Matiushkin

@kirillgrachoff у меня нет никаких проблем с моей экосистемой; я уже давно написал код, который работает, протестирован, и вообще с ним все хорошо.

Мой вопрос звучал так: как сие решают на джаве, го и ноде.

Ответ «консенсус» — это хороший ответ, я приму его к сведению. На го, скорее всего, иначе действительно никак, но везде, где есть виртуальная машина — консенсус в хер не вперся, VM вполне себе в курсе, что, где и как.

А когда падает VM, об этом тут же узнает сервер соединений, и тоже ок.

Kirill

@mudasobwa
А, понял.

Либо etcd, либо Zookeeper часто используют, если это не критично. Если критично, то велосипедят свой консенсус на C++.

𝖋𝖑𝖔𝖗𝖎𝖓

@mudasobwa — ah that’s ez, with OTP you can use … oh w8… java, go, node you said .. ok nvm .. gg 😅

Go Up