Мы столкнулись с сложной проблемой с нашим приложением базы данных. Мы запускаем приложение в 3 разных (но схожих) средах.
Select Insert
Env1 0.81ms 0.94ms
Env2 0.69ms 5.79ms
Env3 0.52ms 15.61ms
Мы протестировали производительность диска и памяти в трех средах. Env3 немного быстрее, чем Env2, который немного быстрее, чем Env1 (не более чем на 10%). Как и следовало ожидать, выборка в Env3 немного быстрее, чем в Env2, которая немного быстрее, чем в Env1. Однако вставки в Env1 В 5 раз быстрее чем в Env2 и В 15 раз быстрее чем в Env3. Чем может объясняться очень низкая производительность записи в Env2 и Env3?
Некоторая справочная информация, если она актуальна.
Приведенные выше цифры были получены с помощью тестового приложения, которое мы написали, чтобы попытаться диагностировать проблему. Выборы и вставки являются основными и выполняются на одном небольшом столе.
Наше тестовое приложение ...
a) был написан на C # и использует классы на основе System.Data.SqlClient.SqlConnection.
б) рассчитал среднее время, выполнив действие 1000 раз и разделив затраченное время на 1000.
в) работал в 2-х режимах ...
я. Наш код 1000 раз вызывал вставку / выбор / обновление
II. Наш код вызвал одну хранимую процедуру, которая 1000 раз вызывала вставку / выбор / обновление.
г) работает на той же машине, что и база данных
Обновления пострадали так же, как и вставки, за исключением случаев, когда хранимая процедура вызывала обновление. Когда хранимая процедура вызвала обновление в Env3, оно было в 4 раза медленнее, чем Env1, но когда клиент вызвал 1000 обновлений, оно было в 17 раз медленнее. В развернутой ниже таблице показана разница. среды.
Select SP Select Insert SP Insert Update SP Update
Env1 0.81ms 0.015ms 0.94ms 0.72ms 0.83ms 0.04ms
Env2 0.69ms 0.019ms 5.79ms 5.32ms 7.42ms 0.09ms
Env3 0.52ms 0.020ms 15.61ms 14.37ms 15.27ms 0.15ms
Устанавливаем «Среда 1». Наш клиент установил «Среду 2 и 3». Среда 2 - это образ VMWare. Когда мы впервые заметили, насколько медленными были вставки и обновления, мы принесли копию образа в наш хостинг-центр. Проблемы с производительностью исчезли.
В каждой среде используется стандартный выпуск SQL Server 2005 (64-разрядная версия) на Windows Server 2008 (64-разрядная версия).
Основные различия между средами:
Env1: Работа в гипервизоре на Dell T610 с двумя четырехъядерными процессорами Intel Xeon E5520. (Виртуальная машина имеет 3 выделенных ядра и 6 ГБ выделенной оперативной памяти.)
Env2: Работает на VMWare VSphere на HP Proliant DL585 G2 с 4 двухъядерными процессорами AMD Opteron 8220 с тактовой частотой 2,8 ГГц. (Виртуальная машина имеет 3 выделенных ядра и 6 ГБ выделенной оперативной памяти.)
Env3: Работает на физической коробке - HP Proliant DL380 G5, 2 * двухъядерных процессора Intel Xeon 3Ghz, 6 ГБ оперативной памяти.
Env1 использует RAID0, Env2 и 3 использовать RAID5
Когда мы скопировали изображение Env2 на наш сервер, мы запустили его с помощью VMPlayer. Мы не смогли воспроизвести проблемы с производительностью.
Env1 работает в нашей сети. Env2 и 3 работают в сети наших клиентов.
Мы попробовали Shared Memory, Named Pipes и TCP в качестве механизма связи без каких-либо заметных различий.
Мы пробовали перестроить индексы, удалить и воссоздать таблицы и т. Д. Низкая производительность наблюдается при всех вставках / обновлении во всех таблицах.
У нас 2 вопроса ...
1) Чем может объясняться очень низкая производительность записи в Env2 и Env3? 2) Какой инструмент мы можем использовать, чтобы увидеть, где расходуются все эти лишние миллисекунды?
Спасибо за любую помощь, которую вы можете нам оказать.
Пища для размышлений: SELECT подаются по памяти. INSERT должны очищать диск журнала. Проверить sys.dm_io_virtual_file_stats
на 3 средах. Надеюсь, вы обнаружите разительные различия в io_stall_write_ms
столбец.
Вот что я хотел бы исследовать: «Env1 использует RAID0, Env2 и 3 используют RAID5»
RAID 5 медленнее записывает.
Помните, что база данных - это интерфейс для дисководов, диски гораздо важнее, особенно на небольшом столе, чем RAM или CPU.
Попробуйте более простые настройки и измените настройки RAID, даже, возможно, не пытайтесь использовать RAID для полного набора данных.
БЫСТРОЕ РЕДАКТИРОВАНИЕ Для более рандомизированного теста убедитесь, что вы тестируете диск, а не ОЗУ или ЦП, пытаясь использовать меньшее количество ОЗУ и ЦП, а также таблицу с 1 миллионом или даже 10 миллионами строк, где вы выбираете строки случайным образом, чтобы повысить шансы, что сервер должен перейти к диску для каждой строки.
Два сервера, использующие RAID 5, определенно вызывают беспокойство (RAID 5 - это быстрое чтение / медленная запись). Вы получите лучшую производительность практически от любой другой конфигурации RAID (хотя RAID 0 не имеет отказоустойчивости).
Измените RAID, и вы, скорее всего, получите желаемую производительность, но я подумал, что добавлю еще кое-что, о чем я еще не думаю:
Индексы, хотя и отлично подходят для выборок, отрицательно влияют на производительность любой операции записи (вы пишете данные, и индексы также должны быть обновлены). Поэтому, даже если замена RAID не дает ожидаемой производительности, я бы посмотрел на индексы в следующий раз.
Выполните запрос Гленна Берри, чтобы получить представление о задержках ввода-вывода для чтения / записи каждой базы данных:
-- Calculates average stalls per read, per write, and per total input/output for each
-- database file.
-- Helps determine which database files on the entire instance have the most I/O
-- bottlenecks
SELECT DB_NAME(fs.database_id) AS [Database Name], mf.physical_name, io_stall_read_ms, num_of_reads,
CAST(io_stall_read_ms/(1.0 + num_of_reads) AS NUMERIC(10,1)) AS [avg_read_stall_ms],io_stall_write_ms,
num_of_writes,CAST(io_stall_write_ms/(1.0+num_of_writes) AS NUMERIC(10,1)) AS [avg_write_stall_ms],
io_stall_read_ms + io_stall_write_ms AS [io_stalls], num_of_reads + num_of_writes AS [total_io],
CAST((io_stall_read_ms + io_stall_write_ms)/(1.0 + num_of_reads + num_of_writes) AS NUMERIC(10,1))
AS [avg_io_stall_ms]
FROM sys.dm_io_virtual_file_stats(null,null) AS fs
INNER JOIN sys.master_files AS mf
ON fs.database_id = mf.database_id
AND fs.[file_id] = mf.[file_id]
ORDER BY avg_io_stall_ms DESC OPTION (RECOMPILE);
Самое первое, что я сделал бы, - это убедиться, что индексы в каждой среде одинаковы, и посмотреть, каков коэффициент заполнения для каждого сервера базы данных. Кроме того, одинаковы ли объемы данных в каждой среде?
Я вижу много вопросов по дискам и таймингу. Я хотел бы знать, что на самом деле делают диски. Какое у них среднее время доступа? Как долго должен ждать запрос ввода-вывода, прежде чем его нужно будет обслужить? Сколько запросов ввода-вывода стоит в очереди? Конечно, есть также вопросы о том, насколько загружен процессор или что происходит с вашей подсистемой памяти. На все эти вопросы можно легко ответить, запустив collectl в другом окне во время выполнения тестов. Я бы сказал, что изменение некоторых настроек и повторное выполнение тестов с целью выяснить, какие настройки имеют значение, могут помочь, но вам действительно нужно добраться до основной причины.
Например, кто-то упомянул raid0 va raid5. Это действительно важно. Как сравнить эти две подсистемы при отсутствии вашей рабочей нагрузки? Попробуйте выполнить простые операции чтения / записи для каждого с помощью такого инструмента, как dd, dt или даже iozone, а затем понаблюдайте, что происходит, с помощью такого инструмента, как collectl или даже iostat. Если есть большая разница между производительностью этих двух (и я знаю, что raid0 будет быстрее при записи, raid5 должен выиграть при чтении), вы можете выполнить все настройки, которые вам нравятся в БД, и вы никогда не превысите то, что диски делать можно.
-отметка