УДК 004.45
Сравнение очереди сообщений Apache Kafka и Nosql базы данных Redis с точки зрения их использования для организации межсервисного взаимодействия в микросервисной архитектуре
Хватов Сергей Андреевич – магистрант Университета ИТМО
Аннотация: Опросы крупнейших IT-компаний в 2020 году показывают, что микросервисная архитектура (MSA) является одним из самых востребованных подходов к проектированию веб-приложений на сегодняшний день. Более 60% всех опрошенных компаний либо уже успешно используют данный архитектурный подход, либо собираются внедрять его в своих будущих проектах. Помимо преимуществ, микросервисный подход также подразумевает решение ряда задач, среди которых немаловажную роль играет организация взаимодействия компонентов внутри системы (inter-process communication, IPC). В настоящее время существует множество готовых решений, однако с каждым годом на рынке появляется все больше технологий, которые можно рассматривать в качестве возможных кандидатов для организации IPC в MSA. Одна из таких технологий – NoSQL база данных Redis. В рамках данной научный работы был проведен комплексный сравнительный анализ данной технологии с другим, более распространенным на рынке, решением – очередью сообщений Apache Kafka. Анализ включает в себя не только оценку производительности обоих решений, но и эмпирическую оценку сложности программных продуктов, использующих обе технологии.
Ключевые слова: микросервисная архитектура, MSA, межсервисное взаимодействие, IPC, Apache Kafka, Redis.
Использованные метрики
Для оценки производительности было принято решение использовать две наиболее распространённых метрики – пропускную способность системы (throughput) и время ответа на запрос (latency).
Пропускная способность – это общее количество запросов, обработанных системой за все время тестирования. Под обработкой подразумевается весь процесс от поступления запроса в систему до получения ответа на него. Чем выше данное значение, тем лучше.
Время ответа на запрос – среднее время, которое уходит на обработку одного запроса. В отличие от пропускной способности, чем меньше данное значение, тем лучше показатели системы.
Помимо этих двух метрик в работе был введен еще один количественный показатель производительности системы – «среднее время между этапами обработки сообщения», который вычисляется по следующей формуле:
, где:
- N – общее число замеров;
- S - множество этапов обработки запроса.
Предложенная метрика позволяет определить те этапы обработки запроса, которые занимают наибольшее время.
В рамках данной работы всего было выделено 6 этапов обработки входящего запроса:
- Регистрация запроса в системе;
- Отправка запроса из сервиса А в сервис B;
- Получение запроса в сервисе В;
- Окончание обработки запроса в сервисе B и отправка его в сервис А;
- Получение сообщения в сервисе А;
- Завершение обработки запроса.
Множество этапов 1–3 представляет асинхронное взаимодействие сервисов, в то время как множество этапов 1-6 – синхронное.
Значение показателя при
представляет для нас наибольший интерес с точки зрения производительности выбранной IPC.
Для оценки сложности использования обеих технологий было принято решение использовать метрики, предназначенные для оценки сложности исходного кода, а именно – количество строк кода (LOC), количество файлов, цикломатическую и когнитивную сложность.
Наибольший интерес представляют последние две метрики.
Цикломатическая сложность была разработан Томасом Дж. Маккейбом в 1976 года [1]. Данная метрика измеряет число линейно независимых путей в методе, которое определяется числом и сложностью условных ветвей, и вычисляется на основе графа потока управления. Низкая цикломатическая сложность обычно указывает, что исходный код прост в понимании, тестировании и обслуживании.
Когнитивная сложность кода – это метрика, позволяющая оценить на сколько сложно воспринимать написанный код. Высокая когнитивная сложность явно указывает на необходимость проведения рефакторинга кода для облегчения его будущей поддержки. Данная метрика была разработана компанией Sonar Source в 2017 году [2].
Программная платформа SonarQube, которая была использована в данной научно-исследовательской работе, позволяет получить значения всех описанных выше метрики, предназначенных для эмпирической оценки сложности кода [3].
Описание тестовой микросервисной системы
Для тестирования была создана простая микросервисная система, состоящая из двух идентичных сервисов. Каждый из них способен принимать HTTP запросы и осуществлять обмен сообщениями посредством выбранной технологии.
Упрощенная схема взаимодействия представлена на рисунке 1.
Рисунок 1. Диаграмма взаимодействия компонентов системы.
Алгоритм взаимодействия сервисов представлен на рисунке 2.
Рисунок 2. Диаграмма последовательности взаимодействия сервисов.
Сервис А отправляет сообщение в топик “service_in”, который прослушивается сервисом В. По завершению обработки, сервис B высылает ответное сообщение в топик "services_out". Как только сервис A получает данное сообщение, процесс обработки запроса считается завершенным.
Тестовое приложение было написано на языке программирования Kotlin с использованием веб-фреймворка Spring [4].
Данное решение обусловлено тем, что Spring, де-факто, является стандартом для разработки веб-серверных приложений на JVM-based языках, к которым, в том числе, относится Kotlin.
Также, немаловажным фактором является наличие большого количества различного рода интеграций Spring с другими сервисами, в том числе Spring For Apache Kafka [5] и Spring Data Redis [6]. Это упростило и ускорило разработку в разы.
Оценка производительности системы
В ходе эксперимента проводилось нагрузочное тестирование тестовых приложений с помощью программы Apache JMeter [7]. В рамках него десять параллельных потоков отправили по 1000 запросов каждый.
В таблице 1 представлены результаты тестирования микросервисной системы, использующей Redis в качестве IPC.
Таблица 1. Среднее время перехода сообщения из одного статуса в другой для Redis.
Из статуса |
В статус |
Время (нс) |
Created random message |
Sending message to Redis |
147468807.7 |
Sending message to Redis |
Successfully sent message to Redis |
228144854.1 |
Successfully sent message to Redis |
Received message in topic [service_out] |
9497148900 |
Received message in topic [service_out] |
Sending message to Redis |
276951993.4 |
Sending message to Redis |
Successfully sent message to Redis |
228144854.1 |
Successfully sent message to Redis |
Finished consuming message in topic [service_out] |
77359555.37 |
Finished consuming message in topic [service_out] |
Received message in topic [service_in] |
4010241127 |
Received message in topic [service_in] |
Finished consuming message in topic [service_in] |
222910802.2 |
Значение показателя Latency составляет 1.46E+10 нс. Все входящие сообщения были обработаны успешно, следовательно, значение параметра Throughput равно 10000.
Наибольшее количество времени занимает передача данных между сервисами – порядка 9.50E+09 нс при отправке сообщения из сервиса А в сервис В, и порядка 4.01E+09 нс в обратную сторону.
Результаты аналогичного эксперимента, проведенного над приложением, использующим Apache Kafka в качестве IPC, представлены в таблице 2.
Таблица 2. Среднее время перехода сообщения из одного статуса в другой для Kafka.
Из статуса |
В статус |
Время (нс) |
Created random message |
Sending message to Kafka |
1.25E+08 |
Sending message to Kafka |
Successfully sent message to Kafka |
1.17E+09 |
Successfully sent message to Kafka |
Received message in topic [service_out] |
4.31E+09 |
Received message in topic [service_out] |
Sending message to Kafka |
1.57E+08 |
Sending message to Kafka |
Successfully sent message to Kafka |
1.17E+09 |
Successfully sent message to Kafka |
Finished consuming message in topic [service_out] |
1.38E+08 |
Finished consuming message in topic [service_out] |
Received message in topic [service_in] |
2.99E+09 |
Received message in topic [service_in] |
Finished consuming message in topic [service_in] |
1.99E+08 |
Значение показателя Latency составляет 9.98E+09 нс. Это в 1.5 раз меньше, чем значение, полученное в ходе тестирования системы, использующей Redis в качестве IPC.
Аналогично предыдущему эксперименту, больше всего времени занимает отправка и получение сообщений. Однако, стоит отметить, что в обоих случаях, затраченное время меньше в 2 и 1.5 раза соответственно.
Также стоит отметить тот факт, что уведомление об успешной отправки сообщения было получено почти в два раза быстрее в случае использования Redis. Это можно объяснить сложностью механизма подтверждения получения и репликации сообщений, который используется в Apache Kafka.
Оценка сложности исходного кода
Значения метрик, описанных ранее, представлены в таблице 3.
Таблица 3. Сравнение сложности кода тестовых приложений.
Kafka |
Redis |
|
Cyclomatic Complexity |
18 |
19 |
Cognitive Complexity |
2 |
2 |
Lines of Code |
319 |
293 |
Number of files |
10 |
10 |
Как можно заметить, оба приложения примерно одинаковы с точки зрения сложности, однако цикломатическая сложность проекта, использующего Redis в качестве IPC немного выше.
Это обусловлено тем фактом, что, в отличии от Spring for Apache Kafka, Spring Data Redis не предоставляет никаких автоконфигураций или дополнительного функционала для упрощения создания продьюсеров и консьюмеров каналов в Redis.
Заключение
Согласно результатам проведенных экспериментов, можно сделать вывод о том, что на текущий момент времени Redis как IPC по всем параметрам проигрывает специализированной очереди сообщений Apache Kafka – как по производительности, так и по сложности внедрения и поддержки в исходном коде проектов.
Список литературы
- J. McCabe. “A Complexity Measure”. In: IEEE Transactions on Software Engineering SE-2.4 (Dec. 1976), pp. 308–320. ISSN: 0098-5589. DOI: 10.1109/TSE.1976.233837
- Ann Campbell. 2018. Cognitive complexity: an overview and evaluation. In Proceedings of the 2018 International Conference on Technical Debt (TechDebt '18). Association for Computing Machinery, New York, NY, USA, 57–58.
- SonarQube Documentation [Электронный ресурс]. – Режим доступа: https://docs.sonarqube.org/latest/ (дата доступа: 20.04.2023).
- Spring Documentation [Электронный ресурс]. – Режим доступа: https://docs.spring.io/spring-framework/docs/current/reference/html/ (дата доступа: 20.04.2023).
- Spring For Apache Kafka Documentation [Электронный ресурс]. – Режим доступа: https://docs.spring.io/spring-kafka/docs/current/reference/html/ (дата доступа: 20.04.2023).
- Spring Data Redis Documentation [Электронный ресурс]. – Режим доступа: https://docs.spring.io/spring-data/redis/docs/current/reference/html/ (дата доступа: 20.04.2023).
- Apache JMeter [Электронный ресурс]. – Режим доступа: https://jmeter.apache.org/ (дата доступа: 20.04.2023).