Эшу быдлокодит
298 subscribers
135 photos
12 videos
7 files
170 links
Дневник C# разработчика.

Личка: @EshuMarabo
Гитхаб: https://github.com/vladzvx

Стек: C#, PostgreSQL
加入频道
Sphagnum. Часть 4. Техобзор. Репликация и отказоустойчивость в PostgreSQL.
#sphagnum@eshu_coding

PostgreSQL предоставляет два вида репликации: физическую и логическую. Физическая репликация создаёт полную копию master-ноды, из которой при желании можно читать, но писать нельзя. Между нодами передаются байтики, записываемые в WAL. В режиме одиночного инстанса WAL удаляется после применения транзакции к данным. При включенной физической репликации - WAL сохраняются дольше и по мере необходимости отдаются репликам.

Логическая репликация передает между инстансами SQL команды. В контексте разработки брокера сообщений - не интересна.

Из коробки механизма поддержания отказоустойчивого кластера в постгресе нет, но есть сторонние решения, например - patroni. Каждому из инстансов replica-set-а постгресов закрепляется по надзирающему сервису. Эти сервисы общаются между собой. В случае падения мастера - выбирается новый мастер, простым голосованием. Прочёл про интересный механизм: если мастер остается изолирован от других реплик, он не начинает думать что он единственный такой в мире, а принудительно гасится patroni, дабы минимизировать шансы грядущей синхронизации двух мастеров.

Итого, из того, что мне пока хотелось бы взять для своего проекта:
1. Механизм распространения WAL для синхронизации.
2. Принудительное гашение мастера при изоляции его от остальной части кластера.

#sphagnum_theory@eshu_coding
#postgresql
🔥1
Sphagnum. Часть 5. Техобзор. Репликация и отказоустойчивость в MongoDB
#sphagnum@eshu_coding

MongoDB в качестве механизма репликации использует распространение между ведомыми нодами oplog-а. Изменения сперва записываются в WAL (Journaling в терминологии MongoDB), затем применяются к master-у (primary node), а затем - записываются в oplog - operation log - отдельную коллекцию (таблицу), из которой асинхронно расходятся по репликам (secondary).

Для организации отказоустойчивого кластера достаточно средств самой MongoDB. Кластер представляет собой primary-ноду и некоторое количество реплик. По ситуации могут быть добавлены специальные инстансы монги для поддержания целостности кластера: один или несколько arbiter. Выбор нового мастера может осуществляться двумя путями:
1. Совместным голосованием оставшихся в живых secondary инстансов
2. Голосованием с участием арбитров.

Ноды в replica set-е раз в две секунды пингуют друг друга. Если какая-то нода не отвечает 10 секунд - она объявляется недоступной. В случае, если это - primary, одна из нод может запустить выборы. Ноды имеют приоритет в очереди на престолонаследие и неравные веса голосов: целое число, минимум - 0, дефолт - 1.

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

Итого, из того, что мне пока хотелось бы взять для своего проекта:
1. Механизм вето запуска голосования.
2. Использование арбитров мне пока видится избыточным, но при проектировании системы стоит предусмотреть такую роль на будущее.

#sphagnum_theory@eshu_coding
#mongodb
😁1
Sphagnum. Часть 5. Техобзор. Репликация и отказоустойчивость в RabbitMQ
#sphagnum@eshu_coding

RabbitMQ поддерживает создание отказоустойчивых кластеров, но есть небольшой нюанс. Сообщения в обычных очередях не передаются между инстансами. То есть мы имеем отказоустойчивый кластер из 3 кроликов. С мастера на реплики продублированы все настройки, пользователи и т.д. Приходит в RabbitMQ цунами из сообщений, мастер ест их пока не захлебнется, а потом падает. И тут на его месте возникает радостная реплика с криками "я новый мастер, я!" и начинает работу. А данные, зависшие в старом мастере - ну когда-нибудь может быть будут отработаны и переданы. Правда, есть специальные очереди, Quorum Queues, сообщения между которыми таки распространяются по репликами и в случае нештатной ситуации таки будут отработаны. По дефолту такие очереди реплицируются по трем инстансам, но можно настроить и большее количество.

Занятно организовано голосование за право быть новым мастером. Когда мастер пропадает, реплики начинают кричать "я новый мастер!", кто успел крикнуть первым - тот и становится мастером. Если голоса равны, происходит повторное голосование. Я конечно утрирую, но логика примерно такая.

Итого, из того, что мне пока хотелось бы взять для своего проекта:
1. Идея разделения данных на реплицируемые и нет - огонь, но в качестве дефолта я бы взял реплицируемые.
2. Механизм голосования довольно забавный, но тут довольно сомнительно.

#sphagnum_theory@eshu_coding
#rabbitmq
🤡1
Sphagnum. Часть 6. Техобзор. Репликация и отказоустойчивость в Kafka
#sphagnum@eshu_coding

Кафка по умолчанию сохраняет все сообщения, которые проходят через нее. У каждого сообщения есть свой offset - его порядковый номер. Соответственно, реплики в случае отставания просто просят у мастера "дай мне все сообщения больше моего оффесета". Если отставания нет - получают их в режиме реального времени. По умолчанию сообщение может быть отправлено клиенту только после того, как все реплики подтвердят его получение. Kafka старается поддерживать реплики в состоянии in-sync replicas (ISR), то есть когда состояние реплик идентично.

Выбор нового мастера в случае отказа предыдущего осуществляются инстансом Кафки, имеющим статус Controller-a. Если контроллер оказался мертв, оставшиеся в живых реплики пытаются на скорость занять его место, кто успел - тот и новый контроллер. Из группы реплик, находящихся в статусе ISR выбирается один лидер, через которого осуществляется дальнейшая работа.

Итого, из того, что мне пока хотелось бы взять для своего проекта:
1. Мне очень понравилась идея хранить историю сообщений и по ситуации отдавать ее с определенного offset-а.
2. Идея ISR тоже хороша.

#sphagnum_theory@eshu_coding
#kafka
Sphagnum. Часть 6. Техобзор. Репликация и отказоустойчивость в Tarantool
#sphagnum@eshu_coding

Тарантул изначально проектировался как решение, которое можно без боли (ха-ха) раскатать в бесконечное по размеру облако. Вообще, про взаимодействие между инстансами можно почитать вполне себе неплохую статью на Хабре. Если кратко, инстансы обмениваются друг с другом "слухами" о происходящих событиях по UDP (с помощью механизма SWIM) и формируют картину мира текущее состояние кластера. В случае падения мастера, выборами занимаются специальные инстансы тарантула, имеющие роль failover coordinator. Текущее состояние кластера сохраняется или в etcd (распределенное хранилище ключ-значенин) или в специфическом инстансе тарантула.

И также неплохая статья про механизм репликации. Если коротко - между мастером и репликами распространяется журнал WAL мастера. При том, распространяется отдельными процессами, живущими рядом с основным тарантулом, по процессу на реплику. Репликация может осуществляться как асинхронно (транзакция считается выполненной до того, как все реплики подтвердят получение данных), так и синхронно. Для синхронной репликации используется алгоритм Raft.

Что мне очень понравилось в тарантуле - удобный ui для создания и управления кластером (входит в Tarantool Cartridge). В нем можно проставить репликам как дефолтные роли (failover coordinator, master, replica, router), так и пользовательские, включающие определенный набор "таблиц" и хранимок. При желании, этот же ui можно использовать для написания или правки хранимых процедур и распространения обновлений по кластеру. Все команды ui также могут быть продублированы в виде скриптов в командной строке (что я и делал).


Итого, из того, что мне пока хотелось бы взять для своего проекта:

1. UI + дублирующие консольные команды, позволяющие создать кластер без боли. И выбор ролей инстансов через UI - тоже огонь.
2. Идея обмена слухами о происходящем в кластере хороша.

#sphagnum_theory@eshu_coding
#tarantool
👍1
Sphagnum. Часть 7. Техобзор. Репликация и отказоустойчивость в NATS
#sphagnum@eshu_coding

NATS - брокер сообщений, написанный на Go как альтернатива мейнстримным решениям - RabbitMQ и Apache Kafka. Отличительная особенность - он может подключаться в приложения, разрабатываемые на Go как dll-ка. Собственно, этот проект и вдохновил меня на разработку своего брокера сообщений. Изначально NATS был легковесным
Standalone решением, не предполагающим
кластеризацию и персистентное хранение данных. Но вскоре эти
механизмы также завезли,
породив по сути два NATS-а - классический и с наворотами. В чём-то это
похоже на развитие Tarantool.

NATS в кластерной версии, как и Tarantool, использует алгоритм Raft для выявления лидера. Кроме того, данные, попавшие в инстанс, отдаются только его непосредственным соседям. А соседи дальше их не передают. Так формируются Stream groups - группы инстансов внутри кластера с синхронизированным состоянием. Впрочем, как я понял, есть пути пустить данные дальше. Аналогично могут формироваться Consumer groups - группировки инстансов по подключенным клиентам-подписчикам. Как я понимаю (возможно ошибочно), таким образом может достигаться ограниченное горизонтальное масштабирование. В NATS данные могут сохраняться как на диск, так и в СУБД, например - постгрес.


Итого, из того, что мне пока хотелось бы взять для своего проекта:

1. Мне очень понравилась идея дополнительной сегментации вроде бы единого кластера.
2. Идея сохранения данных не на диск, а в СУБД выглядит очень интересно, по крайней мере на этапе разработки, чтобы отложить в сторону вопросы оптимальной укладки данных на жёсткий диск.

#sphagnum_theory@eshu_coding
#nats
Вот и закончилась первая часть обзора. Я не ставил себе целью досконально описать каждый из продуктов, для моих целей достаточно общего понимания предметной области.

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

#sphagnum_theory@eshu_coding
Попробую посмешить богов и в этом году. Планы на 2024 год.

1. Читать умные книжки:
- Рихтер
- Внедрение зависимостей на платформе .Net (Симан, ван Дерсен)
- Чистая архитектура (Роберт Мартин)
- Высоконагруженные приложения (Мартин Клеппман)


2. Осознать до конца некоторые архитектурные загибы:
- Аспекто-ориентированное программирование
- Акторы
- Углубиться в DDD

3. На практике освоить магию Source Generators - на этапе компиляции c# проекта, компилятор по заранее заданным правилам анализирует созданное им, на основании анализа генерирует некоторое количество нового c# кода, компилирует снова вместе с генеренным кодом и так сколько настроишь раз.

4. Таки потыкать алгоритмы, задачки на литкоде.

5. Добраться до кода с пет проектом #sphagnum.

6. Добраться до кода с пет проектом #cthulhu

7. Есть желание переписать и перезапустить #палантир@eshu_coding.
👍3🔥1
Sphagnum. Часть 8. Фиксация концепции.
#sphagnum@eshu_coding

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

А пока хочу изложить несколько концепций, которые ложатся в основу проекта.

1.  Создаю гибрид Apache Kafka и RabbitMQ. Логика организации маршрутизации сообщений будет такова:
Exchange и очереди, как в RabbitMQ, с ключами маршрутизации (Routing key). Пока планирую два вида Exchange - один отдает сообщения во все очереди с соответствующим ключем, второй - в одну, выбранную случайным образом. При этом, Exchange хранит всю прокачанную историю сообщений, как это делает Кафка.

2. Данные бэкапятся на диск в виде WAL. Скорее всего будут жить страницами минимум по 4Кб, если сообщение туда влезает. Если нет - отдельная страница для отдельного сообщения.

3. Очередь хранит в себе номер страницы WAL и id сообщения. Хочу попробовать сделать два вида очередей: классическую FIFO и стек - LIFO.

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

5. Алгоритм выборов нового мастера внутри кластера в случае падения пока мне видится следующим:
a) При синхронной репликации выбирается наименее проблемный инстанс.
b) При асинхронной - наименее проблемный из имеющих последнюю версию данных.
Конфликты, когда все параметры кандидатов одинаковы решаются жребием:)

Со временем планирую добавить горизонтальную масштабируемость, но пока по ней есть только сырые идеи.
👍4🤔2👏1
Sphagnum. Часть 9. Доска задач и репозиторий.
#sphagnum@eshu_coding

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

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

Затем я подумал о Гитлабе. Весь нужный функционал есть, но вспомнил, сколько мороки с администрированием и настройкой и расхотел.

Зашёл на гитхаб - ux не очень. Быстро (в течение 2 минут) сделать минималистичный канбан в проекте не удалось.

Тогда я решил причаститься Gitea. Доска конкретного репозитория создалась за минуту, коммиты прилинковались, чек листы в задачах удобные. Зеркалирование на гитхаб настроилось мгновенно.

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

#gitea
#cicd
#devops
👍9👏1
Пожалуй пришло время обновить закреплённый пост. Каналу уже 5 лет, с прошлого закрепа изменилось многое.

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

За прошедшие 5 лет я сменил 4 места работы:
1. Фирма, занимающая АСУ ТП в области учёта ресурсов.
2. Медтех стартап в Сколково, делали системы поддержки принятия врачебных решений.
3. Сеть общепита, делал бэкенд службы доставки.
4. Банк, текущее место работы. Работаю в домене клиентских карточек.

Мой технологический стек:
C#, PostgreSQL. Плотно работал с MongoDB, RabbitMQ, Tarantool, умею строить базовую инфраструктуру: логи (Loki), метрики (Prometheus), девопсятина (gitlab, gitea, github actions, docker).

Поверхностно знаком с Apache Kafka, MS SQL и фронтовыми фреймворками - React.js и AvaloniaUI.

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

Далее будет навигация по каналу.

Общие теги:
#csharp@eshu_coding - общий тег для постов про разные аспекты разработки на языке программирования c#
#postgresql@eshu_coding - разные интересные моменты про PostgreSQL.
#devops@eshu_coding - мои эксперименты в девопсятине и инфраструктуре.
#mongodb@eshu_coding - записки про MongoDB.
#tarantool@eshu_coding - заметки про Tarantool.

Pet - проекты:
#палантир@eshu_coding - завершенный проект, которым я занимался весь 2021 год - поисковик по телеграму.
#sphagnum@eshu_coding - попытка написать свой брокер сообщений, пока застопорилась на стадии изучения теории и прототипирования по причине нехватки времени.

Книги:
#рихтер@eshu_coding - заметки и конспекты по основополагающей книге про C# - CLR via C#. Программирование на платформе Microsoft .NET Framework 4.5 на языке C#, Джеффри Рихтер. Хоть .NET 4.5 вышел до моего появления в IT, внутренности платформы во основном остались прежними.

Конспекты прослушанных выступлений на конференциях:
#dotnext@eshu_coding - Dotnext 2023
#highload@eshu_coding - Highload++ 2024

Шпаргалки и мои заметки для подготовки к собеседованиям #собес@eshu_coding

Природа и путешествия #природа@eshu_coding #путешествие@eshu_coding
7👍6🔥2👎1