воскресенье, 1 июля 2018 г.

Анализ производительности Azure SQL (PaaS) Database на примере DTU

Столкнулся я с довольно стандартной задачей по анализу инфраструктуры SQL PaaS Azure. Microsoft Azure предоставляет нам три варианта, с помощью которых мы можем получить информацию по утилизации ресурса - портал Azure, SQL request, PowerShell. Выглядит всё очень просто и очевидно, но так ли оно? :) Попробуем разобраться с некоторыми особенностями анализа полученных данных.



Самый простой способ приблизительно оценить ресурсы, которые потребляет наша база данных SQL - это посмотреть график на портале Microsoft Azure. Меня, в первую очередь, интересовала утилизация DTU. Для того, чтобы его увидеть, нам надо перейти в обзор базы данных на портале, кликнуть по графику, который предоставляется по дефолту и выбрать набор показателей, которые нас интересуют. Так же указать период, за который надо выводить данные. Вот мой пример:


В данном случае мы видим, что за последнюю неделю пиковая нагрузка составила приблизительно 10,5 DTU. Произошло это примерно в 12:00 27 июля. В моем случае, этой информации было-бы более-менее достаточно, но таких баз данных у меня очень много и анализировать все вручную желания не возникло. Поэтому будем продолжать разбираться дальше.

Официальная документация предлагает для мониторинга нагрузки использовать SQL запросы:
https://docs.microsoft.com/en-us/azure/sql-database/sql-database-single-database-monitor

В статье выше примера запроса потребления DTU нет, поэтому находим еще одну:
https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-db-resource-stats-azure-sql-database?view=azuresqldb-current

В ней есть пример запроса:

SELECT end_time, (SELECT Max(v) FROM (VALUES (avg_cpu_percent), (avg_data_io_percent), 
(avg_log_write_percent)) AS value(v)) AS [avg_DTU_percent] FROM sys.dm_db_resource_stats;

Тут нам надо помнить, что в таблице sys.dm_db_resource_stats содержатся данные только за последний час. Поэтому итоговый вариант будет содержать запрос к таблице sys.resource_stats
в базе master. В нашей задаче мы ищем пиковые значения, поэтому сразу же добавим и сортировку:

SELECT TOP 10 end_time, (SELECT Max(v) FROM (VALUES (avg_cpu_percent), (avg_data_io_percent), 
(avg_log_write_percent)) AS value(v)) AS [DTU] FROM sys.resource_stats
WHERE database name like 'MYDB'
ORDER BY [DTU] DESC;

Теперь запрос идет к таблице sys.resource_stats, данные в которой хранятся 14 дней. Получаем такой результат:



Помним, что предыдущий график показал нам приблизительное время, к тому же в таблице мы видим значения  GMT+0. В итоге можно сделать вывод, что данные для графика на портале, и данные, которые мы получаем по запросу, релевантны.

Теперь попробуем получить эти же данные с помощью командлета Get-AzureRmMetric. Для начала определяемся, какие метрики мы будем анализировать:

D:\> (Get-AzureRmMetricDefinition -ResourceId $dbid ).name 



Нас тут интересует "DTU used". Хорошо, идем дальше:

D:\>  (Get-AzureRmMetric -ResourceId $dbid -StartTime (get-date).AddDays(-4) -MetricNames "dtu_used").Data | Measure-Object -Property Average -Maximum



BANANANA! Получаем пиковое значение DTU 38! Разница практически в 4 раза с тем, что мы видели на графике и при запросе к базе. Теперь надо разобраться, что у нас произошло и каким данным можно доверять.

Выполним запрос, который покажет, что происходило конкретно в то время, когда мы наблюдали пиковую нагрузку:

D:\>  (Get-AzureRmMetric -ResourceId $dbid -StartTime "27-Jun-18 12:24:00" -EndTime "27-Jun-18 12:30:00" -MetricNames "dtu_used").Data  | ft timestamp, Average



Действительно, есть разовый скачек до 38. Но почему мы не видим его на графике и в таблице SQL? Для того, чтобы это понять, обратите внимание на значение TimeStamp. При выполнении командлета Get-AzureRmMetric, мы получаем средние значения DTU за каждую минуту. А теперь посмотрим, какой результат выдаёт запрос к базе:


На скриншоте мы видим, что таблица хранит информацию по среднему значению DTU за 5 минут. Отлично, чтобы приблизительно проверить, одинаковы ли итоговые данные, выполним такой Powershell запрос:

D:\>  (Get-AzureRmMetric -ResourceId $dbid -StartTime "27-Jun-18 12:25:00" -EndTime "27-Jun-18 12:30:00" -MetricNames "dtu_used").Data  | Measure-Object -Property Average -average


Теперь значение DTU более-менее похоже на то, что мы получили на графике и в результате выполнения SQL запроса.

Исходя из данных наблюдений, лично мне сложно сделать однозначный вывод, какой из способов анализа профиля нагрузки базы данных Azure SQL (PaaS) наиболее правильный. Для моей задачи вполне подойдет использование запросов SQL, которые показывают среднюю утилизацию ресурсов за каждые 5 минут. Значение DTU 38, которое возникло разово и на небольшой промежуток времени, мне знать не обязательно (а может даже и вредно :) ). Но помните, что в вашем случае ситуация может быть совершенно другая!

Вывод:
1. Если вам лучше подходит статистика по средним значениям за каждые 5 минут, то более удобно будет использовать запросы SQL (конечно, если у вас есть доступ на чтение к базе master)
2. Если вам нужна статистика по утилизации ресурсов за каждую минуту, то необходимо использовать PowerShell, так как в таблицах SQL такой информации нет

Так же, если вам нужны средние данные за определенный интервал времени (например, за определенные 7 минут), то надо использовать второй вариант.

На этом все, вопросы и дополнения оставляйте в комментариях.


Комментариев нет:

Отправить комментарий