HammerDB를 사용하여 SQL 서버 부하 테스트


이 튜토리얼에서는 HammerDB를 사용하여 Compute Engine SQL Server 인스턴스에서 부하 테스트를 수행하는 방법을 보여줍니다. 다음 튜토리얼을 사용하여 SQL Server 인스턴스를 설치하는 방법을 알아볼 수 있습니다.

사용 가능한 부하 테스트 도구는 다양합니다. 무료이고 오픈소스인 경우도 있지만 라이선스가 필요한 경우도 있습니다. HammerDB는 SQL Server 데이터베이스의 성능을 입증하는 데 일반적으로 효과적인 오픈소스 도구입니다. 이 튜토리얼에서는 HammerDB를 사용하는 기본 단계를 다루지만 사용 가능한 다른 도구도 있으므로 특정 워크로드에 가장 잘 맞는 도구를 선택하는 것이 좋습니다.

목표

  • 부하 테스트를 위해 SQL Server구성
  • HammerDB 설치 및 실행
  • 런타임 통계 수집
  • TPC-C 부하 테스트 실행

비용

이 튜토리얼에서는 Compute Engine에서 실행되는 기존 SQL Server 인스턴스 외에도, 다음과 같은 Google Cloud의 청구 가능한 구성 요소를 사용합니다.

  • Compute Engine
  • Windows Server

가격 계산기를 통해 예상 사용량을 기준으로 예상 비용을 산출할 수 있습니다. 제공된 링크는 이 가이드에서 사용되는 제품의 예상 비용을 보여줍니다. 비용은 하루 평균 16달러(미화)입니다. Google Cloud를 처음 사용하는 사용자는 무료 체험판을 사용할 수 있습니다.

시작하기 전에

  1. Google Cloud 계정에 로그인합니다. Google Cloud를 처음 사용하는 경우 계정을 만들고 Google 제품의 실제 성능을 평가해 보세요. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.
  2. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  3. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  4. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  5. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  6. 로컬 머신에서 Windows를 사용하지 않는 경우에는 타사 원격 데스크톱 프로토콜(RDP) 클라이언트를 설치합니다. 자세한 내용은 Microsoft 원격 데스크톱 클라이언트를 참조하세요.

부하 테스트를 위해 SQL Server 인스턴스 구성

시작하기 전에 Windows 방화벽 규칙이 사용자가 만든 새 Windows 인스턴스의 IP 주소에서 나오는 트래픽을 허용하도록 설정되어 있는지 한 번 더 확인합니다. 그런 다음 TPCC 부하 테스트용 새 데이터베이스를 만들고 다음 단계를 따라 사용자 계정을 구성합니다.

  1. SQL Server Management Studio에서 데이터베이스 폴더를 마우스 오른쪽 버튼으로 클릭하고 새 데이터베이스를 선택합니다.
  2. 새 데이터베이스 이름을 'TPCC'로 지정합니다.
  3. 데이터 파일 초기 크기를 190,000MB로 설정하고 로그 파일을 65,000MB로 설정합니다.
  4. 다음 스크린샷과 같이 줄임표 버튼을 클릭하여 자동 증가 한도를 더 높은 값으로 설정합니다.

    자동 증가 한도 설정

  5. 데이터 파일이 64MB 단위로 무제한 증가하도록 설정합니다.

  6. 로그 파일이 자동으로 증가되지 않도록 설정합니다.

  7. 확인을 클릭합니다.

  8. 새 데이터베이스 대화상자의 왼쪽 창에서 옵션 페이지를 선택합니다.

  9. 호환성 수준SQL Server 2012 (110)으로 설정합니다.

  10. 복구 모델단순으로 설정하여 로드 시 트랜잭션 로그가 채워지지 않도록 합니다.

    복구 모델을 단순으로 설정

  11. 확인을 클릭하여 TPCC 데이터베이스를 만듭니다. 이 작업이 완료하는 데 몇 분 정도 소요될 수 있습니다.

  12. 미리 구성된 SQL Server 이미지에는 Windows 인증만 사용 설정되므로 이 가이드를 따라 SSMS 내에서 혼합 모드 인증을 사용 설정해야 합니다.

  13. 다음 단계를 따라 데이터베이스 서버에서 DBOwner 권한이 있는 새 SQL Server 사용자 계정을 만듭니다. 계정 이름을 'loaduser'로 지정하고 보안 비밀번호를 지정합니다.

  14. 성능 및 보안에 내부 IP 사용이 중요하므로 Get-NetIPAddress commandlet을 사용하여 SQL Server 내부 IP 주소를 기록합니다.

HammerDB 설치

SQL Server 인스턴스에서 직접 HammerDB를 실행할 수 있습니다. 하지만 더 정확하게 테스트하려면 새 Windows 인스턴스를 만들고 SQL Server 인스턴스를 원격으로 테스트합니다.

인스턴스 생성

다음 단계에 따라 새 Compute Engine 인스턴스를 만듭니다.

  1. Google Cloud Console에서 인스턴스 만들기 페이지로 이동합니다.

    인스턴스 만들기로 이동

  2. 이름hammerdb-instance를 입력합니다.

  3. 머신 구성 섹션에서 CPU 수가 데이터베이스 인스턴스의 절반 이상인 머신 유형을 선택합니다.

  4. 부팅 디스크 섹션에서 변경을 클릭한 후 다음을 수행합니다.

    1. 공개 이미지 탭에서 Windows Server 운영체제를 선택합니다.
    2. 버전 목록에서 Windows Server 2012 R2 또는 Windows Server 2012 R2 Core를 클릭합니다.
    3. 부팅 디스크 유형 목록에서 표준 영구 디스크를 선택합니다.
    4. 부팅 디스크 옵션을 확인하려면 선택을 클릭합니다.
  5. 만들기를 클릭하여 VM을 만들고 시작합니다.

소프트웨어 설치

준비되면 RDP 클라이언트를 사용하여 새로운 Windows Server 인스턴스에 연결하고 다음 소프트웨어를 설치합니다.

HammerDB 실행

HammerDB를 설치한 후 hammerdb.bat 파일을 실행합니다. HammerDB는 시작 메뉴의 애플리케이션 목록에 표시되지 않습니다. 다음 명령을 사용하여 HammerDB를 실행합니다.

C:\Program Files\HammerDB-2.20\hammerdb.bat

연결 및 스키마 만들기

애플리케이션이 실행 중일 경우 첫 번째 단계는 연결을 구성하여 스키마를 작성하는 것입니다.

  1. 벤치마크 패널에서 SQL Server를 더블클릭합니다.
  2. TPC-C(Transaction Processing Performance Council - Benchmark C)를 선택합니다. TPC.org 사이트에 TPC-C가 다음과 같이 소개되어 있습니다.
    TPC-C에는 온라인에서 실행되거나 지연된 실행으로 인해 큐에 추가된 형태와 복잡성이 다양한 동시 트랜잭션 5개가 혼합되어 있습니다. 데이터베이스는 다양한 범위의 레코드 및 모집단 규모를 포함한 9가지 유형의 테이블로 구성됩니다. TPC-C는 분당 트랜잭션 수(tpmC)로 측정됩니다.
  3. 확인을 클릭합니다.

    TPC-C 벤치마크 옵션 설정

  4. 벤치마크 패널에서 SQL Server 옆에 있는 더하기 표시(+)를 클릭하여 옵션을 펼칩니다.

  5. TPC-C 아래에서 스키마 빌드를 클릭하고 옵션을 더블클릭합니다.

  6. 아래 그림과 같이 IP 주소, 사용자 이름, 비밀번호를 사용하여 양식을 입력합니다.

    TPC-C 작성 옵션 설정

  7. 스키마 옵션에 업데이트됨을 선택합니다. 그러면 더욱 적절한 구조와 우수한 색인이 포함된 보다 나은 TPC-C 스키마가 생성됩니다.

  8. 이 경우에는 웨어하우스 수(크기)가 2,000으로 설정되어 있지만 웨어하우스 2,000개를 만드는 데 몇 시간이 걸리므로 높게 설정할 필요가 없습니다. 일부 가이드라인에서는 CPU당 웨어하우스를 10~100개 정도 제안합니다. 이 튜토리얼에서는 이 값을 코어 수의 10배로 설정합니다. 예를 들어 16 코어 인스턴스라면 160개로 설정합니다.

  9. 가상 사용자 스키마 빌드에 클라이언트 vCPU 수의 1~2배 수를 선택합니다. 슬라이더 옆에 있는 회색 막대를 클릭하여 수를 조정할 수 있습니다.

  10. 확인을 클릭합니다.

  11. 스키마 빌드 섹션 아래의 빌드 옵션을 더블클릭하여 스키마를 만들고 테이블을 로드합니다. 완료되면 화면 상단 중앙에 있는 빨간색 표시등 아이콘을 클릭하여 가상 사용자를 삭제하고 다음 단계로 진행합니다.

Simple 복구 모델을 사용하여 데이터베이스를 만든 경우 이 시점에서 Full로 다시 변경하여 프로덕션 시나리오를 보다 정확하게 테스트할 수 있습니다. 전체 또는 차등 백업을 수행하여 새 로그 체인이 트리거되어야만 변경사항이 적용됩니다.

드라이버 스크립트 만들기

HammerDB는 드라이버 스크립트를 사용하여 데이터베이스에 대한 SQL 문 흐름을 조정하면서 필요한 부하를 생성합니다.

  1. 벤치마크 패널에서 드라이버 스크립트 섹션을 펼치고 옵션을 더블클릭합니다.
  2. 설정이 스키마 빌드 대화상자에서 사용한 설정과 일치하는지 확인합니다.
  3. 테스트 드라이버 스크립트 타이머 설정을 선택합니다.
  4. 완료 시 체크포인트 옵션은 테스트 종료 후에 데이터베이스가 강제로 모든 내용을 디스크에 쓰도록 하므로 여러 테스트를 차례대로 실행하려는 경우에만 선택합니다.
  5. 철저하게 테스트하려면 증가 시간(분)을 5로, 테스트 기간(분)을 20으로 설정합니다.
  6. 확인을 클릭하여 대화상자를 종료합니다.
  7. 벤치마크 패널의 드라이브 스크립트 섹션에서 로드를 더블클릭하여 드라이버 스크립트를 활성화합니다.

TPC-C 드라이버 옵션 설정

가상 사용자 만들기

실제적인 부하를 만들려면 여러 다른 사용자로 스크립트를 실행해야 합니다.테스트에 사용할 가상 사용자를 몇 명 만듭니다.

  1. 가상 사용자 섹션을 펼치고 옵션을 더블클릭합니다.
  2. 웨어하우스 수(크기)를 160으로 설정한 경우 가상 사용자를 16으로 설정합니다. TPC-C 가이드라인에 따르면 행이 잠기지 않도록 10배 비율이 권장되기 때문입니다. 출력 표시 체크박스를 선택하여 콘솔에서 오류 메시지를 사용 설정합니다.
  3. 확인을 클릭합니다.

런타임 통계 수집

HammerDB 및 SQL Server에서 사용자를 위해 자세한 런타임 통계가 수집되는 과정은 간단하지 않습니다. SQL Server 내부의 깊숙한 곳에서 통계를 확인할 수 있기는 하지만 정기적으로 캡처하고 계산해야 합니다. 이 데이터를 캡처하는 데 도움이 되는 프로시저나 도구가 아직 없는 경우 아래 프로시저를 사용하여 테스트 중에 몇 가지 유용한 측정항목을 캡처할 수 있습니다. 결과는 Windows temp 디렉터리의 CSV 파일에 기록됩니다. 선택하여 붙여넣기 > CSV 붙여넣기 옵션을 사용하여 데이터를 Google 스프레드시트에 복사할 수 있습니다.

이 프로시저를 사용하려면 먼저 OLE 자동화 프로시저를 일시적으로 사용하도록 설정하여 파일을 디스크에 작성합니다. 테스트한 후에는 사용하지 않도록 설정해야 합니다.

sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures', 1;
GO
RECONFIGURE;
GO

다음은 SQL Server Management Studio에서 sp_write_performance_counters 프로시저를 만드는 코드입니다. 부하 테스트를 시작하기 전에 Management Studio에서 다음 프로시저를 실행합니다.

USE [master]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

/***
LogFile path has to be in a directory that SQL Server can Write To.
*/
CREATE PROCEDURE [dbo].[sp_write_performance_counters] @LogFile varchar (2000) = 'C:\\WINDOWS\\TEMP\\sqlPerf.log', @SecondsToRun int =1600, @RunIntervalSeconds int = 2

AS

BEGIN
--File writing variables
DECLARE @OACreate INT, @OAFile INT, @FileName VARCHAR(2000), @RowText VARCHAR(500), @Loops int, @LoopCounter int, @WaitForSeconds varchar (10)
--Variables to save last counter values
DECLARE @LastTPS BIGINT, @LastLRS BIGINT, @LastLTS BIGINT, @LastLWS BIGINT, @LastNDS BIGINT, @LastAWT BIGINT, @LastAWT_Base BIGINT, @LastALWT BIGINT, @LastALWT_Base BIGINT
--Variables to save current counter values
DECLARE @TPS BIGINT, @Active BIGINT, @SCM BIGINT, @LRS BIGINT, @LTS BIGINT, @LWS BIGINT, @NDS BIGINT, @AWT BIGINT, @AWT_Base BIGINT, @ALWT BIGINT, @ALWT_Base BIGINT, @ALWT_DIV BIGINT, @AWT_DIV BIGINT

SELECT @Loops = case when (@SecondsToRun % @RunIntervalSeconds) > 5 then @SecondsToRun / @RunIntervalSeconds + 1 else @SecondsToRun / @RunIntervalSeconds end
SET @LoopCounter = 0
SELECT @WaitForSeconds = CONVERT(varchar, DATEADD(s, @RunIntervalSeconds , 0), 114)
SELECT @FileName = @LogFile + FORMAT ( GETDATE(), '-MM-dd-yyyy_m', 'en-US' ) + '.txt'

--Create the File Handler and Open the File
EXECUTE sp_OACreate 'Scripting.FileSystemObject', @OACreate OUT
EXECUTE sp_OAMethod @OACreate, 'OpenTextFile', @OAFile OUT, @FileName, 2, True, -2

--Write the Header
EXECUTE sp_OAMethod @OAFile, 'WriteLine', NULL,'Transactions/sec, Active Transactions, SQL Cache Memory (KB), Lock Requests/sec, Lock Timeouts/sec, Lock Waits/sec, Number of Deadlocks/sec, Average Wait Time (ms), Average Latch Wait Time (ms)'
--Collect Initial Sample Values
SET ANSI_WARNINGS OFF
SELECT
  @LastTPS= max(case when counter_name = 'Transactions/sec' then cntr_value end),
  @LastLRS = max(case when counter_name = 'Lock Requests/sec' then cntr_value end),
  @LastLTS = max(case when counter_name = 'Lock Timeouts/sec' then cntr_value end),
  @LastLWS = max(case when counter_name = 'Lock Waits/sec' then cntr_value end),
  @LastNDS = max(case when counter_name = 'Number of Deadlocks/sec' then cntr_value end),
  @LastAWT = max(case when counter_name = 'Average Wait Time (ms)' then cntr_value end),
  @LastAWT_Base = max(case when counter_name = 'Average Wait Time base' then cntr_value end),
  @LastALWT = max(case when counter_name = 'Average Latch Wait Time (ms)' then cntr_value end),
  @LastALWT_Base = max(case when counter_name = 'Average Latch Wait Time base' then cntr_value end)
FROM sys.dm_os_performance_counters
WHERE counter_name IN (
'Transactions/sec',
'Lock Requests/sec',
'Lock Timeouts/sec',
'Lock Waits/sec',
'Number of Deadlocks/sec',
'Average Wait Time (ms)',
'Average Wait Time base',
'Average Latch Wait Time (ms)',
'Average Latch Wait Time base') AND instance_name IN( '_Total' ,'')
SET ANSI_WARNINGS ON
WHILE @LoopCounter <= @Loops
BEGIN
WAITFOR DELAY @WaitForSeconds
SET ANSI_WARNINGS OFF
SELECT
  @TPS= max(case when counter_name = 'Transactions/sec' then cntr_value end)   ,
  @Active = max(case when counter_name = 'Active Transactions' then cntr_value end)   ,
  @SCM = max(case when counter_name = 'SQL Cache Memory (KB)' then cntr_value end)   ,
  @LRS = max(case when counter_name = 'Lock Requests/sec' then cntr_value end)   ,
  @LTS = max(case when counter_name = 'Lock Timeouts/sec' then cntr_value end)   ,
  @LWS = max(case when counter_name = 'Lock Waits/sec' then cntr_value end)   ,
  @NDS = max(case when counter_name = 'Number of Deadlocks/sec' then cntr_value end)   ,
  @AWT = max(case when counter_name = 'Average Wait Time (ms)' then cntr_value end)   ,
  @AWT_Base = max(case when counter_name = 'Average Wait Time base' then cntr_value end)   ,
  @ALWT = max(case when counter_name = 'Average Latch Wait Time (ms)' then cntr_value end)   ,
  @ALWT_Base = max(case when counter_name = 'Average Latch Wait Time base' then cntr_value end)
FROM sys.dm_os_performance_counters
WHERE counter_name IN (
'Transactions/sec',
'Active Transactions',
'SQL Cache Memory (KB)',
'Lock Requests/sec',
'Lock Timeouts/sec',
'Lock Waits/sec',
'Number of Deadlocks/sec',
'Average Wait Time (ms)',
'Average Wait Time base',
'Average Latch Wait Time (ms)',
'Average Latch Wait Time base') AND instance_name IN( '_Total' ,'')
SET ANSI_WARNINGS ON

SELECT  @AWT_DIV = case when (@AWT_Base - @LastAWT_Base) > 0 then (@AWT_Base - @LastAWT_Base) else 1 end ,
    @ALWT_DIV = case when (@ALWT_Base - @LastALWT_Base) > 0 then (@ALWT_Base - @LastALWT_Base) else 1 end

SELECT @RowText = '' + convert(varchar, (@TPS - @LastTPS)/@RunIntervalSeconds) + ', ' +
          convert(varchar, @Active) + ', ' +
          convert(varchar, @SCM) + ', ' +
          convert(varchar, (@LRS - @LastLRS)/@RunIntervalSeconds) + ', ' +
          convert(varchar, (@LTS - @LastLTS)/@RunIntervalSeconds) + ', ' +
          convert(varchar, (@LWS - @LastLWS)/@RunIntervalSeconds) + ', ' +
          convert(varchar, (@NDS - @LastNDS)/@RunIntervalSeconds) + ', ' +
          convert(varchar, (@AWT - @LastAWT)/@AWT_DIV) + ', ' +
          convert(varchar, (@ALWT - @LastALWT)/@ALWT_DIV)

SELECT  @LastTPS = @TPS,
    @LastLRS = @LRS,
    @LastLTS = @LTS,
    @LastLWS = @LWS,
    @LastNDS = @NDS,
    @LastAWT = @AWT,
    @LastAWT_Base = @AWT_Base,
    @LastALWT = @ALWT,
    @LastALWT_Base = @ALWT_Base

EXECUTE sp_OAMethod @OAFile, 'WriteLine', Null, @RowText

SET @LoopCounter = @LoopCounter + 1

END

--CLEAN UP
EXECUTE sp_OADestroy @OAFile
EXECUTE sp_OADestroy @OACreate
print 'Completed Logging Performance Metrics to file: ' + @FileName

END

GO

TPC-C 부하 테스트 실행

SQL Server Management Studio에서 다음 스크립트를 사용하여 컬렉션 프로시저를 실행합니다.

Use master
Go
exec dbo.sp_write_performance_counters

HammerDB를 설치한 Compute Engine 인스턴스에서 HammerDB 애플리케이션 테스트를 시작합니다.

  1. 벤치마크 패널의 가상 사용자 아래에서 만들기를 더블클릭하여 가상 사용자를 만듭니다. 그러면 가상 사용자 출력 탭이 활성화됩니다.
  2. 만들기 옵션 바로 아래에 있는 실행을 더블클릭하여 테스트를 시작합니다.
  3. 테스트가 완료되면 가상 사용자 출력 탭에 분당 트랜잭션(TPM) 계산이 표시됩니다.
  4. 수집 프로시저의 결과는 c:\Windows\temp 디렉터리에서 찾을 수 있습니다.
  5. 이러한 모든 값을 Google 스프레드시트에 저장하고 여러 테스트 실행을 비교할 때 사용합니다.

삭제

튜토리얼을 완료한 후에는 만든 리소스를 삭제하여 할당량 사용을 중지하고 요금이 청구되지 않도록 할 수 있습니다. 다음 섹션은 이러한 리소스를 삭제하거나 사용 중지하는 방법을 설명합니다.

프로젝트 삭제

비용이 청구되지 않도록 하는 가장 쉬운 방법은 튜토리얼에서 만든 프로젝트를 삭제하는 것입니다.

프로젝트를 삭제하려면 다음 안내를 따르세요.

  1. Google Cloud 콘솔에서 리소스 관리 페이지로 이동합니다.

    리소스 관리로 이동

  2. 프로젝트 목록에서 삭제할 프로젝트를 선택하고 삭제를 클릭합니다.
  3. 대화상자에서 프로젝트 ID를 입력한 후 종료를 클릭하여 프로젝트를 삭제합니다.

인스턴스 삭제

Compute Engine 인스턴스를 삭제하려면 다음 안내를 따르세요.

  1. Google Cloud 콘솔에서 VM 인스턴스 페이지로 이동합니다.

    VM 인스턴스로 이동

  2. 삭제할 인스턴스.
  3. 인스턴스를 삭제하려면 추가 작업을 클릭하고, 삭제를 클릭한 후 안내를 따르세요.

다음 단계