Брокеры сообщений
Брокер сообщений (очередь сообщений) – это отдельный сервис, который отвечает за хранение и доставку данных от сервисов-отправителей к сервисам-получателям с помощью модели Pub/Sub.
Эта модель предполагает, что асинхронное взаимодействие осуществляется согласно следующей логике двух ролей:
1. Publishers публикуют новую информацию в виде сгруппированных по некоторому атрибуту сообщений;
2. Subscribers подписываются на потоки сообщений с определенными атрибутами и обрабатывают их.
Большинство брокеров предоставляют гарантии “at least once” и “at most once”.
At most once исключает повторную обработку сообщений, однако допускает их потерю. В этом случае брокер будет доставлять сообщения получателям по принципу “отправил и забыл”. Если получатель не смог по какой-то причине обработать сообщение с первой попытки, брокер не будет осуществлять переотправку.
At least once, напротив, гарантирует получение сообщения получателем, однако при этом есть вероятность повторной обработки одних и тех же сообщений.
Зачастую эта гарантия достигается с помощью механизма Ack/Nack (acknowledgement/negative acknowledgement), который предписывает совершать переотправку сообщения, если получатель по какой-то причине не смог его обработать.
Таким образом, для каждого отправленного брокером (но еще не обработанного) сообщения существует три итоговых состояния — получатель вернул Ack (успешная обработка), вернул Nack (неуспешная обработка) или разорвал соединение. Последние два сценария приводят в переотправке сообщения и повторной обработке.
Однако брокер может произвести повторную отправку и при успешной обработке сообщения получателем. Например, если получатель обработал сообщение, но завершил свою работу, не отправив сигнал Ack брокеру.
В этом случае брокер снова положит сообщение в очередь, после чего оно будет обработано повторно, что может привести к ошибкам и порче данных, если разработчик не предусмотрел механизм устранения дублей на стороне получателя.
#архитектура
Брокер сообщений (очередь сообщений) – это отдельный сервис, который отвечает за хранение и доставку данных от сервисов-отправителей к сервисам-получателям с помощью модели Pub/Sub.
Эта модель предполагает, что асинхронное взаимодействие осуществляется согласно следующей логике двух ролей:
1. Publishers публикуют новую информацию в виде сгруппированных по некоторому атрибуту сообщений;
2. Subscribers подписываются на потоки сообщений с определенными атрибутами и обрабатывают их.
Большинство брокеров предоставляют гарантии “at least once” и “at most once”.
At most once исключает повторную обработку сообщений, однако допускает их потерю. В этом случае брокер будет доставлять сообщения получателям по принципу “отправил и забыл”. Если получатель не смог по какой-то причине обработать сообщение с первой попытки, брокер не будет осуществлять переотправку.
At least once, напротив, гарантирует получение сообщения получателем, однако при этом есть вероятность повторной обработки одних и тех же сообщений.
Зачастую эта гарантия достигается с помощью механизма Ack/Nack (acknowledgement/negative acknowledgement), который предписывает совершать переотправку сообщения, если получатель по какой-то причине не смог его обработать.
Таким образом, для каждого отправленного брокером (но еще не обработанного) сообщения существует три итоговых состояния — получатель вернул Ack (успешная обработка), вернул Nack (неуспешная обработка) или разорвал соединение. Последние два сценария приводят в переотправке сообщения и повторной обработке.
Однако брокер может произвести повторную отправку и при успешной обработке сообщения получателем. Например, если получатель обработал сообщение, но завершил свою работу, не отправив сигнал Ack брокеру.
В этом случае брокер снова положит сообщение в очередь, после чего оно будет обработано повторно, что может привести к ошибкам и порче данных, если разработчик не предусмотрел механизм устранения дублей на стороне получателя.
#архитектура
🤔2👍1🔥1
Партиция - последовательность сообщений, раздел топика, а топик - это очередь.
В Кафке процесса доставки как такового нет: каждый читатель сам ответственен за вытягивание (pull) сообщений из партиций, которые он читает.
Каждый получатель закреплен за определенной партицией (или за несколькими партициями) в интересующем его топике, и при появлении нового сообщения получает сигнал на вычитывание следующего элемента в commit log, при этом отмечая, какое последнее сообщение он прочитал. Таким образом при переподключении он будет знать, какое сообщение ему вычитать следующим.
Базовое правило масштабирования Кафки — количество конкурентных читателей (то бишь группа сервисов, реализующих одинаковую логику обработки (реплик)) топика не должно превышать количество партиций в этом топике, иначе какая-то пара читателей будут обрабатывать одинаковый набор данных.
В Кафке процесса доставки как такового нет: каждый читатель сам ответственен за вытягивание (pull) сообщений из партиций, которые он читает.
Каждый получатель закреплен за определенной партицией (или за несколькими партициями) в интересующем его топике, и при появлении нового сообщения получает сигнал на вычитывание следующего элемента в commit log, при этом отмечая, какое последнее сообщение он прочитал. Таким образом при переподключении он будет знать, какое сообщение ему вычитать следующим.
Базовое правило масштабирования Кафки — количество конкурентных читателей (то бишь группа сервисов, реализующих одинаковую логику обработки (реплик)) топика не должно превышать количество партиций в этом топике, иначе какая-то пара читателей будут обрабатывать одинаковый набор данных.
👍2🤔2
Чтобы избежать ситуации с чтением одной партиции конкурентными читателями, в Кафке принято объединять несколько реплик одного сервиса в consumer Group, в рамках которого Zookeeper будет назначать одной партиции не более одного читателя. Так как читатели привязываются непосредственно к партиции (при этом читатель обычно ничего не знает о количестве партиций в топике), ZooKeeper при подключении нового читателя производит перераспределение участников в Consumer Group таким образом, чтобы каждая партиция имела одного и только одного читателя.
Читатель обозначает свою Consumer Group при подключении к Kafka.
Читатель обозначает свою Consumer Group при подключении к Kafka.
👍2
Подытожим основные преимущества Kafka
➕В один топик может писать один или несколько производителей – идеально для агрегирования данных из большого количества источников, что становится особенно полезно при использовании Кафки в качестве системы доставки сообщений в микросервисной архитектуре;
➕Несколько потребителей – с учетом особенностей механизма получения сообщений (pull) один и тот же поток сообщений может читать несколько потребителей, не мешая при этом друг другу. При этом конкурентных читателей (например, реплики одного сервиса) можно объединить в Consumer Group, а ZooKeeper, в свою очередь, будет следить, чтобы каждая партиция одновременно читалась не более, чем одним участником каждой группы;
➕Хранение данных на диске в течение длительного времени позволяет не беспокоится о потере данных при резком росте нагрузки. Кафка, будучи своего рода буфером, компенсирует отставание потребителей, позволяя накапливать в себе сообщения до нормализации нагрузки или масштабирования консьюмеров. Также обеспечивается гибкая конфигурация, где отдельные потоки данных (топики) хранятся на диске с разным сроком;
➕Хорошо масштабируется, за счет меньшей, в сравнении с AMQP брокерами, единицей параллелизма – партицией. Разные партиции могут храниться в разных брокерах, обеспечивая дополнительную гибкость при горизонтальном масштабировании;
➕Быстродействие. В силу простоты механизма, при которой процесса доставки нет как такового, а процесс передачи данных представляет из себя запись-хранение-выдача, Кафка обладает очень большой пропускной способностью – она исчисляется миллионами сообщений в секунду.
➕В один топик может писать один или несколько производителей – идеально для агрегирования данных из большого количества источников, что становится особенно полезно при использовании Кафки в качестве системы доставки сообщений в микросервисной архитектуре;
➕Несколько потребителей – с учетом особенностей механизма получения сообщений (pull) один и тот же поток сообщений может читать несколько потребителей, не мешая при этом друг другу. При этом конкурентных читателей (например, реплики одного сервиса) можно объединить в Consumer Group, а ZooKeeper, в свою очередь, будет следить, чтобы каждая партиция одновременно читалась не более, чем одним участником каждой группы;
➕Хранение данных на диске в течение длительного времени позволяет не беспокоится о потере данных при резком росте нагрузки. Кафка, будучи своего рода буфером, компенсирует отставание потребителей, позволяя накапливать в себе сообщения до нормализации нагрузки или масштабирования консьюмеров. Также обеспечивается гибкая конфигурация, где отдельные потоки данных (топики) хранятся на диске с разным сроком;
➕Хорошо масштабируется, за счет меньшей, в сравнении с AMQP брокерами, единицей параллелизма – партицией. Разные партиции могут храниться в разных брокерах, обеспечивая дополнительную гибкость при горизонтальном масштабировании;
➕Быстродействие. В силу простоты механизма, при которой процесса доставки нет как такового, а процесс передачи данных представляет из себя запись-хранение-выдача, Кафка обладает очень большой пропускной способностью – она исчисляется миллионами сообщений в секунду.
👍2
Недостатки Kafka
➖Кафка не гарантирует упорядоченность сообщений в рамках топика, только в рамках партиции. Решение: хранить события, относящиеся к одной сущности, только в одной партиции.
➖В Кафке масштабирование сложнее, чем в AMQP брокерах. Например, если вы добавите еще один экземпляр читателя и натравите его на ту же партицию, вы получите нулевой КПД, так как в этом случае оба экземпляра будут читать один и тот же набор данных. Правило масштабирования Кафки — количество конкурентных читателей (то бишь группа сервисов, реализующих одинаковую логику обработки (реплик)) топика не должно превышать количество партиций в этом топике, иначе какая-то пара читателей будут обрабатывать одинаковый набор данных. Решение: объединять несколько реплик одного сервиса в consumer Group, в рамках которого Zookeeper будет назначать одной партиции не более одного читателя.
➖Необходимо вести учет последнего прочитанного сообщения в партиции каждым из читателей. В силу простоты структуры партиций, эта информация представлена в виде целочисленного значения, именуемого offset (смещение). Решение: Kafka, начиная с версии 0.9, хранит оффсеты по каждому пользователю в специальном топике __consumer_offsets (до версии 0.9 оффсеты хранились в ZooKeeper). К тому же, вести учет оффсетов можно непосредственно на стороне получателей.
➖В Кафке сложнее (в сравнении с AMQP-брокерами) реализовать приоритет сообщений. Это напрямую вытекает из того факта, что сообщения в партициях хранятся и читаются строго в порядке их добавления. Решение: создать нескольких топиков под сообщения с разным приоритетом (отличаться топики будут только названием), например, events_low, events_medium, events_high, а затем реализовать логику приоритетного чтения перечисленных топиков на стороне приложения-консьюмера.
➖В отличие от классических брокеров, битые сообщения (которые не удается обработать с учетом существующей логики получателя или из-за проблем с десериализацей) нельзя бесконечно перезакидывать в очередь, пока получатель не научится их корректно обрабатывать. В Кафке по умолчанию вычитывание сообщений из партиции останавливается, когда получатель доходит до битого сообщения, и до тех пор, пока оно не будет пропущено и закинуто в “карантинную” очередь (также именуемой “dead letter queue”) для последующей обработки, чтение партиции продолжить не получится.
➖Кафка не гарантирует упорядоченность сообщений в рамках топика, только в рамках партиции. Решение: хранить события, относящиеся к одной сущности, только в одной партиции.
➖В Кафке масштабирование сложнее, чем в AMQP брокерах. Например, если вы добавите еще один экземпляр читателя и натравите его на ту же партицию, вы получите нулевой КПД, так как в этом случае оба экземпляра будут читать один и тот же набор данных. Правило масштабирования Кафки — количество конкурентных читателей (то бишь группа сервисов, реализующих одинаковую логику обработки (реплик)) топика не должно превышать количество партиций в этом топике, иначе какая-то пара читателей будут обрабатывать одинаковый набор данных. Решение: объединять несколько реплик одного сервиса в consumer Group, в рамках которого Zookeeper будет назначать одной партиции не более одного читателя.
➖Необходимо вести учет последнего прочитанного сообщения в партиции каждым из читателей. В силу простоты структуры партиций, эта информация представлена в виде целочисленного значения, именуемого offset (смещение). Решение: Kafka, начиная с версии 0.9, хранит оффсеты по каждому пользователю в специальном топике __consumer_offsets (до версии 0.9 оффсеты хранились в ZooKeeper). К тому же, вести учет оффсетов можно непосредственно на стороне получателей.
➖В Кафке сложнее (в сравнении с AMQP-брокерами) реализовать приоритет сообщений. Это напрямую вытекает из того факта, что сообщения в партициях хранятся и читаются строго в порядке их добавления. Решение: создать нескольких топиков под сообщения с разным приоритетом (отличаться топики будут только названием), например, events_low, events_medium, events_high, а затем реализовать логику приоритетного чтения перечисленных топиков на стороне приложения-консьюмера.
➖В отличие от классических брокеров, битые сообщения (которые не удается обработать с учетом существующей логики получателя или из-за проблем с десериализацей) нельзя бесконечно перезакидывать в очередь, пока получатель не научится их корректно обрабатывать. В Кафке по умолчанию вычитывание сообщений из партиции останавливается, когда получатель доходит до битого сообщения, и до тех пор, пока оно не будет пропущено и закинуто в “карантинную” очередь (также именуемой “dead letter queue”) для последующей обработки, чтение партиции продолжить не получится.
👍3🤔2
Почему микросервисная архитектура
1. Крупный масштаб (в монолите чёрт ногу сломит)
2. Больше гибкость (обновлять можно только 1 сервис, ошибки тоже только там)
1. Крупный масштаб (в монолите чёрт ногу сломит)
2. Больше гибкость (обновлять можно только 1 сервис, ошибки тоже только там)
Разработчики начали создавать API, чтобы сторонние ИТ-сервисы могли подключиться к инфраструктуре. Недостаток этой технологии в том, что она предлагает всем один и тот же набор возможностей. Если вам нужно ограничить объём трафика на смартфонах, а пользователям планшетов предложить собственный метод ввода данных, могут начаться трудности.
Ещё сложнее была задача SoundCloud – компании нужно было интегрироваться со сторонними разработчикам, чтобы те могли встраивать плеер в свои площадки. Для этого API из коробки должно взаимодействовать с любыми платформами, а при каждом обновлении команде нужно убедиться, что доработка не сломает все эти интеграции. На практике этого добиться нереально.
Так и родилась концепция Backend-for-Frontend – легковесного сервиса, который лежит ближе к фронтенду, чем к бэку.
Возможности BFF
Ключевое слово – «легковесный», список возможностей у BFF гораздо меньше, чем у API:
Работать с микросервисами продукта и получать от них данные.
Форматировать эти данные, чтобы они корректно обрабатывались на фронтенде.
Отправлять данные фронтенду.
Ещё сложнее была задача SoundCloud – компании нужно было интегрироваться со сторонними разработчикам, чтобы те могли встраивать плеер в свои площадки. Для этого API из коробки должно взаимодействовать с любыми платформами, а при каждом обновлении команде нужно убедиться, что доработка не сломает все эти интеграции. На практике этого добиться нереально.
Так и родилась концепция Backend-for-Frontend – легковесного сервиса, который лежит ближе к фронтенду, чем к бэку.
Возможности BFF
Ключевое слово – «легковесный», список возможностей у BFF гораздо меньше, чем у API:
Работать с микросервисами продукта и получать от них данные.
Форматировать эти данные, чтобы они корректно обрабатывались на фронтенде.
Отправлять данные фронтенду.
👍1🤔1
BFF - технология предоставления API микросервисов во фронт через промежуточный уровень с минимальной логикой. Это позволяет отформатировать и представить сырые данные из бека во фронт в красивом виде
Чем отличается пунктирная линия и сплошная на логической диаграмме БД?
1. Сплошная - Идентифицирующая связь: При установлении идентифицирующей связи дочерняя сущность автоматически превращается в зависимую. Атрибуты первичного ключа родительской сущности автоматически мигрируют в зону атрибутов первичного ключа дочерней сущности как внешние ключи (Foreign Key)
2. Пунктир - Не идентифицирующая связь: При установлении неидентифицирующей связи дочерняя сущность не превращается в зависимую, а ключевые атрибуты родительской сущности мигрируют в область неключевых атрибутов дочерней сущности
#бд
1. Сплошная - Идентифицирующая связь: При установлении идентифицирующей связи дочерняя сущность автоматически превращается в зависимую. Атрибуты первичного ключа родительской сущности автоматически мигрируют в зону атрибутов первичного ключа дочерней сущности как внешние ключи (Foreign Key)
2. Пунктир - Не идентифицирующая связь: При установлении неидентифицирующей связи дочерняя сущность не превращается в зависимую, а ключевые атрибуты родительской сущности мигрируют в область неключевых атрибутов дочерней сущности
#бд
👍7🔥2