ElasticSearch

검색에 μ΅œμ ν™”λœ μ˜€ν”ˆμ†ŒμŠ€

κ³΅μ‹λ¬Έμ„œ λ₯Ό μ°Έκ³ ν•˜μ—¬ ν•΄λ‹Ή λ‚΄μš©μ„ ν¬μŠ€νŒ…ν•©λ‹ˆλ‹€. 무신사 데이터 μ‚¬μ΄μ–ΈμŠ€ μ—”μ§€λ‹ˆμ–΄ λΈ”λ‘œκ·Έ

ES

01. κ°œμš”

Elasticsearch (ES) λŠ” ν™•μž₯성이 λ›°μ–΄λ‚œ μ˜€ν”ˆμ†ŒμŠ€ ν’€ν…μŠ€νŠΈ 검색 및 뢄석 엔진이닀. λ°©λŒ€ν•œ μ–‘μ˜ 데이터λ₯Ό μ‹ μ†ν•˜κ²Œ,
거의 μ‹€μ‹œκ°„μœΌλ‘œ μ €μž₯, 검색, 뢄석할 수 μžˆλ„λ‘ 지원
ν•©λ‹ˆλ‹€. 일반적으둜 λ³΅μž‘ν•œ 검색 κΈ°λŠ₯ 및 μš”κ΅¬ 사항이 μžˆλŠ”
μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μœ„ν•œ κΈ°λ³Έ 엔진/기술둜 μ‚¬μš©λ©λ‹ˆλ‹€.

ElasticsearchλŠ” λ‹€μŒμ„ λΉ„λ‘―ν•œ λ‹€μ–‘ν•œ ν™œμš© 사둀에 νš¨κ³Όμ μž…λ‹ˆλ‹€.

  • 고객이 판맀 μ œν’ˆμ„ 검색할 수 μžˆλŠ” 컀머슀 웹을 μš΄μ˜ν•˜λŠ”κ²½μš°, Elasticsearchλ₯Ό μ‚¬μš©ν•˜μ—¬ 전체 μ œν’ˆ μΉ΄νƒˆλ‘œκ·Έ 및 재고 정보λ₯Ό μ €μž₯ν•˜κ³  그에 λŒ€ν•œ 검색 및 μžλ™ μ™„μ„± μ œμ•ˆ κΈ°λŠ₯을 μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • Log or Transaction 데이터λ₯Ό μˆ˜μ§‘ν•˜κ³  이 데이터λ₯Ό λΆ„μ„ν•˜κ³  λ§ˆμ΄λ‹ν•˜μ—¬ 좔이, 톡계, μš”μ•½ 정보λ₯Ό μ–»κ±°λ‚˜,
    이상 μš”μΈμ„ μ•Œμ•„λ‚΄λ € ν•©λ‹ˆλ‹€. 이 κ²½μš°μ—λŠ” Logstash (ELK μŠ€νƒμ˜ 일뢀) λ₯Ό μ‚¬μš©ν•˜μ—¬ 데이터 μˆ˜μ§‘, 집계, νŒŒμ‹±μ„ μˆ˜ν–‰ν•œ λ‹€μŒ Logstashμ—μ„œ ES 에 이 데이터λ₯Ό ν”Όλ“œ ν˜•νƒœλ‘œ 전달
    데이터가 ES에 적재되면 검색 및 집계λ₯Ό μ‹€ν–‰ν•˜μ—¬ 관심 μžˆλŠ” μ–΄λ–€ 정보도 λ§ˆμ΄λ‹ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • 고객이 μ–΄λ–€ μ…€λŸ¬μ˜ μ œν’ˆμ΄λ“  가격이 $?? μ•„λž˜λ‘œ λ‚΄λ €κ°€λ©΄ μ•Œλ¦Όμ„ 받을 수 μžˆλ‹€.
    κ³ κ°μ—κ²Œ ν‘Έμ‹œ λ°©μ‹μœΌλ‘œ μ•Œλ¦΄ 수 μžˆλ‹€.
  • BI κΈ°λŠ₯이 ν•„μš”ν•˜λ©° λ°©λŒ€ν•œλ°μ΄ν„°λ₯Ό λŒ€μƒμœΌλ‘œ μ‹ μ†ν•˜κ²Œ 쑰사, 뢄석, μ‹œκ°ν™”, μž„μ‹œ 질의λ₯Ό μˆ˜ν–‰
    ES λ₯Ό μ‚¬μš©ν•˜μ—¬ 데이터저μž₯ν›„ Kibana λ₯Ό μ‚¬μš©ν•˜μ—¬ 데이터 쀑 μ€‘μš”ν•œ μš”μ†Œλ₯Ό μ‹œκ°ν™”ν•œλ‹€.

02. κΈ°λ³Έ κ°œλ…

  • NRT (Near Realtime)
    • ES λŠ” NRT 검색 ν”Œλž«νΌμ΄λ‹€. 즉, λ¬Έμ„œλ₯Ό 색인화(index)ν•˜λŠ” μ‹œμ λΆ€ν„° λ¬Έμ„œκ°€ 검색 κ°€λŠ₯ν•΄μ§€λŠ”
      μ‹œμ κΉŒμ§€μ˜ λŒ€κΈ°μ‹œκ°„(λŒ€κ²Œ 1초)이 μžˆμŠ΅λ‹ˆλ‹€.
  • ν΄λŸ¬μŠ€ν„° (Cluster)
    • ν΄λŸ¬μŠ€ν„°λŠ” ν•˜λ‚˜ μ΄μƒμ˜ λ…Έλ“œ(μ„œλ²„)κ°€ λͺ¨μΈ 것
    • 전체 데이터λ₯Ό μ €μž₯ν•˜κ³ , λͺ¨λ“  λ…Έλ“œλ₯Ό ν¬κ΄„ν•˜λŠ” 톡합 색인화 및 검색 κΈ°λŠ₯을 제곡
    • ν΄λŸ¬μŠ€ν„°λŠ” κ³ μœ ν•œ μ΄λ¦„μœΌλ‘œ μ‹λ³„λ˜λ©°, 기본값은 elasticsearch 이닀.
    • 이름이 μ€‘μš”ν•œ μ΄μœ λŠ”, μ–΄λ–€ λ…Έλ“œκ°€ μ–΄λŠ ν΄λŸ¬μŠ€ν„°μ— ν¬ν•¨λ˜κΈ° μœ„ν•΄μ„œλŠ” 이름에 μ˜ν•΄ ν΄λŸ¬μŠ€ν„° ꡬ성원이 λ˜λ„λ‘ μ„€μ •λ˜κΈ° λ•Œλ¬Έμ΄λ‹€.
    • λ™μΌν•œ ν΄λŸ¬μŠ€ν„° 이름을 μ„œλ‘œ λ‹€λ₯Έ ν™˜κ²½μ—μ„œ μž¬μ‚¬μš© X
    • λ…Έλ“œκ°€ 잘λͺ»λœ ν΄λŸ¬μŠ€ν„°μ— 포함될 μœ„ν—˜μ΄ μžˆλ‹€. 예λ₯Όλ“€μ–΄
    • 개발, μŠ€ν…Œμ΄μ§•, ν”„λ‘œλ•μ…˜ ν΄λŸ¬μŠ€ν„°μ— logging-dev, logging-stage, logging-prod κ°€λŠ₯
    • ν΄λŸ¬μŠ€ν„°μ— ν•˜λ‚˜μ˜ λ…Έλ“œλ§Œ μžˆλŠ” 것도 κ°€λŠ₯ν•˜λ©°, λ˜ν•œ 각자 κ³ μœ ν•œ ν΄λŸ¬μŠ€ν„° 이름을 가진 독립적인 클러슀 μ—¬λŸ¬ 개λ₯Ό λ‘˜ μˆ˜λ„ μžˆλ‹€.
  • λ…Έλ“œ (Node)
    • λ…Έλ“œλŠ” ν΄λŸ¬μŠ€ν„°μ— ν¬ν•¨λœ 단일 μ„œλ²„λ‘œμ„œ 데이터λ₯Ό μ €μž₯ν•˜κ³  ν΄λŸ¬μŠ€ν„°μ˜ 색인화 및 검색 κΈ°λŠ₯에 μ°Έμ—¬
    • λ…Έλ“œλŠ” ν΄λŸ¬μŠ€ν„°μ²˜λŸΌ μ΄λ¦„μœΌλ‘œ μ‹λ³„λ˜λ©°, κΈ°λ³Έ 이름은 μ‹œμž‘ μ‹œ λ…Έλ“œμ— μ§€μ •λœ μž„μ˜ UUID
    • 기본이름 λŒ€μ‹  Custom λ…Έλ“œμ΄λ¦„μ„ μ •μ˜ κ°€λŠ₯
    • 이름은 관리λͺ©μ μ—μ„œ μ€‘μš”ν•˜λ‹€. λ„€νŠΈμ›Œν¬μ˜ μ–΄λ–€ μ„œλ²„κ°€ ES ν΄λŸ¬μŠ€ν„°μ˜ μ–΄λ–€ λ…Έλ“œμ— ν•΄λ‹Ήν•˜λŠ”μ§€ μ‹λ³„ν•„μš”!!
    • λ…Έλ“œλŠ” ν΄λŸ¬μŠ€ν„° 이름을 톡해 μ–΄λ–€ ν΄λŸ¬μŠ€ν„°μ˜ μΌλΆ€λ‘œ ꡬ성될 수 μžˆλ‹€.
    • 기본적으둜 각 λ…Έλ“œλŠ” elasticsearch λΌλŠ” μ΄λ¦„μ˜ ν΄λŸ¬μŠ€ν„°μ— ν¬ν•¨λ˜λ„λ‘ μ„€μ •λœλ‹€.
    • λ„€νŠΈμ›Œν¬μ—μ„œ λ‹€μˆ˜μ˜ λ…Έλ“œλ₯Ό μ‹œμž‘ν•  경우 (각각을 검색할 수 μžˆλ‹€κ³  κ°€μ •) 이 λ…Έλ“œκ°€ λͺ¨λ‘ μžλ™μœΌλ‘œ Elasticsearch λΌλŠ” 단일 ν΄λŸ¬μŠ€ν„°λ₯Ό ν˜•μ„±ν•˜κ³  이 ν΄λŸ¬μŠ€ν„°μ˜ 일뢀가 λ©λ‹ˆλ‹€.
    • ν•˜λ‚˜μ˜ ν΄λŸ¬μŠ€ν„°μ—μ„œ μ›ν•˜λŠ” 개수의 λ…Έλ“œλ₯Ό 포함할 수 μžˆλ‹€.
    • ES 에 λ…Έλ“œκ°€ ν•˜λ‚˜λ„μ—†μ„ μ‹œ, 단일 λ…Έλ“œλ‘œ μ‹œμž‘ν•˜λ©΄ 기본적으둜 elasticsearch λΌλŠ” μ΄λ¦„μ˜ λ‹¨μΌλ…Έλ“œ ν΄λŸ¬μŠ€ν„°κ°€ λ§Œλ“€μ–΄μ§„λ‹€.
  • 인덱슀 (Index)
    • 색인은 λ‹€μ†Œ λΉ„μŠ·ν•œ νŠΉμ„±μ„ 가진 λ¬Έμ„œμ˜ λͺ¨μŒ
    • 고객 데이터에 λŒ€ν•œ 색인, μ œν’ˆ μΉ΄νƒˆλ‘œκ·Έμ— λŒ€ν•œ 색인, μ£Όλ¬Έ 데이터에 λŒ€ν•œ 색인 λ“±λ“±..
    • 색인은 λͺ¨λ‘ μ†Œλ¬Έμžμ΄λ¦„μœΌλ‘œ μ‹λ³„λ˜λ©°, 이 이름은 색인에 ν¬ν•¨λœ λ¬Έμ„œμ— λŒ€ν•œ 색인화, 검색, μ—…λ°μ΄νŠΈ, μ‚­μ œ μž‘μ—…μ—μ„œ ν•΄λ‹Ή 색인을 κ°€λ¦¬ν‚€λŠ” 데 쓰인닀.
    • 단일 ν΄λŸ¬μŠ€ν„°μ—μ„œ μ›ν•˜λŠ” 개수의 색인을 μ •μ˜ν•  수 μžˆλ‹€.
    • RDB둜 λΉ„μœ ν•˜λ©΄ Tableκ³Ό λΉ„μŠ·ν•œ λŠλ‚Œ?
  • νƒ€μž… (Type)
    • ν•˜λ‚˜μ˜ μƒ‰μΈμ—μ„œ ν•˜λ‚˜ μ΄μƒμ˜ μœ ν˜•μ„ μ •μ˜ν•  수 μžˆλ‹€.
    • Type(μœ ν˜•) μ΄λž€, Index(색인)을 λ…Όλ¦¬μ μœΌλ‘œ λΆ„λ₯˜/κ΅¬λΆ„ν•œ 것, κ·Έ 의미 μ²΄κ³„λŠ” μ‚¬μš©μžκ°€ κ²°μ •
    • 일반적으둜 μ—¬λŸ¬ κ³΅ν†΅λœ ν•„λ“œλ₯Ό κ°–λŠ” λ¬Έμ„œμ— λŒ€ν•΄ μœ ν˜•μ΄ μ •μ˜λœλ‹€.
    • 예λ₯Ό λ“€μ–΄, λΈ”λ‘œκ·Έ ν”Œλž«νΌμ„ μš΄μ˜ν•˜κ³  μžˆλŠ”λ° λͺ¨λ“  데이터λ₯Ό ν•˜λ‚˜μ˜ Index(색인)에 μ €μž₯ν•˜κ²Œ λœλ‹€λ©΄,
      이 Index μ—μ„œ μ‚¬μš©μž 데이터, λΈ”λ‘œκ·Έ 데이터, λŒ“κΈ€ 데이터에 λŒ€ν•œ μœ ν˜•(Type)을 각각 μ •μ˜ν•  수 μžˆλ‹€.
  • λ„νλ¨ΌνŠΈ (Document)
    • λ„νλ¨ΌνŠΈ(λ¬Έμ„œ)λŠ” Indexν™”ν•  수 μžˆλŠ” κΈ°λ³Έ 정보 λ‹¨μœ„
    • 단일 고객, 단일 μ œν’ˆ, 단일 주문에 λŒ€ν•œ λ¬Έμ„œκ°€ 각각 μ‘΄μž¬ν•  수 μžˆλ‹€.
    • 이 λ¬Έμ„œλŠ” Jsonν˜•μ‹μ΄λ‹€.
    • ν•˜λ‚˜μ˜ Index/Type 에 μ›ν•˜λŠ” 개수의 Documentλ₯Ό μ €μž₯ν•  수 μžˆλ‹€.
    • λ„νλ¨ΌνŠΈκ°€ λ¬Όλ¦¬μ μœΌλ‘œλŠ” μ–΄λ–€ Index내에 μžˆλ”λΌλ„ λ„νλ¨ΌνŠΈλŠ” Indexν™”λ˜μ–΄ 색인에 ν¬ν•¨λœ μ–΄λ–€ μœ ν˜•μœΌλ‘œ μ§€μ •λ˜μ–΄μ•Ό ν•œλ‹€
  • μƒ€λ“œ/λ ˆν”Œλ¦¬μΉ΄ (Shard/Replica)
    • indexλŠ” λ°©λŒ€ν•œ μ–‘μ˜ 데이터λ₯Ό μ €μž₯ν•  수 μžˆλ‹€.
    • 이 데이터가 단일 λ…Έλ“œμ˜ ν•˜λ“œμ›¨μ–΄ ν•œλ„λ₯Ό μ΄ˆκ³Όν•  μˆ˜λ„ μžˆλ‹€.
      • 10μ–΅ 개의 λ„νλ¨ΌνŠΈλ‘œ κ΅¬μ„±λœ ν•˜λ‚˜μ˜ 색인에 1TB λ””μŠ€ν¬ 곡간이 ν•„μš”ν•œ 경우
      • 단일 λ…Έλ“œμ˜ λ””μŠ€ν¬μ—μ„œ μˆ˜μš©ν•˜μ§€ λͺ»ν•˜κ±°λ‚˜, 단일 λ…Έλ“œμ—μ„œ 검색 μš”μ²­ 처리 μ‹œ 속도가 λ„ˆλ¬΄ λŠλ €μ§ˆμˆ˜μžˆλ‹€.
    • ES λŠ” μ΄λŸ¬ν•œ 문제λ₯Ό ν•΄κ²°ν•˜κ³ μž Index λ₯Ό Shard μƒ€λ“œλΌλŠ” 쑰각으둜 λΆ„ν• ν•˜λŠ” κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€.
    • Indexλ₯Ό μƒμ„±μ‹œ, μ›ν•˜λŠ” μƒ€λ“œ 수λ₯Ό μ„€μ • κ°€λŠ₯
    • 각 μƒ€λ“œλŠ” κ·Έ μžμ²΄κ°€ μ˜¨μ „ν•œ κΈ°λŠ₯을 가진 독립적인 Index이며, ν΄λŸ¬μŠ€ν„°μ˜ μ–΄λ–€ λ…Έλ“œμ—μ„œλ„ ν˜ΈμŠ€νŒ…ν• μˆ˜μžˆλ‹€.
    • 샀딩이 μ€‘μš”ν•œ 2가지 이유
      • μ½˜ν…μΈ  λ³Όλ₯¨μ˜ μˆ˜ν‰ λΆ„ν• /ν™•μž₯이 κ°€λŠ₯해진닀.
      • μž‘μ—…μ„ (μ—¬λŸ¬ λ…Έλ“œμ— μœ„μΉ˜ν•œ) μ—¬λŸ¬ μƒ€λ“œμ— λΆ„μ‚° λ°°μΉ˜ν•˜κ³  λ³‘λ ¬ν™”ν•¨μœΌλ‘œμ¨ μ„±λŠ₯/μ²˜λ¦¬λŸ‰ 늘릴 수 μžˆλ‹€.
    • μƒ€λ“œκ°€ λΆ„μ‚° λ°°μΉ˜λ˜λŠ” 방식 및 κ·Έ λ¬Έμ„œκ°€ λ‹€μ‹œ 검색 μš”μ²­μœΌλ‘œ μ§‘κ³„λ˜λŠ” λ°©μ‹μ˜ λ©”μ»€λ‹ˆμ¦˜μ€ λͺ¨λ‘ ESμ—μ„œ
      κ΄€λ¦¬ν•˜λ©° μ‚¬μš©μžμ—κ²ŒλŠ” 투λͺ…ν•˜κ²Œ 이루어진닀.
    • μ–Έμ œλ“  였λ₯˜κ°€ 일어날 수 μžˆλŠ” λ„€νŠΈμ›Œν¬/ν΄λΌμš°λ“œ ν™˜κ²½μ—μ„œλŠ” μ–΄λ–€ μ΄μœ μ—μ„œλ“  μƒ€λ“œ/λ…Έλ“œκ°€ μ˜€ν”„λΌμΈ μƒνƒœκ°€ λ˜κ±°λ‚˜ μ‚¬λΌμ§€κ²Œ 될 κ²½μš°μ— λŒ€λΉ„ν•˜μ—¬ FailOver λ©”μ»€λ‹ˆμ¦˜μ„ λ§ˆλ ¨ν•˜λŠ” 것이 μœ μ΅ν•˜κ³  λ°”λžŒμ§ν•˜λ‹€.
    • μ΄λŸ¬ν•œ μ·¨μ§€μ—μ„œ ESμ—μ„œλŠ” Index의 Shard에 λŒ€ν•΄ 1개 μ΄μƒμ˜ 볡사본을 생성할 수 μžˆλŠ”λ°, 이λ₯Ό Replica Shard μ€„μ—¬μ„œ λ¦¬ν”Œλ¦¬μΉ΄λΌκ³  ν•œλ‹€.
    • λ¦¬ν”Œλ¦¬μΉ΄λ₯Ό λ§Œλ“œλŠ” λ³΅μ œκ°€ μ€‘μš”ν•œ 2가지 이유
      • μƒ€λ“œ/λ…Έλ“œ 였λ₯˜κ°€ λ°œμƒν•˜λ”λΌλ„ κ³ κ°€μš©μ„±μ„ μ œκ³΅ν•œλ‹€. λ”°λΌμ„œ λ¦¬ν”Œλ¦¬μΉ΄ μƒ€λ“œλŠ” κ·Έ 원본인 κΈ°λ³Έ μƒ€λ“œμ™€ λ™μΌν•œ λ…Έλ“œμ— λ°°μ •λ˜μ§€ μ•ŠλŠ”λ‹€.
      • λͺ¨λ“  λ¦¬ν”Œλ¦¬μΉ΄μ—μ„œ 병렬 λ°©μ‹μœΌλ‘œ 검색을 μ‹€ν–‰ν•  수 μžˆμœΌλ―€λ‘œ 검색 λ³Όλ₯¨/μ²˜λ¦¬λŸ‰μ„ ν™•μž₯ ν•  수 μžˆλ‹€.
    • μš”μ•½
      • 각 Index λŠ” N개의 Shard 둜 λΆ„ν• ν•  수 μžˆλ‹€.
      • ν•˜λ‚˜μ˜ IndexλŠ” λ³΅μ œν•˜μ§€ μ•Šκ±°λ‚˜(λ¦¬ν”Œλ¦¬μΉ΄ μ—†μŒ) 1회 이상 λ³΅μ œν•  수 μžˆλ‹€.
      • 볡제되면 각 IndexλŠ” κΈ°λ³Έ μƒ€λ“œ(λ³΅μ œμ›λ³Έ μƒ€λ“œ)와 λ¦¬ν”Œλ¦¬μΉ΄ μƒ€λ“œ(κΈ°λ³Έ μƒ€λ“œμ˜ 볡제본)λ₯Ό κ°–μŠ΅λ‹ˆλ‹€.
      • Shard 및 Replica의 μˆ˜λŠ” Indexλ³„λ‘œ, Index 생성 μ‹œμ μ— μ •μ˜ κ°€λŠ₯ν•˜λ‹€.
      • Index 생성 이후 탄λ ₯적으둜 Replica의 수λ₯Ό λ³€κ²½ν•  수 μžˆμœΌλ‚˜, Shard μˆ˜λŠ” λ³€κ²½ λΆˆκ°€λŠ₯ν•˜λ‹€.
    • 기본적으둜 ES 의 각 IndexλŠ” κΈ°λ³Έ Shard 5개, Replica 1개λ₯Ό κ°–μŠ΅λ‹ˆλ‹€.
    • λ”°λΌμ„œ ν΄λŸ¬μŠ€ν„°μ— μ΅œμ†Œν•œ 2개의 λ…Έλ“œκ°€ μžˆλ‹€λ©΄ IndexλŠ” κΈ°λ³ΈShard 5개 Replica Shard 5개 (μ™„μ „ν•œ λ¦¬ν”Œλ¦¬μΉ΄ 1개) λ₯Ό κ°€μ§€λ―€λ‘œ Index λ‹Ή 총 10개의 Shard κ°€ μ‘΄μž¬ν•˜κ²Œ λœλ‹€.

03. μ°Έκ³  이미지

ELK = elasticsearch + logstash + kibana

ELK Flow

ES Structure

chart

chart2

chart3

chart4

λŒ“κΈ€λ‚¨κΈ°κΈ°