Lamport Timestamp
В далёком 1978 году Leslie Lamport предложил простой и эффективный способ определения порядка событий в распределённой системе. Позже этот алгоритм так и назвали: Lamport Timestamp. Давайте разберёмся, как данный алгоритм можно использовать на практике. В качестве примера рассмотрим прикладную задачу.🛠
Контекст
Существует таблица, где в качестве первичного ключа используется целочисленный идентификатор. Это типичная и привычная ситуация для монолитных баз данных (PostgreSQL, MySQL и т.п.). Подобные базы имеют встроенный механизм автоматической генерации целочисленных идентификаторов, который можно подключить при создании таблицы. Многие распределённые базы не имеют подобной функциональности, также как и ACID-транзакций, а в качестве первичного ключа предлагают использовать UUID.
Предположим, что по каким-то причинам нет возможности использовать UUID в качестве первичного ключа. Например, производится миграция из существующей монолитной базы в распределенную.
Один из вариантов решения — внешний генератор последовательности. Например, всё та же монолитная база (см.
Проблема
Несколько экземпляров приложения (далее для краткости — клиентов) обращаются к распределённой базе данных с целью добавления новых записей, присваивая каждой уникальный целочисленный идентификатор. При этом база данных не поддерживает ACID-транзакции. В этих условиях нужно решить задачу генерации уникальной согласованной целочисленной последовательности в распределённой среде. Любые коллизии недопустимы.
Решение
В целевой базе данных создать таблицу
🕚
🕚
🕚
Таблица хранит именованные пары
В качестве примера будем использовать Apache Cassandra:
1️⃣ Увеличение счётчика
Каждый клиент знает имя последовательности, имеет уникальный идентификатор и хранит максимальное значение последовательности, о котором он знает. Для генерации нового значения выполняется UPDATE-запрос вида:
Запись обновится только в том случае, если текущее значение совпадает со значением, которое было известно клиенту.
2️⃣ Проверка счётчика
Для проверки успешности обновления счётчика выполняется SELECT-запрос:
Клиент запоминает полученное актуальное значение последовательности и сравнивает свой уникальный идентификатор с полученным. Если идентификаторы идентичны, значит, предыдущий запрос выполнен успешно и можно использовать полученное значение. Если идентификаторы отличаются, значит, нужно повторить все действия с первого шага.
Для минимизации обращений к базе данных и количества возможных конфликтов крайне рекомендуется, чтобы клиент резервировал диапазон значений.
📱 Реализация подхода умещается в один небольшой файл. Пример написан на Java для Apache Cassandra, но его легко можно портировать на любой другой язык и базу данных.
Плюсы
Наипростейшая реализация. База данных полностью самодостаточна.
Минусы
При запросе диапазонов значений возможны некоторые пропуски из-за перезапуска клиента.
〰️ 〰️ 〰️
P.s. Сталкивались ли вы с подобной проблемой на практике и как её решали? 😉
#tip #db
В далёком 1978 году Leslie Lamport предложил простой и эффективный способ определения порядка событий в распределённой системе. Позже этот алгоритм так и назвали: Lamport Timestamp. Давайте разберёмся, как данный алгоритм можно использовать на практике. В качестве примера рассмотрим прикладную задачу.
Контекст
Существует таблица, где в качестве первичного ключа используется целочисленный идентификатор. Это типичная и привычная ситуация для монолитных баз данных (PostgreSQL, MySQL и т.п.). Подобные базы имеют встроенный механизм автоматической генерации целочисленных идентификаторов, который можно подключить при создании таблицы. Многие распределённые базы не имеют подобной функциональности, также как и ACID-транзакций, а в качестве первичного ключа предлагают использовать UUID.
Предположим, что по каким-то причинам нет возможности использовать UUID в качестве первичного ключа. Например, производится миграция из существующей монолитной базы в распределенную.
Один из вариантов решения — внешний генератор последовательности. Например, всё та же монолитная база (см.
SEQUENCE); какой-либо координатор (ZooKeeper, etcd и т.п.); распределённые кэши. Обычно используют то, что уже есть в окружении. Основной недостаток — счетчик может быть сброшен независимо от базы, в которой он используется. Например, в следствии восстановления базы из бэкапа.Проблема
Несколько экземпляров приложения (далее для краткости — клиентов) обращаются к распределённой базе данных с целью добавления новых записей, присваивая каждой уникальный целочисленный идентификатор. При этом база данных не поддерживает ACID-транзакции. В этих условиях нужно решить задачу генерации уникальной согласованной целочисленной последовательности в распределённой среде. Любые коллизии недопустимы.
Решение
🗂 Иллюстрация шагов алгоритма приведена в заголовке статьи.🔼 Клиенты A и B пытаются последовательно увеличить на 1 значение счетчика c в базе, изначально полагая, что значение этого счетчика равно 0. При обращении к базе каждый из клиентов отправляет свой уникальный идентификатор n.
В целевой базе данных создать таблицу
counters с тремя колонками:name — имя последовательности;node — уникальный идентификатор клиента;value — последнее использованное значение последовательности.Таблица хранит именованные пары
(node,value), которые и являются Lamport Timestamps.В качестве примера будем использовать Apache Cassandra:
CREATE TABLE counters (
name text PRIMARY KEY,
node uuid,
value bigint
)
Каждый клиент знает имя последовательности, имеет уникальный идентификатор и хранит максимальное значение последовательности, о котором он знает. Для генерации нового значения выполняется UPDATE-запрос вида:
UPDATE counters SET
node = <client UUID>,
value = <new value> -- <old value> + 1
WHERE name = <seq name>
IF value = <old value>
Запись обновится только в том случае, если текущее значение совпадает со значением, которое было известно клиенту.
Для проверки успешности обновления счётчика выполняется SELECT-запрос:
SELECT node, value
FROM counters
WHERE name = <seq name>
Клиент запоминает полученное актуальное значение последовательности и сравнивает свой уникальный идентификатор с полученным. Если идентификаторы идентичны, значит, предыдущий запрос выполнен успешно и можно использовать полученное значение. Если идентификаторы отличаются, значит, нужно повторить все действия с первого шага.
Для минимизации обращений к базе данных и количества возможных конфликтов крайне рекомендуется, чтобы клиент резервировал диапазон значений.
Плюсы
Наипростейшая реализация. База данных полностью самодостаточна.
Минусы
При запросе диапазонов значений возможны некоторые пропуски из-за перезапуска клиента.
P.s. Сталкивались ли вы с подобной проблемой на практике и как её решали? 😉
#tip #db
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍2⚡1
Чего не написано - того нет
Такую фразу неустанно повторял мой преподаватель в университете. Так он учил нас правильно воспринимать требования в задачах по электротехнике. 😃 Однако я благополучно применяю этот принцип до сих пор и в разных сферах. В нужный момент позволяет остановить галлюцинирование и пойти за уточнением требований. 😃 Особенно хорошо принцип работает в программировании: если вы долго не можете придумать название компоненту, наиболее вероятно, его не существует в природе, остановитесь!🚩 Это серьезный звонок, игнорирование которого чаще всего приводит к неоправданному усложнению решения. Если вы уверены, что это не так, то можно вас поздравить. В очень редких случаях подобная ситуация — свидетельство того, что вы открыли для себя то, чего не знали ранее. Эрик Эванс назвал это результатом переработки (дистилляции) знаний предметной области, который обычно сопровождается качественным скачком в архитектуре. Если это так, то стойте на своем! Однако и в том, и в другом случае нужно быть крайне осторожным, осмотрительным, сделать паузу, выдохнуть и еще раз проанализировать ситуацию. Лучше всего начать с обсуждения с кем-то из своей команды, а далее эскалировать возникший вопрос по мере необходимости.
#view
Такую фразу неустанно повторял мой преподаватель в университете. Так он учил нас правильно воспринимать требования в задачах по электротехнике. 😃 Однако я благополучно применяю этот принцип до сих пор и в разных сферах. В нужный момент позволяет остановить галлюцинирование и пойти за уточнением требований. 😃 Особенно хорошо принцип работает в программировании: если вы долго не можете придумать название компоненту, наиболее вероятно, его не существует в природе, остановитесь!
#view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4💯2🔥1🤝1
Event Storming
Как и многим, мне нравятся простые визуальные нотации, с помощью которых можно быстро понять суть дела. Считаю, что за такими инструментами будущее. Поэтому на прошедшей онлайн-конференции NextConf в центре моего внимания был доклад и воркшоп по Event Storming (не путать с Event Sourcing). Сам метод мне знаком, но всегда была интересна практическая часть. Поделюсь своими открытиями.
Кто не в курсе, скажу, что Event Storming — это визуальная нотация для описания (бизнес- и не только) процессов. Описание делается на (онлайн) доске с помощью стикеров. Стикеры — разноцветные, каждый цвет имеет свой смысл. Стикеры выкладываются на доске слева направо, т.е. в направлении невидимой временной оси. Такая цепочка служит описанием последовательности действий какого-то процесса. За свою простоту, понятность и эффективность метод получил признание среди системных аналитиков и архитекторов и активно набирает популярность. Помимо этого, он очень хорошо сочетается с техниками DDD, что в том числе помогает визуально идентифицировать Bounded Contexts (и наглядно находить границы микросервисов).
Теперь важные моменты, на которые обратили внимание опытные пользователи Event Storming.
Этапы встреч
⭐️ Обсуждение проблематики (Big Picture). Состав: представители бизнеса, владелец продукта, бизнес- и системный аналитик, возможно, архитектор.
⭐️ ⭐️ Обсуждение бизнес-процессов (Processing Model). Состав: уменьшается количество представителей бизнеса, добавляются технические специалисты.
⭐️ ⭐️ ⭐️ Проектирование решения (Software Design). Состав: исключаются представители бизнеса, только архитекторы, разработчики и технические специалисты.
Перед встречей
☑️ Обозначить цель и ограничить время. Будет гораздо продуктивней, если до начала встречи каждый подумает на обозначенную тематику, а в идеале — подготовится.
☑️ Продумать и ограничить состав участников. Собираем только тех, у кого есть вопросы и у кого есть на них ответы. Меньше людей — больше фокус на результате.
Во время встречи
☑️ Выбрать ведущего. Не принципиально, кто им будет. Чаще всего - это наиболее опытный пользователь Event Storming.
☑️ Объяснить правила. Этот шаг необходим только в том случае, если имеется участник, который не знаком с Event Storming.
☑️ Напомнить про цель и ограничение по времени. Это коллективное мероприятие, своеобразный "мозговой штурм". Четко поставленная цель и жесткие временные рамки позволяют сфокусироваться на результате и не распыляться. Не успели, значит, планируем еще одну встречу. В итоге это дисциплинирует.
☑️ Убедиться в понимании поставленной цели. Опыт показывает, что многие приходят неподготовленными. Поэтому до начала нужно устранить все недопонимания. В противном случае некоторые участники не смогут внести свой вклад в результат, и их ресурс будет потрачен впустую.
☑️ Заставьте работать всех. Если кто-то молчал, пусть зачитывает стикеры, проверяя логичность цепочки действий. Это позволяет вовлечь в процесс всех, даже самых застенчивых. Они могут молчать, но иметь важное мнение.
☑️ Главное - добиться цели. Суть не в детализации, а в ответе на поставленный вопрос. По этой причине можно опускать детали (стикеры), которые очевидны или несущественны.
Шаги проведения "Big Picture"
1️⃣ Неструктурированное исследование. Выписываем все события предметной области, которые приходят в голову. Фокус — на позитивных сценариях. Каждое событие формулируется в прошедшем времени (заказ оформлен, оценка получена и т.п.). Порядок и структура не важны, фиксируем всё без фильтрации.
2️⃣ Выстраивание событий в хронологическом порядке. Упорядочиваем все собранные события в хронологическом порядке. Проверяем логичность последовательности; читаем цепочку слева направо и наоборот. Ориентируемся только на то, что написано на стикерах.
3️⃣ Поиск ключевых событий. Выбираем ключевые события. Определяем наиболее важные события с точки зрения бизнеса. Они влияют на ход процесса, меняют состояние системы, разделяют модель на смысловые блоки. Их визуально укрупняют или выделяют.
#conf #arch #tools
Как и многим, мне нравятся простые визуальные нотации, с помощью которых можно быстро понять суть дела. Считаю, что за такими инструментами будущее. Поэтому на прошедшей онлайн-конференции NextConf в центре моего внимания был доклад и воркшоп по Event Storming (не путать с Event Sourcing). Сам метод мне знаком, но всегда была интересна практическая часть. Поделюсь своими открытиями.
Кто не в курсе, скажу, что Event Storming — это визуальная нотация для описания (бизнес- и не только) процессов. Описание делается на (онлайн) доске с помощью стикеров. Стикеры — разноцветные, каждый цвет имеет свой смысл. Стикеры выкладываются на доске слева направо, т.е. в направлении невидимой временной оси. Такая цепочка служит описанием последовательности действий какого-то процесса. За свою простоту, понятность и эффективность метод получил признание среди системных аналитиков и архитекторов и активно набирает популярность. Помимо этого, он очень хорошо сочетается с техниками DDD, что в том числе помогает визуально идентифицировать Bounded Contexts (и наглядно находить границы микросервисов).
Теперь важные моменты, на которые обратили внимание опытные пользователи Event Storming.
Этапы встреч
Перед встречей
Во время встречи
Шаги проведения "Big Picture"
#conf #arch #tools
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2🤝1
Слабая или сильная изоляция транзакций (1/2)
Сегодня я решил затронуть больную и холиварную для многих тему. Но я не вижу иного варианта для пятницы, после очередного сезона Podlodka. Поэтому предлагаю ознакомиться с тезисами и приступить к обсуждению или, по крайней мере, задуматься. 😃
😮💨 Слабая изоляция
Использование более слабого уровня изоляции транзакций не всегда означает компромисс между согласованностью данных и производительностью выполнения запросов. Всё зависит от данных и выполняемых операций. Поэтому в некоторых случаях слабый уровень изоляции действительно может бескомпромиссно обеспечить лучшую производительность.😛
Наряду с этим считается, что более слабая изоляция подходит для большинства ситуаций, а разработчики приложений должны быть достаточно прозорливыми, чтобы выявлять случаи, когда требуется более сильная изоляция, и использовать её по мере необходимости.😏
На практике я не видел примеры удачного жонглирования уровнями изоляции. В лучшем случае запросы на чтение идут с одним уровнем, а на запись — с другим. Чаще всего ультимативно используется что-то типа Read Committed, а прозорливость начинает просыпаться только в момент, когда не проходит интеграционный тест или кто-то находит ошибку.
Данная ситуация усугубляется в том числе разночтениями SQL-стандарта при реализации уровней изоляции. Мартин Клеппманн также подмечает, что это создает неопределенность для разработчиков в понимании того, есть ли в коде приложения ошибки.
В свою очередь, гонки по данным — одна из самых противных ошибок. Её сложно обнаружить и воспроизвести. И зачастую совсем непросто понять, что пошло не так, чтобы исправить.❤️ Пока что не созданы надёжные и удобные инструменты для обнаружения подобных ошибок. А из этого можно сделать вывод, что слабый уровень изоляции — это очень большой кредит, который берет на себя разработчик.
💪 Сильная изоляция
Сильные уровни изоляции транзакций исключают многие аномалии. Возможные баги в большинстве своём будут связаны с бизнес-логикой, а не со спецификой работы базы данных. Такие ошибки хорошо отлавливаются на этапе автоматизированного тестирования. Сам же код становится более простым, не содержащим различных ухищрений, нацеленных на борьбу с аномалиями.😛
Да, старые версии реляционных баз данных приучили нас, что сильные уровни изоляции, такие как Serializable, ставят крест на производительности. Но время не стоит на месте, и технологии хранения развиваются. Например, с появлением SSI, MVCC, Calvin и т.п. реализация Serializable стала намного производительней, чем на базе блокировок.💪
Также не стоит забывать, что концепция ACID-транзакций не подразумевает компромиссов относительно изоляции. Уровни изоляции — это компромисс между согласованностью и производительностью, на который разработчик должен пойти осознанно. Но зачем идти на компромиссы до того, как будет сделано первое нагрузочное тестирование и собраны первые метрики? Как мне кажется, это резонный вопрос.👔
#db #arch
⬇️ ⬇️ ⬇️ ⬇️ ⬇️
Сегодня я решил затронуть больную и холиварную для многих тему. Но я не вижу иного варианта для пятницы, после очередного сезона Podlodka. Поэтому предлагаю ознакомиться с тезисами и приступить к обсуждению или, по крайней мере, задуматься. 😃
Использование более слабого уровня изоляции транзакций не всегда означает компромисс между согласованностью данных и производительностью выполнения запросов. Всё зависит от данных и выполняемых операций. Поэтому в некоторых случаях слабый уровень изоляции действительно может бескомпромиссно обеспечить лучшую производительность.
Наряду с этим считается, что более слабая изоляция подходит для большинства ситуаций, а разработчики приложений должны быть достаточно прозорливыми, чтобы выявлять случаи, когда требуется более сильная изоляция, и использовать её по мере необходимости.
На практике я не видел примеры удачного жонглирования уровнями изоляции. В лучшем случае запросы на чтение идут с одним уровнем, а на запись — с другим. Чаще всего ультимативно используется что-то типа Read Committed, а прозорливость начинает просыпаться только в момент, когда не проходит интеграционный тест или кто-то находит ошибку.
Данная ситуация усугубляется в том числе разночтениями SQL-стандарта при реализации уровней изоляции. Мартин Клеппманн также подмечает, что это создает неопределенность для разработчиков в понимании того, есть ли в коде приложения ошибки.
В свою очередь, гонки по данным — одна из самых противных ошибок. Её сложно обнаружить и воспроизвести. И зачастую совсем непросто понять, что пошло не так, чтобы исправить.
Сильные уровни изоляции транзакций исключают многие аномалии. Возможные баги в большинстве своём будут связаны с бизнес-логикой, а не со спецификой работы базы данных. Такие ошибки хорошо отлавливаются на этапе автоматизированного тестирования. Сам же код становится более простым, не содержащим различных ухищрений, нацеленных на борьбу с аномалиями.
Да, старые версии реляционных баз данных приучили нас, что сильные уровни изоляции, такие как Serializable, ставят крест на производительности. Но время не стоит на месте, и технологии хранения развиваются. Например, с появлением SSI, MVCC, Calvin и т.п. реализация Serializable стала намного производительней, чем на базе блокировок.
Также не стоит забывать, что концепция ACID-транзакций не подразумевает компромиссов относительно изоляции. Уровни изоляции — это компромисс между согласованностью и производительностью, на который разработчик должен пойти осознанно. Но зачем идти на компромиссы до того, как будет сделано первое нагрузочное тестирование и собраны первые метрики? Как мне кажется, это резонный вопрос.
#db #arch
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
Слабая или сильная изоляция транзакций (2/2)
Естественно, существуют разные данные, разные профили нагрузок, и нет единственно верного решения. Решая задачу, мы также принимаем во внимание свой опыт, без этого никуда. Поэтому вышенаписанное — это не призыв к использованию сильных уровней изоляции транзакций по умолчанию, это, скорей, повод задуматься.
#db #arch
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥2
Инструменты Techlead Crew
Прошедший выпуск Podlodka Techlead Crew был посвящен межсервисному взаимодействию. Как и всегда, были и знакомые вещи, и не очень. В конечном счете, невозможно знать и помнить обо всём. Вот и я выписал себе очередной набор инструментов, которые показались мне крайне интересными. Чем и спешу поделиться.🚀
🤝 Contract First
Продолжаю наблюдать популяризацию идеологии Contract First. С ростом компании растет количество сервисов и продуктов, что неминуемо приводит к необходимости их интеграции и согласования работ между командами разработки. Идеология Contract First — один из инструментов для решения этих проблем, масштабирования компании и процессов. Тема абсолютно не новая, но с популяризацией микросервисов и изобилием протоколов и технологий межсервисного взаимодействия вновь начала набирать популярность.
Взяв курс на Contract First, очень важен вопрос выбора инструментов, поскольку они должны унифицировать процесс, контролировать его и ускорять. Иначе говоря, хотелось бы иметь какой-то стандарт или общий подход к описанию API (хотя бы на уровне компании), возможность верифицировать спецификации (делать ревью, архитектурный контроль, тестирование контрактов) и создавать их максимально быстро и удобно.
⚙ TypeSpec
⚙ AsyncAPI
⚙ OpenAPI-diff
⚙ Spring Cloud Contract
⚙ Pact
Несмотря на существование достойной инструментальной поддержки, ряд коллег высказывают озабоченность. Во-первых, остается вопрос, кто именно должен создавать и развивать спецификации (архитектор, системный аналитик, техлид, разработчик). Во-вторых, спецификация сильно оторвана от кода (реальной жизни), что может вызвать проблемы на уровне её реализации. Отсюда вытекает третье сомнение: при большом числе интеграций создание спецификаций вручную выглядит ресурсоемким и опять же может разъехаться с реализацией. Иначе говоря, было сделано предположение, что в идеале спецификация должна определяться на языке, на котором ведется разработка, тогда это сократит "разрыв" до нуля. В конечном счете сошлись на том, что универсального решения не существует и каждый ведёт дела так, как ему удобно.
✍️ Implementation
В современной практике очень часто можно встретить необходимость гетерогенного хранения данных или необходимость в транзакционной логике при выполнении бизнес-процессов с участием нескольких (микро)сервисов. Всё выглядит так, что Temporal позволяет достаточно быстро добавить Saga в существующий проект, особенно если он написан без использования таких структурообразующих фреймворков, как Spring.
Еще одна интересная, но очень сложная задача — это сервис push-уведомлений. Если вы не можете или не готовы использовать какой-нибудь облачный сервис, то писать свою реализацию, пожалуй, не самый лучший вариант. В такой ситуации на помощь приходит Centrifugo.
👀 Observability
Было очень много сказано про техники обеспечения прочности и устойчивости. Два ярких момента, на которые я обратил внимание.
1️⃣ Крупные компании стараются перекладывать всё больше ответственности с кода на инфраструктуру. Например, выполнение некоторых повторов (Retry) можно возложить на инфраструктуру. Однако на этом уровне имеет смысл повторять только HTTP 5xx.
2️⃣ Распределенная трассировка на базе OpenTelemetry — это неотъемлемая часть современного приложения.
При этом было отмечено, что очень важно не маскировать бизнес-ошибки за кодами HTTP 2xx (например, "HTTP 200 Недостаточно средств"). Это создает серьезные проблемы при сборе статистики о работе системы на уровне инфраструктуры.
Что касается распределённой трассировки, то справедливо подмечено, что её хранение может обойтись очень дорого, причём большая часть событий будет неинтересна. По этой причине следует рассматривать данный подход в сочетании с сэмплированием — выдергивать из потока и сохранять только те события, которые потенциально могут представлять интерес.
〰️ 〰️ 〰️
💬 Предлагаю в комментариях делиться опытом работы с этими инструментами. 😉
#tools
Прошедший выпуск Podlodka Techlead Crew был посвящен межсервисному взаимодействию. Как и всегда, были и знакомые вещи, и не очень. В конечном счете, невозможно знать и помнить обо всём. Вот и я выписал себе очередной набор инструментов, которые показались мне крайне интересными. Чем и спешу поделиться.
🗂 Более подробный разбор см. в моей статье на Дзен.
🤝 Contract First
Продолжаю наблюдать популяризацию идеологии Contract First. С ростом компании растет количество сервисов и продуктов, что неминуемо приводит к необходимости их интеграции и согласования работ между командами разработки. Идеология Contract First — один из инструментов для решения этих проблем, масштабирования компании и процессов. Тема абсолютно не новая, но с популяризацией микросервисов и изобилием протоколов и технологий межсервисного взаимодействия вновь начала набирать популярность.
Взяв курс на Contract First, очень важен вопрос выбора инструментов, поскольку они должны унифицировать процесс, контролировать его и ускорять. Иначе говоря, хотелось бы иметь какой-то стандарт или общий подход к описанию API (хотя бы на уровне компании), возможность верифицировать спецификации (делать ревью, архитектурный контроль, тестирование контрактов) и создавать их максимально быстро и удобно.
Несмотря на существование достойной инструментальной поддержки, ряд коллег высказывают озабоченность. Во-первых, остается вопрос, кто именно должен создавать и развивать спецификации (архитектор, системный аналитик, техлид, разработчик). Во-вторых, спецификация сильно оторвана от кода (реальной жизни), что может вызвать проблемы на уровне её реализации. Отсюда вытекает третье сомнение: при большом числе интеграций создание спецификаций вручную выглядит ресурсоемким и опять же может разъехаться с реализацией. Иначе говоря, было сделано предположение, что в идеале спецификация должна определяться на языке, на котором ведется разработка, тогда это сократит "разрыв" до нуля. В конечном счете сошлись на том, что универсального решения не существует и каждый ведёт дела так, как ему удобно.
✍️ Implementation
В современной практике очень часто можно встретить необходимость гетерогенного хранения данных или необходимость в транзакционной логике при выполнении бизнес-процессов с участием нескольких (микро)сервисов. Всё выглядит так, что Temporal позволяет достаточно быстро добавить Saga в существующий проект, особенно если он написан без использования таких структурообразующих фреймворков, как Spring.
Еще одна интересная, но очень сложная задача — это сервис push-уведомлений. Если вы не можете или не готовы использовать какой-нибудь облачный сервис, то писать свою реализацию, пожалуй, не самый лучший вариант. В такой ситуации на помощь приходит Centrifugo.
👀 Observability
Было очень много сказано про техники обеспечения прочности и устойчивости. Два ярких момента, на которые я обратил внимание.
При этом было отмечено, что очень важно не маскировать бизнес-ошибки за кодами HTTP 2xx (например, "HTTP 200 Недостаточно средств"). Это создает серьезные проблемы при сборе статистики о работе системы на уровне инфраструктуры.
Что касается распределённой трассировки, то справедливо подмечено, что её хранение может обойтись очень дорого, причём большая часть событий будет неинтересна. По этой причине следует рассматривать данный подход в сочетании с сэмплированием — выдергивать из потока и сохранять только те события, которые потенциально могут представлять интерес.
#tools
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥1
Миграция данных и HLL
Сегодня я хочу поделиться опытом и наблюдениями в рамках одной очень сложной и интересной задачи. Производим тестирование механизма миграции данных из одной базы данных в другую. Объем очень большой, а модели источника и приемника сильно отличаются. Вместе с этим стоит вторая задача — убедиться, что копирование выполнено корректно.
1️⃣ Самое первое, что приходит в голову, — сравнить количество строк/записей/документов источника и приемника. Действительно, с одной стороны, если модели хранения источника и приемника подобны, то вариант вполне рабочий. Например, перенос простой таблицы из Oracle в PostgreSQL. С другой стороны, на больших объемах могут возникнуть серьезные затруднения. Некоторые базы могут выполнить
2️⃣ Если модели хранения источника и приемника отличаются, то задача подсчета строк становится нетривиальной. В качестве примера можно рассмотреть задачу организации журнала аудита, который содержит события изменения документов. Каждое событие описывается совокупностью атрибутов: ID документа, метка времени, действие, пользователь и т.п. В SQL-базах такой журнал наверняка будет представлен обычной таблицей с колонками, соответствующими атрибутам события. В NoSQL-базах этот же журнал может выглядеть по-разному, и многое будет зависеть от характера запросов (query). Например, если основной сценарий — это запросить все события по документу, тогда в Cassandra журнал может выглядеть в виде записей вида "ID документа - список событий". Ясно, что в этом случае количество записей источника (SQL) и приемника (NoSQL) перестает совпадать.
3️⃣ Сложность подсчета количества строк и разница в моделях данных — это не последняя проблема. Как известно, при миграции данных (обычно) используется механизм CDC (Change Data Capture). Это значит, что в топике приемника может оказаться несколько сообщений для каждой строки источника (по сообщению на каждую операцию Create/Update/Delete). В процессе обработки этих событий могут возникать сбои, что будет приводить к redelivery. Следовательно, вариант с подсчетом количества входящих сообщений и использования этого количества в качестве результирующего числа строк также отпадает. Между тем, эта идея мне показалась вполне интересной, и я задумался, а есть ли способ подсчета количества уникальных элементов в бесконечном потоке данных⁉️
➡️ Конечно, есть, кто бы сомневался! 😃 Один из таких алгоритмов — HyperLogLog (HLL). Это вероятностный алгоритм, оценивающий количество уникальных элементов в потоке данных (data stream). Да, мы не получим точное количество, но мы получим его оценку с погрешностью около 1% (подтверждаю, проверял на практике). В некоторых случаях этого может быть достаточно. Более того, этот алгоритм расходует невероятно мало памяти (используется фиксированный массив размером в несколько Кб). Я не буду описывать детали реализации, лучше расскажу, как можно использовать подобную вероятностную структуру данных на практике (будет псевдокод).
Оценка числа уникальных элементов в потоке данных:
В примере функция
💬 Миграция большого объема данных — это вызов. Конечно, это не только сравнение количества строк, но и сравнение содержимого, много других интересных и сложных вещей. Сегодня я рассказал об одном эпизоде, но задача еще не решена до конца. Друзья, был ли подобный опыт у вас и как вы решали данную задачу? 😉
#db #tip
Сегодня я хочу поделиться опытом и наблюдениями в рамках одной очень сложной и интересной задачи. Производим тестирование механизма миграции данных из одной базы данных в другую. Объем очень большой, а модели источника и приемника сильно отличаются. Вместе с этим стоит вторая задача — убедиться, что копирование выполнено корректно.
count() очень быстро, для других — это смерти подобно. Более того, если в выборке появляется фильтр (копируем не все данные или сложная логика копирования), то при выполнении count() сканирование файлов данных гарантированно (full scan). В таком случае подобное мероприятие слишком рискованно.Оценка числа уникальных элементов в потоке данных:
var hll = new HLL();
hll.add( hash(element1) );
hll.add( hash(element2) );
hll.add( hash(element3) );
...
hll.add( hash(elementN) );
var count = hll.cardinality(); // N±1%
В примере функция
hash() возвращает целочисленный хэш-код элемента. К реализации этой функции нужно подойти ответственно, т.к. от этого во многом будет зависеть получаемая погрешность. Мы на практике использовали MurmurHash, но тут нужно экспериментировать.#db #tip
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8✍1🔥1
YDB Topics
📺 Кстати, прошла новость, что в эту среду, 23 апреля, в 12:00 (МСК) состоится бесплатный вебинар на тему "YDB Topics — корпоративный брокер сообщений от Яндекса".
YDB Topics — совместимый с Apache Kafka корпоративный брокер сообщений, который тесно интегрирован с СУБД Яндекса YDB.
Как мне кажется, очень интересное решение, которое стоит внимания. Тем более что на вебинаре обещают затронуть многие вопросы, касающиеся архитектуры распределенных систем, включая транзакционность, согласованность, outbox-паттерн и т.п.
#conf
YDB Topics — совместимый с Apache Kafka корпоративный брокер сообщений, который тесно интегрирован с СУБД Яндекса YDB.
Как мне кажется, очень интересное решение, которое стоит внимания. Тем более что на вебинаре обещают затронуть многие вопросы, касающиеся архитектуры распределенных систем, включая транзакционность, согласованность, outbox-паттерн и т.п.
#conf
Please open Telegram to view this post
VIEW IN TELEGRAM
yandex.cloud
YDB Topics — корпоративный брокер сообщений от Яндекса
Разработка, миграция, администрирование и отказоустойчивость микросервисной архитектуры.
👍6🔥1
Мир, Труд, Legacy!
Сегодня хотел бы поднять тему Legacy. Но не про то Legacy, которое человек получает по наследству от богатого родственника 😃, а про другое, с которым мы часто сталкиваемся в ИТ, и которое имеет негативную коннотацию.
Всё началось с того, что я наткнулся на текст Patterns of Legacy Displacement. С одной стороны, это статья, в которой в общих чертах и с разных сторон рассматриваются проблемы модернизации Legacy-решений. С другой стороны - это подборка вполне конкретных шаблонов модернизации, ссылки на описание которых приводятся по мере повествования. Авторы заверяют, что будут развивать и поддерживать этот материал в актуальном состоянии, поэтому ссылки на некоторые шаблоны, к сожалению, отсутствуют. В целом, рекомендую для ознакомления или добавления в закладки.
Между тем, хотелось бы определиться, что такое Legacy. Сталкиваясь с этим, в зависимости от ситуации могут возникать двоякие ощущения: страх или жажда всё переписать и сделать нечто совершенное. Первое, как правило, связано с боязнью нарушить работоспособность существующего решения; второе — с моральной усталостью его поддержки. И если нам предоставляется шанс пойти по пути модернизации, то вспомните, с каким опьяняющим азартом мы начинаем махать шашкой и развешивать ярлыки на авторов модернизируемого решения. Кого интересует предыстория?! Нам дали шанс уничтожить ненавистного врага! Знакомо? 😃 Получилось добиться желаемого успеха и прийти к желаемому совершенству? 😉
Прежде чем начинать модернизацию, нужно сделать шаг назад и ответить на вопрос, почему Legacy стал Legacy. Накопился слишком большой технический долг? Или дело в (устаревшем) технологическом стеке? Или просто не осталось специалистов, у которых есть нужные компетенции для поддержки? Конечно, это далеко не полный перечень вопросов, но их цель, я думаю, ясна: не повторить прошлый опыт.
🟢 Апеллируя к своему большому опыту, авторы вышеуказанного текста заключают, что корень проблемы появления Legacy находится всё-таки на уровне культуры организации, её структуры и принятых методов. Таким образом указывают на прямую связь с законом Конвея.
🟢 Вместе с этим отмечается, что нельзя рассматривать инициативу по замене Legacy в отрыве от текущих бизнес-целей. Иначе говоря, если вести разработку как обычно (Business As Usual), а замену Legacy рассматривать как параллельную инициативу без поправок на реалии, ничего не выйдет. В лучшем случае получится то же самое, в худшем — "новая версия", которая слишком сильно или ненужным образом будет отличаться от реалий и желаемого результата. Выражаясь техническим языком, не нужно делать долгоживущие fork-и проекта, они будут слишком сильно оторваны от целей.
🟢 Авторы также указали на острую необходимость декомпозиции. Большой и сложный проект крайне трудно заменить целиком. Любые попытки сделать это часто обречены на полный провал либо на появление еще одной, но новой неуклюжей системы, которая будет жить вечно рядом со старой. Чаще всего можно наблюдать второй вариант, так как бизнес всё равно будет требовать результатов и вывода новой разработки в промышленную эксплуатацию.
〰️ 〰️
Всех поздравляю с Майскими праздниками, желаю прорывных успехов и грандиозных побед!🚀 А в комментариях призываю делиться своим опытом работы с Legacy.😉
Сегодня хотел бы поднять тему Legacy. Но не про то Legacy, которое человек получает по наследству от богатого родственника 😃, а про другое, с которым мы часто сталкиваемся в ИТ, и которое имеет негативную коннотацию.
Всё началось с того, что я наткнулся на текст Patterns of Legacy Displacement. С одной стороны, это статья, в которой в общих чертах и с разных сторон рассматриваются проблемы модернизации Legacy-решений. С другой стороны - это подборка вполне конкретных шаблонов модернизации, ссылки на описание которых приводятся по мере повествования. Авторы заверяют, что будут развивать и поддерживать этот материал в актуальном состоянии, поэтому ссылки на некоторые шаблоны, к сожалению, отсутствуют. В целом, рекомендую для ознакомления или добавления в закладки.
Между тем, хотелось бы определиться, что такое Legacy. Сталкиваясь с этим, в зависимости от ситуации могут возникать двоякие ощущения: страх или жажда всё переписать и сделать нечто совершенное. Первое, как правило, связано с боязнью нарушить работоспособность существующего решения; второе — с моральной усталостью его поддержки. И если нам предоставляется шанс пойти по пути модернизации, то вспомните, с каким опьяняющим азартом мы начинаем махать шашкой и развешивать ярлыки на авторов модернизируемого решения. Кого интересует предыстория?! Нам дали шанс уничтожить ненавистного врага! Знакомо? 😃 Получилось добиться желаемого успеха и прийти к желаемому совершенству? 😉
Прежде чем начинать модернизацию, нужно сделать шаг назад и ответить на вопрос, почему Legacy стал Legacy. Накопился слишком большой технический долг? Или дело в (устаревшем) технологическом стеке? Или просто не осталось специалистов, у которых есть нужные компетенции для поддержки? Конечно, это далеко не полный перечень вопросов, но их цель, я думаю, ясна: не повторить прошлый опыт.
🗂 Посмею сделать небольшую ремарку. Я не могу согласиться с тем, что (устаревший) технологический стек может являться основной причиной получения метки "Legacy". Только если это приводит к серьезным временным/финансовым издержкам/рискам или обусловлено внешним фактором (например, импортозамещением). В остальных случаях это не Legacy. Даже на самой замшелой технологии и древнем языке код может быть написан аккуратно, выглядеть структурно и понятно и не иметь значимых технических долгов. Называя такой проект Legacy, мы просто выражаем своё нежелание работать с ним или указываем на трудность найма специалистов для его поддержки. Проект становится Legacy, когда он серьезно затрудняет развитие бизнеса. Только это может являться поводом внесения значительных изменений, модернизации или замены существующего решения.
Всех поздравляю с Майскими праздниками, желаю прорывных успехов и грандиозных побед!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥4🤝1
Неизбежность эволюции (1/2)
Многие сходятся в том, что, начиная новый проект, нужно начать с чего-то простого, чтобы как можно быстрей сделать MVP и получить первую обратную связь. Вполне разумный и рациональный подход. Действительно, зачем собирать космический корабль, который, возможно, никогда не выйдет за пределы ангара или на содержание которого нет ни денег, ни людей.🚀 Тем не менее в душе каждого творца всегда искрится надежда создать нечто уникальное и неповторимое. Почему бы не поддаться этому порыву в новом/текущем проекте?! 😃 Как понять, что пришло время для особенных решений?!
На самом деле подобная постановка вопроса некорректна. Практически любое решение никогда не бывает финальным, тем более сразу. Об этом пишут многие заслуженные авторы, но самой яркой цитатой, пожалуй, является закон Голла.
Позволю себе внести важные уточнения.
🔘 Простота системы означает не примитивизм, а наличие ограниченного числа взаимодействующих между собой элементов с понятными и прослеживаемыми связями между ними.
🟢 Сложность системы означает не трудность организации самой системы, а её зрелость, точность модели предметной области.
Таким образом, если принять неизбежность эволюционного развития систем, тогда гораздо более важным аспектом является возможность самой эволюции. Для этого нужно обеспечить, как минимум, два условия. Во-первых, поскольку на начальных стадиях слишком много неопределенности, нужно как можно дольше сохранять свободу выбора направления развития. Во-вторых, принимаемые решения должны уточнять вектор движения для развития в желаемом направлении. Именно в этом контексте речь идет о гибкости архитектуры.
Гибкость архитектуры — понятие ортогональное к простоте и сложности, означающее степень готовности системы к изменениям. Простая не значит гибкая, обратное также справедливо. Гибкость становится возможной, в том числе, если система не зависит от специфических возможностей составляющих её элементов или особенностей взаимодействия между ними. Например, гибкость снижается, если появляется зависимость от уникальных особенностей определенной базы данных или зависимость этой базы данных от определённого окружения. Между тем, слишком гибкое решение — бесформенное, рыхлое, оно не может задавать структуру, следовательно, вектор развития, обрекая весь проект на провал.
➡️ Подобные умозаключения не являются каким-то открытием, об этом пишут и говорят многие. Я лишь хочу подчеркнуть, что для архитектора важно не только принять обоснованное решение, но и определить пути его дальнейшего развития. Нужно мыслить на несколько ходов вперед, как можно дольше сохраняя простоту и гибкость решения. Пожалуй, это лучший ответ на исходный вопрос о своевременности и возможности тех или иных решений. Каждый следующий шаг должен приближать нас к цели, формировать базу для следующего шага и уточнять направление развития. Если это так, то действуйте! 🚀
#arch #view
⬇️ ⬇️ ⬇️ ⬇️ ⬇️
Многие сходятся в том, что, начиная новый проект, нужно начать с чего-то простого, чтобы как можно быстрей сделать MVP и получить первую обратную связь. Вполне разумный и рациональный подход. Действительно, зачем собирать космический корабль, который, возможно, никогда не выйдет за пределы ангара или на содержание которого нет ни денег, ни людей.
На самом деле подобная постановка вопроса некорректна. Практически любое решение никогда не бывает финальным, тем более сразу. Об этом пишут многие заслуженные авторы, но самой яркой цитатой, пожалуй, является закон Голла.
🗂 A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over with a working simple system. — John Gall, Systemantics (1975)
Позволю себе внести важные уточнения.
Таким образом, если принять неизбежность эволюционного развития систем, тогда гораздо более важным аспектом является возможность самой эволюции. Для этого нужно обеспечить, как минимум, два условия. Во-первых, поскольку на начальных стадиях слишком много неопределенности, нужно как можно дольше сохранять свободу выбора направления развития. Во-вторых, принимаемые решения должны уточнять вектор движения для развития в желаемом направлении. Именно в этом контексте речь идет о гибкости архитектуры.
Гибкость архитектуры — понятие ортогональное к простоте и сложности, означающее степень готовности системы к изменениям. Простая не значит гибкая, обратное также справедливо. Гибкость становится возможной, в том числе, если система не зависит от специфических возможностей составляющих её элементов или особенностей взаимодействия между ними. Например, гибкость снижается, если появляется зависимость от уникальных особенностей определенной базы данных или зависимость этой базы данных от определённого окружения. Между тем, слишком гибкое решение — бесформенное, рыхлое, оно не может задавать структуру, следовательно, вектор развития, обрекая весь проект на провал.
#arch #view
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍2
Неизбежность эволюции (2/2)
Именно под таким углом нужно смотреть на обоснование очередного решения. По этой причине нужно сразу отбрасывать нижеследующие "обоснования", которые, несмотря на свою комичность, к сожалению, всё-таки встречаются.
Принимая неизбежность эволюционного развития систем, важность гибкости архитектуры на ранних стадиях, а также необходимость постоянной корректировки направления развития (стратегии), остаётся вопрос, почему кто-то начинает не с простых вещей. Почему кто-то сразу начинает с гексагональных архитектур или микросервисов? 😃
Согласен, что иногда это является преждевременным усложнением. Однако, если архитектор или разработчик достаточно опытный, он может позволить себе "срезать углы", действуя на опережение. В данном случае он должен осознавать и указывать на все риски подобных действий, в том числе понимать, кто будет поддерживать и сопровождать такой продукт. Тут можно вернуться к метафоре с "космическим кораблём": нужен ли он на старте, есть ли у вас подходящая команда, инфраструктура, ресурсы? 🤔
P.s. На самом деле я хотел написать пост про распределенные (реляционные) хранилища, но меня понесло немного в другую сторону, и я не стал сопротивляться этому потоку. Надеюсь, что не напрасно. Будем считать данный пост вступлением к следующему. 😃
#arch #view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥2😁1
Распределенные SQL-базы
Данные — это фундамент большинства систем. Они эволюционируют вместе с кодом и архитектурой: происходит развитие способов хранения и работы с данными. Миграция данных всегда сопряжена с риском их потери и нарушения работоспособности системы. А если речь заходит о смене БД, риски и сложность миграции возрастают на несколько порядков. 🙈
В том числе по этой причине многие основательно подходят к выбору БД: фундамент должен быть прочным, его должно хватить надолго, он должен выдерживать нагрузку с хорошим запасом. Поскольку кривая эволюции может увести далеко от начальных архитектурных предположений, большинство делают выбор в пользу универсального и проверенного решения — реляционного хранилища. Чаще всего это монолитные реляционные базы вроде PostgreSQL или MySQL/MariaDB. Откровенно говоря, я не поддерживаю идею выбора хранилища на основе принципа "проверенное — значит подходящее". Выбор следует делать осознанно, учитывая требования к системе, возможности хранилища, результаты прикладных экспериментов и тестов.
Так или иначе, оказавшись в ситуации, когда хранилище перестает отвечать требованиям, начинается процесс усложнения решения. С одной стороны, это нормально. Усложнение можно списать на эволюцию и зрелость. 🆚 С другой стороны, усложнение может являться предвестником того, что достигнут некоторый предел возможностей, и его преодоление возможно лишь за счет "неестественных надстроек". 🩼 Например, недавно рассматривал, что может пойти не так с PostgreSQL и как можно с этим ужиться. Бесспорно, иногда это достойный компромисс вместо того, чтобы менять БД.
О каких усложнениях идет речь? Основные усилия направлены на обеспечение согласованности данных (saga, 2PC, inbox/outbox patterns), в том числе по той причине, что часть данных переносят в отдельное (NoSQL) хранилище и/или микросервис. В таких случаях инфраструктурного кода становится на порядок больше кода с бизнес-логикой. Возрастает вероятность возникновения ошибок, порог входа в проект и требования к специалистам для его поддержания и развития.
Чтобы однажды не дойти до предела возможностей БД и не начать городить огород раньше времени, лучше воспользоваться следующим чек-листом:
🔲 Предвидится большой размер базы данных.
🔲 Необходимо горизонтальное масштабирование.
🔲 Необходимы высокие гарантии отказоустойчивости.
🔲 Необходимы гарантии высокой доступности.
Если хотя бы на один вопрос ответ👍 , то следует смотреть в сторону распределенных (SQL-) баз данных. С одной стороны, это гораздо более сложное решение, чем какой-нибудь легковесный монолитный PostgreSQL, 🆚 с другой стороны, это позволит существенно упростить код приложения, оставив в нём место только для бизнес-логики. Все вопросы согласованности делегируются хранилищу, и кажется, что это очень хорошо и правильно. Может, действительно, не стоит изобретать велосипед?! 🚲
В качестве распределенных SQL-баз мне показались интересными следующие решения:
🔵 YDB
🔵 CockroachDB
🔵 YugabyteDB
🔵 TiDB
По активности развития и зрелости этих решений можно сказать, что они пользуются большим спросом. И не случайно, ведь можно получить лучшую версию удобного и универсального SQL-хранилища со всеми преимуществами масштабирования, которые многие почему-то до сих пор приписывают только NoSQL.
#db #arch
Данные — это фундамент большинства систем. Они эволюционируют вместе с кодом и архитектурой: происходит развитие способов хранения и работы с данными. Миграция данных всегда сопряжена с риском их потери и нарушения работоспособности системы. А если речь заходит о смене БД, риски и сложность миграции возрастают на несколько порядков. 🙈
В том числе по этой причине многие основательно подходят к выбору БД: фундамент должен быть прочным, его должно хватить надолго, он должен выдерживать нагрузку с хорошим запасом. Поскольку кривая эволюции может увести далеко от начальных архитектурных предположений, большинство делают выбор в пользу универсального и проверенного решения — реляционного хранилища. Чаще всего это монолитные реляционные базы вроде PostgreSQL или MySQL/MariaDB. Откровенно говоря, я не поддерживаю идею выбора хранилища на основе принципа "проверенное — значит подходящее". Выбор следует делать осознанно, учитывая требования к системе, возможности хранилища, результаты прикладных экспериментов и тестов.
Ясно, что принести на сопровождение подходящее, но никому неизвестное решение — это зачастую совсем не вариант, особенно на ранних этапах развития продукта. Но это один из возможных вариантов, который нужно отвергать обоснованно. Возможно, что миграция данных в будущем обойдётся дороже, чем освоение нового инструмента на старте.
Так или иначе, оказавшись в ситуации, когда хранилище перестает отвечать требованиям, начинается процесс усложнения решения. С одной стороны, это нормально. Усложнение можно списать на эволюцию и зрелость. 🆚 С другой стороны, усложнение может являться предвестником того, что достигнут некоторый предел возможностей, и его преодоление возможно лишь за счет "неестественных надстроек". 🩼 Например, недавно рассматривал, что может пойти не так с PostgreSQL и как можно с этим ужиться. Бесспорно, иногда это достойный компромисс вместо того, чтобы менять БД.
О каких усложнениях идет речь? Основные усилия направлены на обеспечение согласованности данных (saga, 2PC, inbox/outbox patterns), в том числе по той причине, что часть данных переносят в отдельное (NoSQL) хранилище и/или микросервис. В таких случаях инфраструктурного кода становится на порядок больше кода с бизнес-логикой. Возрастает вероятность возникновения ошибок, порог входа в проект и требования к специалистам для его поддержания и развития.
Чтобы однажды не дойти до предела возможностей БД и не начать городить огород раньше времени, лучше воспользоваться следующим чек-листом:
Если хотя бы на один вопрос ответ
В качестве распределенных SQL-баз мне показались интересными следующие решения:
По активности развития и зрелости этих решений можно сказать, что они пользуются большим спросом. И не случайно, ведь можно получить лучшую версию удобного и универсального SQL-хранилища со всеми преимуществами масштабирования, которые многие почему-то до сих пор приписывают только NoSQL.
#db #arch
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍2
TechLead Conf 2025
Сегодня я выступил с докладом на TechLeadConf 2025 с докладом "Безопасное исполнение ненадёжного кода". Спасибо всем, кто пришел и поддержал!❤️
Пока готовится видео, прикрепляю презентацию и чек-лист по мотивам доклада.🔽 В ближайшем времени, как обычно, более подробно раскрою основные тезисы в текстовом виде.
#conf #untrusted_code
Сегодня я выступил с докладом на TechLeadConf 2025 с докладом "Безопасное исполнение ненадёжного кода". Спасибо всем, кто пришел и поддержал!
Пока готовится видео, прикрепляю презентацию и чек-лист по мотивам доклада.
#conf #untrusted_code
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👏5⚡2🔥1
TechLeadConf X 2025
Прошедшие три недели у меня получились очень насыщенными. 🔥 Получился настоящий марафон. 🏃🏻♂️➡️ Сначала был отпуск в Нижнем Новгороде, затем в Москве, после чего началась стадия итоговой подготовки доклада, состоялся финальный прогон и, наконец, выступление.🎙 И, конечно, же работа. 😃
Нижний Новгород остался в моём сердце навсегда.❤️ Невероятно красивый, спокойный и комфортный город. Набережная, виды на Волгу и Оку, зеленые парки, храмы, фонтаны и, конечно, закаты. Если вы не были там, то посетите его при первой возможности.
По прошествии конференции отдельное спасибо хочется сказать программному комитету и организаторам.❤️ Всё было на высоте, как и всегда. Надеюсь, что участникам и слушателям моего доклада всё также понравилось. 🙈😃
Роль докладчика даёт классную возможность быть и участником конференции, слушать доклады лидеров индустрии. Мне удалось посмотреть несколько докладов очно и в записи. Сделал для себя небольшой конспект самых интересных, на мой взгляд, мыслей, которыми подробней поделюсь чуть позже. Пока отмечу, что много говорилось про необходимость и важность архитектурного контроля (AaC, ADR), про инженерные практики, способы борьбы с техдолгом и legacy. (Полагаю, что растущая популярность последнего напрямую связана с импортозамещением.)
Всем желаю короткой, но очень продуктивной рабочей недели!🚀
#conf
Прошедшие три недели у меня получились очень насыщенными. 🔥 Получился настоящий марафон. 🏃🏻♂️➡️ Сначала был отпуск в Нижнем Новгороде, затем в Москве, после чего началась стадия итоговой подготовки доклада, состоялся финальный прогон и, наконец, выступление.
Нижний Новгород остался в моём сердце навсегда.
По прошествии конференции отдельное спасибо хочется сказать программному комитету и организаторам.
Роль докладчика даёт классную возможность быть и участником конференции, слушать доклады лидеров индустрии. Мне удалось посмотреть несколько докладов очно и в записи. Сделал для себя небольшой конспект самых интересных, на мой взгляд, мыслей, которыми подробней поделюсь чуть позже. Пока отмечу, что много говорилось про необходимость и важность архитектурного контроля (AaC, ADR), про инженерные практики, способы борьбы с техдолгом и legacy. (Полагаю, что растущая популярность последнего напрямую связана с импортозамещением.)
Всем желаю короткой, но очень продуктивной рабочей недели!
#conf
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤1👍1👏1