Производительность SQL-сервера на большом расстоянии
Разумно ли ожидать достойной производительности от сервера SQL, подключенного через оптоволоконную частную глобальную сеть, на расстоянии 5000 км. Оператор сообщает нам, что эта сеть является "наилучшей" из возможных и обеспечивает гарантированную задержку менее 50 мс.
Наша база данных в настоящее время подключена через гигабитный Ethernet к другим нашим машинам в том же центре данных. Получение 5000 км "LAN Extension" между двумя DC является привлекательным для нас. Но когда мы подключаемся через Интернет и VPN, мы обнаруживаем очень низкую производительность при выполнении больших объемов небольших транзакций. У нас нет опыта работы с WAN, поэтому мы не уверены, что большинство компаний делают в этих случаях. Можем ли мы симулировать "задержку" в 5000 км?
2 ответа
5000 км / ч со скоростью света будут задержкой ~17 мс. Оптоволокно, больше как 25мс. И это в лучшем случае межсерверное оптоволокно без задержек для преобразования медиаданных, переключения, маршрутизации, ответа сервера и т. Д.
Минимум 25мс, гарантированный максимум 50мс...
да, есть инструменты для симуляции медленной ссылки, например
http://jagt.github.io/clumsy/ - программа Windows для изменения сетевого трафика
http://wanem.sourceforge.net/ - Linux LiveCD для эмуляции WAN
и множество предложений https://stackoverflow.com/questions/130354/how-do-i-simulate-a-low-bandwidth-high-latency-environment и https://stackoverflow.com/questions/1094760/network- инструменты, которые имитируют-замедленная-сеть связь
Сравните опросы sys.dm_os_wait_stats между периодом симулированной высокой задержки в сети и идентичным периодом нормальной задержки в сети (для той же нагрузки клиента и той же статистики базы данных). Например, следующий скрипт можно использовать для сравнения [wait_rate (ms/Sec)] для 'ASYNC_NETWORK_IO' [wait_type]. Различия, измеренные от Х до низкого ХХ%, вероятно, находятся под влиянием фонового шума (то есть они бессмысленны). Различия, измеренные в XXX%, вероятно, будут существенными. Чтобы дать вам качественное представление об относительной важности wait_rate, вы увидите: Если бы ваш SQL Server имел 500 активных рабочих потоков, и если бы все 500 из этих потоков ожидали только одного wait_type (в течение некоторого заданного периода времени) затем [wait_rate (ms/Sec)] для этого [wait_type] будет 500000 мс / сек. Обычно я игнорирую [wait_rate (ms/Sec)], которые меньше 1000 мс / сек.
Следующий скрипт был написан для сбора данных за 20 секунд. Это может быть скорректировано (в соответствии с вашими потребностями тестирования). Сценарий не объединяет wait_types в категории (например, этот сценарий не объединяет все PAGEIO% ожидания вместе).
DECLARE @hhmmssDelay CHAR(8) = '00:00:20'
SET NOCOUNT ON
CREATE TABLE
#ignored
(
wait_type NVARCHAR(60) PRIMARY KEY
)
INSERT
#ignored
SELECT 'BAD_PAGE_PROCESS'
UNION SELECT 'BROKER_EVENTHANDLER'
UNION SELECT 'BROKER_RECEIVE_WAITFOR'
UNION SELECT 'BROKER_TASK_STOP'
UNION SELECT 'BROKER_TO_FLUSH'
UNION SELECT 'BROKER_TRANSMITTER'
UNION SELECT 'CHECKPOINT_QUEUE'
UNION SELECT 'CLR_AUTO_EVENT'
UNION SELECT 'CLR_MANUAL_EVENT'
UNION SELECT 'DBMIRROR_EVENTS_QUEUE'
UNION SELECT 'DISPATCHER_QUEUE_SEMAPHORE'
UNION SELECT 'FT_IFTS_SCHEDULER_IDLE_WAIT'
UNION SELECT 'FT_IFTSHC_MUTEX'
UNION SELECT 'KSOURCE_WAKEUP'
UNION SELECT 'LAZYWRITER_SLEEP'
UNION SELECT 'LOGMGR_QUEUE'
UNION SELECT 'ONDEMAND_TASK_QUEUE'
UNION SELECT 'PREEMPTIVE_OS_AUTHENTICATIONOPS'
UNION SELECT 'PREEMPTIVE_OS_GETPROCADDRESS'
UNION SELECT 'REQUEST_FOR_DEADLOCK_SEARCH'
UNION SELECT 'RESOURCE_QUEUE'
UNION SELECT 'SLEEP_BPOOL_FLUSH'
UNION SELECT 'SLEEP_SYSTEMTASK'
UNION SELECT 'SLEEP_TASK'
UNION SELECT 'SQLTRACE_BUFFER_FLUSH'
UNION SELECT 'WAITFOR'
UNION SELECT 'XE_DISPATCHER_JOIN'
UNION SELECT 'XE_DISPATCHER_WAIT'
UNION SELECT 'XE_TIMER_EVENT'
UNION SELECT 'SQLTRACE_INCREMENTAL_FLUSH_SLEEP'
UNION SELECT 'DIRTY_PAGE_POLL'
UNION SELECT 'HADR_FILESTREAM_IOMGR_IOCOMPLETION' -- May be useful for AlwaysON (AKA Hadron)
SELECT
GETDATE() 'Poll'
, ows.*
INTO
#os_wait_stats
FROM
sys.dm_os_wait_stats ows
LEFT JOIN
#ignored i
ON
i.wait_type = ows.wait_type
WHERE
i.wait_type IS NULL
WAITFOR DELAY @hhmmssDelay
INSERT
#os_wait_stats
SELECT
GETDATE() 'Poll', ows.*
FROM
sys.dm_os_wait_stats ows
LEFT JOIN
#ignored i
ON
i.wait_type = ows.wait_type
WHERE
i.wait_type IS NULL
DECLARE @SecondsBetweenPolls INT
SELECT
@SecondsBetweenPolls=DATEDIFF(SECOND,MIN(Poll),MAX(Poll))
FROM
#os_wait_stats
DECLARE @SecondsSinceSQLServerStarted BIGINT
DECLARE @LastPoll DATETIME
SELECT
@LastPoll=MAX(Poll)
FROM
#os_wait_stats
SELECT
@SecondsSinceSQLServerStarted =DATEDIFF(SECOND, sqlserver_start_time, @LastPoll)
FROM sys.dm_os_sys_info
SELECT
CONVERT(NUMERIC(38,0),(Later.wait_time_ms-Earlier.wait_time_ms))/CONVERT(NUMERIC(38,0),@SecondsBetweenPolls) 'wait_rate (ms/Sec)'
,Later.wait_type
,Later.waiting_tasks_count-Earlier.waiting_tasks_count 'waiting_tasks_count'
,Later.signal_wait_time_ms-Earlier.signal_wait_time_ms 'signal_wait_time_ms'
,Later.wait_time_ms-Earlier.wait_time_ms 'wait_time_ms'
,CONVERT(NUMERIC(38,0),(Later.wait_time_ms))/CONVERT(NUMERIC(38,0),@SecondsSinceSQLServerStarted)'cumulative_wait_rate (ms/Sec)'
,Later.wait_time_ms 'cumulative_wait_time_ms'
,Earlier.Poll 'earlier_poll'
,Later.Poll 'later_poll'
,Earlier.max_wait_time_ms 'earlier_max_wait_time_ms'
,Later.max_wait_time_ms 'later_max_wait_time_ms'
FROM
#os_wait_stats Later
JOIN
(
SELECT
wait_type
,wait_time_ms
,waiting_tasks_count
,signal_wait_time_ms
,max_wait_time_ms
,Poll
FROM
#os_wait_stats
WHERE
Poll =
(
SELECT
MIN(Poll)
FROM
#os_wait_stats
)
) as Earlier
ON
Earlier.wait_type = Later.wait_type
WHERE
Later.wait_time_ms-Earlier.wait_time_ms > 0
ORDER BY
CONVERT(NUMERIC(38,0),(Later.wait_time_ms-Earlier.wait_time_ms))/CONVERT(NUMERIC(38,0),@SecondsBetweenPolls) -- 'wait_rate (ms/Sec)'
DESC
GO
DROP TABLE #os_wait_stats
GO
DROP TABLE #ignored