Распредчан

⭕️ Anonymous Распредчан 24.10.2025 03:25 #70970

4 октября 2025 года было сказано приступить к проектированию распределённого чана.

Эта нить посвящена проблемам, обсуждению их и публикации новостей по данному проекту.

Распредчан - это кодовое название механизма синхронизации данных между держателями нод нашего чана.

Нода - ресурс, предоставляющий интерфейсы для server2server и server2client взаимодействий, где s2s - связь между нодами, а s2c - связь между нодой и интерфейсом, например между pissykaka и pissychan-front.

Какие проблемы мы хотим решить?

  • Независимое хранение постов без централизации оного в руках полутора анонов.

  • Распределённое хранение файлов.

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

Мы открыты к предложениям, обсуждению и критике данного проекта.

Ответы:
>>70992
>>71002

⭕️ Anonymous 24.10.2025 12:35 #70985

На данный момент мы заняты разработкой системы прав доступа нод.

Одно из предложений звучит так:

> Касательно прав нод у меня такое виденье.> Ноды могут обладать правами:
  • Чтения досок, постов и файлов с других нод - думаю, всем нам проще и спокойнее будет обмениваться данными только с известными нодами.

> 2. Анонс новых постов и файлов.> 3. Анонс новых досок.> 4. Анонс паспортов и отзыв их.> Система прав основана на договоре держателей нод о том, какие евенты они шлют друг другу и обрабатывают.> Удаление постов и файлов - на усмотрение держателей нод. Не хочешь хостить капоп-тред - не хостишь, капоп хостят и просматривают/постят в него на другой ноде. На твоей ноде капопа нет вообще. Файл существует до тех пор, пока хотя бы одна нода его хранит(или он закешировался в IPFS, что сомнительно и недолго).
Ответы:
>>1765862322137210

⭕️ Anonymous 24.10.2025 12:36 #70986

Блядь, попердолил разметку.

Ну вы понели, где и что.

🔰 kugichka Верхнеуровневое видение списка эвентов. 24.10.2025 18:04 #70992

>>70970

Есть: доски, треды/посты, файлы, паспорта

Эвенты доски:

  • создание доски

  • удаление доски

  • модификация метаданных доски (tag, имя, скрыто-статус, etc)

Так же следует отметить следующие кейсы:

  • когда одна из нод содержит исключительно свою доску, эта часть ноды (доска) перестаёт считаться частью сети, эвенты не фиксируются в кафке, а всевозможные коллизии разруливаются хостом ноды

  • сейчас доски имеют свой id в качестве идентификатора, и будет перекат в использование tag в качестве идентификатора

Эвенты постов:

  • создание поста

  • удаление поста (физическое, не модерация)

  • изменение метаданных поста (текст, медиа, updated_at)

  • перемещение оп-поста на другую доску

Эвенты файлов:

  • создание файла

  • изменение меты файла (при модерации например, чтобы вести на заглушку после удаления)

  • удаление файла (физическое опять же)

Эвенты паспортов:

  • создание паспорта

  • разделегирование паспорта (aka удаление)

Эвенты на будущее:

  • смена паблик ключа для подписей/идентификации ноды

Ответы:
>>70993
>>71198

🔰 kugichka 24.10.2025 18:05 #70993

>>70992

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

🔰 kugichka 25.10.2025 00:20 #71002

>>70970

Done: https://github.com/U-Me-Chan/raspredach-schemas

летс дискас

⭕️ Anonymous 31.10.2025 04:15 #71198

>>70992
> когда одна из нод содержит исключительно свою доску, эта часть ноды (доска) перестаёт считаться частью сети, эвенты не фиксируются в кафке, а всевозможные коллизии разруливаются хостом ноды

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

Ответы:
>>71282

⭕️ Anonymous 02.11.2025 05:54 #71282

>>71198

А можно да. А что ты подразумеваешь под «явным выбором»?

Ответы:
>>71292

⭕️ Anonymous 02.11.2025 15:29 #71292

>>71282

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

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

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

Ответы:
>>71301

⭕️ Anonymous 03.11.2025 07:24 #71301

>>71292

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

⭕️ Anonymous 04.11.2025 03:40 #71323

Что ж, я полуркал информацию о том, как можно выполнять верификацию подписи автора поста в распределённой модели.

Напоминаю, что я вижу проблему в таком кейсе:

  • Нода N1 выпустила новый паспорт K1.

  • Пользователь создал пост с подписью от K1.

  • N1 отправила евент о посте в кафку.

  • При попытке отправки евента о новом паспорте N1 упала, и евент не был зафиксирован.

  • N2 синхронизирует события с N1, в них содержится пост с подписью от K1, но у N2 нет K1 для верификации.

  • Что делать?????

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

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

Сейчас используется алгоритм хеширования SHA256 - https://github.com/U-Me-Chan/umechan/blob/master/chan-api/src/Posts/Post/PasswordHash.php#L47C21-L47C21

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

Ответы:
>>71324
>>71335

⭕️ Anonymous 04.11.2025 03:44 #71324

>>71323

Ох, я ввёл в заблуждение.

Для паспорта используется SHA512. SHA256 используется для хеша пароля поста.

⭕️ Anonymous 04.11.2025 18:36 #71335

post media
>>71323

Вообще да. Статуса сейчас да: верифицирован, не верифицирован; добавляется третий. Approved!

Ответы:
>>71336

⭕️ Anonymous 04.11.2025 18:36 #71336

>>71335

/s/сейчас да/сейчас два

⭕️ Anonymous 20.11.2025 19:43 #71770

@kugichka, ты предполагаешь, что события в кафке не удаляются никогда?

Ответы:
>>71782

🔰 kugichka 21.11.2025 07:58 #71782

>>71770

Не предполагаю, а щито?

Ответы:
>>71784

⭕️ Anonymous 21.11.2025 12:14 #71784

>>71782

А как новые ноды будут синкать старые посты?

Ответы:
>>71785

⭕️ Anonymous 21.11.2025 12:27 #71785

>>71784

Это хороший вопрос. Мне тут на работе архитектор микросервисов сказал, что юзать кафку для синхронизации данных ПОВЕРХ уже существующих -- самое то, а вот чтобы с нуля восстановить состояние -- кафку не юзают, типа она ваще не для этого. Из тех же рабочих кейсов: тимлид просто присылает дамп бд стейджа, ну или сам вытягиваешь если доступ есть. Это хуйня решение, но чисто технически самое простое.

Тот же чел посоветовал механизм запилить, типа, условный GET /db/all (с ключом ноды) и оно отдаёт всё что есть на текущий момент. При условии, конечно, что ты не всю базу отдаешь за раз, а по отдельным табличкам, при том с оффсетами-лимитами.

Ответы:
>>71786

⭕️ Anonymous 21.11.2025 12:30 #71786

>>71785

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

Ответы:
>>71804

⭕️ Anonymous 21.11.2025 22:05 #71804

>>71786

Да, давай договоримся так, «месяца хватит всем», ящитаю.

⭕️ Anonymous 16.12.2025 09:18 #1765862322137210

>>70985

Мне не нравится IPFS по многим причинам:

  • Большой транзитный трафик.

  • Невозможность инкрементальных бекапов штатными средствами.

  • Трудности с деплоем на публичных хостингах - BitTorrent обычно запрещён правилами.

  • Нет возможности организовать приватную сеть из коробки.

Ответы:
>>1765862866083682

⭕️ Anonymous 16.12.2025 09:27 #1765862866083682

>>1765862322137210
> инкрементальные бекапы

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

⭕️ Anonymous 26.12.2025 04:48 #1766710102977458

Что ж. Лог мыслей.

Я развернул локально Kafka-ноду в режиме KRaft, пописял в тестовый топик сообщениями с помощью консольных скриптов продюсера и консьюмера, входящих в поставку образа apache/kafka с Dockerhub.

Пытался завести kafka-ui - не вышло, находящиеся в одной подсети контейнер кафки и кафка-юайя не видят, штоли, друг друга.

Полюркал насчёт библиотек для работы с Kafka в PHP - есть по сути лишь одна (актуальная), она требует отдельного PECL-модуля.

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

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

Очень много настроек самой кафки, в которых я пока нифига не понимаю.

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

Ответы:
>>1766711966605713
>>1769282673099122

⭕️ Anonymous 26.12.2025 05:19 #1766711966605713

>>1766710102977458
> Полюркал насчёт библиотек для работы с Kafka в PHP - есть по сути лишь одна (актуальная), она требует отдельного PECL-модуля.

...и я не могу его собрать, т.к. он требует в alpine linux librdkafka-dev, который гвоздями прибит к openssl, вместо которого у меня используется libressl-dev для решения проблемы сборки модуля memcached. Уф. Перекатывать образ на бубунту снова?

Ответы:
>>1766750005523988

⭕️ Anonymous 26.12.2025 15:53 #1766750005523988

>>1766711966605713

Сегодня выяснил, что для модуля memcached уже не надо libressl-dev, он собирается и без этого. Крутяк!!

⭕️ Anonymous 30.12.2025 11:53 #1767081231441257

@kugichka, почему мы свои инстансы кафки не можем объединить в единый кластер, например? Ты такую схему и предполагал?

Получается же три пути:

  • Единый кластер. Каждая нода потребляет и продюссирует в локальный инстанс кафки.

  • Каждая нода продюссирует сообщения в локальную кафку и потребляет из удалённой кафки.

  • Перед удалённой кафкой есть какое-то API? Не, бред какой-то же.

Расскажи свой взгляд.

Ответы:
>>1768062026241065

🔰 kugichka 10.01.2026 20:20 #1768062026241065

>>1767081231441257

Ну, вот второй варик и предлагал.

Ответы:
>>1768292495026871

⭕️ Anonymous 13.01.2026 12:21 #1768292495026871

>>1768062026241065

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

⭕️ Anonymous 24.01.2026 22:22 #1769278946216015

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

Ответы:
>>1770017776401876

⭕️ Anonymous 24.01.2026 23:24 #1769282673099122

>>1766710102977458

Эти два дня я боролся с проблемой, присущей PHP. У меня не успевали некоторые события, если их несколько на запрос, складываться в Kafka. При этом, если я делал sleep(2) после выполнения операции отправки очереди сообщений в брокер, до всё доходило! Дрожащими руками полез в Сеть, и нашёл параметр socket.timeout.ms, который(неочевидно из названия) отвечает за время блокировки сокета брокером(?). Это время применяется к операции чтения расширением librdkafka из сокета, а также как часто основной тред расширения будет проверять, является ли сокет terminated. Посоветовавшись с некоторыми материалами Сети, нейродаунов и issues на гитхабе расширения, выяснил, что стандартное время установлено в 1000, а ежели его установить в меньшее по совету источников, то сообщения будут приходить во-вре-мя. Выглядит как рабочее колдунство; смущает.

Полюркал инфу про аутентификацию консумеров, интересует прежде всего SASL/PLAIN, т.к. он не требует многих телодвижений с java keystore и форматами сертификатов. Пока не осилил. Боюсь обосраться в этом моменте, а ведь мне торчать этой полуголой жопой как минимум для одного адреса в Сети.

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

⭕️ Anonymous 02.02.2026 11:36 #1770017776401876

>>1769278946216015

Разберём причины появления такого инцидента и пути решения.

Почему могут расходится БД pissykaka и epds?

  • В pissykaka приходит запрос на создание поста.

  • Pissykaka кладёт пост в БД, затем пытается отправить евент в брокер.

  • Брокер упал/не сделали flush/другое.

  • Теперь пост есть на pissykaka и нет в edps.

Самый глупый способ разрешения:

  • К chan.kugi.club приходит запрос на получение определённого поста.

  • Поста нет в epds.

  • chan.kugi.club отдаёт 404 с надписью "возможно, такого поста не было никогда либо он ещё не синхронизирован".

  • epds делает запрос к pissykaka по HTTP и вытягивает данные поста.

Сетевое взаимодействие, отсутствие гарантии доставки евента, неоднородные сообщения состояния.

Способ второй:

  • Каждый пост обладает статусом, который принимает такие значения: "Локальный", "Синхронизирован", "В процессе".

  • Если мы сохранили пост в БД, то затем некий сервис получает такие посты и отправляет евенты брокеру, обновляя затем статус поста. Получаем что-то вроде Outbox курильщика.

Много операций записи, отдельный сервис-продюсер.

Способ два с половиной, оутбокс с очередью.

  • Принимаем запрос, складываем его в in-memory очередь навроде memcached, redis, etc.

  • Сервис затем складывает их в БД и кафку.

Отдельный сервис, отсутствие гарантии сохранности поста при падении сервиса очереди.

Способ третий:

  • При обработке запроса на запись данных поста мы гарантируем, что отдадим 201 тогда и только тогда, когда пост будет сохранён в БД и будет отправлен евент в кафку. Если кафка упала - откатываем транзакцию в БД.

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

Почему расходятся epds и pissykaka, version 2:

  • epds и chan.kugi.club с пару месяцев являются лидером.

  • pissykaka подняли

  • Надо как-то синхронизироваться, в кафка евенты уже протухли.

  • pissychan как-то должен узнать, кто лидер. (epds и pissykaka должны как-то решать, кто из них лидер и когда. Балансер? Роунд-робин? А мы федерацию делаем или мастер-слейв?)

  • epds и pissykaka должны иметь идентичный REST API для c2s-коннектов с pissychan и другими.

Бекендер вернётся с другими неприятными мыслями через некоторое время.

Ответы:
>>1770076703417562

⭕️ Anonymous 03.02.2026 03:58 #1770076703417562

>>1770017776401876

Оффсет сохраняется для конкретной партиции топика и consumer group_id! Ранее я считал, что оффсет привязан лишь к партиции - это не так. Следовательно, два потребителя могут читать из одного топика и одной партиции независимо сообщения, сохраняя оффсет в кафку manual путём, т.е., без автокоммита.

Я боялся, что в случае разрастания сети придётся либо отправлять сообщения в разные топики/партиции, увеличивая количество I/O операций на процесс обработки запроса создания поста, либо строить сеть по принципу тунеллирования - новая нода синхронизируется epds, тот синхронизируется с pissykaka для равномерного распределения подключений.

Но полученная инфа всё меняет. Я могу спокойно при обработке запроса использовать механизм распределённой транзакции:

  • Открыть транзакцию в СУБД.

  • Записать туда данные поста.

  • Отправить сообщение в Kafka.

  • Если при отправке в Kafka произошла ошибка - выполнить rollback у СУБД, отдать неуспешный ответ клиенту. Возможно, положить обработку сообщения в отдельный топик "на потом".

  • Если всё успешно - закрыть транзакцию в СУБД, отдать успешный ответ клиенту.

> epds и pissykaka должны иметь идентичный REST API для c2s-коннектов с pissychan и другими.

Совершенно необязательно. @Oxore может просто решить зависить всегда от стабильности pissykaka, как сейчас, и не имплементировать интерфейс к epds.

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

⭕️ Anonymous 11.02.2026 04:12 #1770768777726367

С грехом пополам и с помощью alice.yandex.ru я смог настроить механизм SASL/PLAIN для порта Kafka, который у меня будет принимать коннекты от внешних консумеров. SASL/SSL не хочу, надо будет либо выпускать самоподписанные сертификаты, либо готовить PEM-сертификат из моего публичного. Как решение, попробую проксировать соединение к Kafka с помощью Nginx в режиме stream proxy.

Починенные евенты скоро.