YCSB는 삽입, 읽기, 업데이트, 삭제 및 스캔과 같은 기본 작업을 지원하고 구현하는 모든 드라이버로 쉽게 확장할 수 있도록 제작된 훌륭한 벤치마킹 도구입니다. YCSB가 도입한 일반 합성 데이터는 이러한 패러다임에 완벽하게 부합합니다.

하지만 배열 및 중첩된 객체 쿼리, 조인 및 집계 실행 등 쿼리가 훨씬 더 정교해졌기 때문에 Couchbase 및 MongoDB와 같은 JSON 데이터베이스로 작업할 때는 YCSB가 유용합니다.

한편으로 YCSB-JSON 확장은 데이터베이스에서 지원되는 모든 가능한 JSON 연산을 활용할 수 있어야 합니다.
반면에, 이 접근 방식을 구현하는 것은 YCSB와 MongoDB, Couchbase 또는 any 다른 데이터베이스 드라이버가 지원하는 JSON 쿼리 수준과 상관없이 사용할 수 있습니다.

YCSB-JSON 연결은 실제적인 최종 사용자 시나리오를 더 잘 에뮬레이션하도록 설계되었습니다. 이 도구는 실제 데이터 세트나 의사 현실 또는 완전 합성 등 모든 JSON 데이터에서 작동하도록 설계되었습니다. 그리고 이 도구의 요구 사항 중 하나는 쿼리 술어에 하드코딩된 값이 없어야 한다는 것입니다. 사용자는 데이터 세트 생성 프로세스 중에만 데이터 카디널리티를 제어할 수 있습니다. 

 그림 1. YCSB-JSON 구현 한눈에 보기

데이터 모델

이 벤치마크를 위해 선택한 데이터 모델은 이 문서에 잘 설명되어 있습니다: https://dzone.com/articles/ycsb-json-benchmarking-json-databases-by-extending
데이터 세트는 페이크잇 도구를 사용하여 생성하고 외부 스크립트를 통해 데이터베이스(Couchbase, MongoDB)에 로드합니다. 모델이 정의되고 고정 값이 무작위로 생성되는 반면, 이 데이터는 무작위로 생성되지만 인위적인 것은 아닙니다.

 

데이터 관리

워크로드의 각 작업에 대해 쿼리는 고정되어 있지만 매개변수화된 각 술어에 대한 바운드 값은 비결정적입니다. 따라서 다음과 같은 데이터 관리 흐름이 선택되었습니다:

  1. 페이크잇으로 문서를 생성하세요. 
  2. 외부 스크립트를 통해 생성된 데이터를 데이터베이스에 로드합니다.
  3. 로드 단계를 실행합니다. 이 단계에서 YCSB는 생성된 문서의 임의의 하위 집합을 읽고 모든 값을 내부 캐시에 저장합니다.
  4. 실행 단계에서 YCSB는 데이터베이스에 대한 쿼리를 바인딩하고 실행하는 동안 캐시에 있는 값을 사용합니다.

 

술어 생성기

YCSB는 데이터로 작업할 때 제너레이터를 사용합니다. 커넥터는 특정 데이터 모델에 매핑된 자체 생성기를 도입합니다. 매핑과 모델은 제너레이터 네임스페이스 내에만 존재합니다. 생성기 출력은 특정 쿼리에 대한 일반 술어(필드-값 쌍)의 집합입니다. 이를 통해 사용자는 나머지 핵심 코드를 수정하지 않고도 모델을 수정하고 다른 쿼리로 도구를 확장할 수 있습니다.

생성기를 예측합니다: Generator.java 

 

예: #1:  페이지 매김 쿼리

YCSB-JSON 연산 중 하나인 페이지 매김 쿼리는 다음 문으로 표현할 수 있습니다:

SELECT * FROM WHERE address.zip = OFFSET LIMIT

쿼리 술어는 객체 내의 필드입니다. Couchbase N1QL을 사용하는 경우 이 필드는 "address.zip"으로 간단히 액세스할 수 있습니다. 그러나 다른 데이터베이스는 유연성이 떨어질 수 있으므로 YCSB-JSON 생성기는 부모 술어(주소)와 자식/중첩 술어(zip)의 두 가지 술어를 생성합니다.

그리고 하위 술어는 이 특정 필드에 대한 샘플 값 목록에서 무작위로 선택된 값을 갖습니다. 

아래 함수는 SoeQueryPredicate 개체
Where 이름 는 "주소"
그리고 중첩 술어 라는 이름을 가진 또 다른 SoeQueryPredicate 객체입니다.zip" 및 값  :

 

예 #2  쿼리 보고

더 복잡한 쿼리에 대한 술어도 같은 방식으로 생성됩니다. 다만 쿼리에 여러 개의 술어가 포함된 경우 단일 술어 대신 술어 시퀀스(술어 배열)가 생성된다는 차이점이 있습니다. 다음은 보고서 쿼리입니다:

SELECT o2.month, c2.address.zip, SUM(o2.sale_price) FROM c2
내부 조인 주문 o2 ON 키 c2.order_list
WHERE c2.address.zip = "value" AND o2.month = "value"
GROUP BY o2.month, c2.address.zip ORDER BY SUM(o2.sale_price)

아래 함수는 다음의 시퀀스를 생성합니다:
"월" 술어, 중첩된 "우편" 술어가 있는 "주소" 술어, "판매_가격" 술어 등이 있습니다:

다른 쿼리 생성기는 여기에서 찾을 수 있습니다:
https://github.com/couchbaselabs/YCSB/blob/soe/core/src/main/java/com/yahoo/ycsb/generator/soe/Generator.java

 

새로운 작업

새 작업으로 코드를 업데이트해야 합니다.

DB 클래스의 서명: 
https://github.com/couchbaselabs/YCSB/blob/soe/core/src/main/java/com/yahoo/ycsb/DB.java#L140:

DBWrapper에서 구현: 
https://github.com/couchbaselabs/YCSB/blob/soe/core/src/main/java/com/yahoo/ycsb/DBWrapper.java#L346:

새로운 작업으로 코어워크로드 확장: SoeWorkload.java

 

다음에 대한 YCSB-JSON 작업 구현 카우치베이스 및 몽고DB

YCSB-JSON 작업의 DB 드라이버 함수는 생성기 객체라는 추가 매개변수를 받습니다. 이 매개변수는 Workload 클래스에 의해 전달되며 특정 술어 시퀀스가 미리 빌드되어 있습니다.

술어 구조와 시퀀스는 생성기에 의해 잘 정의되어 있으므로 DB 드라이버는 이름과 값에 직접 액세스하고 기본 쿼리 언어 또는 기타 액세스 방법을 사용하여 쿼리를 구성할 수 있습니다. 다음은 페이지 및 보고서 쿼리 구현의 예입니다.

페이지 쿼리, 카우치베이스에 대한 쿼리문을 생성합니다:

로 설정합니다:

쿼리 보고, Couchbase:

MongoDB:

모든 카우치베이스 구현: Couchbase2Client.java

모든 몽고DB 구현: MongoDbClient.java

참조

기사 파트 1:
 https://www.couchbase.com/blog/ycsb-json-benchmarking-json-databases-by-extending-ycsb/

YCSB-JSON 구현:
https://github.com/couchbaselabs/YCSB/tree/soe

FakeIt:
 https://github.com/bentonam/fakeit

다음 단계

데이터 및 쿼리 술어 생성을 간소화하기 위해 페이크잇과 유사한 생성기를 구현합니다.

작성자

게시자 알렉스 기릭

알렉스 기릭은 카우치베이스의 성능 부문 수석 소프트웨어 엔지니어입니다. Couchbase에 입사하기 전에는 Forte Group에서 수석 성능 분석가로 몇 년간 근무했습니다.

댓글 남기기