Skip to content

Repository files navigation

WikiEngine

나무위키, 한국어/영어 위키백과, 뉴스, 웹텍스트 등 6개 공개 데이터셋에서 수집한 12,156,589건의 문서를 대상으로 한 검색 엔진입니다.

위키 문서를 그대로 사용하지 않고, 실제 커뮤니티 게시판처럼 변환하여 적재했습니다. 단순히 "검색 기능을 만들었다"가 아니라, 가장 느린 상태에서 시작하여 병목이 드러날 때마다 다음 기술로 전환하는 과정 전체를 기록한 프로젝트입니다.


Architecture

Architecture

더 자세한 설명은 docs/ARCHITECTURE.md (C4 Model 경량) 와 docs/adr/ (주요 기술 결정 7건의 why) 를 참고하세요.


Tech Stack

구분기술
BackendSpring Boot 4.0.1 · Java 25 · Spring Modulith 2.0.2
SearchLucene 10.3.2 · Nori 한국어 형태소 분석 · XGBoost4J LTR
DatabaseMySQL 8.0 (Primary-Replica) · Flyway
CacheCaffeine (L1) + Redis 7.4 (L2) · Consistent Hashing 3-Shard
MessagingKafka 4.2 (KRaft) · Debezium 3.4 CDC
AIGoogle Gemini 3.1 Flash Lite · Spring AI (RAG 검색 요약)
FrontendNext.js · Vercel
InfraOCI Free Tier ARM · Docker · Ansible · Nginx L7 LB
MonitoringPrometheus · Grafana · Loki · Alloy · cAdvisor · k6
CI/CDGitHub Actions · GHCR

Data Sources

모든 데이터는 HuggingFace 및 Wikimedia의 공개 데이터셋입니다.

소스건수출처
나무위키 (2021.03)571,364Bingsu/namuwiki_20210301_filtered
한국어 위키백과 (2026.03)739,791Wikimedia Dumps (kowiki)
영어 위키백과 (2026.02)7,139,510Wikimedia Dumps (enwiki)
한국어 뉴스159,639sieu-n/korean-newstext-dump
한국어 웹텍스트1,284,822HAERAE-HUB/KOREAN-WEBTEXT
C4 한국어 클린2,261,463blueapple8259/c4-ko-cleaned-2
합계12,156,58930개 카테고리 · 태그 ~216만 개

Server Configuration

Oracle Cloud Free Tier 4대로 구성했습니다.

서버스펙역할
Server 1ARM 2 vCPU · 12GBApp + MySQL Primary + Redis + Nginx LB + Lucene Index (42GB)
Server 2ARM 2 vCPU · 12GBApp Replica + MySQL Replica + Kafka + Debezium + Redis Shard 2,3
Server 3AMD 1 vCPU · 1GBGrafana + Loki + InfluxDB + Nginx
Server 4AMD 1 vCPU · 1GBPrometheus + Node Exporter

Key Features

Search Engine

  • Lucene 10.3 + Nori: 한국어 형태소 분석, BM25 기반 검색, NRT(Near Real-Time) 색인
  • Tiered Cache: Caffeine L1 + Redis L2 2단 캐시, 캐시 히트율 ~82%
  • 동의어 확장: "AI" → "인공지능", "자바" → "Java" 양방향 확장
  • 오타 교정: Levenshtein Distance 기반 "혹시 OO을 찾으셨나요?" 제안
  • 카테고리 Facet: 검색 결과를 30개 카테고리별로 집계

Autocomplete (CQRS + MapReduce)

CQRS Architecture

  • CQRS 패턴: 읽기(Redis flat KV, O(1)) / 쓰기(MySQL search_logs) 분리
  • MapReduce 파이프라인: SearchLogCollector → MySQL 집계 → 접두사 분해 + Top-K → Redis 서빙
  • Spring Batch: 1시간 주기 자동완성 재계산
  • 한글 자모 검색: "ㅈㅂ" → "자바", "ㅋㅍㅌ" → "컴퓨터"

LTR (Learning to Rank)

Ranking Model

  • XGBoost LambdaMART: 14개 피처 (BM25 3필드 + 태그 중복 + 문서 시그널)로 Two-Phase Ranking
  • Gemini LLM-as-a-Judge: 학습 데이터 자동 생성 (200쌍, NDCG@10 CV +4.8%p)
  • XGBoost4J: ONNX 변환 미지원(Issue #382) → 네이티브 Java 바인딩, inplace_predict thread-safe
  • 클릭 로그 인프라: Kafka "search.clicks" + Beacon API dwell time → implicit feedback 수집

CDC (Change Data Capture)

CDC Flow

  • Debezium: MySQL binlog → Kafka topic → Lucene 인덱스 + 자동완성 + 캐시 자동 갱신
  • Spring Modulith 이벤트: CRUD → 이벤트 발행 → Lucene/Cache/Autocomplete 각각 처리

RAG (검색 결과 AI 요약)

  • Spring AI + Gemini: 검색 결과 상위 문서를 요약하여 AI 요약 카드 생성
  • SSE 스트리밍: 실시간 요약 결과 전송
  • 피드백 시스템: thumbs up/down + 카테고리별 피드백 수집

Distributed Infrastructure

Request Flow

  • Nginx R/W Split: GET → Round Robin(Server 1,2) / POST,PUT,DELETE → Server 1(Primary)
  • MySQL Replication: Primary-Replica 구성, Replication Lag ~1s
  • Redis Consistent Hashing: 3-Shard 분산, 노드 추가/제거 시 최소 키 재배치

Consistent Hashing

Content Moderation

  • 금칙어 필터링: Aho-Corasick 알고리즘으로 O(n) 멀티 패턴 매칭
  • 자동완성 negative caching: 금칙어 포함 검색어 캐시 제외
  • blinded 컬럼: 관리자 게시글 블라인드 처리

Performance (k6 Load Test)

100 VU, 20분, LOAD 프로필 기준:

시나리오평균P95
전체263ms1.17s
검색548ms2.61s
자동완성43ms99ms
게시글 목록62ms113ms
상세 조회80ms225ms
쓰기 (생성+좋아요)49ms142ms
에러율0.00%

Project Structure

backend/
src/main/java/com/wiki/engine/
auth/ # JWT 인프라 (JwtTokenProvider, JwtAuthenticationFilter)
user/ # 사용자 도메인 + 인증 엔드포인트
post/ # 게시글 도메인
internal/
lucene/ # Lucene 검색 + LTR + 피처 추출
search/ # SearchLogCollector + ClickLog + 자동완성
cdc/ # Debezium Kafka Consumer
rag/ # Spring AI + Gemini RAG
category/ # 카테고리 분류
config/ # DataSource, Cache, Redis Shard 설정
src/main/resources/
db/migration/ # Flyway V1~V5
ltr/ # XGBoost model.xgb
ltr_queries.txt
frontend/ # Next.js (Vercel 배포)
ansible/ # 서버 프로비저닝 (4대)
backend/k6/ # 부하 테스트 스크립트
backend/scripts/ # LTR 학습 (train_ltr.py)
docs/ # 설계 문서 + 스크린샷

Getting Started

Prerequisites

  • Java 25
  • Gradle 9.3
  • MySQL 8.0
  • Redis 7.4
  • Kafka 4.2 (optional, CDC)
  • Node.js 20+ (frontend)

Backend

cd backend
./gradlew bootRun

Frontend

cd frontend
npm install
npm run dev

Deployment (Ansible)

cd ansible
ansible-vault decrypt group_vars/all.yml
ansible-playbook -i inventory.yml site.yml --ask-vault-pass

로컬 환경 셋업 / 테스트 / JVM 진단은 docs/DEVELOPMENT.md 참조.


Documentation

문서내용
docs/ARCHITECTURE.mdC4 Model 경량 — Context · Container · Component 3단계
docs/adr/Architecture Decision Records — 기술 결정 7건의 why
docs/DEVELOPMENT.md로컬 개발 환경, 테스트, JVM 진단
docs/JVM_MEMORY_NOTES.mdJVM/메모리 튜닝 관점 정리 (Heap vs Page Cache, GC, Off-heap 등)
CHANGELOG.md버전별 변경 이력 (Keep a Changelog 포맷)

License

이 프로젝트는 MIT License 하에 배포됩니다.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages