Skip to content

πŸ› οΈ [refactor] κ°•μ˜ μ˜€ν”ˆμ‹œ μˆ˜κ°•μƒ 정보 Redis에 μΊμ‹±ν•˜κΈ°Β #62

@binary-ho

Description

@binary-ho

πŸ› οΈ λ¦¬νŒ©ν† λ§μ΄ ν•„μš”ν•œ λΆ€λΆ„

학생이 μΆœμ„ μ‹œλ„μ‹œ, μˆ˜κ°• μ‹ μ²­ 데이터가 많으면 데이터λ₯Ό κ°€μ Έμ˜€λŠ”λ°μ— μ—„μ²­λ‚œ μ‹œκ°„μ΄ μ†Œμš”λ˜λŠ” 것을 ν™•μΈν–ˆλ‹€,
(1000건 λ™μ‹œμš”μ²­μ‹œ 10λ§Œκ±΄μ—μ„  μ•„μ˜ˆ 600건 이상 νƒ€μž„μ•„μ›ƒ)
κ·Έλž˜μ„œ 인덱싱을 톡해 해결을 μ‹œλ„ν•˜λ‹ˆ μ•½ 6.5μ΄ˆλ§Œμ— μ „λΆ€ μ„±κ³΅ν–ˆλ‹€ -> #57

κ·ΈλŸ¬λ‚˜, 6.5μ΄ˆλ„ μ—¬μ „νžˆ μœ μ € μž…μž₯에선 μ—¬μ „νžˆ λŠλ¦¬λ‹€κ³  μƒκ°λ˜μ–΄, κ°•μ˜λ₯Ό μ—΄ λ•Œ μˆ˜κ°•μƒ 정보λ₯Ό 캐싱을 ν•΄λ³΄κΈ°λ‘œ ν–ˆλ‹€.

κ³„νš

1. 캐싱 λŒ€μƒ

  1. μ—΄λ¦° κ°•μ˜ 정보 (hash μ΄μš©ν•΄ κ°•μ˜ idλ₯Ό key둜, κ°•μ˜ 정보듀을 field와 value둜 μ €μž₯)
  2. μˆ˜κ°•μƒμ΄ μΆœμ„ κ°€λŠ₯ν•œ κ°•μ˜ λͺ©λ‘ (key : 학생 id, value : μ—΄λ¦° κ°•μ˜ id λͺ©λ‘ set)

2. κ°œμ„ λœ μΆœμ„ κ³Όμ •

  1. μˆ˜κ°•μƒλ“€μ€ μžμ‹ μ΄ 승인된 κ°•μ˜ 쀑, μΆœμ„ κ°€λŠ₯ν•œ κ°•μ˜κ°€ μžˆλŠ”μ§€ μΊμ‹œ λ¨Όμ € ν™•μΈν•œλ‹€.
  2. μžˆλŠ” 경우 μΊμ‹±λœ μ—΄λ¦° κ°•μ˜ μ •λ³΄μ—μ„œ 정보λ₯Ό κ°€μ Έμ˜¨λ‹€.
  3. μ—†λŠ” 경우 DBμ—μ„œ 직접 데이터λ₯Ό κ°€μ Έμ˜¨λ‹€.
  4. μΆœμ„μ΄ κ°€λŠ₯ν•œ μƒνƒœμ—μ„œ μƒˆλ‘œ μˆ˜κ°• μŠΉμΈλ˜λŠ” ν•™μƒμ˜ 경우 승인 이후 λ°”λ‘œ μΊμ‹±λœλ‹€.

3. μˆ˜μ—… μ •λ³΄λŠ” 같은 νŠΈλžœμž­μ…˜, 학생 μ •λ³΄λŠ” 비동기 μžμ‹ νŠΈλžœμž­μ…˜ (+Eventλ₯Ό ν†΅ν•œ κ΅¬ν˜„)

섀계 κ³Όμ •μ—μ„œ μ—¬λŸ¬κ°€μ§€ 방법을 κ³ λ―Όν–ˆλŠ”λ°, κ²°κ΅­ κ΅¬ν˜„μ€‘ Eventλ₯Ό λ°œν–‰ν•΄μ„œ 캐싱을 λ”°λ‘œ μ²˜λ¦¬ν•˜κΈ°λ‘œ κ²°μ •ν–ˆλ‹€. κ·Έ μ΄μœ λŠ” λ‹€μŒκ³Ό κ°™λ‹€

  1. 강사가 μˆ˜μ—…μ„ μ—΄ λ•Œ κΈ°λŒ€ν•œ ν–‰μœ„μ™€ 응닡은 "μˆ˜μ—…μ„ μ—¬λŠ” ν–‰μœ„" μžμ²΄μ— λŒ€ν•œ κ²ƒμ΄μ—¬ν•œλ‹€.
    "μ—΄λ¦° μˆ˜μ—…", "μˆ˜κ°•μƒ"을 μ €μž₯ν•˜λŠ” μž‘μ—…μ€ μˆ˜μ—…μ„ μ—¬λŠ” ν–‰μœ„λ₯Ό μš”μ²­ν•˜λŠ” 강사 μͺ½μ—μ„  관심사가 μ•„λ‹ˆλ‹€.
  2. λ”°λΌμ„œ, "μˆ˜μ—…μ„ μ—¬λŠ” ν–‰μœ„"μ™€λŠ” λ”°λ‘œ μ²˜λ¦¬ν•˜κ³ , μˆ˜μ—…μ΄ 열리면 λΉ λ₯΄κ²Œ 그에 λŒ€ν•œ 응닡을 λ°˜ν™˜ν•΄ μ£Όκ³  μ‹Άλ‹€.
  3. μ•„μ˜ˆ λ³„κ°œμ˜ νŠΈλžœμž­μ…˜μ„ μ΄μš©ν•΄ 캐싱 μžμ²΄κ°€ μ‹€νŒ¨ν•˜λ”λΌλ„ 영ν–₯을 λ°›μ§€ μ•Šμ•˜μœΌλ©΄ μ’‹κ² λ‹€.
  4. ν•˜μ§€λ§Œ, "μˆ˜μ—…μ„ μ—¬λŠ” ν–‰μœ„"의 νŠΈλžœμž­μ…˜μ΄ μ‹€νŒ¨ν•œλ‹€λ©΄ 캐싱은 μ§„ν–‰λ˜μ§€ μ•Šμ•˜μœΌλ©΄ μ’‹κ² λ‹€.

이 쑰건을 λͺ¨λ‘ λ§Œμ‘±μ‹œν‚€λŠ” κ°„λ‹¨ν•œ 방법이 Eventλ₯Ό μ‚¬μš©ν•˜λŠ” 것이라고 μƒκ°λ˜μ—ˆλ‹€.

μ²˜μŒμ—” Eventλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  λ‹¨μˆœ μ„œλΉ„μŠ€λ‘œ κ΅¬ν˜„ν–ˆκ³ , @Async 와 @Transactional(propagation = NESTED둜 ν•΄κ²°ν•  수 μžˆμ„ 쀄 μ•Œμ•˜λ‹€.

ν•˜μ§€λ§Œ, ν…ŒμŠ€νŠΈ ν•΄λ³Έ κ²°κ³Ό μ˜ˆμƒκ³ΌλŠ” λ‹€λ₯΄κ²Œ λΆ€λͺ¨ νŠΈλžœμž­μ…˜μ΄ μ‹€νŒ¨ν•΄λ„ μžμ‹ νŠΈλžœμž­μ…˜μ΄ μ‹€νŒ¨ν•˜μ§€ μ•Šμ•˜λ‹€.

이벀트λ₯Ό μ‚¬μš©ν•œλ‹€λ©΄ TransactionalListner의 Phase 섀정을 After Commit으둜 λ‘λ©΄μ„œ νŽΈλ¦¬ν•˜κ²Œ μ»€λ°‹μ‹œμ—λ§Œ μ €μž₯λ˜λ©΄μ„œλ„ λΉ„λ™κΈ°μ μœΌλ‘œ μž‘λ™ν•˜κ²Œ λ§Œλ“€ 수 μžˆλ‹€.

μ’…ν•©ν•˜λ©΄ λ‚΄ λͺ©ν‘œλŠ” μ•„λž˜μ™€ 같이 이룰 수 μžˆλ‹€.

  1. @Asyncλ₯Ό 톡해 μˆ˜μ—…μ„ μ—¬λŠ” ν–‰μœ„μ— λŒ€ν•œ 응닡을 λ°”λ‘œ 돌렀주고, 캐싱은 λΉ„λ™κΈ°μ μœΌλ‘œ 처리
  2. Transaction의 Require New μ˜΅μ…˜μ„ 톡해 캐싱을 μœ„ν•œ μ•„μ˜ˆ λ‹€λ₯Έ νŠΈλžœμž­μ…˜μ„ 생성
  3. Phase 섀정을 톡해, "μˆ˜μ—…μ„ μ—¬λŠ” ν–‰μœ„"κ°€ μ„±κ³΅ν–ˆμ„ λ•Œλ§Œ μΊμ‹±ν•˜λ„λ‘ κ΅¬ν˜„

4. μœ μ˜ν•  점

  1. Max MemoryλŠ” 5MB둜 μ„€μ •ν•œλ‹€ -> Memoryλ₯Ό λ„ˆλ¬΄ 많이 μ‚¬μš©ν•˜λŠ” 것을 막기 μœ„ν•¨μœΌλ‘œ λΉ„μ¦ˆλ‹ˆμŠ€λ₯Ό μƒκ°ν•˜λ©΄ 5MBλŠ” 닿을 수 없을 만큼 크닀. 학생 데이터λ₯Ό 보수적으둜 set으둜 μ €μž₯ν•˜λŠ” 경우 μ•½ 200 초반의 λ°”μ΄νŠΈκ°€ ν•„μš”ν•˜λ‹€.
    1만λͺ…μ˜ 학생이 μžˆλ‹€κ³  ν–ˆμ„ λ•Œ, 2MBκ°€ μ΅œλŒ€μ΄λ‹€. 그리고 이 1만λͺ…μ˜ 학생이 λ™μ‹œμ— κ°€μž…ν•œλ‹€κ³  해도, 이메일 데이터가 100 μ΄ˆλ°˜λŒ€μ΄λ―€λ‘œ, 2MB에 λ‹ΏκΈ° μ–΄λ ΅λ‹€.
    결둠적으둜 5MB의 곡간이 μžˆλ‹€λ©΄, 1만λͺ…μ˜ 학생이 λ™μ‹œμ— κ°€μž…ν•˜λ©΄μ„œ, μ¦‰μ‹œ μˆ˜μ—… 정보λ₯Ό 캐싱할 수 μžˆλ‹€.
    ν˜„μž¬ 1000λͺ… λ™μ‹œ μΆœμ„μ΄ λͺ©ν‘œμΈ μ‹œμ μ—μ„œ μ•„μ£Ό μΆ©λΆ„ν•œ 값이닀. (ν˜„μž¬ EC2 μŠ€νŽ™μ€ 1GiB)
  2. eviction 정책은 volitle ttl : μ•±μ—μ„œ λ‹€μ–‘ν•œ μ’…λ₯˜μ˜ 캐싱을 ν•˜μ§€λ§Œ, κ°€μž₯ 큰 μš©λŸ‰μ„ μ°¨μ§€ν•˜λŠ” 것은 이 μˆ˜κ°•μƒ 정보이닀. λ¬Έμ œλŠ” μˆ˜κ°•μƒ μ •λ³΄λŠ” μ‚¬μš©λ˜μ§€ μ•Šμ€ 데이터 일수둝 였히렀 μ‚¬μš© ν™•λ₯ μ΄ λ†’λ‹€λŠ” 점이닀 μ΄λŠ” 기쑴의 캐싱 μ •μ±…λ“€κ³Ό λ°˜λŒ€μ΄λ‹€
    μ™œλƒν•˜λ©΄ ν•œλ²ˆ μΆœμ„ν•œ 학생은 였히렀 또 μΆœμ„ν•  일이 μ—†κ³ , μΆœμ„ν•˜μ§€ μ•Šμ€ 학생이 μƒˆλ‘œ μΆœμ„ν•  κ°€λŠ₯성이 λ†’κΈ° 떄문이닀. κ·Έλž˜μ„œ λ ˆλ””μŠ€μ— 이 상황에 100% λ§žλŠ” μ μ ˆν•œ 정책이 μ—†λ‹€. (보톡은 자주 μ“°μ΄λŠ” 데이터λ₯Ό 더 μ‚΄λ € λ†“λŠ”λ‹€)
    κ·Έλ‚˜λ§ˆ μ μ ˆν•΄ λ³΄μ΄λŠ” 것이 volitle-ttl이닀. (정책이 μ•„μ˜ˆ μ—†λŠ” κ²½μš°μ—” μƒˆλ‘œμš΄ μ €μž₯이 μ•ˆ λœλ‹€.) κ·Έλž˜μ„œ volitle-ttl을 μ„ νƒν–ˆλ‹€.
    λ¬Έμ œλŠ” μ•±μ—μ„œ μΊμ‹±ν•˜λŠ” λ‹€μ–‘ν•œ 데이터 쀑에 μΊμ‹±λœ 데이터가 μˆ˜κ°•μƒ 데이터가 제일 사라져도 λ¬Έμ œκ°€ μ—†λŠ” λ°μ΄ν„°λž€ 것이고, λ‹€λ₯Έ 데이터듀은 μ‚¬λΌμ§€λŠ” 경우 λ¬Έμ œκ°€ λœλ‹€.

    μ΄μ œκΉŒμ§€ 사라져선 μ•ˆ λ˜λŠ” 데이터듀은 μ œν•œ μ‹œκ°„μ΄ μ‹€μ œ λΉ„μ¦ˆλ‹ˆμŠ€μ μœΌλ‘œλ„ μ‘΄μž¬ν•˜λŠ” λ°μ΄ν„°λ“€μ΄μ—¬μ„œ λΉ„μ¦ˆλ‹ˆμŠ€μ μΈ μ œν•œ μ‹œκ°„κ³Ό redis exprire time을 λ˜‘κ°™μ΄ λ§žμ·„λ‹€. 이젠, 이 λ°μ΄ν„°λ“€μ˜ exprire time을 2배둜 늘리고, λ”°λ‘œ 유효 μ‹œκ°„μ„ μ €μž₯ν•˜λŠ” 방식을 κ³ λ €ν•΄λ΄€λ‹€.
    κ·ΈλŸ¬λ‹ˆκΉŒ μœ„ν—˜μ„ λŒ€λΉ„ν•΄ μ €μž₯ μš©λŸ‰μ„ 늘리게 λ˜λŠ” 것이닀.
    이 방법은 기쑴의 일반적인 캐싱과 같은 상황에선 λΉ„μ‹Ό λ©”λͺ¨λ¦¬ μžμ›μ„ 더 μ†Œλͺ¨ν•˜λŠ” κ²ƒμž„μœΌλ‘œ λ¬Έμ œκ°€ λ˜κ² μ§€λ§Œ, 우리 μ„œλΉ„μŠ€μ—μ„  이런 λ°©μ‹μœΌλ‘œ μΆ”κ°€ λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•΄ μ €μž₯ν•˜λŠ” μžλ£Œκ°€ 적음으둜 κ³ λ €ν• λ§Œν•΄ 보인닀. λ§Œμ•½ μš©λŸ‰μ΄ 그리 λ„‰λ„‰ν•˜μ§€ μ•Šμ•˜λ”λΌλ©΄, μœ νš¨μ‹œκ°„μ„ λŒ€ν­ μ€„μ΄λŠ” λ°©λ²•μœΌλ‘œ 바꿨을 것이닀. -> λ˜λ‹€λ₯Έ μ΄μŠˆκ°€ ν•„μš”ν•˜λ‹€
  3. κ°•μ˜λ₯Ό OPEN 쀑에 μƒˆλ‘œμš΄ 학생이 승인될 수 μžˆλ‹€ (μΆœμ„ κ°€λŠ₯ν•œ 학생이 λ™μ μœΌλ‘œ 생겨날 수 있음)
    -> 강사가 학생을 μŠΉμΈν–ˆμ„ λ•Œ, κ°•μ˜κ°€ 이미 μ—΄λ €μžˆλ‹€λ©΄ λ ˆλ””μŠ€μ— μΊμ‹±ν•œλ‹€.
  4. redis transaction support : redis templateμ—μ„œ κ΄€λ ¨ 섀정을 true둜 μ„€μ •ν•΄μ•Ό /@transactional 을 뢙인 λ©”μ„œλ“œμ—μ„œ RedisTemplateλ₯Ό μ‚¬μš©ν•  λ•Œ, μš°λ¦¬κ°€ ν‰μ†Œμ— DBλ₯Ό μ‚¬μš©ν•  λ•Œμ™€ 같이 λ™μž‘ν•œλ‹€. (ν•˜λ‚˜μ˜ νŠΈλžœμž­μ…˜μœΌλ‘œ 묢이고, λ‘€λ°±μ‹œ λ‘€λ°± λ“±)

λ¦¬νŒ©ν† λ§ μž‘μ—… 브랜치

feature/student-caching

β˜‘ Refactoring TODO

  • λ ˆλ””μŠ€ μ„€μ • 적용
  • Open된 κ°•μ˜ 정보인 OpenLecture κ΅¬ν˜„
  • μΆœμ„ 번호λ₯Ό μ €μž₯ν•˜λ˜ AttendanceNumber Repository 제거
  • μˆ˜κ°•μƒ 정보λ₯Ό μ €μž₯ν•˜λŠ” LectureStudentRepository κ΅¬ν˜„
  • μˆ˜μ—…μ„ μ—΄ λ•Œ, OpenLecture 정보와 μˆ˜κ°•μƒ 정보λ₯Ό μ €μž₯ν•˜λŠ” κΈ°λŠ₯ κ΅¬ν˜„
  • μΆœμ„ κ°€λŠ₯ν•œ κ°•μ˜λ₯Ό κ°€μ Έμ˜€λŠ” 과정에 μΊμ‹œ 데이터λ₯Ό λ¨Όμ € 확인 ν•˜λŠ” κ³Όμ • μΆ”κ°€
  • 학생이 μΆœμ„μ„ μ‹œλ„ν•  λ•Œλ„ 캐싱을 λ¨Όμ € ν™•μΈν•˜λŠ” κ³Όμ • μΆ”κ°€
  • 학생을 μŠΉμΈν•΄μ€„ λ•Œ, μ—΄λ €μžˆλŠ” 경우 μΊμ‹±ν•˜λŠ” κ³Όμ • μΆ”κ°€
  • μ „κ³Όμ • ν…ŒμŠ€νŠΈ μΆ”κ°€
  • Eventλ₯Ό λ°œν–‰ν•˜μ—¬ μ²˜λ¦¬ν•˜λŠ” λ°©μ‹μœΌλ‘œ λ³€κ²½

Metadata

Metadata

Assignees

No one assigned

    Labels

    Refactorλ¦¬νŒ©ν† λ§

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions