Научная статья на тему 'ПОНИМАНИЕ CQRS: АРХИТЕКТУРНЫЙ ШАБЛОН ДЛЯ РАЗДЕЛЕНИЯ ОПЕРАЦИЙ ЧТЕНИЯ И ЗАПИСИ ДАННЫХ'

ПОНИМАНИЕ CQRS: АРХИТЕКТУРНЫЙ ШАБЛОН ДЛЯ РАЗДЕЛЕНИЯ ОПЕРАЦИЙ ЧТЕНИЯ И ЗАПИСИ ДАННЫХ Текст научной статьи по специальности «Компьютерные и информационные науки»

263
24
i Надоели баннеры? Вы всегда можете отключить рекламу.
Ключевые слова
CQRS / АРХИТЕКТУРНЫЙ ШАБЛОН / ОПЕРАЦИИ ЧТЕНИЯ И ЗАПИСИ ДАННЫХ / КОМАНДНЫЕ МОДЕЛИ / МОДЕЛИ ЗАПРОСОВ / ШИНЫ КОМАНД / ШИНЫ ЗАПРОСОВ / МАСШТАБИРУЕМОСТЬ / ХРАНЕНИЕ ДАННЫХ / АГРЕГАЦИЯ ДАННЫХ / ТРАНЗАКЦИИ / СОГЛАСОВАННОСТЬ ДАННЫХ

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Пивоваров В.В., Нуркаев Р.Р., Хабибуллин Р.М.

Статья представляет обзор архитектурного шаблона Command Query Responsibility Segregation (CQRS) и его применение в разработке программного обеспечения. Ее цель - помочь разработчикам понять и применить CQRS для создания более гибких и масштабируемых систем, обеспечивая оптимальную производительность и удовлетворение требований бизнеса. CQRS - это подход, который основывается на принципе разделения операций чтения и записи данных в системе. Авторами предлагается подробное объяснение концепции CQRS, включая различия между командами и запросами. Объясняется, как CQRS может помочь в улучшении масштабируемости, производительности и гибкости системы. Описываются основные компоненты CQRS, такие как командные модели, модели запросов, шины команд и шины запросов. Исследуется практическая реализация CQRS, включая различные аспекты, такие как хранение данных, обработка команд и запросов, агрегация данных и согласование между командами и запросами. Обсуждаются различные стратегии синхронизации данных и подходы к обновлению представлений. В заключение подводятся итоги и подчеркиваются преимущества и недостатки CQRS, а также обсуждаются области его наилучшего применения.

i Надоели баннеры? Вы всегда можете отключить рекламу.
iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

UNDERSTANDING CQRS: AN ARCHITECTURAL PATTERN FOR SEPARATING DATA READS AND WRITES

The article provides an overview of the Command Query Responsibility Segregation (CQRS) architectural pattern and its application in software development. Its goal is to help developers understand and apply CQRS to build systems that are more flexible and scalable for optimal performance and business requirements. CQRS is an approach that is based on the principle of separating reads and writes of data in the system. The authors offer a detailed explanation of the concept of CQRS, including the differences between commands and queries. Explains how CQRS can help improve system scalability, performance, and flexibility. Describes the main components of CQRS, such as command models, query models, command buses, and query buses. The practical implementation of CQRS is explored, including various aspects such as data storage, command and query processing, data aggregation, and coordination between commands and queries. Various data synchronization strategies and approaches to updating views are discussed. The conclusion summarizes and highlights the advantages and disadvantages of CQRS and discusses its best applications.

Текст научной работы на тему «ПОНИМАНИЕ CQRS: АРХИТЕКТУРНЫЙ ШАБЛОН ДЛЯ РАЗДЕЛЕНИЯ ОПЕРАЦИЙ ЧТЕНИЯ И ЗАПИСИ ДАННЫХ»

Понимание ООРБ: Архитектурный шаблон для разделения операций чтения и записи данных_

Пивоваров Виталий Владиславович

бакалавр, инженер-программист, Университет Иннополис, pivovarov.vitaliy.work@gmail.com

Нуркаев Руставиль Рустамович

бакалавр, инженер-программист Swedbank Group, rustaviln@gmail.com

Хабибуллин Ринат Мударисович

специалист, специалист технического обслуживания, Smertrios Limited mail@rinat.pro

Статья представляет обзор архитектурного шаблона Command Query Responsibility Segregation (CQRS) и его применение в разработке программного обеспечения. Ее цель - помочь разработчикам понять и применить CQRS для создания более гибких и масштабируемых систем, обеспечивая оптимальную производительность и удовлетворение требований бизнеса. CQRS - это подход, который основывается на принципе разделения операций чтения и записи данных в системе. Авторами предлагается подробное объяснение концепции CQRS, включая различия между командами и запросами. Объясняется, как CqRs может помочь в улучшении масштабируемости, производительности и гибкости системы. Описываются основные компоненты CQRS, такие как командные модели, модели запросов, шины команд и шины запросов. Исследуется практическая реализация CQRS, включая различные аспекты, такие как хранение данных, обработка команд и запросов, агрегация данных и согласование между командами и запросами. Обсуждаются различные стратегии синхронизации данных и подходы к обновлению представлений. В заключение подводятся итоги и подчеркиваются преимущества и недостатки CQRS, а также обсуждаются области его наилучшего применения.

Ключевые слова: CQRS, архитектурный шаблон, операции чтения и записи данных, командные модели, модели запросов, шины команд, шины запросов, масштабируемость, хранение данных, агрегация данных, транзакции, согласованность данных.

п

сч

о

сч

(0

01

Z

52

Введение

CQRS (Command Query Responsibility Segregation) - это паттерн проектирования, который получил значительное внимание в области архитектуры и разработки программного обеспечения. Он предоставляет уникальный подход к управлению сложностью современных приложений, разделяя задачи чтения данных (запросы) и модификации данных (команды). Это разделение позволяет создавать высокомасштабируемые и эффективные системы, которые лучше справляются с растущими требованиями современных приложений.

В данной статье мы подробно рассмотрим концепцию CQRS, обсудим его основные принципы, преимущества и стратегии реализации. Мы рассмотрим фундаментальные концепции, лежащие в основе CQRS, включая разделение операций чтения и записи, использование разных моделей для каждой операции и роль событийного источника и архитектуры на основе событий.

Кроме того, мы рассмотрим преимущества применения паттерна CQRS в проектах разработки программного обеспечения. Мы исследуем, как он обеспечивает повышенную производительность, масштабируемость и поддерживаемость приложений, а также облегчает реализацию сложных бизнес-требований. Мы обсудим потенциальные проблемы и соображения, которые разработчики должны учитывать при реализации CQRS в своих проектах.

На протяжении всей статьи мы предоставим практические примеры и идеи, чтобы помочь читателям получить четкое представление о CQRS и его применимости в реальных сценариях. В конце статьи читатели будут иметь всеобъемлющее представление о CQRS и будут оснащены знаниями, чтобы оценить, подходит ли он для их собственных проектов разработки программного обеспечения.

Цели исследования

Цели исследования CQRS могут включать в себя следующие аспекты:

1. Изучение принципов и концепций CQRS. Основной целью исследования является понимание принципов, концепций и основных преимуществ CQRS. Это включает разделение задач чтения и записи, использование разных моделей данных, применение событийного источника и архитектуры на основе событий.

2. Оценка применимости CQRS в конкретном контексте. Исследование должно позволить оценить, насколько CQRS соответствует требованиям и целям конкретного проекта или системы. Это включает анализ основных преимуществ и недостатков

CQRS и определение, какие сценарии и бизнес-задачи могут наиболее эффективно использовать этот подход.

3. Анализ влияния CQRS на производительность и масштабируемость. Одним из главных аспектов исследования CQRS является оценка его влияния на производительность и масштабируемость системы. Исследование должно позволить оценить, насколько CQRS может помочь в улучшении производительности приложения, особенно в условиях повышенной нагрузки и больших объемов данных.

4. Исследование лучших практик и стратегий реализации CQRS. Целью исследования является изучение различных подходов и стратегий реализации CQRS. Исследование должно помочь определить наиболее эффективные методы и рекомендации по проектированию и разработке систем, использующих CQRS.

В целом, исследование CQRS направлено на обеспечение более глубокого понимания этого паттерна и его применимости в различных контекстах. Результаты исследования могут помочь разработчикам и архитекторам принять обоснованные решения относительно применения CQRS в своих проектах и улучшить производительность и масштабируемость своих систем.

Что такое CQRS?

CQRS (Command Query Responsibility Segregation) - это архитектурный паттерн, который позволяет разделять операции записи и чтения в приложении на два разных компонента. Этот подход нашел широкое применение в распределенных системах, где обработка операций записи и чтения может занимать большое количество времени и ресурсов.

Основная идея CQRS заключается в том, что операции чтения и записи являются разными и должны быть реализованы в виде отдельных компонентов. Компонент, отвечающий за операции записи, работает с моделью данных, обеспечивая изменение ее состояния. Компонент, отвечающий за операции чтения, работает с копией модели данных, которая не изменяется в процессе операций чтения.

Для реализации CQRS необходимо разделить модель данных на две части: одну для операций записи и другую для операций чтения. Модель данных, используемая для операций записи, может быть более сложной, чем модель данных для операций чтения, поскольку она должна обеспечивать возможность изменения состояния объектов. Модель данных, используемая для операций чтения, должна быть оптимизирована для быстрого доступа к данным и быстрого выполнения запросов.

CQRS может быть использован в различных типах приложений, таких как электронная коммерция, финансовые приложения, системы управления заказами и т.д. В этих приложениях операции записи и чтения могут занимать большое количество вре-

мени и ресурсов, поэтому использование CQRS может значительно повысить производительность и масштабируемость систем.

Основные компоненты CQRS

В CQRS основными компонентами являются: командные модели (Command Models), модели запросов (Query Models), шины команд (Command Buses) и шины запросов (Query Buses). Вот их подробное описание [1]:

1. Командные модели (Command Models): Командные модели представляют структуру данных и логику, которые определяют операции записи или изменения состояния системы. Они представляют команды, которые инициируют изменения данных в системе. Командные модели могут содержать вали-дацию данных, бизнес-логику и правила, связанные с операциями записи. Когда команда отправляется в систему, командная модель обрабатывает эту команду и выполняет необходимые изменения в данных.

2. Модели запросов (Query Models): Модели запросов представляют структуру данных и логику, которые определяют операции чтения или получения данных из системы. Они представляют запросы, которые возвращают информацию или представления состояния системы. Модели запросов ориентированы на предоставление оптимизированных и оптимизированных для чтения представлений данных. Эти модели могут быть оптимизированы для конкретных запросов и предоставлять только необходимую информацию.

3. Шины команд (Command Buses): Шины команд представляют средства для отправки команд из пользовательского интерфейса или других компонентов системы к соответствующим командным моделям для их обработки. Шины команд обычно предоставляют механизмы маршрутизации команд к соответствующим обработчикам и управления потоком команд в системе. Они могут также обеспечивать дополнительные функции, такие как очереди сообщений, распределение команд и контроль доступа.

4. Шины запросов (Query Buses): Шины запросов представляют средства для отправки запросов из пользовательского интерфейса или других компонентов системы к соответствующим моделям запросов для получения данных. Шины запросов обеспечивают механизмы маршрутизации запросов к соответствующим обработчикам и управления потоком запросов в системе. Они могут также обеспечивать дополнительные функции, такие как кэширование результатов запросов и оптимизация выполнения запросов.

Эти компоненты CQRS позволяют явно разделить операции чтения и записи данных в системе. Они обеспечивают более гибкую архитектуру, позволяющую оптимизировать каждую сторону разделенных операций и обеспечить более эффективное использование ресурсов. Командные модели и модели запросов определяют структуру данных и биз-

О *

О X

о

3

S *

и

с т ■и о s т о а г

о т

09 8)

сч о сч

нес-логику, а шины команд и запросов обеспечивают механизмы и инфраструктуру для обработки команд и запросов в системе.

Примеры применения ООКБ:

1. Использование CQRS в микросервисной архитектуре. В микросервисной архитектуре CQRS может использоваться для разделения операций записи и чтения на разные микросервисы. Например, у нас может быть микросервис, который отвечает только за операции записи данных в базу данных, а другой микросервис отвечает только за операции чтения данных из базы данных.

2. Использование CQRS в приложении для продажи билетов. В приложении для продажи билетов CQRS может использоваться для разделения операций записи и чтения на разные модели. Мы можем иметь модель для операций записи (например, создание нового мероприятия или продажа билетов), и модель для операций чтения (например, получение списка мероприятий или билетов).

3. Использование CQRS в системе управления задачами. В системе управления задачами CQRS может использоваться для разделения операций записи и чтения на разные модели. Например, у нас может быть модель для операций записи (например, создание новой задачи или изменение статуса задачи), и модель для операций чтения (например, получение списка задач или информации о задаче).

4. Использование CQRS в системе управления транзакциями. В системе управления транзакциями CQRS может использоваться для разделения операций записи и чтения на разные модели. Например, у нас может быть модель для операций записи (например, создание новой транзакции или изменение статуса транзакции), и модель для операций чтения (например, получение списка транзакций или информации о транзакции).

Преимущества [2,3]:

1. Разделение задач. Одним из основных преимуществ CQRS является разделение задач на два разных компонента - для операций записи и чтения. Это позволяет упростить модель данных и увеличить гибкость архитектуры, так как каждый компонент может быть оптимизирован для своих задач.

2. Оптимизация производительности. Компоненты CQRS могут быть оптимизированы для своих задач. Компонент, отвечающий за операции записи, может использовать более сложные модели данных для обеспечения возможности изменения состояния объектов. Компонент, отвечающий за операции чтения, может использовать упрощенные модели данных, что обеспечивает более быстрый доступ к данным и увеличивает производительность приложения.

3. Масштабируемость. CQRS обеспечивает возможность масштабирования системы горизонтально, позволяя каждой части системы масштабироваться независимо от другой части. Это позволяет достичь более высокой производительности и снизить нагрузку на систему в целом.

4. Улучшенная безопасность. Использование разных моделей данных для операций записи и чтения позволяет обеспечить более гранулярный контроль над доступом к данным и улучшить безопасность приложения.

5. Расширяемость. CQRS позволяет легко добавлять новые функции и компоненты, так как каждый компонент может быть разработан для своих задач и не зависит от других компонентов. Это обеспечивает более гибкую и расширяемую архитектуру приложения.

6. Более чистый код. Разделение задач на два компонента упрощает модель данных и обеспечивает более чистый код, что делает приложение более понятным и легко поддерживаемым.

7. Лучшая поддержка доменной модели. CQRS поддерживает использование доменной модели в приложении, что позволяет создавать более гибкие и масштабируемые приложения.

Недостатки [2,3]:

1. Усложнение архитектуры. Использование CQRS усложняет архитектуру приложения, так как требует создания двух отдельных компонентов для обработки операций записи и чтения. Это может привести к увеличению времени разработки и усложнению поддержки приложения.

2. Сложность внесения изменений. Внесение изменений в систему, построенную на CQRS, может быть сложным, так как изменения могут затронуть как компоненты записи, так и компоненты чтения. Это требует более тщательного тестирования и может привести к увеличению времени на внесение изменений.

3. Дополнительная нагрузка на сервер. Использование CQRS может привести к дополнительной нагрузке на сервер, так как каждый компонент должен обрабатывать свои задачи. Это может привести к увеличению затрат на аппаратное обеспечение и снижению производительности приложения.

4. Усложнение разработки. CQRS может усложнить разработку приложения, так как требует более глубокого понимания доменной модели и более сложной архитектуры приложения. Это может быть особенно сложным для разработчиков, не имеющих опыта работы с CQRS.

5. Дополнительные затраты на обучение. Использование CQRS требует обучения разработчиков, чтобы они могли понимать и использовать этот паттерн проектирования. Это может привести к дополнительным затратам на обучение и повышение квалификации персонала.

6. Увеличение времени отклика. Использование CQRS может привести к увеличению времени отклика на запросы, так как каждый компонент должен обрабатывать свои задачи. Это может быть особенно заметным при обработке запросов на чтение данных, когда каждый запрос должен быть обработан отдельно.

7. Необходимость поддержки транзакций. При использовании CQRS необходимо обеспечить поддержку транзакций между компонентами записи и

чтения, что может привести к дополнительным затратам на разработку и поддержку приложения.

Принципы и стратегии реализации CQRS

Основные принципы и стратегии реализации CQRS (Command Query Responsibility Segregation) включают [4]:

1. Разделение ответственности. Основной принцип CQRS заключается в явном разделении операций чтения (запросов) и операций записи (команд). Вместо того, чтобы использовать единую модель для обоих типов операций, CQRS предлагает разработку двух отдельных моделей: модель команд для операций записи и модель запросов для операций чтения.

2. Отделение моделей данных. В контексте CQRS, модели данных для операций чтения и записи могут быть разными. Модель чтения оптимизирована для предоставления быстрого доступа к данным и удовлетворения запросов, в то время как модель записи фокусируется на обработке команд и изменении состояния системы.

3. Использование асинхронной коммуникации. Для обеспечения эффективной коммуникации между моделью команд и моделью запросов, CQRS рекомендует использовать асинхронные механизмы передачи информации, такие как сообщения или события. Это позволяет разделить обработку команд и обновление модели записи от обработки запросов и получения данных из модели чтения.

4. Использование событийного источника. Часто CQRS сочетается с паттерном событийного источника (Event Sourcing). Событийный источник предлагает сохранять все изменения состояния системы в виде событий, которые могут быть записаны и воспроизведены. Это позволяет хранить историю изменений, а также восстанавливать состояние системы в прошлом.

5. Применение архитектуры на основе событий. CQRS хорошо сочетается с архитектурой на основе событий (Event-Driven Architecture, EDA), где компоненты системы взаимодействуют через асинхронную обработку событий. Это позволяет создавать более гибкие, расширяемые и отказоустойчивые системы.

6. Управление консистентностью данных. Разделение операций чтения и записи может привести к возникновению проблем с консистентностью данных. Для решения этой проблемы, CQRS предлагает использование подходов, таких как асинхронная репликация данных, использование консистентных хэшей (consistent hashing) или использование моделей консистентности, таких как Eventual Consistency (конечная консистентность).

Проблемы и решения реализации CQRS в проектах

При реализации CQRS в своих проектах разработчики должны учитывать следующие потенциальные проблемы [4, 5-7]:

1. Сложность и увеличение сложности кода. Разделение операций чтения и записи может приве-

сти к увеличению сложности кода и архитектуры системы. Разработчики должны быть готовы к этой сложности и принять подходящие методы и инструменты для управления этой сложностью, такие как использование шаблонов проектирования, хорошей организации кода и четкой документации.

2. Согласованность данных. Разделение операций чтения и записи может создавать проблемы с согласованностью данных в системе. При обновлении состояния системы через операции записи, может возникнуть необходимость в обновлении соответствующих данных в модели чтения. Разработчики должны разработать стратегии для обеспечения согласованности данных, например, использование асинхронной репликации данных или применение моделей консистентности данных, таких как Eventual Consistency (конечная консистентность).

3. Сложности в обеспечении консистентность. При использовании CQRS может возникнуть сложность в обеспечении консистентности между моделью чтения и моделью записи. Разработчики должны разработать стратегии и механизмы для обеспечения согласованности данных между моделями, такие как использование транзакций, событийного источника или механизмов согласования, чтобы избежать возникновения инконсистентного состояния.

4. Повышенная сложность тестирования. Разделение операций чтения и записи может повысить сложность тестирования системы, поскольку тестирование каждой модели может требовать различных подходов и средств. Разработчики должны разработать хороший план тестирования, который учитывает специфику каждой модели и обеспечивает полное покрытие тестами.

5. Увеличение накладных расходов. Внедрение CQRS может привести к увеличению накладных расходов на разработку и обслуживание системы. Разработчики должны оценить эти накладные расходы и убедиться, что выгоды, такие как повышенная производительность и масштабируемость, оправдывают эти дополнительные расходы.

При реализации CQRS разработчики должны иметь ясное понимание этих потенциальных проблем и выбирать подходы и стратегии, которые помогут справиться с ними в конкретном контексте своего проекта [5].

Заключение

В заключение, CQRS (Command Query Responsibility Segregation) представляет собой мощный архитектурный подход, который может принести значительные преимущества разработчикам приложений. Разделение операций чтения и записи позволяет оптимизировать производительность и масштабируемость системы, улучшить поддержи-ваемость и облегчить реализацию сложных бизнес-требований.

CQRS требует тщательного проектирования и реализации, поскольку он вносит дополнительную сложность в архитектуру приложения. Разработчики должны учитывать потенциальные проблемы, такие

О *

О X

о

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

3

S *

8)

с т

■и о

s

т

ф а г

о т

09 8)

как согласованность данных и сложность тестирования, и применять соответствующие стратегии и инструменты для их управления.

Однако, если правильно применить CQRS, можно достичь значительного улучшения производительности, масштабируемости и поддерживаемо-сти приложений. Разработчики получают большую гибкость в разработке и эволюции системы, а бизнес может получить более эффективное и отзывчивое приложение, соответствующее своим требованиям.

В целом, CQRS представляет собой мощный инструмент, который стоит рассмотреть для проектирования и разработки сложных и масштабируемых приложений, с целью повышения производительности, эффективности и удовлетворения требований бизнеса.

Литература

1. Betts, D., Domínguez, J., Melnik, G., Simonazzi F., Subramanian, M., Young, G. (2013) Exploring CQRS and Event Sourcing: A journey into high scalability, availability, and maintainability with Windows Azure. N.Y.: Microsoft patterns & Practices.

2. Millett, S., Tune, N. (2015) Patterns, Principles, and Practices of Domain-Driven Design. Rochester: Wrox Press.

3. Newman, S. (2015) Building Microservices: Designing Fine-Grained Systems. CA: O'Reilly Media.

4. Nijhof, M., Hermida, S. (2013) CQRS, The example. Roskey: Cre8iveThought, Leanpub.

5. Вернон, В. (2020) Предметно-ориентированное проектирование. Самое основное; пер. с англ. Д.А. Клюшкин. М.: Диалектика.

6. Эванс Э. Предметно-ориентированное проектирование (DDD). Структуризация сложных программных систем; пер. с англ. В.Л. Бородовой. - М.: Вильямс, 2018. - 448 с.

7. Vernon, V. (2013) Implementing Domain-Driven Design. N.Y.: Addison-Wesley Professional.

Understanding CQRS: An architectural pattern for separating data reads and writes

Pivovarov V.V., Nurkaev R.R., Khabibullin R.M.

Innopolis University, Swedbank Group, Smertrios Limited

The article provides an overview of the Command Query Responsibility Segregation (CQRS) architectural pattern and its application in software development. Its goal is to help developers understand and apply CQRS to build systems that are more flexible and scalable for optimal performance and business requirements. CQRS is an approach that is based on the principle of separating reads and writes of data in the system. The authors offer a detailed explanation of the concept of CQRS, including the differences between commands and queries. Explains how CQRS can help improve system scalability, performance, and flexibility. Describes the main components of CQRS, such as command models, query models, command buses, and query buses. The practical implementation of CQRS is explored, including various aspects such as data storage, command and query processing, data aggregation, and coordination between commands and queries. Various data synchronization strategies and approaches to updating views are discussed. The conclusion summarizes and highlights the advantages and disadvantages of CQRS and discusses its best applications.

Keywords: CQRS, architectural pattern, data read and write operations, command models, query models, command buses, query buses, scalability, data storage, data aggregation, transactions, data consistency.

References

1. Betts, D., Dominguez, J., Melnik, G., Simonazzi F., Subramanian, M., Young, G. (2013) Exploring CQRS and Event Sourcing: A journey into high scalability, availability, and maintainability with Windows Azure. N.Y.: Microsoft patterns & practices.

2. Millett, S., Tune, N. (2015) Patterns, Principles, and Practices of Domain-Driven Design. Rochester: Wrox Press.

3. Newman, S. (2015) Building Microservices: Designing Fine-Grained Systems. CA: O'Reilly Media.

4. Nijhof, M., Hermida, S. (2013) CQRS, The example. Roskey: Cre8iveThought, Leanpub.

6. Vernon, V. (2020) Domain-Driven Design. The most basic; per. from English. YES. Klyushkin. Moscow: Dialectics.

7. Evans E. Domain-oriented design (DDD). Structuring of complex software systems; per. from English. V.L. Borodova. - M.: Williams, 2018. - 448 p.

8. Vernon, V. (2013) Implementing Domain-Driven Design. N.Y.: Addison-Wesley Professional.

(0 СЧ

о

СЧ (О

i Надоели баннеры? Вы всегда можете отключить рекламу.