Azure SQL на личном опыте с высокой нагрузкой

Вот уже больше года мы активно используем Azure SQL для своих проектов.
Хотелось бы поедлиться опытом и подводными камнями на которые мы наткнулись за последний год.



Решил остановиться и описать один отдельный проект в общих чертах активно использующий azure SQL.

Суть проекта сводиться в обработке большого потока данных от удалённых мобильных клиентов.
На текущий момент база данных пополняется примерно 38-45 GB в месяц.

Наш выбор упал на Azure SQL поскольку:

1) Мы решили вывести весь проект-сервис в облако
2) Работа с MS SQL нашей комманде была уже очень знакома
3) Мы поверили в отказоустоичивость и стабильность работы базы данных
4) Есть возможность легко масштабировать производительность бд

На текущий момент в течении 24 часов мы обрабатываем примерно 1000000 подключений и сессий загрузки данных в БД в том числе примерно 1.2 GB текста каждых 24 часа.

Всё это работает в связке: Удалённый клиент -> Web сервис -> Azure SQL

По сути, удалённый клиент выгружает свои данные на веб сервис, который в свою очередь обрабатывает эти данные и загружает в базу данных.



Как видно на картинке, на момент написания статьй к базе данных подключено 903 обработчика а в пиковые моменты эта цифра доходит до 1800.

Собственно одна из проблем с которой мы столкнулись:

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

Как оказалось проблема скрывалась в следующем: 

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

Обратившись в суппорт Майкрософта нам просто посоветовали наш sql запрос: 

DELETE FROM [unknown_table] WHERE [date_time] < '12-01-2012'

разбить на несколько поочерёдно запускаемых.

DELETE FROM [unknown_table] WHERE [date_time] < '01-01-2012'
DELETE FROM [unknown_table] WHERE [date_time] < '02-01-2012'
DELETE FROM [unknown_table] WHERE [date_time] < '03-01-2012'


Данное замечание справедливо для любого SQL запроса, буть до INSERT, SELECT,DELETE или UPDATE.

По сути смешное решение, но это решение было рекомендовано нам службой поддержки Microsoft.

Перевод письма Microsoft support:: «На текущий момент лог транзакций ограничен размером в 1GB но возможно в ближайшем будующем это измениться. Мы внимательно изучаем подобного рода проблемы сообщённые нашими клиентами. В ближайшем времени мы постараемся данное ограничение снять.»

Очередная проблема с которой мы столкнулись была производительность после переезда :

На начальном этапе проекта у нас работал локальный сервер в нашем офисе 
(2) Intel Xeon X5550 2.66 8MB/1333 QC CPU-1.

Практически сразу после миграции базы данных в SQL Azure мы заметили что произоводительность сервиса резко упала.

И мы для себя нашли очень удобную утилиту CSS SQL Azure Diagnostis



Которая позволяет проанализировать БД и сообщеает об ошибках либо недостающих желательных индексов как показано на картинке ниже:



Как было бы логично предположить, что это исправило наши проблемы с производительностью некоторых запросов.

То есть по сути после переноса базы данных из MS SQL на Azure SQL было необходимо/желательно перепроверить индексы и создать предлагаемые.

Однако утилита конечно же анализирует логи работы SQL запросов и если вы только мигрировали базу данных — рекоммендуемых недостающих индексов эта утилита показать не сможет.

Автор статьи: Владимир Юнев.