Упускаемый из виду эффект размера данных
Особая благодарность Озгюру Каракая , с которым я написал этот пост в соавторстве.
PDP (страница сведений о продукте) в Trendyol — это группа, отвечающая за предоставление информации о конкретных продуктах. Эта информация включает в себя цену, размер, цвет продукта или другую важную информацию, которую клиенты хотят знать перед покупкой. Информация может быть представлена двумя разными способами: первый — в виде одной страницы сведений о продукте, в основном, когда вы нажимаете на продукт и переходите на страницу, где отображается конкретная информация о продукте. Команда также отвечает за предоставление сведений о продукте другим представлениям на веб-сайте, т. е. ваш список избранного, рекомендуемые продукты и оформление заказа. Оба способа обрабатывались одной службой под названием API сведений о продукте, поддерживаемой базой данных NoSQL, обслуживающей отдельные запросы (одна страница сведений о продукте), а также массовые запросы (список избранного и т. д.).
Перед событием «Черная пятница» 2021 года команда поставила цель обрабатывать 8 миллионов запросов в минуту для массовых запросов. Одна из проблем заключалась в том, что служба работала плохо в виде повышенного использования памяти и значительного количества ошибок при высокой пропускной способности. Задача состояла в том, чтобы найти способ оптимизировать сервис.
Итак, вот это путешествие.
Мозговой штурм и анализ
На этапе анализа команда PDP обнаружила, что клиенты, отправляющие массовые запросы, не используют все поля в документе базы данных. Первым пунктом оптимизации было введение новой модели документа без этих ненужных полей. Преимущества такой реструктуризации:
- оптимизация размера данных
- фокус домена массового содержания
Ниже представлена схема существующей и новой архитектуры того времени:
Пунктирные внешние прямоугольники определяют границы услуги. Обратите внимание, что на этой первой иллюстрации одна служба отвечала за обработку всего конвейера операций. Сама оптимизация заключалась в разделении конвейера преобразования на два отдельных процесса, как это видно во второй архитектуре: процесс преобразования во время индексирования и служба массового содержимого. Последний — это служба чтения, которая обрабатывает HTTP-запросы. Первый оказался управляемым событиями процессом, который считывает данные из ProductContent CB (Source Of Truth), частично обрабатывает, а затем сохраняет их в Counchbase Bucket для использования последним. Но об этом чуть позже.
В предлагаемой новой архитектуре основное преимущество заключается в том, что процесс выполнения будет оптимизирован, что, в свою очередь, сократит время отклика службы.
В этом блоге мы сосредоточимся на процессе Index-time. Для получения дополнительной информации о «Службе массового контента» проверьте этот пост Энеса Тургута.
PS Я использую термин время выполнения здесь довольно свободно. В контексте этого блога мы определяем время выполнения как последовательность операций, запускаемых входящим HTTP-запросом.
Существующие решения
На данный момент команда остановилась на новой архитектуре. Теперь пришло время его реализовать. То, что мы пытаемся достичь, — это решение для преобразования дивана в диван в режиме, близком к реальному времени. Couchbase уже предлагает репликацию по всему кластеру, однако форму данных необходимо изменить, поэтому обычная репликация, очевидно, не подходит. Разве не было бы здорово, если бы существовал способ манипулирования данными во время процесса репликации? просматривая документацию Couchbase, мы наткнулись на Couchbase Eventing Service. Мы только что сорвали джекпот?
Событие Couchbase:
Couchbase Eventing Service — это платформа для работы с изменениями данных в режиме реального времени. События — это изменения данных в кластере Couchbase.
Couchbase Eventing показался нам подходящим, потому что вы можете :
- Распространение изменений на другие системы
- Обогащайте документ в режиме реального времени
- Не требует обслуживания
Нет джекпота.
Наше решение (конвертер данных массового содержания)
Вдохновленный коннектором CB Elasticsearch .
Couchbase Elasticsearch Connector реплицирует ваши документы с сервера Couchbase на Elasticsearch почти в реальном времени. Коннектор использует высокопроизводительный протокол изменения базы данных (DCP) для получения уведомлений об изменении документов в Couchbase.
Замените Elasticsearch на Couchbase, и вы получите именно то, что нам нужно. Все, что нам нужно сделать, это принять мутации (обновления) документа из очереди DCP, обработать их, а затем записать в новую корзину.
Имейте в виду, что решение должно уметь:
- Масштабируйте по мере роста количества документов и мутаций.
- Выполняйте сквозной процесс (прием сообщений из очереди, преобразование модели данных и запись ее в новую корзину) почти в режиме реального времени.
- Управляйте существующими, а не только новыми документами, когда новые поля добавляются в модель документа или удаляются из нее.
- Предоставьте механизм для восстановления документов с нуля в случае серьезного повреждения данных.
Ну, здесь есть что распаковать, давайте сначала подведем итоги:
Приведенная выше архитектура показывает окончательное решение. В конечном счете, Product Detail Service будет обрабатывать отдельные запросы, а Bulk Content Service — массовые запросы. Услуги поддерживаются различными источниками диванной базы. В то время как ProductContent CB представляет собой Источник Истины, ProductSummary CB представляет собой его сводную предварительно обработанную версию. Преобразование будет выполняться в Bulk Content Data Converter практически в режиме реального времени путем принятия изменений документа из очереди DCP. Каждая мутация документа представляет собой состояние документа после того, как произошло обновление. Это еще один способ сказать, что конвертер автоматически получит весь обновленный документ из ProductContent CB.при каждом обновлении.
Чтобы понять, как именно масштабируется это решение, стоит взглянуть на конфигурационный файл конвертера:
{
"group": {
"name": "v20220909",
"membership": {
"memberNumber": 1,
"totalMembers": n
},
"limit": {
"bytes": "5m",
"actions": 100,
"timeout": "1m",
"concurrency": 2
},
"version": 1,
"ignoreDelete": false
},
"dcp": {
"sourceConfig": {
"hosts": ["source_couchbase_host"],
"network": "auto",
"bucket": "bucketName",
"metadataBucket": "metadataBucketName",
"scope": "",
"collections": [],
"compression": true,
"flowControlBuffer": "16m",
"persistencePollingInterval": "100ms"
},
"targetConfig": {
"hosts": ["taget_couchbase_host"],
"bucket": "targetBucketName"
}
}
}
Другой важной частью конфигурации является group.name , которая представляет группу потребителей, в которой хранится смещение, подобно группам потребителей Kafka. Изменение этой конфигурации сбрасывает индекс смещения, что означает, что все состояние базы данных будет отправлено через очередь DCP. Это особенно удобно, когда требуется обновление модели документа, добавление или удаление новых полей из целевого сегмента требует полного обновления всех сохраненных документов, включая документы, которые в противном случае просто не обновлялись бы в целевом сегменте. потому что в исходных документах не произошло бы никаких мутаций. Он также может функционировать как механизм полной регенерации базы данных в случае серьезного повреждения данных.
Для получения дополнительной информации о конфигурации, пожалуйста, проверьте ссылку на документацию .
Другой момент оптимизации заключался в том, чтобы уменьшить размер целевого документа за счет использования аббревиатур или отдельных символов в качестве узлов JSON. Эксперты в предметной области и продакт-менеджеры не должны понимать смысл этого документа, и именно поэтому нам могут сойти с рук такие злые взломы. Ниже приведен пример документа:
И по состоянию на 31 октября результат…
Этот простой хак позволил нам уменьшить размер корзины с 2,92 ТБ до 595 ГБ! Уменьшение размера удара примерно на 80%!
Также следует заметить, что количество документов в целевой БД уменьшилось примерно на 12 миллионов. Причина в том, что мы исключили товары, которых нет в наличии и которые не обновлялись в течение 12 месяцев. В корзине с исходным кодом нам все еще могут понадобиться эти документы, но иметь их здесь не имеет смысла, отсюда и разница в количестве.
Мониторинг и производительность
Пока у нас есть готовое решение. Но как точно определить, достаточно ли он эффективен? что, если он, гипотетически, выполняет преобразование, но отстает, скажем, на 2 секунды? Это было бы полной катастрофой! такая возможная согласованность будет просачиваться в пользовательский интерфейс веб-сайта и серьезно влиять на работу пользователей. Запуск изменений в производственной базе данных вручную невозможен и не должен использоваться в первую очередь для тестирования. Необходим системный подход, чтобы точно определить источник отставания, если оно произойдет. Задержка происходит из-за перегрузки в очереди DCP? Или это из-за того, что у конвертера какая-то ошибка?
Чтобы ответить на эти вопросы, мы ввели три показателя, как показано на рисунке ниже:
Исходный документ содержит отметку времени последнего обновления, мы называем это LMD (дата последнего изменения). Как только конвертер получает мутацию, время « Ожидание в очереди DCP» можно легко рассчитать, вычитая LMD из time.now() . Затем метрики предоставляются Prometheus, как показано на графиках ниже:
Ограничения:
Помните, я говорил ранее, что масштабирование — это всего лишь вопрос увеличения общего количества преобразователей? Что ж, здесь есть небольшая оговорка: конфигурация решения немного жестко привязана к инфраструктуре, с которой оно взаимодействует; Автоматическая перебалансировка потребителей в очереди DCP и распределение потребителей по виртуальным корзинам жестко связаны со статической конфигурацией, которую потребитель имеет при запуске. Чтобы изменить это, необходимо изменить сам файл конфигурации, что требует нового развертывания. Более того, каждому потребителю нужен свой собственный статический файл конфигурации, что означает, что каждому потребителю необходимо — в терминологии Kubernetes — иметь свои собственные файлы ресурсов развертывания. В Trendyol мы широко используем ArgoCD с Kustomize для управления нашими развертываниями, масштабирование решения требует добавления — в терминологии ArgoCD — нового ApplicationSet.
Однако до сих пор наша шкала из 8 потребителей справляется с большой нагрузкой с эффективностью, близкой к реальному времени. Но по мере того, как ведро источника становится больше, а количество мутаций растет, требуется ручная перенастройка потребителей.
Внутреннее использование других команд
Будучи уверенными в разработанном соединителе CB-to-CB, команда PDP решила представить его другим командам в Trendyol. Команда получила много положительных отзывов, и, прежде чем мы узнали об этом, команда поиска решила разветвить проект и использовать его в своем домене, где они хранят события домена в базе данных Couchbase и используют соединитель CB-to-CB для создания другой модели документа. для последующего использования. Такое внедрение решений, разработанных внутри компании, вдохновляет всех нас двигаться вперед и продолжать улучшать и совершенствовать использование технологий.
Подайте заявку на наши открытые вакансии здесь !

![В любом случае, что такое связанный список? [Часть 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































