Skip to content

Performance

Seon-woong edited this page Aug 28, 2020 · 1 revision

μ†Œν”„νŠΈμ›¨μ–΄μ μΈ μ΅œμ ν™” - 1. λ°μ΄ν„°λ² μ΄μŠ€ 인덱슀

κ°€μž₯ λ¨Όμ € μ²˜λ¦¬ν•  뢀뢄은 λ°μ΄ν„°λ² μ΄μŠ€μ— 인덱슀λ₯Ό μΆ”κ°€ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 인덱슀λ₯Ό μΆ”κ°€ν•œλ‹€λŠ” 말은 λ°μ΄ν„°λ² μ΄μŠ€ μƒμ˜ 데이터듀을 자주 μ‚¬μš©ν•˜λŠ” 칼럼 μ€‘μ‹¬μœΌλ‘œ μ •λ ¬ν•΄λ‘λŠ” 것을 λ§ν•©λ‹ˆλ‹€. κ°œλ°œμžλ“€μ΄ μ μ ˆν•œ μΉΌλŸΌμ— 인덱슀λ₯Ό μΆ”κ°€ν•˜λŠ” 슀크립트λ₯Ό ν•œ 번 μ‹€ν–‰ν•˜λ©΄ λ˜λŠ”λ°, 이 μž‘μ—…λ§ŒμœΌλ‘œλ„ λ°μ΄ν„°λ² μ΄μŠ€ 읽기 속도가 κ°œμ„ λ˜μ–΄ μ„œλΉ„μŠ€κ°€ λΉ¨λΌμ§‘λ‹ˆλ‹€.

μ†Œν”„νŠΈμ›¨μ–΄μ μΈ μ΅œμ ν™” - 2. 이미지 리사이징

κ·Έλ‹€μŒ μ²˜λ¦¬ν•  뢀뢄은 이미지 μ‚¬μ΄μ¦ˆλ₯Ό μ΅œμ ν™”ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 느린 μ‚¬μ΄νŠΈμ˜ 원인 쀑 μƒλ‹Ήνžˆ 높인 λΉ„μœ¨μ΄ 큰 이미지 μ‚¬μ΄μ¦ˆ λ•Œλ¬Έμ— λ°œμƒν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 10λ©”κ°€κ°€ λ„˜λŠ” 이미지λ₯Ό 리사이징 없이 μ €μž₯ν•˜κ³  κ·ΈλŒ€λ‘œ λ‘œλ”©ν•˜λ©΄ 전체 νŽ˜μ΄μ§€κ°€ 느리게 ν‘œμ‹œλ©λ‹ˆλ‹€. μ‚¬μš©μžλŠ” λͺ‡ λ©”κ°€κ°€ λ„˜λŠ” 이미지λ₯Ό 슀마트폰 μΉ΄λ©”λΌλ‘œ μ°μ–΄μ„œ κ·ΈλŒ€λ‘œ μ—…λ‘œλ“œν•  수 μžˆμ§€λ§Œ 이λ₯Ό μ„œλ²„μ—μ„œ μ €μž₯ν•  λ•ŒλŠ” μ μ ˆν•œ λ²„μ „μ˜ μ΄λ―Έμ§€λ‘œ 리사이징 ν•΄μ„œ μ €μž₯ν•΄μ•Ό ν•©λ‹ˆλ‹€.

λͺ©λ‘μ—μ„œ 보여쀄 μž‘μ€ 썸넀일 이미지, 상세 ν™”λ©΄μ—μ„œ 보여쀄 슀마트폰 κ°€λ‘œ μ‚¬μ΄μ¦ˆ(ν˜Ήμ€ 해상도에 따라 κ°€λ‘œ μ‚¬μ΄μ¦ˆμ˜ 2~3λ°°, 파일 ν¬κΈ°λŠ” μ›λ³Έμ˜ 1/20 )μ •λ„μ˜ 이미지, 그리고 ν™•λŒ€ν•΄μ„œ 보여쀄 ν•„μš”κ°€ μžˆμ„ λ•Œ 그에 λ§žλŠ” μ‚¬μ΄μ¦ˆμ˜ μ΄λ―Έμ§€κΉŒμ§€ λͺ‡ 개의 리사이징 된 버전을 μ €μž₯ν•΄ 두고 ν•΄λ‹Ή νŽ˜μ΄μ§€μ—μ„œ μ μ ˆν•œ μ‚¬μ΄μ¦ˆμ˜ 이미지λ₯Ό ν‘œμ‹œν•˜λ©΄ νŽ˜μ΄μ§€ λ‘œλ”© 속도λ₯Ό λͺ‡ λ°°κΉŒμ§€λ„ κ°œμ„ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

10개의 이미지λ₯Ό ν™”λ©΄μ˜ 절반 정도 크기둜 ν‘œμ‹œν•˜λŠ” 경우, 10λ©”κ°€μ˜ 원본 이미지 κ·ΈλŒ€λ‘œ μ‚¬μš©ν•˜λ©΄ 총 100λ©”κ°€μ˜ 이미지λ₯Ό λ‹€μš΄λ‘œλ“œν•˜μ—¬μ•Όμ§€ νŽ˜μ΄μ§€κ°€ ν‘œμ‹œλ©λ‹ˆλ‹€. νŽ˜μ΄μ§€κ°€ ν‘œμ‹œλ˜λŠ”λ° 10~20μ΄ˆκ°€ 걸릴 수 μžˆμŠ΅λ‹ˆλ‹€. 10λ©”κ°€μ˜ 고해상도 이미지라고 해도 ν‘œμ‹œλ˜λŠ” μ˜μ—­μ΄ μž‘μœΌλ©΄ 였히렀 이미지가 κΉ¨μ Έ 보이게 λ©λ‹ˆλ‹€. 이λ₯Ό 1024px μ •λ„μ˜ μ‚¬μ΄μ¦ˆλ‘œ μ€„μ΄κ²Œ 되면 10메가인 원본 이미지보닀 λΆ€λ“œλŸ½κ²Œ λ³΄μ΄λ©΄μ„œλ„ μš©λŸ‰μ€ 500K, 즉 10λ©”κ°€μ˜ 20λΆ„μ˜ 1에 λΆˆκ³Όν•˜λ―€λ‘œ 총 5λ©”κ°€μ˜ μ΄λ―Έμ§€λ§Œ λ‹€μš΄λ‘œλ“œν•˜λ©΄ 1초 이내에 νŽ˜μ΄μ§€μ— λͺ¨λ“  이미지가 λ°”λ‘œ ν‘œμ‹œλ  수 μžˆμŠ΅λ‹ˆλ‹€.

μ†Œν”„νŠΈμ›¨μ–΄μ μΈ μ΅œμ ν™” - 3. 쿼리 및 μ—°μ‚° μ½”λ“œ κ°œμ„ 

κ·Έλ‹€μŒμ€ λΉ„νš¨μœ¨μ μΈ μ½”λ“œλ₯Ό κ°œμ„ ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 특히 개발 μ΄ˆμ€‘λ°˜μ— μ„œλΉ„μŠ€λ₯Ό λΉˆλ²ˆν•˜κ²Œ μˆ˜μ •ν•˜λ‹€ 보면 λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ 데이터λ₯Ό κ°€μ Έμ˜€λŠ” μ½”λ“œλ‚˜ 연산을 ν•˜λŠ” μ½”λ“œ, 화면에 ν‘œμ‹œν•˜λŠ” μ½”λ“œ 등이 λΉ„νš¨μœ¨μ μœΌλ‘œ μž‘μ„±λ˜μ–΄ μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. λͺ‡ 개의 λ°μ΄ν„°λ§Œ κ°€μ Έμ˜€λ©΄ λ˜λŠ”λ° 전체 데이터λ₯Ό λ‘œλ“œν•˜κ³  μžˆλŠ” κ²½μš°λ„ 있고, 일뢀 칼럼 λ°μ΄ν„°λ§Œ ν•„μš”ν•œλ° 전체 칼럼 데이터λ₯Ό λ‘œλ“œν•΄μ˜€κ±°λ‚˜ μž¬μ‚¬μš©ν•  수 μžˆλŠ” 데이터λ₯Ό 맀번 λ‹€μ‹œ κ³„μ‚°ν•˜κ³  μžˆμ„ μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. λΉ„νš¨μœ¨μ μΈ μ½”λ“œ ν•œ 두 μ€„μ˜ λ³€κ²½λ§ŒμœΌλ‘œ λͺ‡ 배의 속도λ₯Ό κ°œμ„ ν•  수 μžˆμŠ΅λ‹ˆλ‹€

ν•œμ°½ ν”Œλž«νΌμ΄ 개발 쀑일 λ•ŒλŠ” μ½”λ“œ μ΅œμ ν™”κ°€ μ΅œμš°μ„  사항은 μ•„λ‹™λ‹ˆλ‹€. μΆœμ‹œκΉŒμ§€ λ§Žμ€ 기획 λ³€κ²½κ³Ό ꡬ쑰 변경이 μžˆμ„ 텐데 μ΅œμ ν™”λΆ€ν„° κ³ λ €ν•˜λ‹€ 보면 κ΅¬ν˜„ 및 변경이 μ–΄λ €μ›Œμ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€. 기획적인 μ˜μ‚¬κ²°μ •μ΄ μ–΄λŠ 정도 μ™„κ²°λ˜κ³  개발이 λ§ˆλ¬΄λ¦¬λ˜μ–΄ ꡬ쑰적인 변경이 더 이상 없을 λ•Œ μ΅œμ ν™”λ₯Ό μ§„ν–‰ν•˜λŠ” 것이 νš¨κ³Όμ μž…λ‹ˆλ‹€. 심지어 λ‹Ήμž₯ 속도가 λŠλ¦¬μ§€ μ•Šλ‹€λ©΄ 일단 μΆœμ‹œν•œ ν›„ μ‚¬μš©λŸ‰ 증가와 νŽ˜μ΄μ§€ 속도λ₯Ό κ΄€μ°°ν•˜λ©΄μ„œ μ§€μ†μ μœΌλ‘œ μ½”λ“œλ₯Ό κ°œμ„ ν•΄λ‚˜κ°€λ„ λœλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. λͺ¨λ“  뢀뢄을 μ΅œμ ν™”ν•˜κΈ°λ³΄λ‹€λŠ” 많이 μ ‘μ†λ˜λ©΄μ„œλ„ 느린 뢀뢄을 μš°μ„ μ μœΌλ‘œ μ΅œμ ν™”ν•˜λŠ” 것이 개발 λ¦¬μ†ŒμŠ€μ™€ λΉ„μš©μ„ 쀄일 수 μžˆμŠ΅λ‹ˆλ‹€.

μ†Œν”„νŠΈμ›¨μ–΄μ μΈ μ΅œμ ν™” - 4. 데이터 캐싱

ν†΅κ³„λ‚˜ μ •μ‚° κΈ°λŠ₯의 경우 μ£Όλ¬Έ 데이터 λ“± λ§Žμ€ 데이터λ₯Ό ν•œ λ²ˆμ— κΊΌλ‚΄μ™€μ„œ κ³„μ‚°ν•˜κ³  κ°€κ³΅ν•΄μ„œ ν‘œμ‹œν•˜κ²Œ λ©λ‹ˆλ‹€. κ³Όκ±° λ°μ΄ν„°μ˜ 경우 μˆ˜μ •λ  일이 적기 λ•Œλ¬Έμ— μ§€λ‚œλ‹¬ ν†΅κ³„λ‚˜ μ •μ‚° 데이터도 크게 변동이 μ—†λŠ” κ²½μš°κ°€ λ§Žμ€λ° 톡계/μ •μ‚° νŽ˜μ΄μ§€λ₯Ό μ—΄ λ•Œλ§ˆλ‹€ 수만 개의 데이터λ₯Ό 가져와 연산을 ν•˜λ‹€ 보면 νŽ˜μ΄μ§€ 접속이 λŠλ €μ§€κ²Œ λ©λ‹ˆλ‹€. 주기적으둜 톡계/μ •μ‚° 데이터λ₯Ό 생성해낸 ν›„ 이λ₯Ό λ³„λ„μ˜ λ°μ΄ν„°λ² μ΄μŠ€μ— μ €μž₯ν•΄λ‘μ—ˆλ‹€κ°€ κΊΌλ‚΄μ˜€λ©΄ μˆ˜λ§Žμ€ 연산을 λ°˜λ³΅ν•  ν•„μš”κ°€ μ—†μ–΄μ„œ 속도 κ°œμ„ μ΄ λ©λ‹ˆλ‹€.

또 λ‹€λ₯Έ μ‚¬λ‘€λ‘œ, μƒν’ˆμ— λŒ€ν•œ 찜 κ°œμˆ˜λ‚˜ 리뷰 평균 점수λ₯Ό 맀번 κ³„μ‚°ν•˜κ²Œ 되면 μƒν’ˆ λͺ©λ‘ νŽ˜μ΄μ§€λ₯Ό ν‘œμ‹œν•  λ•Œλ§ˆλ‹€ λͺ©λ‘ μƒμ˜ μƒν’ˆλ“€μ˜ λͺ¨λ“  찜 개수λ₯Ό μ„Έκ³  λͺ¨λ“  리뷰 데이터λ₯Ό κ°€μ Έμ™€μ„œ 연산을 ν•΄μ•Ό ν•©λ‹ˆλ‹€. λ°μ΄ν„°λ² μ΄μŠ€μ— λ§Žμ€ 질의λ₯Ό 보내야 ν•˜κΈ°λ„ ν•˜μ§€λ§Œ κ°€μ Έμ™€μ„œ 개수λ₯Ό μ„Έκ³  평균을 λ‚΄λŠ” 연산도 ν•„μš”ν•˜κ²Œ λ©λ‹ˆλ‹€. λ°μ΄ν„°λ² μ΄μŠ€μ— μ§ˆμ˜ν•  λ•Œ 찜 κ°œμˆ˜λ‚˜ 리뷰 평균을 κ³„μ‚°ν•˜λŠ” 쿼리λ₯Ό μž‘μ„±ν•  μˆ˜λ„ μžˆμ§€λ§Œ 쿼리가 λ³΅μž‘ν•΄μ§€κ³  μ›Ή ν”„λ ˆμž„μ›Œν¬μ˜ ORM을 λ²—μ–΄λ‚˜λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•΄μ•Ό ν•©λ‹ˆλ‹€(μ½”λ“œ 관리 λ‚œμ΄λ„ 증가).

쒋은 해결책은 νŠΉμ • μƒν’ˆμ— μƒˆλ‘œμš΄ 찜이 일어날 λ•Œλ§ˆλ‹€ ν•΄λ‹Ή μƒν’ˆμ˜ 찜 개수λ₯Ό λ°μ΄ν„°λ² μ΄μŠ€μ— μ €μž₯ν•΄ 두고, 리뷰도 μƒˆλ‘œ μž‘μ„±λ˜κ±°λ‚˜ μˆ˜μ •λ˜μ—ˆμ„ λ•Œλ§Œ 리뷰 평균 점수λ₯Ό κ³„μ‚°ν•΄μ„œ μ €μž₯해두면 μƒν’ˆμ— λŒ€ν•œ 찜과 리뷰 데이터λ₯Ό 맀번 쿼리둜 가져와 μ—°μ‚°ν•  ν•„μš” 없이 μƒν’ˆμ— ν•¨κ»˜ μ €μž₯λ˜μ–΄ μžˆλŠ” 찜 κ°œμˆ˜μ™€ 리뷰 평균 점수λ₯Ό ν‘œμ‹œλ§Œ ν•˜λ©΄ λ©λ‹ˆλ‹€.

μ†Œν”„νŠΈμ›¨μ–΄μ μΈ μ΅œμ ν™” - 5. νŽ˜μ΄μ§€ 캐싱

μ‚¬μš©μžμ—κ²Œ 자주 보이고 변경이 자주 μΌμ–΄λ‚˜μ§€ μ•ŠλŠ” νŽ˜μ΄μ§€λŠ” νŽ˜μ΄μ§€ 캐싱을 ν•˜λ©΄ μ—­μ‹œ 속도가 λͺ‡ λ°° κ°œμ„ λ©λ‹ˆλ‹€. 뭐만 ν•˜λ©΄ 속도가 λͺ‡ λ°° κ°œμ„ λœλ‹€λŠ” 이야기가 ν˜„μ‹€μ„± μ—†κ²Œ 듀릴 μˆ˜λ„ μžˆμ§€λ§Œ μ‹€μ œλ‘œ λΉ„νš¨μœ¨μ μΈ νŽ˜μ΄μ§€λŠ” λ‘œλ”©λ˜λŠ” 데 10μ΄ˆκ°€ λ„˜κ²Œ 걸릴 수 μžˆμ§€λ§Œ μ—¬λŸ¬ κ°€μ§€ μ†Œν”„νŠΈμ›¨μ–΄μ μΈ νŠœλ‹μ„ ν•œ 이후에 0.1초 μ΄ν•˜λ‘œ 응닡속도가 κ°œμ„ λ˜λŠ” 사둀가 ν”ν•©λ‹ˆλ‹€.

νŽ˜μ΄μ§€ 캐싱은 μ›Ή μ„œλ²„ λ˜λŠ” μΊμ‹œ μ„œλ²„ λ‹¨κ³„μ—μ„œ 미리 μ €μž₯ν•΄λ‘” νŽ˜μ΄μ§€λ₯Ό λΈŒλΌμš°μ €λ‚˜ λͺ¨λ°”μΌλ‘œ λ³΄λ‚΄κ²Œ λ˜μ–΄ λ°μ΄ν„°λ² μ΄μŠ€ μΏΌλ¦¬λ‚˜ μ—°μ‚°, μ›Ή ν”„λ ˆμž„μ›Œν¬μ˜ μ—¬λŸ¬ κ°€μ§€ μ²˜λ¦¬λ“€μ„ κ±΄λ„ˆλ›°κ²Œ λ©λ‹ˆλ‹€. 단, νŽ˜μ΄μ§€ 캐싱은 μ‚¬μš©μžλ³„λ‘œ νŽ˜μ΄μ§€λ‚˜ 데이터가 λ‹¬λΌμ§€λŠ” κ°œμΈν™” μ˜μ—­ λ“±μ—λŠ” μ ν•©ν•˜μ§€ μ•Šκ³ , μƒν’ˆ νŽ˜μ΄μ§€λ‚˜ μ½˜ν…μΈ  νŽ˜μ΄μ§€μ²˜λŸΌ λΉˆλ²ˆν•œ μˆ˜μ •μ΄ μ—†κ³  μ ‘μ†λŸ‰μ€ λ§Žμ€ νŽ˜μ΄μ§€μ— μ μš©ν•˜λ©΄ νš¨κ³Όμ μž…λ‹ˆλ‹€.

캐싱은 μ‚¬μš©μžκ°€ λŠ˜μ–΄ μ„œλΉ„μŠ€κ°€ λŠλ €μ§€λŠ” μ‹œμ κΉŒμ§€ μ΅œλŒ€ν•œ λ―Έλ£¨μ—ˆλ‹€κ°€ μ μš©ν•˜λŠ” 것이 λ‚˜μ„ 수 μžˆλŠ”λ°, 일단 캐싱이 λ™μž‘ν•˜λŠ” μƒνƒœμ—μ„œλŠ” 개발과 ν…ŒμŠ€νŠΈκ°€ μ–΄λ €μ›Œμ§‘λ‹ˆλ‹€. 캐싱이 μ μš©λ˜μ–΄ 있으면 μ½”λ“œλ₯Ό μˆ˜μ •ν•œ νŽ˜μ΄μ§€κ°€ μˆ˜μ •λ˜μ§€ μ•Šμ€ 이전 μƒνƒœλ‘œ 보이기 λ•Œλ¬Έμ— ν•œμ°½ 개발 쀑일 λ•ŒλŠ” 캐싱이 개발 및 ν…ŒμŠ€νŠΈ 과정을 λ°©ν•΄ν•˜κ²Œ λ©λ‹ˆλ‹€. 또 캐싱을 μ μš©ν•œ 후에 μ–Έμ œ 캐싱 데이터λ₯Ό κ°±μ‹ ν•΄μ•Ό ν•˜λŠ”μ§€μ— λŒ€ν•œ 만료 및 κ°±μ‹  쑰건 등을 μ„€μ •ν•˜λŠ” 것이 맀우 κΉŒλ‹€λ‘­κΈ° λ•Œλ¬Έμ— 데이터 μˆ˜μ •/λ³€κ²½ 정책이 ν™•μ •λ˜μ—ˆμ„ λ•Œ μ μš©λ˜μ–΄μ•Ό μ•ˆμ „ν•©λ‹ˆλ‹€.

κ·Έ 후에 κ³ λ €ν•˜λŠ” ν•˜λ“œμ›¨μ–΄μ  & 가상 μ»¨ν…Œμ΄λ„ˆμ˜ ν™•μž₯

이와 같은 λ‹€μ–‘ν•œ μ†Œν”„νŠΈμ›¨μ–΄μ μΈ μ„±λŠ₯ κ°œμ„ μ΄ 일차적으둜 μ§„ν–‰λœ 후에, μ„œλ²„μ˜ μŠ€νŽ™μ„ λ†’μ΄κ±°λ‚˜ λ°μ΄ν„°λ² μ΄μŠ€ μ„œλ²„, μ›Ή μ„œλ²„, μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„œλ²„, 에셋 μŠ€ν† λ¦¬μ§€, μΊμ‹œ μ„œλ²„, μ±„νŒ… μ„œλ²„, 큐 μ„œλ²„, CDN μ„œλ²„ λ“±μ˜ μ‹œμŠ€ν…œ λ ˆμ΄μ–΄λ₯Ό λΆ„λ¦¬ν•˜κ³  이λ₯Ό ν•˜λ“œμ›¨μ–΄μ μœΌλ‘œλ„ λΆ„λ¦¬ν•œ λ‹€μŒμ—μ„œμ•Ό μ„œλ²„ λŒ€μˆ˜λ₯Ό λŠ˜λ¦¬λŠ” ν™•μž₯을 ν•˜κ²Œ λ©λ‹ˆλ‹€. λ§ˆμŠ€ν„°/슬레이브둜 λ³΅μ‚¬ν•˜κ³  λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μͺΌκ°œλŠ” λ“±μ˜ 쑰치λ₯Ό μ·¨ν•˜κ³ μš”. μ„œλ²„ λŒ€μˆ˜ 쑰정이 λΉˆλ²ˆν•˜κ²Œ 이루어진닀면 물리 μ„œλ²„λ³΄λ‹€λŠ” ν΄λΌμš°λ“œ μ„œλ²„κ°€ 운용이 νŽΈλ¦¬ν•œ 단계가 λ©λ‹ˆλ‹€. **μ˜€ν† μŠ€μΌ€μΌλ„ 이 λ•Œ κ³ λ €ν•˜κ²Œ λ©λ‹ˆλ‹€. **

ν•˜λ“œμ›¨μ–΄μ μΈ ν™•μž₯을 ν•˜κΈ° 전에 μš°μ„  μ†Œν”„νŠΈμ›¨μ–΄μ μΈ μ΅œμ ν™” λ§ŒμœΌλ‘œλ„ κ½€ λ§Žμ€ νŠΈλž˜ν”½μ„ 감당해낼 수 μžˆμŠ΅λ‹ˆλ‹€. 접속 λΉˆλ„κ°€ νŠΉλ³„νžˆ 높은 μ„œλΉ„μŠ€κ°€ μ•„λ‹ˆλΌλ©΄ 수 만 λͺ…μ˜ νšŒμ›μ€ μ›” 7λ§Œμ› λŒ€μ˜ μ„œλ²„ ν•œ λŒ€λ‘œλ„ μΆ©λΆ„ν•©λ‹ˆλ‹€. μ„œλ²„ λŒ€μˆ˜λ₯Ό λŠ˜λ¦¬κ±°λ‚˜ ν΄λΌμš°λ“œλ‘œ μ΄μ „ν•˜λŠ” νŒλ‹¨μ„ ν•˜κΈ° 전에 μ†Œν”„νŠΈμ›¨μ–΄μ μΈ μ‘°μΉ˜λ“€μ„ λ¨Όμ € μ·¨ν•˜μ‹œκΈ°λ₯Ό κΆŒν•©λ‹ˆλ‹€.

Clone this wiki locally