Dev-Kyuu
article thumbnail

μ΄λ²ˆμ£Όμ— λ“€μ–΄μ„œλΆ€ν„° μ—¬λŸ¬ κΈ°λŠ₯을 μ‘°κΈˆμ”© νŒŒκΈ°λ³΄λ‹€λŠ” ν•œ κΈ°λŠ₯에 μ§‘μ€‘ν•΄μ„œ λΆ„μ„ν•˜κ³  κ³΅λΆ€ν•˜λŠ” μ‹œκ°„μ„ κ°€μ§€κ³  μžˆλ‹€

그게 μ§„μ •ν•œ μ±Œλ¦°μ§€νŒ€μ˜ 묘미라고 ν•΄μ„œ ,, πŸ‘€

 

μ›”μš”μΌμ—λŠ” ν…ŒμŠ€νŠΈμ½”λ“œ(Junit), λ™μ‹œμ„±μ œμ–΄μ— λŒ€ν•΄μ„œ 곡뢀λ₯Ό ν•˜μ˜€κ³ 

ν™”μš”μΌ~μˆ˜μš”μΌμ—λŠ” κ³΅λΆ€ν•œκ²ƒμ„ λ°”νƒ•μœΌλ‘œ λ‚΄ ν”„λ‘œμ νŠΈμ— μ μš©ν•΄λ³΄κ³ , λ‚΄κ°€ μ„±λŠ₯ κ°œμ„ ν•  κΈ°λŠ₯에 λŒ€ν•΄ λœ―μ–΄λ³΄λŠ” μ‹œκ°„μ„ κ°€μ‘Œλ‹€.

μ•„λž˜μ˜ λ‚΄μš©μ€ 였늘 λ‚΄κ°€ κΈ°λŠ₯을 λœ―μ–΄λ³΄λ©΄μ„œ, μ–΄λ–»κ²Œ κ΅¬ν˜„ν• μ§€ 고민을 ν•œ 뢀뢄이닀 ! 

 


μŠ€ν† μ–΄ 정보 μ—…λ°μ΄νŠΈ, μ–΄λ–€ μ‹œμ μ— μ–΄λ–»κ²Œ μ²˜λ¦¬ν•΄μ•Όν• κΉŒ ? πŸ€”

κΈ°λŠ₯ :

  • μŠ€ν† μ–΄μ •λ³΄(별점 & 방문자 리뷰 갯수) μ—…λ°μ΄νŠΈ κΈ°λŠ₯

κΈ°λŠ₯ λͺ…μ„Έ :

  • 정보가 μ—…λ°μ΄νŠΈ 된 μŠ€ν† μ–΄κ°€ μžˆμ„ 경우 주기적으둜 ν™•μΈν•˜μ—¬ 정보λ₯Ό κ°±μ‹ ν•˜λŠ” κΈ°λŠ₯

κ΅¬ν˜„ λ°©ν–₯ :

  • μ‚¬μš©μž 리뷰 등둝 μ‹œ μƒνƒœκ°€ μ—…λ°μ΄νŠΈ 된 μŠ€ν† μ–΄ 정보(ex. μŠ€ν† μ–΄ ID, 별점 λ“±)λ₯Ό Redis Cache에 μ €μž₯
  • Redis에 μ €μž₯된 정보λ₯Ό 일정 μ£ΌκΈ°λ§ˆλ‹€ μ½μ–΄μ„œ λ³€κ²½λœ 정보λ₯Ό Store ν…Œμ΄λΈ”μ— μ—…λ°μ΄νŠΈ 처리
    ⇒ 이 뢀뢄을 μ–΄λ–»κ²Œ μ²˜λ¦¬ν• μ§€μ— λŒ€ν•œ κ³ λ―Ό !!

기술적 고민:

 

1) Redis에 μ–΄λ–€ 정보λ₯Ό μ €μž₯ν•˜κ³ , μ–΄λ–»κ²Œ μ‚¬μš©ν• κ²ƒμΈμ§€?

*) Redis Cache에 데이터 μ €μž₯방식은 Set λ°©μ‹μœΌλ‘œ μ €μž₯됨(μ€‘λ³΅λœ κ°’ μ €μž₯ X)

 

Case1 . μ—…λ°μ΄νŠΈ 된 μŠ€ν† μ–΄ ID μ •λ³΄λ§Œ Redis Cache에 μ €μž₯(μƒˆλ‘œ μ μš©ν•œ 방식)

  • μ—…λ°μ΄νŠΈ 된 μŠ€ν† μ–΄ID만 μ €μž₯ν•˜κ³  Review ν…Œμ΄λΈ”μ—μ„œ μŠ€ν† μ–΄ID와 μΌμΉ˜ν•˜λŠ” λ ˆμ½”λ“œλ“€μ„ μ‘°νšŒν•˜μ—¬ μŠ€ν† μ–΄ 정보λ₯Ό κ°±μ‹ ν•˜λŠ” 방법
  • λ°°μΉ˜ν”„λ‘œκ·Έλž¨μ΄ λ™μž‘ν•˜κΈ° 이전에 λͺ‡κ°œμ˜ 리뷰가 λ“±λ‘λ˜μ—ˆλŠ”μ§€ μ²΄ν¬ν•˜μ§€μ•Šκ³ , μ—…λ°μ΄νŠΈκ°€ λ˜μ—ˆλŠ”μ§€/μ•ˆλ˜μ—ˆλŠ”μ§€λ§Œ ν™•μΈν•˜μ—¬ 
    Redis에 정보가 λ³€κ²½ 된 StoreIdλ₯Ό μ €μž₯ν•˜λŠ” 방식

 

쿼리문 및 μ‹€ν–‰ 속도

// μ‚¬μš©ν•˜λŠ” 쿼리문

UPDATE store a 
SET 
a.review_cnt = ( SELECT count(*) FROM review where storeid = μŠ€ν† μ–΄ID),
a.star_score = TRUNCATE((select avg(star_score) from review where storeid = μŠ€ν† μ–΄ID),2)
WHERE store_id= μŠ€ν† μ–΄ID;

⇒ Thoughput : 1.1/sec , μ΅œμ†Œμ‹œκ°„ 20 / μ΅œλŒ€μ‹œκ°„ 511

 

 

 

Case2 . μ—…λ°μ΄νŠΈ 된 μŠ€ν† μ–΄ ID , 별점 정보, μ‚¬μš©μž 정보 Redis Cache에 μ €μž₯(κΈ°μ‘΄ 적용 방식)

  • μ—…λ°μ΄νŠΈ 된 μŠ€ν† μ–΄ID 및 κ°±μ‹ λœ 정보듀을 μ €μž₯ν•˜μ—¬ Redis에 μ €μž₯된 μ •λ³΄λ‘œ DB에 μ—…λ°μ΄νŠΈ ν•˜λŠ” 방법
  • Redis Cache에 μžˆλŠ” 데이터λ₯Ό 기반으둜 Store 정보λ₯Ό μ—…λ°μ΄νŠΈ ν•˜λŠ” 방식 μΊμ‹œμ— μ €μž₯λ˜λŠ” λ°μ΄ν„°μ˜ 무결성이 μ€‘μš”ν•¨!

 

쿼리문 및 μ‹€ν–‰ 속도

// μ‚¬μš©ν•˜λŠ” 쿼리문

UPDATE store a 
SET 
a.review_cnt = review_cnt + 1, 
a.star_score = TRUNCATE (((((review_cnt - 1) * star_score) + μž…λ ₯된 별점) / review_cnt), 2) 
WHERE store_id= μŠ€ν† μ–΄ID;

⇒ Thoughput : 1.1/sec , μ΅œμ†Œμ‹œκ°„ 17 / μ΅œλŒ€μ‹œκ°„ 154

 


2) 두가지 방식 비ꡐ

  • μ‹€ν–‰ 속도 :
    ⇒ Case 2 방식이 Case 1 방식보닀 μˆ˜ν–‰ μ†λ„λŠ” μ•½ 3λ°° 느림

  • 반볡 횟수 :
    ⇒ Case 1 방식은 1번  / Case 방식은 10번의 쿼리가 μˆ˜ν–‰ 됨
    ⇒ Case 1 방식은 4번 / Case 2 방식은 40번 μˆ˜ν–‰ 됨
  • 상황 별 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ :
    상황 1. A μŠ€ν† μ–΄ 리뷰가 10개 등둝 λ˜μ—ˆμ„ 경우
        ⇒ Case 1 방식은 1번만 쿼리 / Case 방식은 10번의 쿼리가 μˆ˜ν–‰

    상황 2. A,B,C,D μŠ€ν† μ–΄μ— 리뷰가 각각 10κ°œμ”© λ“±λ‘λ˜μ—ˆμ„ 경우
       ⇒ Case 1 방식은 4번 쿼리 질의 μˆ˜ν–‰ / Case 2 방식은 40번 μˆ˜ν–‰ 됨

κ³ λ―Όν–ˆλ˜ 점 ❓

 

Q.

쿼리 μˆ˜ν–‰ μ‹œκ°„ μžμ²΄λŠ” κ°μ†Œλ˜μ§€λ§Œ, λ§Žμ€ 쿼리λ₯Ό λ‚ λ¦¬κ²Œ λ˜λŠ” Case 2 방식을 μ‚¬μš©ν•˜λŠ”κ²Œ νš¨μœ¨μ μΌμ§€?

μˆ˜ν–‰μ‹œκ°„μ€ μ¦κ°€λ˜μ§€λ§Œ, 적은 쿼리λ₯Ό λ°œμƒμ‹œν‚€κ³  Redis Cache에 데이터λ₯Ό 적게 μ μž¬ν•˜λŠ” 1 방식이 νš¨μœ¨μ μΌμ§€?

 

  • Case1을 μ μš©ν•˜κ³ , 쿼리 μ‹œκ°„μ„ κ°μ†Œ μ‹œν‚¬ 수 μžˆλŠ” λ°©μ•ˆμ— λŒ€ν•΄ κ³ λ―Όν•˜λŠ”κ²ƒμ΄ 쒋을 것 κ°™μŒ!
  • Case2 λ°©μ‹μœΌλ‘œ μ‚¬μš©ν•˜μ˜€μ„ λ•Œ DB에 μƒλ‹Ήν•œ 뢀담을 쀄 수 μžˆμ„ 것이라고 νŒλ‹¨
    ⇒ 뢀담도 쀄이고, 쿼리 μˆ˜ν–‰ 속도도 μ€„μ΄λŠ” λ°©ν–₯으둜 κ³  !
    ( 1μ°¨ 적용 : View ν…Œμ΄λΈ” 생성 및 적용 )

 

Q.

Case 1 방식을 μ‚¬μš©ν•  λ•Œ κΌ­ Redis Cacheλ₯Ό μ‚¬μš©ν•΄μ•Όν• κΉŒ?

μ•„λ‹ˆλ©΄ λ‹€λ₯Έ λŒ€μ²΄ 방법이 어떀것이 μžˆμ„κΉŒ? 🧐

 

  • 리뷰 등둝 μ‹œ Review ν…Œμ΄λΈ”μ— μ‹λ³„μžλ₯Ό μ£Όμ–΄ κ΅¬λ³„ν•˜λŠ” 방법
    ⇒ 배치 μ„œλΉ„μŠ€μ—μ„œλŠ” DBμ—μ„œ UpdateInfoκ°€ True인 Storeμ •λ³΄λ§Œ μ—…λ°μ΄νŠΈ
    ⇒ Review Table에 UpdateInfo λΌλŠ” μ»¬λŸΌμ„ μΆ”κ°€ν•˜μ—¬ 리뷰 등둝 μ‹œ True둜 값을 λ³€κ²½ν•œλ‹€.

이 밖에도 λ™μ‹œμ„± μ œμ–΄ 뢀뢄을 κ³ λ―Όν•˜κ³ μžˆλŠ”λ° μ§€κΈˆκΉŒμ§€ ν…ŒμŠ€νŠΈ ν•œ κ²ƒμœΌλ‘œλŠ” μœ„μ˜ 방식을 μ μš©ν–ˆμ„ λ•Œ 

λ™μ‹œμ„± μ΄μŠˆκ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€ (ν΄λΌμ΄μ–ΈνŠΈκ°€ μ—¬λŸΏμ΄μ—¬λ„ DB에 μ—…λ°μ΄νŠΈν•˜λŠ” 주체(Redis)λŠ” ν•œκ°œμ΄κΈ° λ•Œλ¬Έμž„) 
내일 쑰금 더 고민해보고 λ‹€λ₯Έ λΆ€λΆ„μ—μ„œ λ™μ‹œμ„± μ΄μŠˆκ°€ ν„°μ§ˆλ§Œν•œ 뢀뢄은 μ—†λŠ”μ§€? μΆ”κ°€ν•΄μ„œ κΈ€ μž‘μ„±ν•΄λ‘¬μ•Όκ² λ‹Ή

 

profile

Dev-Kyuu

@kyuu_ng

ν¬μŠ€νŒ…μ΄ μ’‹μ•˜λ‹€λ©΄ "μ’‹μ•„μš”β€οΈ" λ˜λŠ” "κ΅¬λ…πŸ‘πŸ»" ν•΄μ£Όμ„Έμš”!