Планирование уведомлений

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

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

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

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

SELECT ProductNumber, Name FROM Production.Product WHERE ListPrice < 300
SELECT ProductNumber, Name FROM Production.Product WHERE ListPrice < 500

В этом случае подписки на оба уведомления разделяют один общий внутренний шаблон, таким образом создавая в SQL Server меньшую дополнительную нагрузку, чем создают две подписки на запросы с разной структурой. Однако обратите внимание на то, что параметры запросов также учитываются. Несмотря на то, что запросы имеют общий шаблон, добавление элемента со значением 350 в поле ListPrice вызывает уведомление о втором запросе, а не о первом.

Если для таблицы определены активные уведомления о запросах, обновления данных в ней становятся более ресурсоемкими, поскольку компонент Database Engine выполняет дополнительную работу, проверяя подписки и при необходимости формируя уведомления. Повторное использование внутренних шаблонов позволяет минимизировать дополнительную нагрузку, приходящуюся на одну подписку. Поэтому уведомления о запросах следует использовать только для тех приложений, которые выполняют запросы с одинаковой структурой. Не стоит использовать их для приложений, выполняющих запросы с разной структурой.

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

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

Планирование эффективной стратегии уведомлений о запросах

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

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

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

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

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

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

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

Альтернативы уведомлениям о запросах

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

  • Создайте на отслеживаемой таблице триггер AFTER UPDATE, действие которой использует компонент SQL Server Service Broker для отправки сообщения сущности, ожидающей уведомления. Этого можно добиться несколькими способами, например добавить в нужную таблицу столбец с указанием сущности, которую следует оповещать об изменениях; кроме того, можно присоединить главную таблицу ко второй таблице, содержащей сведения о сущности, требующей уведомления.

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

  • Используйте кэш Windows Server App Fabric, поддерживающий механизм уведомлений об изменениях, основанный на хранимом в памяти кэше объектов и функциях обратного вызова, которые можно зарегистрировать в объектах.

См. также

Основные понятия