0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>В предыдущих заметках мы рассказывали про<a>горизонтальное масштабирование</a>, CQRS и архитектурный паттерн<a>Event Sourcing</a>. Но, как известно, в системах с Event Sourcing нет строгой согласованности. А это значит, что нам можно задействовать сразу несколько хранилищ, причем без синхронизации между этими хранилищами.</p>
1
<p>В предыдущих заметках мы рассказывали про<a>горизонтальное масштабирование</a>, CQRS и архитектурный паттерн<a>Event Sourcing</a>. Но, как известно, в системах с Event Sourcing нет строгой согласованности. А это значит, что нам можно задействовать сразу несколько хранилищ, причем без синхронизации между этими хранилищами.</p>
2
<p>Так как задача заключается в построении быстрого и отказоустойчивого сервиса, то мы можем: •<strong>разделить файлы по типам</strong>. К примеру, изображения и видео можно декодировать, выбрав наиболее эффективный формат; •<strong>разделить аккаунты по странам</strong>. Эта схема архитектуры предоставляет такую возможность автоматически, но вообще, необходимость в этом может возникнуть и по законодательным причинам.</p>
2
<p>Так как задача заключается в построении быстрого и отказоустойчивого сервиса, то мы можем: •<strong>разделить файлы по типам</strong>. К примеру, изображения и видео можно декодировать, выбрав наиболее эффективный формат; •<strong>разделить аккаунты по странам</strong>. Эта схема архитектуры предоставляет такую возможность автоматически, но вообще, необходимость в этом может возникнуть и по законодательным причинам.</p>
3
<p>Однако если вы пожелаете осуществить перенос данных из одного хранилища в другое, стандартными средствами здесь не обойтись. К сожалению, в этом случае надо будет остановить очередь, сделать миграцию, а далее запустить ее. В общей ситуации вы не сможете перенести данные, что называется, "на лету", но если очередь событий сохраняется полностью, и у вас существуют слепки предыдущих состояний вашего хранилища, то можно переиграть события следующим образом:</p>
3
<p>Однако если вы пожелаете осуществить перенос данных из одного хранилища в другое, стандартными средствами здесь не обойтись. К сожалению, в этом случае надо будет остановить очередь, сделать миграцию, а далее запустить ее. В общей ситуации вы не сможете перенести данные, что называется, "на лету", но если очередь событий сохраняется полностью, и у вас существуют слепки предыдущих состояний вашего хранилища, то можно переиграть события следующим образом:</p>
4
<p>• так как в Event Source каждое событие имеет собственный id (в идеале он не уменьшается), то в хранилище добавляем поле - идентификатор последнего обработанного элемента; • выполняем дублирование очереди, чтобы события смогли обрабатываться для нескольких независимых хранилищ (первое хранилище - это хранилище, где данные хранятся уже сейчас, второе - новое хранилище, пока пустое). При этом 2-я очередь пока обрабатываться не будет; • выполняем запуск 2-й очереди (начинаем переигрывать события); • если новая очередь будет относительно пуста (речь идет о том, чтобы средняя разница во времени между добавлением и извлечением элемента была приемлема), можно приступать к переключению пользователей на новое хранилище.</p>
4
<p>• так как в Event Source каждое событие имеет собственный id (в идеале он не уменьшается), то в хранилище добавляем поле - идентификатор последнего обработанного элемента; • выполняем дублирование очереди, чтобы события смогли обрабатываться для нескольких независимых хранилищ (первое хранилище - это хранилище, где данные хранятся уже сейчас, второе - новое хранилище, пока пустое). При этом 2-я очередь пока обрабатываться не будет; • выполняем запуск 2-й очереди (начинаем переигрывать события); • если новая очередь будет относительно пуста (речь идет о том, чтобы средняя разница во времени между добавлением и извлечением элемента была приемлема), можно приступать к переключению пользователей на новое хранилище.</p>
5
<p>К чему в итоге пришли? В системе до сих пор нет строгой согласованности. Зато есть eventual constistency и гарантия того, что события будут обрабатываться в одинаковом порядке (правда, возможно, с разной задержкой). А уже пользуясь этим, мы сможем относительно легко перенести данные на другой конец планеты, не останавливая при этом систему.</p>
5
<p>К чему в итоге пришли? В системе до сих пор нет строгой согласованности. Зато есть eventual constistency и гарантия того, что события будут обрабатываться в одинаковом порядке (правда, возможно, с разной задержкой). А уже пользуясь этим, мы сможем относительно легко перенести данные на другой конец планеты, не останавливая при этом систему.</p>
6
<p>Какие<strong>плюсы</strong>дает подобная архитектура, если мы строим онлайн-хранилище для файлов: • есть возможность перемещать объекты поближе к пользователям, причем делая это динамически. А значит, повышается качество сервиса; • есть возможность хранить часть информации внутри компаний. К примеру, Enterprise-пользователи часто требуют хранить свои данные в подконтрольных дата-центрах (для предотвращения утечек). А благодаря sharding мы можем без проблем это обеспечить. Причем задача становится еще более простой, если в распоряжении заказчика есть совместимое облако (допустим, Azure self hosted); • не обязательно сразу писать код. Для начала нас вполне устроит одно хранилище для всех аккаунтов (это позволит быстрее начать работу). Таким образом, мы подходим к<strong>ключевой особенности системы</strong>- пусть она и расширяема, однако на начальном этапе она относительно проста. Следовательно, нет необходимости сразу же писать код, который будет работать с миллионом независимых отдельных очередей и т. п. То есть если понадобится, мы просто сделаем это в будущем.</p>
6
<p>Какие<strong>плюсы</strong>дает подобная архитектура, если мы строим онлайн-хранилище для файлов: • есть возможность перемещать объекты поближе к пользователям, причем делая это динамически. А значит, повышается качество сервиса; • есть возможность хранить часть информации внутри компаний. К примеру, Enterprise-пользователи часто требуют хранить свои данные в подконтрольных дата-центрах (для предотвращения утечек). А благодаря sharding мы можем без проблем это обеспечить. Причем задача становится еще более простой, если в распоряжении заказчика есть совместимое облако (допустим, Azure self hosted); • не обязательно сразу писать код. Для начала нас вполне устроит одно хранилище для всех аккаунтов (это позволит быстрее начать работу). Таким образом, мы подходим к<strong>ключевой особенности системы</strong>- пусть она и расширяема, однако на начальном этапе она относительно проста. Следовательно, нет необходимости сразу же писать код, который будет работать с миллионом независимых отдельных очередей и т. п. То есть если понадобится, мы просто сделаем это в будущем.</p>
7
<p>По материалам блога компании "Технологический Центр Дойче Банка" (https://habr.com/ru/company/dbtc/).</p>
7
<p>По материалам блога компании "Технологический Центр Дойче Банка" (https://habr.com/ru/company/dbtc/).</p>
8
8