Skip to content

benchmark: validate ObjectId write locality and random I/O in post_likes #70

@seonghooncho

Description

@seonghooncho

근본 목적

MongoDB ObjectId를 RDB에 저장할 때, timestamp 기반 정렬 특성이 실제 적재 경로의 random I/O를 줄이는지 검증한다.
목적은 post_likesObjectId를 어떤 형식으로 저장할지 lookup 편의가 아니라 write locality와 적재 비용 관점에서 실측으로 판단할 수 있게 만드는 것이다.

비목적

이번 이슈의 목적은 exact lookup 최적화만을 비교하거나, 단순히 VARCHAR(24)BINARY(12)보다 크다는 사실만 다시 확인하는 것이 아니다.
또한 MongoDB _id 전체 설계 철학, 서비스 전반의 PK 전략, feed 조회 최적화까지 한 번에 결론내리려는 작업도 아니다.

배경

  • MongoDB ObjectId는 12바이트 구조이며, 앞 4바이트는 timestamp 성격을 가진다.
  • 따라서 생성 시점 순서가 유지된 _id를 그대로 적재하면, 키가 시간축을 따라 어느 정도 정렬된 상태로 들어올 가능성이 있다.
  • 이 특성이 InnoDB의 clustered/secondary 인덱스 적재 경로에서 page split과 random I/O를 줄일 수 있다는 것이 이번 실험의 주 가설이다.
  • 다만 ObjectId를 hex string으로 저장해도 문자 순서가 원래 바이트 순서를 보존하므로, timestamp ordering 효과와 string vs binary key width 효과를 분리해 측정해야 한다.

주 가설

가설 1. 순차 적재 가설

생성 시점 순서가 유지된 ObjectId를 사용하면 shuffled insert 대비 write path locality가 좋아지고, random I/O가 감소할 것이다.

예상 효과:

  • Innodb_buffer_pool_reads 감소
  • Innodb_data_reads 감소
  • insert latency 감소
  • page split 또는 페이지 재배치 징후 감소

가설 2. 표현 형식 보조 가설

같은 insert order라면 BINARY(12)VARCHAR(24)보다 key width가 짧아 write amplification과 저장 비용이 더 낮을 가능성이 있다.

예상 효과:

  • data_length, index_length 감소
  • page density 증가
  • 동일한 ordering 조건에서 추가적인 I/O 절감 가능

핵심 해석 원칙

이번 이슈의 중심 질문은 “binary가 짧아서 빠른가”가 아니라, ObjectId의 시간 순서가 실제 적재 경로를 더 순차적으로 만드는가이다.
따라서 ordering 효과key width 효과를 섞지 않도록 실험 매트릭스를 설계한다.

실험 질문

  1. timestamp order를 유지한 insert가 shuffled insert보다 random I/O를 줄이는가?
  2. 그 차이가 VARCHAR(24)BINARY(12) 모두에서 나타나는가?
  3. BINARY(12)가 추가로 주는 이득이 있다면, 그것은 ordering 효과와 별개로 어느 정도인가?
  4. 결과를 보면 ordering 효과key width 효과를 분리해서 설명할 수 있는가?

비교 대상

이번 실험은 2 x 2 매트릭스로 설계한다.

축 1. 저장 형식

  • Case S: post_id VARCHAR(24)
  • Case B: post_id BINARY(12)

축 2. 적재 순서

  • Order T: ObjectId 생성 시점 순서 유지
  • Order R: 동일한 _id 집합을 shuffle 해서 무작위 순서 적재

최종 매트릭스

  • S_T: string + time-ordered insert
  • S_R: string + shuffled insert
  • B_T: binary + time-ordered insert
  • B_R: binary + shuffled insert

이 구성이 필요한 이유:

  • T vs R 비교로 timestamp ordering 효과를 본다.
  • S vs B 비교로 key width 효과를 본다.
  • 둘을 섞으면 “왜 빨라졌는지” 설명할 수 없다.

통제 조건

아래 조건은 네 케이스에서 동일하게 유지한다.

  • row count
  • 동일한 ObjectId 집합
  • 동일한 member_id 분포
  • 동일한 PK/UK 구성
  • 동일한 secondary index 구성
  • 동일한 MySQL buffer pool 크기
  • 동일한 컨테이너 메모리 제한
  • 동일한 실행 반복 횟수
  • 동일한 배치 크기 또는 insert 방식

실험 범위

이번 단계에서는 read path가 아니라 write path를 본다.

초기 비교 범위:

  • bulk insert
  • insert-heavy workload
  • 적재 후 저장 구조

이번 단계에서 제외:

  • exact lookup latency
  • feed 조회
  • soft delete
  • covering index
  • 서비스 API 응답 시간

실험 스키마 초안

첫 실험은 PK 전략을 고정하고 post_id 표현 형식과 적재 순서만 비교한다.

권장 기본안:

  • PRIMARY KEY (post_id, member_id)
  • 공통 컬럼: member_id, created_at
  • string case: post_id VARCHAR(24)
  • binary case: post_id BINARY(12)

주의:

  • PK 전략 차이까지 동시에 섞으면 write locality 원인을 분리하기 어렵다.
  • 따라서 1차 실험은 PK(post_id, member_id) 고정이 적절하다.

데이터셋 계획

  • row count 후보: 100,000, 300,000, 1,000,000
  • 분포 후보:
    • uniform
    • 필요 시 hot post 집중 skew
  • ObjectId 생성 규칙:
    • 동일한 _id 집합 생성
    • _id는 생성 시점 순서를 보존한 원본 시퀀스를 가짐
    • 같은 집합을 shuffle 한 시퀀스도 별도로 생성
  • member_id 생성 규칙:
    • 각 케이스에서 동일한 짝(pair) 집합 유지

중요:

  • 네 케이스는 _id 표현 형식과 insert order만 다르고, 논리 데이터는 동일해야 한다.

측정 항목

write path I/O

  • Innodb_buffer_pool_reads
  • Innodb_buffer_pool_read_requests
  • Innodb_data_reads
  • 필요 시 Innodb_pages_written, Innodb_data_writes

latency

  • bulk insert elapsed time
  • 반복 실행 평균 및 분산

저장 구조

  • information_schema.tables.data_length
  • information_schema.tables.index_length
  • mysql.innodb_table_stats.clustered_index_size
  • mysql.innodb_table_stats.sum_of_other_index_sizes

밀집도

  • row_count / clustered_pages
  • row_count / other_pages
  • 필요 시 index별 rows_per_leaf_page

보조 관찰

  • 적재 후 EXPLAIN 또는 인덱스 통계
  • page split 징후를 간접적으로 보여주는 지표

핵심 판정 기준

ordering 효과 판정

  • S_T < S_R, B_T < B_R 형태로 I/O와 latency가 개선되면 ordering 효과가 있다고 본다.
  • 특히 buffer_pool_reads, data_reads 감소가 일관되면 “더 순차적인 적재” 근거로 본다.

key width 효과 판정

  • 같은 적재 순서에서 B_T < S_T 또는 B_R < S_R이면 binary key width 이점이 있다고 본다.
  • data_length, index_length, rows/page 차이도 함께 본다.

해석 우선순위

  1. 먼저 ordering 효과가 있는지 본다.
  2. 그 다음 binary key width가 추가 이득을 주는지 본다.
  3. 둘 중 무엇이 주요 원인인지 분리해 기록한다.

예상 결과

예상 방향은 아래와 같다.

  • time-ordered insert가 shuffled insert보다 write path random I/O를 줄일 가능성이 높다.
  • BINARY(12)는 동일 ordering 조건에서 더 작은 key width 덕분에 저장 구조와 I/O에서 추가 이득이 있을 수 있다.
  • 만약 T vs R 차이가 작고 S vs B 차이만 크다면, 주된 원인은 timestamp ordering이 아니라 key width일 수 있다.
  • 반대로 T vs R 차이가 분명하면, ObjectId의 시간 순서 특성이 적재 locality에 실제 영향을 준다고 해석할 수 있다.

산출물

  • write locality benchmark 스크립트
  • 결과 디렉터리
  • summary.tsv
  • raw insert run 로그
  • *_table_stats.tsv
  • 필요 시 *_index_stats.tsv
  • 결과 보고서 Markdown

후속 작업

  • 1차 실험에서 ordering 효과가 확인되면, post_likes 저장 형식 제안에 반영한다.
  • 필요 시 2차 실험으로 secondary index가 추가된 경우 write locality 변화도 본다.
  • exact lookup 비교는 후속 보조 실험으로 분리해 기록한다.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions