Elasticsearch

GreenBeanΒ·2021λ…„ 9μ›” 29일
0
post-thumbnail

Elasticsearch

  • 검색 엔진 (search engine) 은 μ›Ήμ—μ„œ 정보λ₯Ό μˆ˜μ§‘ν•΄ 검색 κ²°κ³Όλ₯Ό μ œκ³΅ν•˜λŠ” ν”„λ‘œκ·Έλž¨
    • 검색 엔진은 검색 결과둜 μ œκ³΅λ˜λŠ” λ°μ΄ν„°μ˜ νŠΉμ„±μ— 따라 κ΅¬ν˜„ ν˜•νƒœκ°€ 각각 달라짐
  • 검색 μ‹œμŠ€ν…œ (search system) 은 λŒ€μš©λŸ‰ 데이터λ₯Ό 기반으둜 μ‹ λ’°μ„± μžˆλŠ” 검색 κ²°κ³Όλ₯Ό μ œκ³΅ν•˜κΈ° μœ„ν•΄ 검색 엔진을 기반으둜 κ΅¬μΆ•λœ μ‹œμŠ€ν…œμ„ ν†΅μΉ­ν•˜λŠ” μš©μ–΄
    • μˆ˜μ§‘κΈ°λ₯Ό μ΄μš©ν•΄ λ°©λŒ€ν•œ 데이터λ₯Ό μˆ˜μ§‘ν•˜κ³  이λ₯Ό λ‹€μˆ˜μ˜ 검색 엔진을 μ΄μš©ν•΄ μƒ‰μΈν•˜κ³  검색 κ²°κ³Όλ₯Ό UI둜 제곡
    • μ‹œμŠ€ν…œ λ‚΄λΆ€μ˜ 정책에 따라 관련도가 높은 λ¬Έμ„œλ₯Ό 검색 결과의 μƒμœ„μ— λ°°μΉ˜ν•  수 μžˆμ„ λΏλ”λŸ¬ νŠΉμ • ν•„λ“œλ‚˜ λ¬Έμ„œμ— κ°€μ€‘μΉ˜λ₯Ό λ‘¬μ„œ κ²€μƒ‰μ˜ 정확도λ₯Ό 높일 수 있음
  • 검색 μ„œλΉ„μŠ€ (search service) λŠ” 검색 엔진을 기반으둜 κ΅¬μΆ•ν•œ 검색 μ‹œμŠ€ν…œμ„ ν™œμš©ν•΄ 검색 κ²°κ³Όλ₯Ό μ„œλΉ„μŠ€λ‘œ 제곡
  • Elasticsearch λŠ” μ—„λ°€νžˆ λ§ν•˜μžλ©΄ 검색 엔진이며 검색 μ„œλΉ„μŠ€λ₯Ό μ œκ³΅ν•˜κΈ° μœ„ν•΄ Elasticsearch λ₯Ό μ΄μš©ν•΄ 검색 μ‹œμŠ€ν…œμ„ ꡬ좕 ν•  수 있음

Elasticsearch λž€?

  • Elasticsearch λŠ” ν…μŠ€νŠΈ βˆ™ 숫자 βˆ™ μœ„μΉ˜ 기반 정보 βˆ™ μ •ν˜• 및 λΉ„μ •ν˜• 데이터 λ“± λͺ¨λ“  μœ ν˜•μ˜ 데이터λ₯Ό μœ„ν•œ 무료 검색 및 뢄석 엔진
  • Apache Lucene (μ•„νŒŒμΉ˜ 루씬) 기반의 Java μ˜€ν”ˆμ†ŒμŠ€ λΆ„μ‚° 검색 엔진
  • Elasticsearch λ₯Ό 톡해 Lucene 라이브러리λ₯Ό λ‹¨λ…μœΌλ‘œ μ‚¬μš©ν•  수 있게 λ˜μ—ˆμœΌλ©° λ°©λŒ€ν•œ μ–‘μ˜ 데이터λ₯Ό 거의 μ‹€μ‹œκ°„ (NRT: Near Real Time) 으둜 μ €μž₯ βˆ™ 검색 βˆ™ 뢄석할 수 있음
  • Elasticsearch λŠ” 검색을 μœ„ν•΄ λ‹¨λ…μœΌλ‘œ μ‚¬μš©λ˜κΈ°λ„ ν•˜λ©° ELK Stack (Elasticsearch / Logstatsh / Kibana) 으둜 μ‚¬μš©λ˜κΈ°λ„ 함

Tip! ELK Stackμ΄λž€?

  • Logstash (λ‘œκ·ΈμŠ€νƒœμ‹œ)
    λ‹€μ–‘ν•œ μ†ŒμŠ€ (DB βˆ™ CSV 파일 λ“±) 의 둜그 λ˜λŠ” νŠΈλžœμž­μ…˜ 데이터λ₯Ό μˆ˜μ§‘ βˆ™ 집계 βˆ™ νŒŒμ‹±ν•˜μ—¬ Elasticsearch 둜 전달
  • Elasticsearch (μ—˜λΌμŠ€ν‹±μ„œμΉ˜)
    Logstash λ‘œλΆ€ν„° 받은 데이터λ₯Ό 검색 및 집계λ₯Ό ν•˜μ—¬ ν•„μš”ν•œ 관심 μžˆλŠ” 정보λ₯Ό νšλ“
  • Kibana (ν‚€λ°”λ‚˜)
    Elasticsearch 의 λΉ λ₯Έ 검색을 톡해 데이터λ₯Ό μ‹œκ°ν™” 및 λͺ¨λ‹ˆν„°λ§

Elasticsearch의 νŠΉμ§•

μ˜€ν”ˆμ†ŒμŠ€ (Open Source)

  • Elasticsearch 의 핡심 κΈ°λŠ₯듀은 Apache 2.0 λΌμ΄μ„ΌμŠ€λ‘œ 배포되고 있고 Elastic Stack 의 λͺ¨λ“  μ œν’ˆλ“€μ€ ( https://github.com/elastic ) λ ˆν¬μ§€ν† λ¦¬μ—μ„œ μ†ŒμŠ€λ₯Ό 찾을 수 있음
  • 6.3 버전 λΆ€ν„°λŠ” Elastic λΌμ΄μ„ΌμŠ€μ™€ Apache λΌμ΄μ„ΌμŠ€κ°€ μ„žμ—¬ μžˆμ§€λ§Œ 각각의 버전에 λŒ€ν•΄ 별도 배포판이 μ‘΄μž¬ν•˜κ³  λΌμ΄μ„ΌμŠ€ νŒŒμΌμ—μ„œ μ–΄λ–€ 경둜의 νŒŒμΌλ“€μ΄ μ–΄λ–€ λΌμ΄μ„ΌμŠ€λ‘œ λ˜μ–΄ μžˆλŠ”μ§€ 확인이 κ°€λŠ₯
  • ν˜„μž¬λŠ” x-pack 디렉토리 μ•„λž˜ μžˆλŠ” νŒŒμΌλ“€λ§Œμ΄ Elastic λΌμ΄μ„ΌμŠ€λ₯Ό λ”°λ₯΄κ³  κ·Έ μ™Έμ˜ νŒŒμΌλ“€μ€ Apache λΌμ΄μ„ΌμŠ€λ₯Ό 따름
  • Lucene 이 Java 둜 λ§Œλ“€μ–΄μ‘ŒκΈ° λ•Œλ¬Έμ— Elasticsearch 도 λ§ˆμ°¬κ°€μ§€λ‘œ Java 둜 코딩이 λ˜μ–΄ 있음
  • Lucene 은 Hadoop (ν•˜λ‘‘) 을 κ°œλ°œν•œ Doug Cutting (더그 μ»€νŒ…) 에 μ˜ν•΄ 처음 λ§Œλ“€μ–΄μ‘Œμ§€λ§Œ Elasticsearch μ—”μ§€λ‹ˆμ–΄λ“€ μ€‘μ—λŠ” Lucene 컀미터듀이 λ‹€μˆ˜ μžˆμ–΄μ„œ Lucene 을 맀우 κΉŠμ€ λ ˆλ²¨μ—μ„œ 닀루고 있음
    • Elastic μ‚¬μ˜ Lucene 컀미터인 κ°œλ°œμžλ“€μ΄ μ‹€μ œλ‘œ Lucene ν”„λ‘œμ νŠΈμ˜ 절반 μ΄μƒμ˜ κΈ°λŠ₯을 κ°œλ°œμ— κΈ°μ—¬ν•˜κ³  있음

μ‹€μ‹œκ°„ 뢄석 (Real-Time)

  • Elasticsearch 의 κ°€μž₯ 큰 νŠΉμ§• 쀑 ν•˜λ‚˜λŠ” μ‹€μ‹œκ°„ (real-time) 뢄석 μ‹œμŠ€ν…œ
  • ν˜„μž¬ λŒ€μš©λŸ‰ 데이터 뢄석에 κ°€μž₯ 널리 μ‚¬μš©λ˜κ³  μžˆλŠ” 것은 Hadoop ν”Œλž«νΌ μœ„μ—μ„œ μ‹€ν–‰λ˜λŠ” Pig βˆ™ Hive와 같은 λ‹€μ–‘ν•œ Map Reducer (맡 λ¦¬λ“€μ„œ)
  • Hadoop 은 기본적으둜 배치 기반의 뢄석 μ‹œμŠ€ν…œμœΌλ‘œ 뢄석에 μ‚¬μš©λ  μ†ŒμŠ€ 데이터 βˆ™ 뢄석을 μˆ˜ν–‰ ν•  ν”„λ‘œκ·Έλž¨μ„ 올렀 놓고 뢄석을 μ‹€ν–‰ν•˜μ—¬ κ²°κ³Ό 셋이 λ‚˜μ˜€λ„λ‘ ν•˜λŠ” ν•˜λ‚˜μ˜ λ£¨ν‹΄μœΌλ‘œ μ‹€ν–‰
  • Elasticsearch λŠ” Hadoop μ‹œμŠ€ν…œκ³Ό 달리 Elasticsearch ν΄λŸ¬μŠ€ν„°κ°€ μ‹€ν–‰λ˜κ³  μžˆλŠ” λ™μ•ˆμ—λŠ” κ³„μ†ν•΄μ„œ 데이터가 μž…λ ₯ (검색 μ—”μ§„μ—μ„œλŠ” 색인: 인덱싱 indexing 이라고 ν‘œν˜„) 되고 그와 λ™μ‹œμ— μ‹€μ‹œκ°„μ— κ°€κΉŒμš΄ (NRT: Near Real Time) μ†λ„λ‘œ μƒ‰μΈλœ λ°μ΄ν„°μ˜ 검색 βˆ™ 집계가 κ°€λŠ₯

Tip! 맡 λ¦¬λ“€μ„œ (Map reducer) λž€?
κ±°λŒ€ν•œ 인풋 데이터λ₯Ό μͺΌκ°œμ–΄ μˆ˜λ§Žμ€ λ¨Έμ‹ λ“€μ—κ²Œ λΆ„μ‚°μ‹œμΌœμ„œ λ‘œμ§μ„ μˆ˜ν–‰ν•œ λ‹€μŒ κ²°κ³Όλ₯Ό ν•˜λ‚˜λ‘œ ν•©μΉ˜μžλŠ” 것이 핡심 아이디어

  • Map Reduce 진행 μˆœμ„œ
    • μͺΌκ°œκΈ° (Split): 크기가 큰 인풋 νŒŒμΌμ„ μž‘μ€ λ‹¨μœ„μ˜ μ²­ν¬λ“€λ‘œ λ‚˜λˆ„μ–΄ λΆ„μ‚° 파일 μ‹œμŠ€ν…œ (μ˜ˆμ‹œ: HDFS) 에 μ €μž₯
    • 데이터 μ²˜λ¦¬ν•˜κΈ° (Map): 잘게 μͺΌκ°œμ–΄μ§„ νŒŒμΌμ„ μΈν’‹μœΌλ‘œ λ°›μ•„μ„œ 데이터λ₯Ό λΆ„μ„ν•˜λŠ” λ‘œμ§μ„ μˆ˜ν–‰
    • 처리된 데이터 ν•©μΉ˜κΈ° (Reduce): 처리된 데이터λ₯Ό λ‹€μ‹œ ν•©μΉ¨

μ „λ¬Έ (Full Text) 검색 엔진

  • Lucene 은 기본적으둜 Inverted File Index (μ—­νŒŒμΌ 색인) λΌλŠ” ꡬ쑰둜 데이터λ₯Ό μ €μž₯
  • Lucene 을 μ‚¬μš©ν•˜κ³  μžˆλŠ” Elasticsearch 도 λ§ˆμ°¬κ°€μ§€λ‘œ μƒ‰μΈλœ λͺ¨λ“  데이터λ₯Ό μ—­νŒŒμΌ 색인 ꡬ쑰둜 μ €μž₯ν•˜μ—¬ κ°€κ³΅λœ ν…μŠ€νŠΈλ₯Ό 검색
    • 이런 νŠΉμ„±μ„ μ „λ¬Έ (full text) 검색이라고 함
  • JSON λ¬Έμ„œ 기반 Elasticsearch λŠ” λ‚΄λΆ€μ μœΌλ‘œλŠ” μ—­νŒŒμΌ 색인 ꡬ쑰둜 데이터λ₯Ό μ €μž₯ν•˜κ³  μžˆμœΌλ‚˜ μ‚¬μš©μžμ˜ κ΄€μ μ—μ„œλŠ” JSON ν˜•μ‹μœΌλ‘œ 데이터λ₯Ό 전달
  • JSON ν˜•μ‹μ€ κ°„κ²°ν•˜κ³  κ°œλ°œμžλ“€μ΄ 닀루기 νŽΈν•œ ꡬ쑰둜 λ˜μ–΄ μžˆμ–΄ 색인 ν•  λŒ€μƒ λ¬Έμ„œλ₯Ό 가곡 ν•˜κ±°λ‚˜ λ‹€λ₯Έ ν΄λΌμ΄μ–ΈνŠΈ ν”„λ‘œκ·Έλž¨κ³Ό μ—°λ™ν•˜κΈ°μ— 용이
  • λ˜ν•œ key-value ν˜•μ‹μ΄ μ•„λ‹Œ λ¬Έμ„œ 기반으둜 λ˜μ–΄ μžˆκΈ°μ— 볡합적인 정보λ₯Ό ν¬ν•¨ν•˜λŠ” ν˜•μ‹μ˜ λ¬Έμ„œλ₯Ό μžˆλŠ” κ·ΈλŒ€λ‘œ μ €μž₯이 κ°€λŠ₯ν•˜λ©° μ‚¬μš©μžκ°€ μ§κ΄€μ μœΌλ‘œ μ΄ν•΄ν•˜κ³  μ‚¬μš©ν•  수 있음
  • Elasticsearch μ—μ„œ μ§ˆμ˜μ— μ‚¬μš©λ˜λŠ” μΏΌλ¦¬λ¬Έμ΄λ‚˜ 쿼리에 λŒ€ν•œ 결과도 λͺ¨λ‘ JSON ν˜•μ‹μœΌλ‘œ μ „λ‹¬λ˜κ³  λ°˜ν™˜
  • λ‹€λ§Œ JSON이 Elasticsearch κ°€ μ§€μ›ν•˜λŠ” μœ μΌν•œ ν˜•μ‹μ΄κΈ° λ•Œλ¬Έμ— 사전에 μž…λ ₯ν•  데이터λ₯Ό JSON ν˜•μ‹μœΌλ‘œ κ°€κ³΅ν•˜λŠ” 것이 ν•„μš”
  • CSV βˆ™ Apache log βˆ™ Syslog λ“±κ³Ό 같이 널리 μ‚¬μš©λ˜λŠ” ν˜•μ‹λ“€μ€ Logstash μ—μ„œ λ³€ν™˜μ„ μ§€μ›ν•˜κ³  있음

RESTFul API

  • ν˜„μž¬ λŒ€κ·œλͺ¨ μ‹œμŠ€ν…œλ“€μ€ λŒ€λΆ€λΆ„ MSA (마이크둜 μ„œλΉ„μŠ€ μ•„ν‚€ν…μ²˜) λ₯Ό 기본으둜 섀계
    • μ΄λŸ¬ν•œ ꡬ쑰에 빠질 수 μ—†λŠ” 것이 REST API 와 같은 ν‘œμ€€ μΈν„°νŽ˜μ΄μŠ€
  • Elasticsearch λŠ” Rest API λ₯Ό 기본으둜 μ§€μ›ν•˜λ©° λͺ¨λ“  데이터 쑰회 βˆ™ μž…λ ₯ βˆ™ μ‚­μ œλ₯Ό HTTP ν”„λ‘œν† μ½œμ„ 톡해 Rest API 둜 처리

Tip!

  • Elasticsearch λŠ” 기본적으둜 HTTP λ₯Ό 톡해 JSON ν˜•μ‹μ˜ RESTful API λ₯Ό 이용
    • Elasticsearch λŠ” Java 둜 κ°œλ°œλμ§€λ§Œ μ—¬λŸ¬ 가지 ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄λ₯Ό 톡해 ν™œμš©ν•  μˆ˜λ„ 있음

  • Elasticsearch λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•œ API μš”μ²­ ꡬ쑰
    • curl -X(λ©”μ„œλ“œ) http://host:port/(인덱슀)/(νƒ€μž…)/(λ¬Έμ„œ id) -d '{json 데이터}'
  • Elasticsearch λŠ” κ΄€κ³„ν˜• λ°μ΄ν„°λ² μ΄μŠ€ 검색보닀 훨씬 μœ μ—°
    • μ—­μƒ‰μΈλ˜λŠ” λ¬Έμžμ—΄ 전체λ₯Ό 정책에 따라 μ†Œλ¬Έμž ν˜Ήμ€ λŒ€λ¬Έμžλ‘œ μƒμ„±ν•˜κ³  쿼리가 λ“€μ–΄μ˜€λŠ” ν•„ν„°λ₯Ό 색인 μ‹œκ°„κ³Ό 검색 μ‹œκ°„μ— λ™μΌν•˜κ²Œ μ§€μ •ν•œλ‹€λ©΄ ν•΄λ‹Ή μΏΌλ¦¬λŠ” μ–΄λ– ν•œ λ¬Έμžμ—΄ (λŒ€μ†Œλ¬Έμž ꡬ뢄 μ—†μŒ) 이 듀어와도 검색이 κ°€λŠ₯
    • λ˜ν•œ Elasticsearch λŠ” κ΅¬μ‘°ν™”λ˜μ§€ μ•Šμ€ λΉ„μ •ν˜• 데이터도 검색이 κ°€λŠ₯
    • λ°μ΄ν„°λ² μ΄μŠ€λŠ” μŠ€ν‚€λ§ˆλ₯Ό 미리 μ •μ˜ν•΄μ•Όλ§Œ 데이터 μ €μž₯κ³Ό μ‘°νšŒκ°€ κ°€λŠ₯ν•œ 반면 Elasticsearch λŠ” κ΅¬μ‘°ν™”λ˜μ§€ μ•Šμ€ λ°μ΄ν„°κΉŒμ§€ 슀슀둜 뢄석해 μžλ™μœΌλ‘œ ν•„λ“œλ₯Ό μƒμ„±ν•˜κ³  μ €μž₯
  • Elasticsearch λŠ” NoSQL의 μΌμ’…μœΌλ‘œμ„œ λΆ„λ₯˜κ°€ κ°€λŠ₯ν•˜κ³  λΆ„μ‚° 처리λ₯Ό 톡해 μ‹€μ‹œκ°„μ— μ€€ν•˜λŠ” λΉ λ₯Έ 검색이 κ°€λŠ₯
    • κΈ°μ‘΄ λ°μ΄ν„°λ² μ΄μŠ€λ‘œλŠ” μ²˜λ¦¬ν•˜κΈ° μ–΄λ €μš΄ λŒ€λŸ‰μ˜ λΉ„μ •ν˜• 데이터도 검색할 수 있으며 μ „λ¬Έ 검색 (Full Text) κ³Ό ꡬ쑰 검색 λͺ¨λ‘λ₯Ό 지원

λ©€ν‹°ν…Œλ„Œμ‹œ (Multitenancy)

  • Elasticsearch 의 데이터듀은 인덱슀 (Index) λΌλŠ” 논리적인 집합 λ‹¨μœ„λ‘œ κ΅¬μ„±λ˜λ©° μ„œλ‘œ λ‹€λ₯Έ μ €μž₯μ†Œμ— λΆ„μ‚°λ˜μ–΄ μ €μž₯
  • μ„œλ‘œ λ‹€λ₯Έ μΈλ±μŠ€λ“€μ„ λ³„λ„μ˜ 컀λ„₯μ…˜ 없이 ν•˜λ‚˜μ˜ 질의둜 λ¬Άμ–΄μ„œ κ²€μƒ‰ν•˜κ³  검색 결과듀을 ν•˜λ‚˜μ˜ 좜λ ₯으둜 λ„μΆœν•  수 μžˆλŠ”λ° Elasticsearch 의 μ΄λŸ¬ν•œ νŠΉμ§•μ„ λ©€ν‹°ν…Œλ„Œμ‹œ 라고 함

Tip! μΆ”κ°€ λ‚΄μš©

검색 μ‹œμŠ€ν…œμ˜ κ΅¬μ„±μš”μ†Œ

  • 검색 μ‹œμŠ€ν…œμ˜ κΈ°λ³Έ κ΅¬μ‘°λŠ” 일반적으둜 정보λ₯Ό μˆ˜μ§‘ν•˜λŠ” μˆ˜μ§‘κΈ° βˆ™ μˆ˜μ§‘ν•œ 데이터λ₯Ό μ €μž₯ν•˜λŠ” μŠ€ν† λ¦¬μ§€ βˆ™ μˆ˜μ§‘ν•œ 데이터λ₯Ό 검색에 μ μ ˆν•œ ν˜•νƒœλ‘œ λ³€ν™˜ν•˜λŠ” 색인기 βˆ™ μƒ‰μΈλœ λ°μ΄ν„°μ—μ„œ μΌμΉ˜ν•˜λŠ” λ¬Έμ„œλ₯Ό μ°ΎλŠ” κ²€μƒ‰κΈ°λ‘œ ꡬ성

μˆ˜μ§‘κΈ°

  • μˆ˜μ§‘κΈ°λŠ” μ›Ήμ‚¬μ΄νŠΈ βˆ™ λΈ”λ‘œκ·Έ βˆ™ 카페 λ“± μ›Ήμ—μ„œ ν•„μš”ν•œ 정보λ₯Ό μˆ˜μ§‘ν•˜λŠ” ν”„λ‘œκ·Έλž¨
    • 크둀러 (Crawler) βˆ™ μŠ€νŒŒμ΄λ” (Spider) βˆ™ μ›œ (Worms) βˆ™ μ›Ήλ‘œλ΄‡ (Web Robot) λ“±μœΌλ‘œ 뢈림
    • 파일 βˆ™ λ°μ΄ν„°λ² μ΄μŠ€ βˆ™ μ›ΉνŽ˜μ΄μ§€ λ“± μ›Ή μƒμ˜ λŒ€λΆ€λΆ„μ˜ 정보가 μˆ˜μ§‘ λŒ€μƒ

μŠ€ν† λ¦¬μ§€

  • λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ 데이터λ₯Ό μ €μž₯ν•˜λŠ” 물리적인 μ €μž₯μ†Œ
    • 검색 엔진은 μƒ‰μΈν•œ 데이터λ₯Ό μŠ€ν† λ¦¬μ§€μ— 보관

색인기

  • 검색 엔진이 μˆ˜μ§‘ν•œ μ •λ³΄μ—μ„œ μ‚¬μš©μž μ§ˆμ˜μ™€ μΌμΉ˜ν•˜λŠ” 정보λ₯Ό 찾으렀면 μˆ˜μ§‘λœ 데이터λ₯Ό 검색 κ°€λŠ₯ν•œ ꡬ쑰둜 κ°€κ³΅ν•˜κ³  μ €μž₯ν•΄μ•Ό 함
    • κ·Έ 역할을 ν•˜λŠ” 것이 색인기
    • μƒ‰μΈκΈ°λŠ” λ‹€μ–‘ν•œ ν˜•νƒœμ†Œ 뢄석기λ₯Ό μ‘°ν•©ν•΄ μ •λ³΄μ—μ„œ μ˜λ―Έκ°€ μžˆλŠ” μš©μ–΄λ₯Ό μΆ”μΆœν•˜κ³  검색에 μœ λ¦¬ν•œ 역색인 ꡬ쑰둜 데이터λ₯Ό μ €μž₯

검색기

  • κ²€μƒ‰κΈ°λŠ” μ‚¬μš©μž 질의λ₯Ό μž…λ ₯λ°›μ•„ μƒ‰μΈκΈ°μ—μ„œ μ €μž₯ν•œ 역색인 κ΅¬μ‘°μ—μ„œ μΌμΉ˜ν•˜λŠ” λ¬Έμ„œλ₯Ό μ°Ύμ•„ 결과둜 λ°˜ν™˜
    • μ§ˆμ˜μ™€ λ¬Έμ„œκ°€ μΌμΉ˜ν•˜λŠ”μ§€λŠ” μœ μ‚¬λ„ 기반의 검색 μˆœμœ„ μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ νŒλ‹¨ν•˜λŠ”λ° 검색기 λ˜ν•œ 색인기와 λ§ˆμ°¬κ°€μ§€λ‘œ ν˜•νƒœμ†Œ 뢄석기λ₯Ό μ΄μš©ν•΄ μ‚¬μš©μž μ§ˆμ˜μ—μ„œ μœ μ˜λ―Έν•œ μš©μ–΄λ₯Ό μΆ”μΆœν•΄ 검색
    • λ”°λΌμ„œ μ‚¬μš©ν•˜λŠ” ν˜•νƒœμ†Œ 뢄석기에 따라 검색 ν’ˆμ§ˆμ΄ 달라짐

  • κ΄€κ³„ν˜• λ°μ΄ν„°λ² μ΄μŠ€λŠ” SQL 문을 μ΄μš©ν•΄ μ›ν•˜λŠ” μ •λ³΄μ˜ 검색이 κ°€λŠ₯ν•œλ° ν…μŠ€νŠΈ 맀칭을 ν†΅ν•œ λ‹¨μˆœν•œ κ²€μƒ‰λ§Œ κ°€λŠ₯
    • ν…μŠ€νŠΈλ₯Ό μ—¬λŸ¬ λ‹¨μ–΄λ‘œ λ³€ν˜•ν•˜κ±°λ‚˜ μ—¬λŸ¬ 개의 λ™μ˜μ–΄λ‚˜ μœ μ˜μ–΄λ₯Ό ν™œμš©ν•œ 검색은 λΆˆκ°€λŠ₯
  • 반면 검색 엔진은 λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œλŠ” λΆˆκ°€λŠ₯ν•œ λΉ„μ •ν˜• 데이터λ₯Ό μƒ‰μΈν•˜κ³  검색할 수 있음
    • ν˜•νƒœμ†Œ 뢄석을 톡해 μ‚¬λžŒμ΄ κ΅¬μ‚¬ν•˜λŠ” μžμ—°μ–΄μ˜ μ²˜λ¦¬κ°€ κ°€λŠ₯해지고 역색인 ꡬ쑰λ₯Ό λ°”νƒ•μœΌλ‘œ λΉ λ₯Έ 검색 속도λ₯Ό 보μž₯

κΈ°λ³Έ μš©μ–΄

  • Elasticsearch 의 λ°μ΄ν„°λŠ” λ‹€μŒκ³Ό 같이 인덱슀 βˆ™ νƒ€μž… βˆ™ λ¬Έμ„œ βˆ™ ν•„λ“œ ꡬ쑰둜 ꡬ성

인덱슀 (Index)

  • 인덱슀 (Index) λŠ” 데이터 μ €μž₯ 곡간
    • ν•˜λ‚˜μ˜ μΈλ±μŠ€λŠ” ν•˜λ‚˜μ˜ νƒ€μž…λ§Œ 가지며 ν•˜λ‚˜μ˜ 물리적인 λ…Έλ“œμ— μ—¬λŸ¬ 개의 논리적인 인덱슀λ₯Ό 생성할 수 있음
    • 검색 μ‹œ 인덱슀 μ΄λ¦„μœΌλ‘œ λ¬Έμ„œ 데이터λ₯Ό κ²€μƒ‰ν•˜λ©° μ—¬λŸ¬ 개의 인덱슀λ₯Ό λ™μ‹œμ— κ²€μƒ‰ν•˜λŠ” 것도 κ°€λŠ₯
  • Elasticsearch λ₯Ό λΆ„μ‚° ν™˜κ²½μœΌλ‘œ κ΅¬μ„±ν•˜λ©΄ ν•˜λ‚˜μ˜ μΈλ±μŠ€κ°€ μ—¬λŸ¬ λ…Έλ“œμ— λΆ„μ‚° μ €μž₯λ˜μ–΄ 관리됨에 따라 λΆ„μ‚° μ²˜λ¦¬μ— λ”°λ₯Έ μ—¬λŸ¬ 이점을 λˆ„λ¦΄ 수 있음
    • Elasticsearch λŠ” 인덱슀 μƒμ„±μ‹œ 기본적으둜 5개의 프라이머리 (Primary) μƒ€λ“œμ™€ 1개의 λ ˆν”Œλ¦¬μΉ΄ (Replica) μƒ€λ“œ μ„ΈνŠΈλ₯Ό 생성
    • 각각의 μƒ€λ“œ μˆ˜λŠ” 인덱슀λ₯Ό 생성할 λ•Œ μ˜΅μ…˜μ„ μ΄μš©ν•΄ λ³€κ²½ν•  수 있음
  • 인덱슀의 이름은 λͺ¨λ‘ μ†Œλ¬Έμžμ—¬μ•Ό ν•˜λ©° μΆ”κ°€ βˆ™ μˆ˜μ • βˆ™ μ‚­μ œ βˆ™ 검색은 RESTful API 둜 μˆ˜ν–‰ν•  수 있음
    • λ§Œμ•½ μΈλ±μŠ€κ°€ μ—†λŠ” μƒνƒœμ—μ„œ 데이터가 μΆ”κ°€λœλ‹€λ©΄ 데이터λ₯Ό μ΄μš©ν•΄ μΈλ±μŠ€κ°€ μžλ™μœΌλ‘œ 생성됨

μƒ€λ“œ (Shard)

  • μƒ‰μΈλœ λ¬Έμ„œλŠ” ν•˜λ‚˜μ˜ μΈλ±μŠ€μ— λ‹΄κΉ€
    • 인덱슀 내뢀에 μƒ‰μΈλœ λ°μ΄ν„°λŠ” 물리적인 곡간에 μ—¬λŸ¬ 개의 νŒŒν‹°μ…˜μœΌλ‘œ λ‚˜λ‰˜μ–΄ κ΅¬μ„±λ˜λŠ”λ° 이 νŒŒν‹°μ…˜μ„ Elasticsearch μ—μ„œλŠ” μƒ€λ“œ (Shard) 라고 뢀름
    • Elasticsearch λŠ” λ‹€μˆ˜μ˜ μƒ€λ“œλ‘œ λ¬Έμ„œλ₯Ό λΆ„μ‚° μ €μž₯ν•˜κ³  μžˆμ–΄ 데이터 손싀 μœ„ν—˜μ„ μ΅œμ†Œν™”ν•  수 있음

νƒ€μž… (Type)

  • νƒ€μž… (Type) 은 인덱슀의 논리적 ꡬ쑰λ₯Ό μ˜λ―Έν•˜λ©° 인덱슀 속성에 따라 λΆ„λ₯˜ν•˜κΈ°λ„ 함
    • Elasticsearch 6.0 버전 μ΄ν•˜μ—μ„œλŠ” ν•˜λ‚˜μ˜ μΈλ±μŠ€μ— μ—¬λŸ¬ νƒ€μž… 섀정이 κ°€λŠ₯ν–ˆμ§€λ§Œ 6.1 λ²„μ „λΆ€ν„°λŠ” μΈλ±μŠ€λ‹Ή ν•˜λ‚˜μ˜ νƒ€μž…λ§Œ μ‚¬μš©ν•  수 있음
  • Elasticsearch 6.0 μ΄ν•˜ λ²„μ „μ—μ„œλŠ” νŠΉμ • μΉ΄ν…Œκ³ λ¦¬λ₯Ό λΆ„λ₯˜ν•˜λŠ” λͺ©μ μœΌλ‘œ νƒ€μž…μ΄ 많이 μ‚¬μš©λ˜μ—ˆμŒ
    • 예λ₯Ό λ“€μ–΄ music μ΄λΌλŠ” μΈλ±μŠ€κ°€ μ‘΄μž¬ν•œλ‹€λ©΄ μž₯λ₯΄λ³„ (Rock βˆ™ K-pop βˆ™ Classic) 둜 뢄리해 μ‚¬μš©ν–ˆμœΌλ‚˜ ν˜„μž¬λŠ” νƒ€μž…μ„ μ‚¬μš©ν•˜λŠ” 것을 ꢌμž₯ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μž₯λ₯΄ λ³„λ‘œ λ³„λ„μ˜ 인덱슀λ₯Ό 각각 μƒμ„±ν•΄μ„œ μ‚¬μš©ν•΄μ•Ό 함

λ¬Έμ„œ (Document)

  • λ¬Έμ„œ (Document) λŠ” Elasticsearch μ—μ„œ 데이터가 μ €μž₯λ˜λŠ” μ΅œμ†Œ λ‹¨μœ„
    • 기본적으둜 JSON 포맷으둜 데이터가 μ €μž₯
    • λ°μ΄ν„°λ² μ΄μŠ€μ™€ λΉ„κ΅ν•˜μžλ©΄ ν…Œμ΄λΈ”μ˜ 행이 Elasticsearch 의 λ¬Έμ„œμ— ν•΄λ‹Ήν•œλ‹€κ³  λ³Ό 수 있음
    • ν•˜λ‚˜μ˜ λ¬Έμ„œλŠ” λ‹€μˆ˜μ˜ ν•„λ“œλ‘œ ꡬ성돼 μžˆλŠ”λ° 각 ν•„λ“œλŠ” λ°μ΄ν„°μ˜ ν˜•νƒœμ— 따라 μš©λ„μ— λ§žλŠ” 데이터 νƒ€μž… (Data Type) 을 μ •μ˜ν•΄μ•Ό ν•˜λ©° λ¬Έμ„œλŠ” 쀑첩 ꡬ쑰λ₯Ό μ§€μ›ν•˜κΈ° λ•Œλ¬Έμ— 이λ₯Ό μ΄μš©ν•΄ λ¬Έμ„œ μ•ˆμ— λ¬Έμ„œλ₯Ό μ§€μ •ν•˜λŠ” 것도 κ°€λŠ₯

ν•„λ“œ (Field)

  • ν•„λ“œ (Field) λŠ” λ¬Έμ„œλ₯Ό κ΅¬μ„±ν•˜κΈ° μœ„ν•œ 속성이라고 ν•  수 있음
    • 일반적으둜 λ°μ΄ν„°λ² μ΄μŠ€μ˜ 칼럼 (Column) κ³Ό 비ꡐ할 수 μžˆμœΌλ‚˜ 컬럼이 정적 (static) 인 데이터 νƒ€μž…μΈ 데 λ°˜ν•΄ ν•„λ“œλŠ” μ’€ 더 동적 (dynamic) 인 데이터 νƒ€μž…μ΄λΌκ³  ν•  수 있음
  • ν•˜λ‚˜μ˜ ν•„λ“œλŠ” λͺ©μ μ— 따라 λ‹€μˆ˜μ˜ 데이터 νƒ€μž…μ„ κ°€μ§ˆ 수 있음
    • μ˜ν™” 정보λ₯Ό λ‹΄μ•„λ‘” λ¬Έμ„œμ— 제λͺ© ν•„λ“œκ°€ μžˆλ‹€κ³  κ°€μ •ν–ˆμ„ λ•Œ μ˜ν™” 제λͺ©μ„ κ²€μƒ‰ν• λ•Œ 맀칭 검색을 ν•˜κ±°λ‚˜ μ΄ˆμ„±μ„ μ΄μš©ν•œ 검색이 λͺ¨λ‘ μ§€μ›λ˜λ„λ‘ 제λͺ© ν•„λ“œλŠ” 2개의 데이터 νƒ€μž…μ„ κ°€μ Έμ•Ό 함

맀핑 (Mapping)

  • 맀핑 (Mapping) 은 λ¬Έμ„œμ˜ ν•„λ“œμ™€ ν•„λ“œμ˜ 속성을 μ •μ˜ν•˜κ³  그에 λ”°λ₯Έ 색인 방법을 μ •μ˜ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€
    • 인덱슀의 맀핑 μ •λ³΄μ—λŠ” μ—¬λŸ¬ 가지 데이터 νƒ€μž…μ„ 지정할 수 μžˆμ§€λ§Œ ν•„λ“œλͺ…은 μ€‘λ³΅ν•΄μ„œ μ‚¬μš©ν•  수 μ—†μŒ

κΈ°λ³Έ ꡬ성

  • ν΄λŸ¬μŠ€ν„°λŠ” 물리적인 λ…Έλ“œ μΈμŠ€ν„΄μŠ€λ“€μ˜ λͺ¨μž„
    • ν΄λŸ¬μŠ€ν„°λŠ” λͺ¨λ“  λ…Έλ“œμ˜ 검색과 색인 μž‘μ—…μ„ κ΄€μž₯ν•˜λŠ” 논리적인 κ°œλ…μ΄λΌ ν•  수 있음
    • κ΄€κ³„ν˜• λ°μ΄ν„°λ² μ΄μŠ€μ˜ 경우 λͺ¨λ“  μš”μ²­μ„ μ„œλ²„ ν•˜λ‚˜μ—μ„œ μ²˜λ¦¬ν•΄μ„œ κ²°κ³Όλ₯Ό μ œκ³΅ν•˜μ§€λ§Œ Elasticsearch 의 κ²½μš°μ—λŠ” λ‹€μˆ˜μ˜ μ„œλ²„λ‘œ λΆ„μ‚°ν•΄μ„œ μ²˜λ¦¬ν•˜λŠ” 것이 κ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έμ— λŒ€μš©λŸ‰ 데이터λ₯Ό μ²˜λ¦¬ν•  수 있음
  • λΆ„μ‚° 처리λ₯Ό μœ„ν•΄μ„œλŠ” λ‹€μ–‘ν•œ ν˜•νƒœμ˜ λ…Έλ“œλ“€μ„ μ‘°ν•©ν•΄μ„œ ν΄λŸ¬μŠ€ν„°λ₯Ό ꡬ성해야 함
    • 기본적으둜 λ§ˆμŠ€ν„° λ…Έλ“œκ°€ 전체적인 ν΄λŸ¬μŠ€ν„°λ₯Ό κ΄€λ¦¬ν•˜κ³  데이터 λ…Έλ“œκ°€ μ‹€μ œ 데이터λ₯Ό 관리
    • Elasticsearch λŠ” 각 섀정에 따라 4가지 μœ ν˜•μ˜ λ…Έλ“œλ₯Ό μ œκ³΅ν•˜λŠ”λ° 섀정에 따라 각 λ…Έλ“œλŠ” ν•œκ°€μ§€ μœ ν˜•μœΌλ‘œ λ™μž‘ν•  μˆ˜λ„ 있고 μ—¬λŸ¬ 개의 μœ ν˜•μ„ κ²Έν•΄μ„œ λ™μž‘ν•  μˆ˜λ„ 있음

λ§ˆμŠ€ν„° λ…Έλ“œ (Master Node)

  • λ§ˆμŠ€ν„° λ…Έλ“œλŠ” 인덱슀λ₯Ό 생성 βˆ™ μ‚­μ œν•˜λŠ” λ“± ν΄λŸ¬μŠ€ν„°μ™€ κ΄€λ ¨λœ μ „λ°˜μ μΈ μž‘μ—…μ„ λ‹΄λ‹Ή
    • λ”°λΌμ„œ λ„€νŠΈμ›Œν¬ 속도가 λΉ λ₯΄κ³  지연이 μ—†λŠ” λ…Έλ“œλ₯Ό λ§ˆμŠ€ν„° λ…Έλ“œλ‘œ μ„ μ •ν•΄μ•Ό 함
    • λ‹€μˆ˜μ˜ λ…Έλ“œλ₯Ό λ§ˆμŠ€ν„° λ…Έλ“œλ‘œ μ„€μ •ν•  수 μžˆμ§€λ§Œ 결과적으둜 ν•˜λ‚˜μ˜ λ…Έλ“œλ§Œμ΄ λ§ˆμŠ€ν„° λ…Έλ“œλ‘œ μ„ μΆœλ˜μ–΄ λ™μž‘ν•¨
  • λ§Œμ•½ λ…Έλ“œλ₯Ό λ§ˆμŠ€ν„° λ…Έλ“œ μ „μš©μœΌλ‘œ μ„€μ •ν•˜κ³ μž ν•œλ‹€λ©΄ Elasticsearch μ„œλ²„μ˜ conf 폴더 μ•ˆμ˜ elasticsearch.yml νŒŒμΌμ„ μ—΄κ³  λ‹€μŒκ³Ό 같이 μ„€μ •ν•˜λ©΄ 됨
node.master: true
node.data: false
node.ingest: false
search.remote.connect: false

데이터 λ…Έλ“œ (Data Node)

  • 데이터 λ…Έλ“œλŠ” λ¬Έμ„œκ°€ μ‹€μ œλ‘œ μ €μž₯λ˜λŠ” λ…Έλ“œ
    • 데이터가 μ‹€μ œλ‘œ λΆ„μ‚° μ €μž₯λ˜λŠ” 물리적 곡간인 μƒ€λ“œκ°€ λ°°μΉ˜λ˜λŠ” λ…Έλ“œμ΄κΈ°λ„ 함
    • 색인 μž‘μ—…μ€ CPU βˆ™ λ©”λͺ¨λ¦¬ βˆ™ μŠ€ν† λ¦¬μ§€ 같은 μ»΄ν“¨νŒ… λ¦¬μ†ŒμŠ€λ₯Ό 많이 μ†Œλͺ¨ν•˜κΈ° λ•Œλ¬Έμ— λ¦¬μ†ŒμŠ€ λͺ¨λ‹ˆν„°λ§μ΄ ν•„μš”
  • 데이터 λ…Έλ“œλŠ” κ°€λŠ₯ν•œ ν•œ λ§ˆμŠ€ν„° λ…Έλ“œμ™€ λΆ„λ¦¬ν•΄μ„œ κ΅¬μ„±ν•˜λŠ”κ²Œ μ’‹μŒ
    • 단, 색인할 λ¬Έμ„œμ˜ μˆ˜κ°€ 적으면 ν•¨κ»˜ ꡬ성해도 상관은 μ—†μŒ
    • elasticsearch.yml νŒŒμΌμ„ λ‹€μŒκ³Ό 같이 μˆ˜μ •ν•˜λ©΄ 데이터 λ…Έλ“œ μ „μš©μœΌλ‘œ μ„€μ •ν•  수 있음
node.mster: false
node.data: true
node.ingest: false
search.remote.connect: false

μ½”λ””λ„€μ΄νŒ… λ…Έλ“œ (Coordinating Node)

  • 데이터 λ…Έλ“œ βˆ™ λ§ˆμŠ€ν„° λ…Έλ“œ βˆ™ 인제슀트 λ…Έλ“œμ˜ 역할을 ν•˜μ§€ μ•Šκ³  λ“€μ–΄μ˜¨ μš”μ²­μ„ λ‹¨μˆœνžˆ λΌμš΄λ“œλ‘œλΉˆ λ°©μ‹μœΌλ‘œ λΆ„μ‚°μ‹œμΌœμ£ΌλŠ” λ…Έλ“œ
    • ꡬ성 방법은 μ•„λž˜μ™€ κ°™μŒ
node.master: false
node.data: false
node.ingest: false
search.remote.connect: false

인제슀트 λ…Έλ“œ (Ingest Node)

  • 색인에 μ•žμ„œ 데이터λ₯Ό μ „μ²˜λ¦¬ν•˜κΈ° μœ„ν•œ λ…Έλ“œ
    • λ°μ΄ν„°μ˜ 포맷을 λ³€κ²½ν•˜κΈ° μœ„ν•΄ 슀크립트둜 μ „μ²˜λ¦¬ νŒŒμ΄ν”„λΌμΈμ„ κ΅¬μ„±ν•˜κ³  μ‹€ν–‰ν•  수 있음
    • ꡬ성 방법은 λ‹€μŒκ³Ό κ°™μŒ
node.master: false
node.data: false
node.ingest: true
search.remote.connect: false

ν΄λŸ¬μŠ€ν„° βˆ™ λ…Έλ“œ βˆ™ μƒ€λ“œ

  • Elasticsearch ν΄λŸ¬μŠ€ν„°λŠ” 인덱슀의 λ¬Έμ„œλ₯Ό μ‘°νšŒν•  λ•Œ λ§ˆμŠ€ν„° λ…Έλ“œλ₯Ό 톡해 2개의 λ…Έλ“œλ₯Ό λͺ¨λ‘ μ‘°νšŒν•΄μ„œ 각 데이터λ₯Ό μ·¨ν•©ν•œ ν›„ κ²°κ³Όλ₯Ό ν•˜λ‚˜λ‘œ ν•©μ³μ„œ 제곡
  • μ—¬λŸ¬ 개의 ν΄λŸ¬μŠ€ν„°λ₯Ό μ—°κ²°ν•΄μ„œ ꡬ성할 μˆ˜λ„ 있으며 μ΄λ•ŒλŠ” ν΄λŸ¬μŠ€ν„°μ˜ μ΄λ¦„μœΌλ‘œ 각각을 ꡬ뢄
    • λ§Œμ•½ ν΄λŸ¬μŠ€ν„°μ˜ 이름이 λͺ…μ‹œμ μœΌλ‘œ μ„€μ •λ˜μ§€ μ•Šμ•˜λ‹€λ©΄ Elasticsearch λŠ” ν΄λŸ¬μŠ€ν„°μ˜ 이름을 μž„μ˜μ˜ λ¬Έμžμ—΄λ‘œ 지정
    • λ˜ν•œ ν΄λŸ¬μŠ€ν„°μ— μžˆλŠ” λ…Έλ“œλŠ” μ‹€μ‹œκ°„μœΌλ‘œ μΆ”κ°€ βˆ™ μ œκ±°κ°€ κ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έμ— κ°€μš©μ„±μ΄λ‚˜ ν™•μž₯μ„± μΈ‘λ©΄μ—μ„œ 맀우 μœ μ—°
  • Elasticsearch λŠ” μž₯μ• μ‹œ λ ˆν”Œλ¦¬μΉ΄ μƒ€λ“œλ₯Ό μ΄μš©ν•΄ μƒ€λ“œλ₯Ό 볡ꡬ
    • μž₯μ• κ°€ λ°œμƒν•˜λ©΄ λ§ˆμŠ€ν„° λ…Έλ“œλŠ” 데이터λ₯Ό μž¬λΆ„λ°°ν•˜κ±°λ‚˜ λ ˆν”Œλ¦¬μΉ΄ μƒ€λ“œλ₯Ό 프라이머리 μƒ€λ“œλ‘œ μŠΉκ²©μ‹œμΌœ μ„œλΉ„μŠ€ 쀑단 μ—†λŠ” 볡ꡬ가 κ°€λŠ₯
    • λ”°λΌμ„œ μž₯애극볡 (Failover) 상황을 염두에 두고 λ…Έλ“œμ™€ μƒ€λ“œμ˜ 수λ₯Ό 적절히 ꡬ성해야 함

Elasticsearch μ—μ„œ μ œκ³΅ν•˜λŠ” μ£Όμš” API

  • Elasticsearch λŠ” RESTful λ°©μ‹μ˜ APIλ₯Ό μ œκ³΅ν•˜λ©° 이λ₯Ό 톡해 JSON 기반으둜 톡신
    • Elasticsearch λŠ” 기본적으둜 HTTP 톡신을 μœ„ν•΄ 9200번 포트λ₯Ό μ‚¬μš©
      • 인덱슀 관리 API (Indices API): 인덱슀 관리
      • λ¬Έμ„œ 관리 API (Document API): λ¬Έμ„œμ˜ μΆ”κ°€ βˆ™ μˆ˜μ • βˆ™ μ‚­μ œ
      • 검색 API (Search API): λ¬Έμ„œ 쑰회
      • 집계 API (Aggregation API): λ¬Έμ„œ 톡계
  • λ¬Έμ„œλ₯Ό μƒ‰μΈν•˜κΈ° μœ„ν•΄μ„œλŠ” 기본적으둜 인덱슀λ₯Ό 생성해야 함
    • 인덱슀λ₯Ό 톡해 μž…λ ₯λ˜λŠ” λ¬Έμ„œμ˜ ν•„λ“œλ₯Ό μ •μ˜ν•˜κ³  각 ν•„λ“œμ— μ•Œλ§žμ€ 데이터 νƒ€μž…μ„ 지정할 수 있음
    • μ΄λŸ¬ν•œ 과정을 톡해 쒀더 효율적인 색인이 κ°€λŠ₯해짐

Index vs Indices

  • 색인은 데이터가 ν† ν°ν™”λ˜μ–΄ μ €μž₯λ˜λŠ” 자료 ꡬ쑰λ₯Ό μ˜λ―Έν•˜λ©° Index λΌλŠ” 단어λ₯Ό λ²ˆμ—­ν•œ 것
    • ν•˜μ§€λ§Œ Elasticsearch μ—μ„œλŠ” μΈλ±μŠ€λΌλŠ” μš©μ–΄λ₯Ό μƒ‰μΈκ³ΌλŠ” λ‹€λ₯Έ 의미둜 μ‚¬μš©
    • Elasticsearch μ—μ„œλŠ” μš©μ–΄μ— λ”°λ₯Έ ν˜Όλž€μ„ λ°©μ§€ν•˜κΈ° μœ„ν•΄ 색인을 μ˜λ―Έν•  경우 Index λΌλŠ” 단어λ₯Ό μ‚¬μš©ν•˜κ³  맀핑 μ •μ˜ 곡간을 μ˜λ―Έν•  경우 Indices λΌλŠ” λ‹¨μ–΄λ‘œ ν‘œν˜„
      • Index: 색인 데이터
      • Indexing: μƒ‰μΈν•˜λŠ” κ³Όμ •
      • Indices: 맀핑 정보λ₯Ό μ €μž₯ν•˜λŠ” 논리적인 데이터 곡간
  • Elasticsearch λŠ” μ‚¬μš© νŽΈμ˜μ„±μ„ μœ„ν•΄ μŠ€ν‚€λ§ˆλ¦¬μŠ€ (Schemaless) λΌλŠ” κΈ°λŠ₯을 제곡
    • λ¬Έμ„œλ₯Ό μƒ‰μΈν•˜κΈ° μœ„ν•΄μ„œλŠ” 기본적으둜 인덱슀λ₯Ό μƒμ„±ν•˜λŠ” 과정이 ν•„μš”ν•œλ° 인덱슀λ₯Ό μƒμ„±ν•˜λŠ” κ³Όμ • 없이 λ¬Έμ„œλ₯Ό μΆ”κ°€ν•˜λ”λΌλ„ λ¬Έμ„œκ°€ μƒ‰μΈλ˜λ„λ‘ μ§€μ›ν•˜λŠ” μΌμ’…μ˜ 편의 κΈ°λŠ₯
    • Elasticsearch λŠ” 졜초 λ¬Έμ„œκ°€ μƒ‰μΈλ λ•Œ 인덱슀의 쑴재 μ—¬λΆ€λ₯Ό ν™•μΈν•˜κ³  λ§Œμ•½ μΈλ±μŠ€κ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ λ¬Έμ„œλ₯Ό λΆ„μ„ν•΄μ„œ λ¬Έμ„œκ°€ 색인될 수 있게 인덱슀λ₯Ό μžλ™μœΌλ‘œ 생성

μŠ€ν‚€λ§ˆλ¦¬μŠ€ κΈ°λŠ₯은 가급적이면 μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€

  • μŠ€ν‚€λ§ˆλ¦¬μŠ€ κΈ°λŠ₯을 μ΄μš©ν•˜λ©΄ λ‹€μ–‘ν•œ ν˜•νƒœμ˜ λΉ„μ •ν˜• 데이터λ₯Ό ν•˜λ‚˜μ˜ 인덱슀둜 ꡬ성할 수 μžˆμ§€λ§Œ μ΄λŠ” μ„±λŠ₯κ³Ό λ°€μ ‘ν•œ 연관이 있기 λ•Œλ¬Έμ— νŠΉμˆ˜ν•œ μƒν™©μ—μ„œλ§Œ μ‚¬μš©ν•΄μ•Ό 함
    • λ§Œμ•½ μŠ€ν‚€λ§ˆλ¦¬μŠ€λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€λ©΄ 데이터 ꡬ쑰 및 검색 방식을 ν™•μ‹€νžˆ 이해해야 함
  • μΈλ±μŠ€κ°€ μžλ™μœΌλ‘œ μƒμ„±λ˜λ©΄ 세뢀적인 ν•„λ“œ 정보가 λ§€ν•‘λ˜μ§€ μ•ŠμŒ
    • 이런 μ‹μœΌλ‘œ 인덱슀λ₯Ό μžλ™ 생성할 경우 νŠΉμ • 단어λ₯Ό 검색할 λ•Œ 검색 κ²°κ³Όμ—μ„œ λˆ„λ½λ˜λŠ” λ“± λ¬Έμ œκ°€ λ°œμƒν•  κ°€λŠ₯성이 높아짐
  • 기본적으둜 λͺ¨λ“  ν•„λ“œκ°€ text νƒ€μž…κ³Ό keyword νƒ€μž…μ„ λ™μ‹œμ— μ œκ³΅ν•˜λŠ” λ©€ν‹°ν•„λ“œ κΈ°λŠ₯으둜 ꡬ성됨
    • ν•˜μ§€λ§Œ νŠΉμ • ν•„λ“œλŠ” text νƒ€μž…λ§Œ ν•„μš”ν•  μˆ˜λ„ 있고 keyword νƒ€μž…λ§Œ ν•„μš”ν•  μˆ˜λ„ μžˆλŠ”λ° μ΄λŸ¬ν•œ 경우 데이터 κ³΅κ°„μ˜ λ‚­λΉ„λ₯Ό μ΄ˆλž˜ν•¨
  • Elasticsearch λŠ” μŠ€ν‚€λ§ˆλ¦¬μŠ€λΌλŠ” νŠΉμ„±μ— 따라 데이터에 λŒ€ν•œ 맀핑을 μžλ™μœΌλ‘œ μƒμ„±ν•˜λŠ” νŽΈλ¦¬ν•œ κΈ°λŠ₯을 μ œκ³΅ν•˜μ§€λ§Œ 이 κΈ°λŠ₯은 νŠΉμˆ˜ν•œ μƒν™©μ—μ„œλ§Œ μ œν•œμ μœΌλ‘œ μ‚¬μš©ν•΄μ•Ό 함
    • 사싀상 μ‹€λ¬΄μ—μ„œλŠ” λŒ€λΆ€λΆ„ μ‚¬μš©ν•˜μ§€ μ•ŠμŒ
    • μ‹€λ¬΄μ—μ„œλŠ” 데이터가 λŒ€λΆ€λΆ„ λ³΅μž‘ν•œ ꡬ쑰λ₯Ό κ°–κΈ° λ•Œλ¬Έμ— 자칫 검색 ν’ˆμ§ˆμ΄ λ–¨μ–΄μ§€κ±°λ‚˜ μ„±λŠ₯상 λ¬Έμ œκ°€ λ°œμƒν•  κ°€λŠ₯성이 컀지기 λ•Œλ¬Έ
  • 예λ₯Ό λ“€μ–΄ "아버지가 방에 λ“€μ–΄ κ°€μ‹ λ‹€" 와 같은 λ¬Έμž₯을 μƒ‰μΈν•œλ‹€κ³  κ°€μ •ν–ˆμ„ λ•Œ
    • μŠ€ν‚€λ§ˆλ¦¬μŠ€λ₯Ό μ΄μš©ν•΄ μƒ‰μΈν•œλ‹€λ©΄ 기본적으둜 text νƒ€μž…μ˜ Standard Analyzer λ₯Ό μ‚¬μš©ν•˜λŠ” 데이터 νƒ€μž…μ΄ μ •μ˜λ  것
    • μ΄λŸ¬ν•œ 경우 ν•΄λ‹Ή λΆ„μ„κΈ°λŠ” "아버지가" βˆ™ "방에" βˆ™ "λ“€μ–΄" βˆ™ "κ°€μ‹ λ‹€"λΌλŠ” ν† ν°μœΌλ‘œ λΆ„λ¦¬λ˜μ–΄ ν…€ (Term) 이 μƒμ„±λ˜κ³  검색 μ‹œ "아버지"λΌλŠ” ν‚€μ›Œλ“œκ°€ μž…λ ₯λ˜λ”λΌλ„ ν•΄λ‹Ή λ¬Έμ„œλŠ” κ²€μƒ‰λ˜μ§€ μ•Šμ„ 것
    • 검색을 μœ„ν•΄μ„œλŠ” Standard Analyzer κ°€ λΆ„λ¦¬ν•œ 토큰 κ·ΈλŒ€λ‘œ "아버지가"λΌλŠ” ν‚€μ›Œλ“œλ₯Ό μž…λ ₯ν•΄μ•Όλ§Œ 함
  • μ›ν•˜λŠ” κ²°κ³Όλ₯Ό μ–»κΈ° μœ„ν•΄μ„œλŠ” ν•œκΈ€ ν˜•νƒœμ†Œλ₯Ό λΆ„μ„ν•˜λŠ” 뢄석기λ₯Ό μ‚¬μš©ν•˜λ„λ‘ 데이터 νƒ€μž…μ„ 직접 μ •μ˜ν•΄μ•Ό 함
    • μ›ν•˜λŠ” κ²°κ³Όλ₯Ό μ–»κΈ° μœ„ν•΄μ„œλΌλ„ μŠ€ν‚€λ§ˆλ¦¬μŠ€ λ°©μ‹μ˜ μ‚¬μš©μ„ μ§€μ–‘ν•˜κ³  λ°˜λ“œμ‹œ 인덱슀λ₯Ό 직접 μ •μ˜ν•΄μ„œ μ‚¬μš©ν•˜λŠ” μŠ΅κ΄€μ„ λ“€μ΄λŠ” 것이 μ’‹μŒ
  • μŠ€ν‚€λ§ˆλ¦¬μŠ€ κΈ°λŠ₯을 μ‚¬μš©ν•˜κ³  싢지 μ•Šλ”λΌλ„ 인덱슀λ₯Ό μ„€μ •ν•˜μ§€ μ•Šκ³  μ‹€μˆ˜λ‘œ 데이터λ₯Ό μƒ‰μΈν•˜λ©΄ Elasticsearch λŠ” 인덱슀λ₯Ό μžλ™μœΌλ‘œ 생성
    • μ΄λŠ” 자칫 μ‹œμŠ€ν…œμ˜ μ•ˆμ •μ„±μ„ ν•΄μΉ  μˆ˜λ„ 있음
    • μ΄λŸ¬ν•œ μ‹€μˆ˜λ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•΄ μŠ€ν‚€λ§ˆλ¦¬μŠ€ κΈ°λŠ₯을 λͺ…μ‹œμ μœΌλ‘œ μ‚¬μš©ν•˜μ§€ μ•Šλ„λ‘ μ„€μ •ν•˜λŠ” 것이 κ°€λŠ₯
  • λ…Έλ“œ μ„€μ • νŒŒμΌμ—μ„œ action.auto_create_index λ₯Ό false 둜 μ„€μ •ν•  경우 μžλ™μœΌλ‘œ μΈλ±μŠ€κ°€ μƒμ„±λ˜μ§€ μ•ŠμŒ
    • λ˜λŠ” 인덱슀 λ³„λ‘œ μ œκ³΅λ˜λŠ” index.maapper.dynamic 섀정을 false 둜 μ„€μ •ν•˜λ©΄ νŠΉμ • 칼럼의 μžλ™ 맀핑 생성을 λΉ„ν™œμ„±ν™”ν•  수 있음

인덱슀 관리 API

  • 인덱슀 관리 API λŠ” 인덱슀λ₯Ό κ΄€λ¦¬ν•˜κΈ° μœ„ν•œ API
    • 이λ₯Ό μ΄μš©ν•΄ 인덱슀λ₯Ό μΆ”κ°€ν•˜κ±°λ‚˜ μ‚­μ œν•  수 μžˆλŠ”λ° 인덱슀 관리 API λŠ” HTTP λ©”μ„œλ“œλ₯Ό μ§€μ •ν•˜λŠ” 방식을 톡해 μ‚¬μš©ν•  수 있음
    • 인덱슀λ₯Ό μƒμ„±ν• λ•ŒλŠ” λ§€ν•‘μ΄λΌλŠ” μ„ΈλΆ€ 섀정을 μ΄μš©ν•  수 μžˆλŠ”λ° 맀핑은 λ¬Έμ„œμ™€ λ¬Έμ„œμ— ν¬ν•¨λœ ν•„λ“œ βˆ™ ν•„λ“œ νƒ€μž… 등을 μ„Έμ„Έν•˜κ²Œ μ§€μ •ν•˜λŠ” 것이 κ°€λŠ₯ν•œ μ„€μ • 방식
    • 인덱슀 생성 μ‹œ μ΄λŸ¬ν•œ 맀핑 정보λ₯Ό μΆ”κ°€ν•  수 μžˆλŠ”λ° ν•œκ°€μ§€ μ£Όμ˜ν•  점은 ν•œλ²ˆ μƒμ„±λœ 맀핑 μ •λ³΄λŠ” λ³€κ²½ν•  수 μ—†λ‹€λŠ” 점
    • λ§Œμ•½ 잘λͺ» μƒμ„±ν–ˆκ±°λ‚˜ λ³€κ²½ν•΄μ•Ό ν•˜λŠ” κ²½μš°μ—λŠ” 데이터λ₯Ό μ‚­μ œν•˜κ³  λ‹€μ‹œ μƒ‰μΈν•˜λŠ” 수 밖에 μ—†μŒ
  • Elasticsearch μ—μ„œλŠ” λ‹€μ–‘ν•œ ν˜•νƒœμ˜ 데이터 νƒ€μž…μ„ 제곡
    • λ‹¨μˆœνžˆ λ¬Έμžμ—΄λ‘œ μ €μž₯ν•˜κ³  싢을 경우 keyword νƒ€μž…μ„ μ‚¬μš©ν•˜λ©΄ 되고 ν˜•νƒœμ†Œ 뢄석을 원할 경우 text νƒ€μž…μ„ μ‚¬μš©
    • 예λ₯Ό λ“€μ–΄ 맀핑 μ„€μ •μœΌλ‘œ μ •μ˜λœ ν•„λ“œ 쀑 ν•œκΈ€ μ˜ν™” 이름 (movieNm) κ³Ό 영문 μ˜ν™” 이름 (moviceNmEn) 은 검색에 μ‚¬μš©λ˜κΈ° λ•Œλ¬Έμ— ν˜•νƒœμ†Œ 뢄석이 κ°€λŠ₯ν•˜λ„λ‘ text 둜 νƒ€μž…μ„ 지정
    • μ˜ν™” μ½”λ“œ (movieCd) 와 μ œμž‘μ—°λ„ (prdtYear) λŠ” 숫자 데이터 νƒ€μž…μœΌλ‘œ μ§€μ •ν•˜κ³  κ°œλ΄‰μΌ (openDt) 은 λ‚ μ§œ νƒ€μž…μœΌλ‘œ 지정
    • κ·Έ λ°–μ˜ ν•„λ“œ νƒ€μž…μ€ λͺ¨λ‘ keyword νƒ€μž…
  • 인덱슀λ₯Ό ν•œλ²ˆ μ‚­μ œν•˜λ©΄ λ‹€μ‹œλŠ” 볡ꡬ할 수 μ—†κΈ° λ•Œλ¬Έμ— 인덱슀 μ‚­μ œλŠ” μ‹ μ€‘ν•˜κ²Œν•΄μ•Ό 함

λ¬Έμ„œ 관리 API

  • λ¬Έμ„œ 관리 API λŠ” μ‹€μ œ λ¬Έμ„œλ₯Ό 색인 βˆ™ 쑰회 βˆ™ μˆ˜μ • βˆ™ μ‚­μ œλ₯Ό μ§€μ›ν•˜λŠ” API
    • Elasticsearch λŠ” 기본적으둜 검색 엔진이기 λ•Œλ¬Έμ— 검색을 μœ„ν•΄ λ‹€μ–‘ν•œ 검색 νŒ¨ν„΄μ„ μ§€μ›ν•˜λŠ” Search API λ₯Ό λ³„λ„λ‘œ 제곡
    • ν•˜μ§€λ§Œ μƒ‰μΈλœ λ¬Έμ„œμ˜ IDλ₯Ό κΈ°μ€€μœΌλ‘œ ν•œ 건의 λ¬Έμ„œλ₯Ό 닀뀄야 ν•˜λŠ” 경우 λ¬Έμ„œ 관리 API λ₯Ό μ‚¬μš©
  • λ¬Έμ„œ 관리 APIλŠ” λ‹€μŒκ³Ό 같은 μ„ΈλΆ€ κΈ°λŠ₯을 제곡
    • Index API: ν•œ 건의 λ¬Έμ„œλ₯Ό 색인
    • Get API: ν•œ 건의 λ¬Έμ„œλ₯Ό 쑰회
    • Delete API: ν•œ 건의 λ¬Έμ„œλ₯Ό μ‚­μ œ
    • Update API: ν•œ 건의 λ¬Έμ„œλ₯Ό μ—…λ°μ΄νŠΈ
  • λ¬Έμ„œ 관리 API λŠ” 기본적으둜 ν•œ 건의 λ¬Έμ„œλ₯Ό μ²˜λ¦¬ν•˜κΈ° μœ„ν•œ κΈ°λŠ₯을 μ œκ³΅ν•˜λ©° Single document API 라고도 뢀름
    • ν•˜μ§€λ§Œ ν΄λŸ¬μŠ€ν„°λ₯Ό μš΄μ˜ν•˜λ‹€ 보면 λ‹€μˆ˜μ˜ λ¬Έμ„œλ₯Ό μ²˜λ¦¬ν•΄μ•Ό ν•˜λŠ” κ²½μš°λ„ μ’…μ’… λ°œμƒν•˜λŠ”λ° μ΄λŸ¬ν•œ κ²½μš°μ— λŒ€λΉ„ν•΄ Multi-document API 도 제곡
    • Multi Get API: λ‹€μˆ˜μ˜ λ¬Έμ„œλ₯Ό 쑰회
    • Bulk API: λŒ€λŸ‰μ˜ λ¬Έμ„œλ₯Ό 색인
    • Delete By Query API: λ‹€μˆ˜μ˜ λ¬Έμ„œλ₯Ό μ‚­μ œ
    • Update By Query API: λ‹€μˆ˜μ˜ λ¬Έμ„œλ₯Ό μ—…λ°μ΄νŠΈ
    • Reindex API: 인덱슀의 λ¬Έμ„œλ₯Ό λ‹€μ‹œ 색인

IDλ₯Ό μ§€μ •ν•˜μ§€ μ•Šκ³  λ¬Έμ„œλ₯Ό 생성

  • _id 값을 직접 μ§€μ •ν•˜μ§€ μ•Šκ³  URI에 인덱슀λͺ…κ³Ό νƒ€μž…λ§Œ μ§€μ •ν•œλ‹€λ©΄ Elasticsearch κ°€ μžλ™μœΌλ‘œ _id 값을 μƒμ„±ν•˜κ²Œ 됨
    • μ΄λ•Œ _id 값은 UUID λ₯Ό 톡해 λ¬΄μž‘μœ„λ‘œ 생성됨
  • μ΄λŸ¬ν•œ 방식이 자칫 νŽΈλ¦¬ν•΄ 보일 μˆ˜λ„ μžˆμ§€λ§Œ λ¬΄μž‘μœ„λ‘œ μƒμ„±λœ Id κ°’ λ•Œλ¬Έμ— ν•΄λ‹Ή λ¬Έμ„œλ₯Ό μ—…λ°μ΄νŠΈ ν•  λ•Œ 문제 사항이 생길 수 있음
    • 예λ₯Ό λ“€μ–΄ Elasticsearch 와 λ™κΈ°ν™”λœ λ°μ΄ν„°λ² μ΄μŠ€μ˜ 데이터가 변경됐닀고 κ°€μ •ν–ˆμ„ λ•Œ
      • 검색 엔진은 ν•΄λ‹Ή λ°μ΄ν„°λ² μ΄μŠ€μ™€ 주기적으둜 동기화해야 ν•˜κΈ° λ•Œλ¬Έμ— λ³€κ²½λœ λ‚΄μš©μ„ 따라 동기화돼야 ν•  것
    • 이λ₯Ό μœ„ν•΄μ„œλŠ” Elasticsearch 에 μƒ‰μΈλœ _id 값을 λ°μ΄ν„°λ² μ΄μŠ€μ˜ PK (Primary Key) ν˜Ήμ€ 식별이 λ˜λŠ” ν‚€ κ°’κ³Ό λ§€μΉ­ν•œ 정보가 μ–΄λ”˜κ°€μ—λŠ” μ €μž₯λ˜μ–΄ 관리돼야 함
    • ν•˜μ§€λ§Œ 1천만 κ±΄μ΄λ‚˜ 1얡건 정도 λ˜λŠ” 데이터에 ν•΄λ‹Ή 식별 값을 μ–΄λ”˜κ°€μ— λ³„λ„λ‘œ μ €μž₯ν•œλ‹€λŠ” 것은 거의 λΆˆκ°€λŠ₯
    • κ·Έλž˜μ„œ μƒ‰μΈλœ λ¬Έμ„œμ˜ _id 값은 μ—…λ°μ΄νŠΈλ₯Ό κ³ λ €ν•΄μ„œ λ°μ΄ν„°λ² μ΄μŠ€ ν…Œμ΄λΈ”μ˜ 식별 κ°’κ³Ό 맞좰 μ£ΌλŠ” 것이 μ€‘μš”

검색 API

  • Elasticsearch 검색 API 의 μ‚¬μš© 방식은 λ‹€μŒκ³Ό 같이 크게 두 κ°€μ§€λ‘œ λ‚˜λ‰¨
    • HTTP URI (Uniform Resource Identifier) ν˜•νƒœμ˜ νŒŒλΌλ―Έν„°λ₯Ό URI 에 μΆ”κ°€ν•΄ κ²€μƒ‰ν•˜λŠ” 방법
    • RESTful API 방식인 QueryDSL 을 μ‚¬μš©ν•΄ μš”μ²­ λ³Έλ¬Έ (Request Body) 에 질의 λ‚΄μš©μ„ μΆ”κ°€ν•΄ κ²€μƒ‰ν•˜λŠ” 방법
  • Request Body 방식은 URI 방식보닀 μ œμ•½μ‚¬ν•­μ΄ 적기 λ•Œλ¬Έμ— ν˜„μ—…μ—μ„œλŠ” Request Body 방식을 μ„ ν˜Έ
    • URI 방식은 κ°„λ‹¨ν•œ 쿼리 검색을 ν•˜κ±°λ‚˜ 디버깅할 λ•Œ κ°„νŽΈν•˜κ²Œ μ‚¬μš©ν•˜λŠ” κ²½μš°μ— μ’…μ’… 이용
  • κ°„λ‹¨ν•œ ν‘œν˜„μ‹μ΄λΌλ©΄ 두가지 ν˜•μ‹μ„ μ„žμ–΄μ„œ μ‚¬μš©ν•˜λŠ” 것도 κ°€λŠ₯
    • 예λ₯Ό λ“€μ–΄ Query λ₯Ό URI λ°©μ‹μœΌλ‘œ μ‚¬μš©ν•˜κ³  λ‚˜λ¨Έμ§€ κΈ°λŠ₯을 JSON ν˜•νƒœλ‘œ μ‚¬μš©ν•΄λ„ 됨
GET /movice/_doc/_search?q=prdtYear:2017&pretty=true
{
    "sort": {
        "movieCd": {
            "order" : "asc"
        }
    }
}
  • QueryDSL 을 μ‚¬μš©ν•˜λ©΄ 가독성이 λ†’κ³  JSON ν˜•μ‹μœΌλ‘œ λ‹€μ–‘ν•œ ν‘œν˜„μ΄ κ°€λŠ₯
    • Query 의 쑰건을 μ—¬λŸ¬ 개 λ§Œλ“€κ±°λ‚˜ 톡계λ₯Ό μœ„ν•œ 집계 (Aggregation) 쿼리 λ“± λ³΅μž‘ν•œ 쿼리λ₯Ό μž‘μ„±ν•˜λ €λ©΄ QueryDSL 을 μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŒ
    • URI둜 μ—¬λŸ¬ λ‹¨κ³„μ˜ ꡬ쑰λ₯Ό κ°€μ§€λŠ” μ€‘μ²©λœ ν˜•νƒœ ν‘œν˜„ν•˜λŠ” 것은 λΆˆκ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έ

URI λ°©μ‹μ˜ 검색 질의

  • λ¨Όμ € μ‚΄νŽ΄λ³Ό URI λ°©μ‹μ˜ 검색 μ§ˆμ˜λŠ” λ¬Έμ„œ ID인 _id 값을 μ‚¬μš©ν•΄ λ¬Έμ„œλ₯Ό μ‘°νšŒν•˜λŠ” 방식
    • κ²°κ΅­ URL에 νŒŒλΌλ―Έν„°λ₯Ό λΆ™μ—¬ μ‘°νšŒν•˜λŠ” 식
    • λ‹€μŒμ€ q νŒŒλΌλ―Έν„°λ₯Ό μ‚¬μš©ν•΄ ν•΄λ‹Ή μš©μ–΄μ™€ μΌμΉ˜ν•˜λŠ” λ¬Έμ„œλ§Œ μ‘°νšŒν•¨
POST /movie/_search?q=μž₯편
  • 응닡 κ²°κ³Όλ₯Ό ν™•μΈν•˜λ©΄ JSON 포맷 ν—€λ”μ—λŠ” 쿼리가 μ‹€ν–‰λœ 총 μ‹œκ°„ (took) κ³Ό κ²°κ³Όλ₯Ό λ³΄μ—¬μ€Œ
    • _shards μ—μ„œλŠ” μ„±κ³΅μ μœΌλ‘œ λ°˜ν™˜ν•œ μƒ€λ“œμ˜ μˆ˜μ™€ μ‹€νŒ¨ν•œ μƒ€λ“œμ˜ 수λ₯Ό μ•Œ 수 있음
    • hits μ—μ„œλŠ” μΌμΉ˜ν•˜λŠ” λ¬Έμ„œμ˜ μˆ˜μ™€ ν•¨κ»˜ 점수 (_score) κ°€ κ°€μž₯ 높은 μƒμœ„ 10개의 λ¬Έμ„œλ₯Ό λ³΄μ—¬μ€Œ
    • 검색에 μ‹€νŒ¨ν•œ μƒ€λ“œμ˜ μˆ˜λŠ” κ²€μƒ‰μ‹œ μ„€μ •λœ time_out 에 따라 결정됨
    • time_out μ‹œκ°„μ΄ 초과되면 κ·Έλ•ŒκΉŒμ§€ κ²€μƒ‰λœ λ‚΄μš©κΉŒμ§€λ§Œ 검색 결과둜 λ°˜ν™˜λ˜κΈ° λ•Œλ¬Έμ— μ‹€νŒ¨ν•œ μƒ€λ“œμ˜ μˆ˜κ°€ μ§€λ‚˜μΉ˜κ²Œ λ§Žλ‹€λ©΄ time_out μ‹œκ°„μ„ 적절히 μ‘°μ •ν•΄μ•Ό 함
  • q νŒŒλΌλ―Έν„°λ₯Ό μ‚¬μš©ν• λ•Œ λ³„λ„μ˜ ν•„λ“œλͺ…을 μ§€μ •ν•˜μ§€ μ•ŠμœΌλ©΄ μ‘΄μž¬ν•˜λŠ” λͺ¨λ“  ν•„λ“œλ₯Ό λŒ€μƒμœΌλ‘œ 검색을 μˆ˜ν–‰ν•¨
    • νŠΉμ • ν•„λ“œλ§Œ μ‘°νšŒν•˜κ³  μ‹Άλ‹€λ©΄ λ‹€μŒ μ½”λ“œμ™€ 같이 ν•„λ“œλͺ…을 ν¬ν•¨ν•΄μ„œ μš”μ²­ν•˜λ©΄ 됨
    • λ‹€μŒμ€ typeNm ν•„λ“œμ˜ 값이 "μž₯편"인 λ¬Έμžμ—΄λ§Œ κ²€μƒ‰ν•œ 예
POST /movie/_search?q=typeNm:μž₯편

Request Body λ°©μ‹μ˜ 검색 질의

  • URI 검색 μ§ˆμ˜λŠ” μ—¬λŸ¬ ν•„λ“œλ₯Ό 각기 λ‹€λ₯Έ κ²€μƒ‰μ–΄λ‘œ μ§ˆμ˜ν•˜λŠ” 것이 어렀움
    • 쿼리의 쑰건이 λ³΅μž‘ν•˜κ³  길어지기 λ•Œλ¬ΈμΈλ° 이럴 λ•ŒλŠ” JSON λ°©μ‹μœΌλ‘œ μ§ˆμ˜ν•˜λŠ”κ²Œ μ’‹μŒ
    • JSON 포맷을 μ΄μš©ν•΄ RESTful λ°©μ‹μœΌλ‘œ μ§ˆμ˜ν•˜λ©΄ 맀우 λ³΅μž‘ν•œ 쿼리도 μ‰½κ²Œ ν‘œν˜„ν•  수 있고 μ—¬λŸ¬ 쑰건을 ν•œλ²ˆμ— μ²˜λ¦¬ν•  수 있음
POST /{indexλͺ…}/_search
{
  JSON 쿼리 ꡬ문
}
  • movie 인덱슀의 typeNm ν•„λ“œλ₯Ό κ²€μƒ‰ν•˜λŠ” μ˜ˆλŠ” λ‹€μŒκ³Ό κ°™μŒ
POST movie/_search
{
  "query": {
    "term": {"typeNm": "μž₯편"}
  }
}
  • 쿼리 ꡬ문은 λ‹€μŒκ³Ό 같이 μ—¬λŸ¬ 개의 ν‚€λ₯Ό μ‘°ν•©ν•΄ 객체의 ν‚€ κ°’μœΌλ‘œ μ‚¬μš©ν•  수 있음
{
   size: 
     # λͺ‡κ°œμ˜ κ²°κ³Όλ₯Ό λ°˜ν™˜ν• μ§€ κ²°μ •ν•œλ‹€(기본값은 10)
   
   from: 
     # μ–΄λŠ μœ„μΉ˜λΆ€ν„° λ°˜ν™˜ν• μ§€λ₯Ό κ²°μ •ν•œλ‹€
     # 0λΆ€ν„° μ‹œμž‘ν•˜λ©΄ μƒμœ„ 0~10건의 데이터λ₯Ό λ°˜ν™˜ν•œλ‹€(기본값은 0)
   
   _source: 
     # νŠΉμ • ν•„λ“œλ§Œ 결과둜 λ°˜ν™˜ν•˜κ³  μ‹Άμ„λ•Œ μ‚¬μš©ν•œλ‹€.
   
   sort: 
     # νŠΉμ • ν•„λ“œλ₯Ό κΈ°μ€€μœΌλ‘œ μ •λ ¬ν•œλ‹€.
     # asc, desc의 μ˜€λ¦„μ°¨μˆœ, λ‚΄λ¦Όμ°¨μˆœ 정렬을 지정할 μˆ˜λ„ μžˆλ‹€.
   
   query: {
     # 검색될 쑰건을 μ •μ˜ν•œλ‹€. 
   }
   
   filter: {
     # 검색 κ²°κ³Ό 쀑 νŠΉμ •ν•œ 값을 λ‹€μ‹œ 보여쀀닀.
     # κ²°κ³Ό λ‚΄μ—μ„œ μž¬κ²€μƒ‰ν•  λ•Œ μ‚¬μš©ν•˜λŠ” κΈ°λŠ₯ 쀑 ν•˜λ‚˜μ΄λ‹€.
     # λ‹€λ§Œ ν•„ν„°λ₯Ό μ‚¬μš©ν•˜κ²Œ 되면 μžλ™μœΌλ‘œ score 값이 μ •λ ¬λ˜μ§€ μ•ŠλŠ”λ‹€.
   }
}

집계 API

  • κ³Όκ±°μ—λŠ” 톡계 μž‘μ—…μ„ μœ„ν•΄ Lucene 이 μ œκ³΅ν•˜λŠ” νŒ¨μ‹― (Facets) κΈ°λŠ₯을 많이 ν™œμš©ν–ˆμŒ
    • νŒ¨μ‹― κΈ°λŠ₯은 기본적으둜 λ””μŠ€ν¬ 기반으둜 λ™μž‘ν–ˆκ³  λΆ„μ‚° ν™˜κ²½μ—λŠ” μ΅œμ ν™”λ˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— λŒ€μš©λŸ‰ λ°μ΄ν„°μ˜ 톡계 μž‘μ—…μ—λŠ” μ ν•©ν•˜μ§€ μ•ŠμŒ
    • 이둜 인해 λ§Žμ€ μž₯μ• κ°€ λ°œμƒν–ˆκΈ° λ•Œλ¬Έ
  • Elasticsearch μ—μ„œλŠ” 5.0 이후에 νŒ¨μ‹― λ°©μ‹μ˜ 톡계 κΈ°λŠ₯을 μ œκ±°ν•˜κ³  λ…μžμ μΈ 집계 (Aggregation) APIλ₯Ό λ‚΄λ†“μ•˜μŒ
    • 집계 APIλŠ” 기본적으둜 λ©”λͺ¨λ¦¬ 기반으둜 λ™μž‘ν•˜κΈ° λ•Œλ¬Έμ— λŒ€μš©λŸ‰μ˜ 데이터 톡계 μž‘μ—…μ΄ κ°€λŠ₯ν•΄μ‘ŒμŒ
  • Elasticsearch λŠ” 집계 APIλ₯Ό 톡해 기쑴의 νŒ¨μ‹― APIλ‘œλŠ” ν•˜κΈ° μ–΄λ €μš΄ μž‘μ—…μ„ μ²˜λ¦¬ν•˜λŠ” 것이 κ°€λŠ₯ν•΄μ‘ŒμŒ
    • 쿼리에 μ‚¬μš©λ˜λŠ” 집계에 따라 수치λ₯Ό κ³„μ‚°ν•˜κ³  λ™μ μœΌλ‘œ μΉ΄μš΄νŒ…ν•˜κ±°λ‚˜ νžˆμŠ€ν† κ·Έλž¨ 같은 μž‘μ—… 등도 ν• μˆ˜ 있음
    • Elasticsearch 의 집계 APIλŠ” 각쒅 톡계 데이터λ₯Ό μ‹€μ‹œκ°„μœΌλ‘œ μ œκ³΅ν•  수 μžˆλŠ” κ°•λ ₯ν•œ κΈ°λŠ₯

데이터 집계

  • 예λ₯Ό λ“€μ–΄ movie 인덱슀의 λ¬Έμ„œλ₯Ό μž₯λ₯΄λ³„λ‘œ 집계할 λ•Œ
    • _search API λ₯Ό μ‚¬μš©ν•΄ 집계 쿼리λ₯Ό λ§Œλ“€κ³  terms ν‚€μ›Œλ“œλ₯Ό μ΄μš©ν•΄ genreAlt λΌλŠ” ν•„λ“œμ˜ 데이터λ₯Ό κ·Έλ£Ήν™”
POST /movie/_search?size=0
{
  "aggs": {
    "genre": {
      "terms": {
        "field": "genreAlt"
      }
    }
  }
}
  • 집계 κ²°κ³Όλ₯Ό μ‚΄νŽ΄λ³΄λ©΄ 버킷 (Buckets) μ΄λΌλŠ” ꡬ쑰 μ•ˆμ— κ·Έλ£Ήν™”λœ 데이터가 포함돼 있음
    • Elasticsearch 의 집계가 κ°•λ ₯ν•œ 이유 쀑 ν•˜λ‚˜λŠ” 버킷 μ•ˆμ— λ‹€λ₯Έ λ²„ν‚·μ˜ κ²°κ³Όλ₯Ό μΆ”κ°€ν•  수 μžˆλ‹€λŠ” 점인데 μ΄λŸ¬ν•œ νŠΉμ„±μ„ μ΄μš©ν•΄ λ‹€μ–‘ν•œ 집계 μœ ν˜•μ„ κ²°ν•©ν•˜κ±°λ‚˜ 쀑첩 βˆ™ μ‘°ν•©ν•˜λŠ” 것이 κ°€λŠ₯해짐
  • λ‹€μŒμ€ μž₯λ₯΄λ³„ κ΅­κ°€ ν˜•νƒœλ₯Ό μ€‘μ²©ν•΄μ„œ λ³΄μ—¬μ£ΌλŠ” μ§‘κ³„μ˜ 예
POST movie/_search?size=0
{
   "aggs": {
      "genre": {"terms": {"field": "genreAlt"}},
      "aggs": {
         "nation": {"terms": {"field": "nationAlt"}}
      }
   }
}

Tip! μΆ”κ°€ λ‚΄μš©

검색 속도 λΉ λ₯Έ 이유

  • MySQLκ³Ό 같은 κ΄€κ³„ν˜• λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ ν…Œμ΄λΈ”μ΄ 인덱싱 (색인 μž‘μ—…) 되면 λ³΅μž‘ν•œ μΏΌλ¦¬μ—μ„œ 훨씬 더 λ‚˜μ€ μ„±λŠ₯을 λ³΄μ—¬μ€Œ
    • 인덱싱은 λΉ λ₯Έ 검색을 μœ„ν•΄ ν•„λ“œ 값을 μ—΄μ΄λ‚˜ Document에 맀핑 ν•˜λŠ” 것을 의미
  • 주어진 검색어에 λŒ€ν•΄μ„œ λͺ¨λ“  열을 μ°Ύμ•„λ³΄λŠ” λŒ€μ‹ μ— 인덱슀 (색인) λ₯Ό μ΄μš©ν•΄μ„œ μ–΄λ–€ λ¬Έμ„œλ‚˜ 열에 ν•΄λ‹Ήλ˜λŠ”μ§€ 찾을 수 있음
    • 이것이 μΈλ±μŠ€κ°€ 쿼리 속도λ₯Ό μ—„μ²­λ‚˜κ²Œ λΉ λ₯΄κ²Œ λ§Œλ“œλŠ” 이유
  • Elasticsearch λŠ” (검색어가 될 수 μžˆλŠ”) λ¬Έμžλ“€μ„ μœ μ—°ν•˜κ²Œ ν† ν°ν™”ν•˜κ³  μΈλ±μ‹±ν•˜λŠ”λ° νŠΉν™”λ˜μ–΄ 있음
    • 예λ₯Ό λ“€μ–΄ "Hello to the world" λΌλŠ” ν•˜λ‚˜μ˜ λ¬Έμžμ—΄μ„ λ‹€μ–‘ν•œ λ°©λ²•μœΌλ‘œ 인덱싱을 진행 ν•  수 있음
      • λ¬Έμž₯ 전체
        • μ˜ˆμ‹œ: ["Hello to the world"]
      • 단어
        • μ˜ˆμ‹œ: ["hello", "to", "the", "world"]
      • μ „μΉ˜μ‚¬λ‚˜ 관사 등을 μ œμ™Έν•œ 의미 μžˆλŠ” 단어
        • μ˜ˆμ‹œ: ["hello", "world"]
      • μ‚¬μš©μžκ°€ μ›ν•˜λŠ” κ·œμΉ™
        • "to" λΌλŠ” μ „μΉ˜μ‚¬λ₯Ό μ€‘μš”ν•˜κ²Œ μƒκ°ν•œλ‹€λ©΄ μΆ”κ°€ κ°€λŠ₯
        • μ˜ˆμ‹œ: ["hello", "to", "world"]
    • μ΄λ ‡κ²Œ ν† ν°ν™”λœ 단어듀이 인덱슀 ν‚€κ°€ λ˜μ–΄ 훨씬 λΉ λ₯΄κ³  효율적인 λ¬Έμ„œ 검색을 진행

  • μœ„μ˜ 사진을 보면 μ–΄λ–€ λ°©μ‹μœΌλ‘œ λ¬Έμžμ—΄ λ˜λŠ” Document κ°€ 단어 λ³„λ‘œ μΈλ±μ‹±λ˜μ–΄ μ €μž₯λ˜λŠ”μ§€ μ•Œ 수 있음
    • κ΄€μ‚¬λ‚˜ μ „μΉ˜μ‚¬ 등을 μ œμ™Έν•œ μœ μ˜λ―Έν•œ ν‚€μ›Œλ“œλ“€μ„ μΆ”λ €λ‚΄κ³  각 ν‚€μ›Œλ“œκ°€ μ–΄λ–€ Document 에 μ €μž₯λ˜μ–΄ μžˆλŠ”μ§€ μ €μž₯
    • 인덱싱 이후 "best" λΌλŠ” ν‚€μ›Œλ“œλ‘œ 검색을 μ§„ν–‰ν•˜λ©΄ Document 2μ—μ„œ best λΌλŠ” ν‚€μ›Œλ“œκ°€ μ‚¬μš©λ˜μ—ˆμŒμ„ λ°”λ‘œ 찾을 수 있음
      • λ§Œμ•½ 이λ₯Ό μ„ ν˜• κ²€μƒ‰μœΌλ‘œ μ§„ν–‰ν•œλ‹€λ©΄ Document 1, Document 2, Document 3에 λͺ¨λ“  단어듀을 ν•˜λ‚˜μ”© 비ꡐ λŒ€μ‘°ν•˜μ—¬ 찾아봐야 함
    • 이런 ꡬ쑰라면 ν•˜λ‚˜μ˜ ν‚€μ›Œλ“œλ₯Ό 찾을 λ•Œ 마치 해쉬 (hash) ν…Œμ΄λΈ”μ„ μ΄μš©ν•˜λŠ” κ²ƒμ²˜λŸΌ μ‹œκ°„λ³΅μž‘λ„λŠ” O(1)에 수렴
      • μ‹€μ‹œκ°„ 검색이 κ°€λŠ₯ν•œ 이유
  • SQL λ°μ΄ν„°λ² μ΄μŠ€λ“€μ€ λ§Žμ€ 인덱슀λ₯Ό λ‹€λ£° λ•Œ μ„±λŠ₯이 μ €ν•˜λ˜λŠ” 반면 Elasticsearch λŠ” λ³΅μž‘ν•˜κ³  μƒλ‹Ήν•œ μ–‘μ˜ 인덱슀λ₯Ό 닀루더라도 μ„±λŠ₯에 μ €ν•˜κ°€ 거의 μ—†μŒ
    • 그리고 찾은 데이터λ₯Ό 효과적으둜 λ‹€λ£¨λŠ” λŠ₯λ ₯도 가지고 있음

단점

  • Elasticsearch λŠ” SQL λ°μ΄ν„°λ² μ΄μŠ€λ³΄λ‹€ κ°œλ³„ λ ˆμ½”λ“œ 검색을 μˆ˜ν–‰ν•˜λŠ” λŠ₯λ ₯이 떨어짐
    • 특히 데이터λ₯Ό μ—…λ°μ΄νŠΈ ν•  λ•ŒλŠ” μ„±λŠ₯이 크게 떨어짐
    • κ·ΈλŸ¬λ―€λ‘œ λ§Œμ•½ 자주 정보λ₯Ό μ—…λ°μ΄νŠΈ ν•΄μ•Όν•˜λŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄λΌλ©΄ Elasticsearch λŠ” μ μ ˆν•œ 기술이 μ•„λ‹˜
  • SQL λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ ν…Œμ΄λΈ” κ°„μ˜ 쑰인을 μˆ˜ν–‰ν•˜λŠ” κ²ƒμ²˜λŸΌ Document κ°„μ˜ 쑰인을 μˆ˜ν–‰ν•  수 μ—†μŒ
    • λŒ€μ‹  쑰인을 μˆ˜ν–‰ν•˜λŠ” κ²ƒμ²˜λŸΌ 2번의 λ³„κ°œλ‘œ μˆ˜ν–‰ν•΄μ•Ό 함
    • 2번의 쿼리λ₯Ό μˆ˜ν–‰ν•˜λŠ” 것이 SQL 쑰인 보닀 λΉ λ₯Ό 순 μžˆμ§€λ§Œ 이런 ν–‰μœ„λ₯Ό λˆ„μ ν•΄μ„œ μ‹œν–‰ν•œλ‹€λ©΄ 크게 느껴 질 수 있음
profile
🌱 Backend-Dev | hwaya2828@gmail.com

0개의 λŒ“κΈ€