Использование SqlDependency вместо периодического опроса таблицы (влияние на производительность)

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

Во время тестирования мы заметили, что производительность базы данных SQL снижается из-за службы уведомлений SqlDependency. Мы уменьшили количество таблиц, которые использовали SqlDependency, и заметили значительный прирост производительности. Итак, мы подумали, что просто перебрали его, и пошли дальше. Сейчас у нас осталось всего несколько столиков.

Позже мы обнаружили, что не можем уменьшить уровень доступа безопасности для имени пользователя, которое установит зависимость. У нас может быть более одной строки подключения для каждой БД (одна для зависимости и одна для остальной части приложения), но с несколькими БД и зеркалированием БД это проблема (с точки зрения администратора БД SQL и разработки приложений).

На данный момент мы просто думаем о полном отказе от SqlDependency на основе следующей логики:

  1. Нам не нужно «мгновенное» уведомление о том, что данные изменились. Если бы мы знали в течение 1 секунды, это было бы достаточно быстро.
  2. С небольшим рефакторингом мы могли сократить его до одной таблицы и опрашивать эту таблицу раз в секунду.

Кто-нибудь видит изъян в этой логике?

Будет ли опрос одной таблицы раз в секунду вызывать большую или меньшую нагрузку на БД, чем SqlDependency?

У кого-нибудь была похожая проблема с производительностью с SqlDependency?


person SLoret    schedule 07.01.2013    source источник
comment
Как ваш опрос обнаружит, что произошли изменения? Триггеры?   -  person Martin Smith    schedule 08.01.2013
comment
В качестве боковой панели; Я никогда не использовал эту технологию, но она может оказаться полезной: msdn.microsoft.com/en-us/library/ms130764(v=sql.105).aspx   -  person MarkD    schedule 08.01.2013
comment
Я считаю комплиментом, что никто даже не попытался ответить на этот вопрос.   -  person SLoret    schedule 09.01.2013
comment
Как насчет того, чтобы сделать оба? То есть использовать триггеры для заполнения сводной таблицы флагов, а затем использовать SQLDependency для сводной таблицы?   -  person Jon Seigel    schedule 09.01.2013
comment
@JonSeigel - мы попробовали это, и это прекрасно работает, если у вас не так много изменений. Однако по мере увеличения объема изменений даже наличие зависимости только от одной таблицы снижает общую производительность. Мы пришли к выводу, что если у вас происходит небольшое количество изменений, sqldependency = самая низкая нагрузка на БД. Если у вас большое количество изменений, опрос = минимальная нагрузка на БД.   -  person SLoret    schedule 10.01.2013
comment
@SLoret Каков сейчас статус вашего проекта? Вы вернулись к опросу или все еще используете SqlDependency? Я работаю над проектом, который требует мгновенного уведомления с довольно большим объемом трафика. Основываясь на своем опыте работы с SqlDependency и опросами, могли бы вы сказать, что SqlDependency не лучший выбор для этого? Я также видел ответ Майкла Виктора Старберга ниже, и он, кажется, указывает на то, что уведомления должны быть оставлены как ответственность приложения, а не БД. Вы согласны?   -  person Anshul    schedule 19.09.2013
comment
@Anchul Мы работали в производстве без единой заминки с опросом. Лично я не буду пытаться реализовать SqlDependency в ближайшее время. Слишком большая нагрузка на БД, которая в большинстве случаев является узким местом. Для будущих реализаций мы планируем использовать memcached.org или что-то похожее на результаты кэширования из базы данных с аналогичным опросом для обнаружить изменения, чтобы мы могли обновить кеш.   -  person SLoret    schedule 02.10.2013
comment
Итак, как вы реализовали memcached? возможно, вы могли бы ответить на этот вопрос   -  person bjan    schedule 09.05.2015
comment
@bjan мы закончили внедрение memcached, используя ту же философию, и она хорошо работает для нас. У нас есть memcached, распределенный по 4 серверам, на каждом сервере есть задание, которое опрашивает назначенную таблицу в БД. Если они находят запись, они пытаются удалить эту запись. Какой бы сервер ни успешно удалил запись, этот сервер обновляет memcached новой копией данных (удаленная запись из назначенной таблицы имеет имена таблиц и идентификационные номера). Мы используем триггеры для таблиц, данные которых будут кэшироваться, для ввода записей в назначенную таблицу, которая опрашивается заданиями.   -  person SLoret    schedule 04.06.2015


Ответы (1)


Осмелюсь попробовать ответить на ваш вопрос. Но я не уверен, что вы получите ответ, на который надеялись...

Я помню еще в начале 90-х годов, когда Borland продвигала эту грандиозную новую функцию «обратных вызовов» в своей базе данных Interbase, которая давала вызывающей стороне (Delphi) «уведомления» с помощью какой-то очень изящной новой технологии, где было обещано, что база данных может быть «активной». '.

Позже это стало известно как «теория пустой траты времени.

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

Так что языки программирования в помощь. Вернее, идея сервис-ориентированной архитектуры (SOA). Многие путают SOA с «веб-сервисами», что действительно было частью этой новой концепции.

Но если вы посмотрите на шаблон проектирования Fiefdom/Emissary (или шаблон Master/Agent, переименованный, чтобы он звучал более круто и профессионально), вы обнаружите, что основная идея заключается в монопольном контроле его ресурсов (читай баз данных) и что все вызовы направляются через один единственный адаптер данных.

Очевидно, что такой дизайн вообще не работает ни с триггерами, ни с какими-либо фреймворками обратного вызова.

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

Чтобы показать, насколько странными могут быть вещи, когда они «ориентированы на базу данных», вот очень реальный живой пример того, как не отправлять электронное письмо, написанное давным-давно кодером, который меня не очень впечатлил:

Факт 1: Sql Server может отправлять электронные письма.

Факт 2: Кодировщик Asp3 не знает, можно ли и как это сделать в VbScript.

Asp3: прочитать адрес электронной почты текстового поля, отправить на уровень com+

Com+: взять адрес электронной почты и отправить на уровень данных

Datalayer: возьмите адрес электронной почты и перешлите в хранимую процедуру

Sproc: возьмите адрес электронной почты и перешлите в функцию sql

функция: делать странные вещи с подстрокой, чтобы проверить, что адрес электронной почты имеет @ . в этом. вернуть истину или ложь.

Sproc: вернуть набор записей с одним столбцом и одной строкой, содержащей 1 или 0

Уровень данных: вернуть таблицу как есть.

Com+: преобразовать первый столбец и строку со значением 1 или 0 в true или false

Asp3: если верно, отправьте адрес электронной почты с темой и текстом электронной почты на com+

Com+: отправляет точную информацию на уровень данных

Уровень данных: вызывает хранимую процедуру.

Sproc: вызывает sql-функцию...

функция: использует почтовый агент SQL Server для отправки электронной почты

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

person Michael Viktor Starberg    schedule 15.01.2013
comment
Можете быть более конкретными? - person Uri Abramson; 01.01.2017