BE 스토리지 계층 벤치마크 도구
목적
benchmark_tool은 Apache Doris BE 스토리지 계층(예: segment, page)의 성능을 테스트합니다. 입력 데이터로 지정된 객체를 구성하고 google benchmark를 통해 성능 테스트를 실행합니다.
컴파일
- Doris 자체를 컴파일할 수 있는 환경이 준비되어 있는지 확인합니다. 컴파일 및 배포를 참고하세요.
- Doris 저장소에서
run-be-ut.sh를 실행합니다. - 컴파일된 실행 파일은
./be/ut_build_ASAN/test/tools/benchmark_tool에 생성됩니다.
사용법
공통 매개변수
| 매개변수 | 의미 | 기본값 |
|---|---|---|
--operation | 테스트 유형입니다. 자세한 내용은 아래 시나리오를 참고하세요. | 없음(필수) |
--column_type | segment 테이블 스키마의 컬럼 타입입니다. int, char, varchar, string을 지원합니다. | int,varchar |
--rows_number | 데이터 행 수입니다. | 10000 |
--iterations | 테스트 반복 횟수입니다. 0으로 설정하면 benchmark가 자동으로 결정합니다. | 10 |
--input_file | 파일에서 데이터를 가져올 때 사용할 데이터 파일 경로입니다. | 없음 |
타입별 길이 규칙:
| 타입 | 길이 |
|---|---|
char | 8 |
varchar | 최댓값 |
string | 최댓값 |
무작위 데이터 세트 생성 규칙:
| 타입 | 규칙 |
|---|---|
int | [1, 1000000] 범위에서 무작위로 생성 |
char | 길이는 [1, 8] 범위에서 무작위로 정하며, 문자 집합은 영문 대문자와 소문자 |
varchar | 길이는 [1, 128] 범위에서 무작위로 정하며, 문자 집합은 영문 대문자와 소문자 |
string | 길이는 [1, 100000] 범위에서 무작위로 정하며, 문자 집합은 영문 대문자와 소문자 |
테스트 시나리오 한눈에 보기
| 시나리오 | 명령어 |
|---|---|
| 무작위 데이터 세트를 사용한 Segment 읽기 테스트 | ./benchmark_tool --operation=SegmentScan --column_type=int,varchar --rows_number=10000 --iterations=0 |
| 무작위 데이터 세트를 사용한 Segment 쓰기 테스트 | ./benchmark_tool --operation=SegmentWrite |
| 파일에서 가져온 데이터 세트를 사용한 Segment 읽기 테스트 | ./benchmark_tool --operation=SegmentScanByFile --input_file=./sample.dat |
| 파일에서 가져온 데이터 세트를 사용한 Segment 쓰기 테스트 | ./benchmark_tool --operation=SegmentWriteByFile --input_file=./sample.dat |
| 무작위 데이터 세트를 사용한 Page 사전 인코딩 테스트 | ./benchmark_tool --operation=BinaryDictPageEncode --rows_number=10000 --iterations=0 |
| 무작위 데이터 세트를 사용한 Page 사전 디코딩 테스트 | ./benchmark_tool --operation=BinaryDictPageDecode |
무작위로 생성한 데이터 세트를 사용한 Segment 읽기 테스트
먼저 데이터 세트를 사용해 segment 파일을 쓴 다음, 전체 segment를 스캔하는 데 걸리는 시간을 측정합니다.
./benchmark_tool --operation=SegmentScan --column_type=int,varchar --rows_number=10000 --iterations=0
무작위로 생성한 데이터 세트를 사용한 Segment 쓰기 테스트
데이터 세트를 segment에 추가하고 디스크에 쓰는 과정에 걸리는 시간을 측정합니다.
./benchmark_tool --operation=SegmentWrite
파일에서 가져온 데이터 세트를 사용한 Segment 읽기 테스트
./benchmark_tool --operation=SegmentScanByFile --input_file=./sample.dat
input_file은 가져올 데이터 세트 파일입니다. 파일의 첫 번째 줄은 테이블 스키마를 정의하며, 이후 각 줄은 데이터 한 행에 해당하고 컬럼은 ,로 구분합니다.
int,char,varchar
123,hello,world
321,good,bye
지원되는 타입은 마찬가지로 int, char, varchar, string입니다. char 타입 데이터의 길이는 8을 초과할 수 없습니다.
파일에서 가져온 데이터 세트를 사용한 Segment 쓰기 테스트
./benchmark_tool --operation=SegmentWriteByFile --input_file=./sample.dat
무작위로 생성한 데이터 세트를 사용한 Page 사전 인코딩 테스트
./benchmark_tool --operation=BinaryDictPageEncode --rows_number=10000 --iterations=0
varchar 값을 길이가 [1, 8] 범위가 되도록 무작위로 생성하고 인코딩 시간을 측정합니다.
무작위로 생성한 데이터 세트를 사용한 Page 사전 디코딩 테스트
./benchmark_tool --operation=BinaryDictPageDecode
varchar 값을 길이가 [1, 8] 범위가 되도록 무작위로 생성한 뒤 인코딩하고, 디코딩 시간을 측정합니다.
사용자 정의 테스트
직접 작성한 함수로 성능 테스트를 실행할 수 있습니다. 구현은 /be/test/tools/benchmark_tool.cpp에 있습니다.
1. 테스트 함수 작성
void custom_run_plus() {
int p = 100000;
int q = 0;
while (p--) {
q++;
if (UNLIKELY(q == 1024)) q = 0;
}
}
void custom_run_mod() {
int p = 100000;
int q = 0;
while (p--) {
q++;
if (q %= 1024) q = 0;
}
}
2. CustomBenchmark 등록
benchmarks.emplace_back(
new doris::CustomBenchmark("custom_run_plus", 0,
custom_init, custom_run_plus));
benchmarks.emplace_back(
new doris::CustomBenchmark("custom_run_mod", 0,
custom_init, custom_run_mod));
여기서 init은 각 테스트 회차의 초기화 단계이며, 소요 시간 측정에는 포함되지 않습니다. 객체를 초기화해야 한다면 CustomBenchmark의 파생 클래스를 통해 구현하세요.
3. 실행 출력 예시
2021-08-30T10:29:35+08:00
Running ./benchmark_tool
Run on (96 X 3100.75 MHz CPU s)
CPU Caches:
L1 Data 32 KiB (x48)
L1 Instruction 32 KiB (x48)
L2 Unified 1024 KiB (x48)
L3 Unified 33792 KiB (x2)
Load Average: 0.55, 0.53, 0.39
----------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------
custom_run_plus 0.812 ms 0.812 ms 861
custom_run_mod 1.30 ms 1.30 ms 539
자주 묻는 질문
질문: benchmark_tool 실행 파일을 찾을 수 없나요?
먼저 run-be-ut.sh를 실행해 BE 단위 테스트를 완전히 빌드하세요. 실행 파일은 ./be/ut_build_ASAN/test/tools/benchmark_tool에 생성됩니다.
질문: 사용자 정의 테스트 결과가 예상과 다른가요?
custom_init에 테스트 대상 함수의 로직이 포함되어 있지 않은지 확인하고, 옵티마이저가 제거하지 않도록 각 custom_run_* 함수의 본문이 충분히 큰지 확인하세요.