복제본이 두 번째 사이트로 옮겨진 뒤 쓰기 지연 시간이 치솟았고, 터널이 가장 최신 구성 요소라서 비난을 받습니다. 터널은 결백할 수 있습니다. 동기 커밋 가용성 그룹에서는 주 복제본이 원격 로그 쓰기가 완료되기 전에는 커밋을 승인할 수 없으므로, 링크가 몇 메가비트를 나르든 모든 트랜잭션이 왕복을 지불합니다. 처리량은 초당 바이트를 재고, 지연 시간은 한 번의 교환에 걸리는 시간을 재며, 커밋이 끝나는 데 필요한 것은 작은 교환 하나뿐입니다. 한 가지 숫자가 논쟁을 끝냅니다. 작은 트랜잭션의 커밋 소요 시간을 가용성 데이터베이스 안에서, 그리고 같은 인스턴스의 로컬 테이블에 대고 다시 측정하는 것입니다.

주 복제본이 실제로 기다리는 것

동기 커밋에서 주 복제본은 파트너가 로그 레코드가 경화되었다고 확인할 때까지 커밋 승인을 붙잡습니다. 경화되었다는 것은 보조 복제본의 트랜잭션 로그에 내구성 있게 기록되었다는 뜻이며, 데이터 페이지로 다시 실행되었다는 뜻이 아닙니다. redo는 주 복제본의 커밋에 밀리초 하나도 더하지 않고 몇 분씩 뒤처질 수 있습니다.

가용성 모드에 관한 Microsoft 문서 는 그 핸드셰이크를 설명하고 파트너가 빠졌을 때 플랫폼이 무엇을 하는지 서술합니다. 동기로 표시된 복제본은 기다림에 관한 규칙이며, 모든 커밋마다 건강한 원격 사본이 있다는 영구적인 약속이 아닙니다. 연결이 끊긴 경로는 따로 정의되며, 단순히 커밋이 실패한다는 뜻이 아닙니다.

따라서 여러분이 보는 대기는 합계입니다. 로그 전송, 두 호스트에서의 스케줄링, 원격 스토리지 쓰기입니다. 로그 볼륨이 포화된 보조 복제본은 어떤 속도 테스트도 보여 주지 않을 시간을 더합니다. 그 디스크는 불만이 VPN을 지목할 때 거의 측정되지 않습니다.

대역폭은 왕복 지연이 아니다

속도 테스트는 경로를 잠깐 넘치게 하고 속도를 보고합니다. 커밋은 더 좁은 것을 묻습니다. 작은 메시지가 반대편에 도달하고 영구 저장되고 돌아오는 데 걸리는 시간입니다. 경로 길이, 대기열, 패킷 손실이 그 숫자를 정하며, 공급자가 상한을 올려도 어느 것도 나아지지 않습니다.

그래서 «빠른» 터널은 많은 작은 순차 트랜잭션으로 이루어진 쓰기 중심 워크로드에 눈에 보이는 페널티를 더할 수 있습니다. 같은 총 바이트를 천 개의 커밋으로 나누면 왕복을 천 번 지불하고, 한 번의 대량 전송은 한 번만 지불합니다.

네트워크 소유자에게 대표 부하 아래에서 복제본 경로 자체의 지연과 손실을 측정해 달라고 하십시오. 사무실 노트북에서 VPN 게이트웨이로 보내는 ping이나 가까운 노드로의 속도 테스트는 로그가 실제로 지나는 경로에 거의 아무것도 돌리지 않습니다. 측정 창이 쓰기가 느린 시간대와 겹치게 하십시오.

무엇이든 바꾸기 전에 복제본 상태를 읽으십시오

인스턴스가 스스로에 대해 보고하는 것에서 시작하십시오. 파트너십이 얼마나 건강한지에 대해 양쪽이 의견을 달리할 수 있고, 대시보드 평균은 어느 대기열이 움직이는지 감춥니다. 아래 쿼리는 서로 다른 질문에 답합니다. 하나는 데이터베이스별 복제 상태를 읽고, 다른 하나는 각 복제본이 어떻게 구성되었는지 읽습니다. 모드를 건드리기 전에 둘 다 실행하십시오.

SELECT ag.name AS ag_name, drs.database_id, drs.synchronization_state_desc,
       drs.log_send_queue_size, drs.redo_queue_size, drs.secondary_lag_seconds
FROM sys.dm_hadr_database_replica_states AS drs
JOIN sys.availability_groups AS ag ON ag.group_id = drs.group_id;

SELECT ar.replica_server_name, ar.availability_mode_desc, ar.failover_mode_desc
FROM sys.availability_replicas AS ar;

첫 번째 결과는 로그 전송과 redo를 분리합니다. log_send_queue_size 이 오르는 동안 redo_queue_size 이 평평하면 로그가 도착하지 않은 것입니다. 반대라면 도착했고 재생이 뒤처진 것입니다. 커밋 경로에 놓이는 것은 첫 번째 경우뿐입니다.

두 번째 결과는 어떤 복제본이 정말로 여러분이 가정한 대로 구성되었는지 확인합니다. 이전 사고 중에 바뀐 모드는 바뀐 채로 문서화되지 않고 남는 경향이 있기 때문입니다. 그룹 기본값 대신 관심 있는 행을 읽으십시오. availability_mode_desc 과 failover_mode_desc 은 복제본별입니다. secondary_lag_seconds 는 SQL Server 2016 이상에만 있으므로, 오래된 빌드는 보내기 큐와 redo 열만 남깁니다.

그다음 대시보드 평균을 믿는 대신 대표 쓰기를 측정하십시오. 아래 블록을 가용성 데이터베이스에서 실행하고, 같은 인스턴스의 그룹 밖 데이터베이스에서 같은 테이블 모양에 대고 다시 실행하십시오. 두 소요 시간의 차이는 원격 로그의 대략적인 값이며, 네트워크 팀과의 논쟁에서 그래프보다 훨씬 잘 버팁니다. 그 뒤에는 한 번에 변수 하나만 바꾸십시오. 그렇지 않으면 차이는 의미를 잃습니다.

IF OBJECT_ID('dbo.CommitProbe') IS NULL
    CREATE TABLE dbo.CommitProbe (probe_id int PRIMARY KEY, touched_at datetime2(3));
IF NOT EXISTS (SELECT 1 FROM dbo.CommitProbe WHERE probe_id = 1)
    INSERT INTO dbo.CommitProbe (probe_id) VALUES (1);
SET STATISTICS TIME ON;
BEGIN TRANSACTION;
UPDATE dbo.CommitProbe SET touched_at = SYSUTCDATETIME() WHERE probe_id = 1;
COMMIT TRANSACTION;
SET STATISTICS TIME OFF;

비동기 커밋이 사는 것과 치르는 것

비동기 커밋에서는 주 복제본이 원격 경화 확인을 기다리는 것을 멈추므로 왕복이 커밋 경로에서 빠집니다. 커밋 지연 시간이 떨어지고 보조 복제본은 아무도 통제하지 않는 만큼 뒤처질 자유를 얻습니다. 그것은 대기에 대한 실제 수정이고 약속에 대한 실제 변경입니다.

대가는 복구 지점에 대한 결정입니다. 주 복제본이 실제로 사용할 수 있는 장애 조치 대상에 로그가 도달하기 전에 죽으면, 서비스를 비동기 사본으로 옮기는 것은 애플리케이션이 이미 커밋되었다고 보고한 트랜잭션을 버립니다. 어떤 구성 대화 상자도 그렇게 제시하지 않습니다. 그것은 허용 가능한 손실에 관한 비즈니스 질문이지 성능 설정이 아니기 때문입니다. 허용하는 손실 창을 사고 전에 적어 두십시오. 사고 중이 아니라.

데이터를 소유한 사람과 모드를 문서로 합의하고, 선호 대상이 사용할 수 없을 때의 장애 조치 절차도 함께 두십시오. 설계 문서의 동기는 운영 런북이 아니고, 비동기는 대기열 감시를 멈출 허가도 아닙니다.

나중에 변호할 수 있는 수정을 고르십시오

정직한 선택지는 네 가지입니다. 애플리케이션 의미론이 일괄 처리를 허용하는 곳에서는 피할 수 있는 커밋 왕복을 잘라내고, 측정한 전송이나 스토리지 병목을 고치며(더 큰 파이프 대신 보조 복제본의 더 빠른 로그 볼륨을 뜻할 수 있습니다), 왕복이 줄도록 복제본을 가까이 옮기고, 또는 보호 정책을 완화하고 더 넓은 손실 창을 받아들이십시오. 각각은 다른 무언가를 써서 지연 시간을 사고, 네 번째는 내구성을 씁니다. 고르기 전에 쓰는 것을 이름 붙이십시오.

워크로드의 지연 시간 목표와 내구성 요구를 동시에 눈앞에 두고 결정하십시오. 하나를 최적화하는 것이 다른 하나를 조용히 쓰기 때문입니다. 그다음 변경 전에 측정한 같은 트랜잭션을 다시 실행하십시오. 그 숫자를 움직이지 못하는 수정은 변경 티켓을 걸친 추측입니다.

변경 기록에 전후 측정값을 남기십시오. 그렇지 않으면 느린 쓰기를 본 다음 사람이 조사를 처음부터 다시 하고 또 터널을 탓하는 데서 시작합니다.

관련 글