Разумно ли ожидать достойной производительности от SQL-сервера, подключенного через оптоволоконную частную WAN - на расстоянии 5000 км. Оператор связи говорит нам, что эта сеть является «лучшей» из возможных и обеспечит гарантированную задержку менее 50 мс.
Наша база данных в настоящее время подключена через гигабитный Ethernet к другим нашим машинам в том же центре обработки данных. Нам нравится наличие «удлинения LAN» на 5000 км между двумя DC. Но когда мы подключаемся через Интернет и VPN, мы обнаруживаем, что производительность очень низкая при выполнении больших объемов небольших транзакций. У нас нет опыта работы с WAN, поэтому мы не уверены, что большинство компаний делают в таких случаях. Можем ли мы смоделировать «задержку» в 5000 км / с?
При скорости 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-tools-that-simulate-slow-network-connection
Сравните опросы sys.dm_os_wait_stats между периодом имитации высокой сетевой задержки и идентичным периодом нормальной сетевой задержки (для той же клиентской нагрузки и той же статистики базы данных). Например, следующий сценарий может использоваться для сравнения [wait_rate (ms / sec)] для 'ASYNC_NETWORK_IO' [wait_type]. Различия, измеренные от X до низких XX%, скорее всего, вызваны влиянием фонового шума (т.е. они бессмысленны). Различия, измеряемые в XXX%, вероятно, будут актуальными. Чтобы дать вам качественное представление об относительной важности wait_rates, вы увидите: если ваш SQL Server должен иметь 500 активных рабочих потоков, и если все 500 из этих потоков ожидают только одного wait_type (в течение некоторого заданного периода времени) , тогда [wait_rate (ms / sec)] для этого [wait_type] будет 500 000 мс / сек. Обычно я игнорирую [wait_rate (ms / sec)], которые меньше 1000 ms / sec.
Следующий сценарий был написан для сбора данных за период в 20 секунд. Это можно изменить (в соответствии с вашими требованиями к тестированию). Сценарий не объединяет типы ожидания по категориям (например, этот сценарий не объединяет все ожидания 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