λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

개발

μ•ˆμ • ν•΄μ‹œ 섀계

'가상 λ©΄μ ‘ μ‚¬λ‘€λ‘œ λ°°μš°λŠ” λŒ€κ·œλͺ¨ μ‹œμŠ€ν…œ μ„€κ³„ κΈ°μ΄ˆ' μ±…을 λ³΄λ©΄μ„œ '5μž₯ μ•ˆμ • ν•΄μ‹œ μ„€κ³„' λ‹¨μ›μ„ μ½μ–΄λ³΄μ•˜λŠ”λ°, μž˜ μ΄ν•΄κ°€ κ°€μ§€ μ•Šμ•„μ„œ λ‹€μ‹œ ν•œλ²ˆ μ •λ¦¬ν•΄λ³΄κ³ μž ν•œλ‹€.

일단, ν•΄λ‹Ή λ‹¨μ›의 ν•΄μ‹œ κΈ°μˆ μ€ API μ„œλ²„κ°€ μ•„λ‹Œ λ°μ΄ν„°λ² μ΄μŠ€λ‚˜ μΊμ‹œ μ„œλ²„와 κ°™μ€ λ°μ΄ν„° μ €μž₯μ†Œ μ‹œμŠ€ν…œμ— μ‚¬μš©λ˜λŠ” κ²ƒμ΄λ‹€. μ™œλƒν•˜λ©΄ API μ„œλ²„λŠ” κΈ°λ³Έμ μœΌλ‘œ Stateless이기에 μš”μ²­ μ²˜λ¦¬λ₯Ό μœ„ν•΄ κΌ­ κ°™μ€ μ„œλ²„μ—κ²Œ μš”청을 λ³΄λ‚΄μ•Ό ν•˜λŠ” κ²ƒλ„ μ•„λ‹ˆλ©°, μ„œλ²„λ₯Ό μΆ”κ°€ λ° μ œκ±° ν•œλ‹€κ³  ν•΄μ„œ λ¬Έμ œκ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€. κ·Έλ¦¬κ³  μ΄λŸ° API μ„œλ²„에 λŒ€ν•œ λΆ€ν•˜ λΆ„산은 λ‘œλ“œ λ°ΈλŸ°μ„œκ°€ λ”°λ‘œ ν•˜κΈ° λ•Œλ¬Έμ— κ΄€κ³„μ—†λ‹€!

μ•ˆμ • ν•΄μ‹œμ˜ λͺ©μ μ€ κΈ°μ‘΄ ν•΄μ‹œλ₯Ό ν†΅ν•œ λ°μ΄ν„°μ €μž₯μ†Œ λΆ„μ‚° λ°©μ‹μ˜ λ‹¨μ μ„ ν•΄μ†Œν•˜κΈ° μœ„함이닀.
κΈ°μ‘΄ ν•΄μ‹œ λ°©λ²•은 μ„œλ²„μ˜ μ •보λ₯Ό λ°°μ—΄ κ°™μ€ μžλ£Œκ΅¬μ‘°μ— λ‹΄μ•„두고, ν‚€ κ°’을 ν•΄μ‹œν•˜μ—¬ λ‚˜μ˜¨ κ°’을 `% μ„œλ²„μ˜ μˆ˜` μ—°μ‚°μ„ ν†΅ν•΄ μΈλ±μŠ€λ‘œ μ ‘κ·Όν•œλ‹€. ν•˜μ§€λ§Œ μ—¬κΈ°μ„œ μ„œλ²„κ°€ μΆ”κ°€λ˜κ±°λ‚˜, μ‘΄μž¬ν•˜λ˜ μ„œλ²„ μ€‘ ν•˜λ‚˜κ°€ μž₯μ• κ°€ λ°œμƒν–ˆμ„ λ•Œ λ¬Έμ œκ°€ μƒκΈΈ μˆ˜ μžˆλ‹€.

예λ₯Ό λ“€μ–΄, key1의 ν•΄μ‹œ κ°’이 7 μΌ λ•Œ, μ„œλ²„κ°€ 3개 μ‘΄μž¬ν–ˆλ‹€λ©΄ 3으둜 λ‚˜λˆˆ λ‚˜λ¨Έμ§€λŠ” 1이닀. μ—¬κΈ°μ„œ μ„œλ²„κ°€ μΆ”κ°€λœλ‹€λ©΄ 4둜 λ‚˜λˆ„κ²Œ λ˜λŠ”λ°, μ΄λŸ¬λ©΄ λ‚˜λ¨Έμ§€κ°€ 1이 μ•„λ‹Œ 3이 λœλ‹€. λ§Œμ•½ μΊμ‹œ μ„œλ²„라면 μΊμ‹œ λ―ΈμŠ€κ°€ λ‚˜κ²Œ λ˜λŠ” μƒν™©μ΄κ³ , λ°μ΄ν„°λ² μ΄μŠ€ μƒ€λ”©μ΄μ—ˆλ‹€λ©΄ ν•„μš”ν•œ λ°μ΄ν„°κ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” λ°μ΄ν„°λ² μ΄μŠ€μ— μ ‘κ·Όν•˜κ²Œ λ˜λŠ” μƒν™©μ΄ λ°œμƒν•œλ‹€. 

이 뿐만 μ•„λ‹ˆλΌ κΈ°μ‘΄ 3개의 μ„œλ²„ 쀑 1개의 μ„œλ²„κ°€ μ£½μ—ˆλ‹€λ©΄, `% 2`κ°€ λ˜μ–΄ 킀듀이 λͺ¨λ‘ μž¬λΆ„λ°° λ˜μ–΄μ„œ μš”μ²­μ΄ κ· λ“±ν•˜κ²Œ λΆ„ν¬λ˜μ§€ μ•ŠλŠ” κ²½μš°κ°€ λ°œμƒν•  μˆ˜λ„ μžˆλ‹€. 이렇듯 κΈ°μ‘΄ ν•΄μ‹œλŠ” μœ„μ˜ 두 단점이 μžˆμ—ˆκΈ° λ•Œλ¬Έμ— 이λ₯Ό ν•΄μ†Œν•˜κΈ° μœ„ν•΄ 'μ•ˆμ • ν•΄μ‹œ' 기술이 λ‚˜μ˜€κ²Œ 된 것이닀.

μ•ˆμ • ν•΄μ‹œμ˜ λ™μž‘ 방식은 ν•΄μ‹œ ν•¨μˆ˜μ˜ 좜λ ₯κ°’ λ²”μœ„λ₯Ό μ˜λ―Έν•˜λŠ” ν•΄μ‹œ 곡간을 논리적인 μ›ν˜• 링 ν˜•νƒœλ‘œ λ§Œλ“œλŠ” κ²ƒμœΌλ‘œ μ‹œμž‘ν•œλ‹€. 이제 μ„œλ²„λŠ” 인덱슀 방식이 μ•„λ‹Œ ν•΄μ‹œ κ³΅κ°„μ—μ„œ νŠΉμ • μ’Œν‘œλ₯Ό κ°–κ²Œ 되고, ν‚€ 값도 λ™μΌν•˜κ²Œ νŠΉμ • μ’Œν‘œλ₯Ό κ°–κ²Œ λœλ‹€. μ—¬κΈ°μ„œ κ°–λŠ”λ‹€ν•¨μ€ μ‹€μ œλ‘œ 이 값을 λ³΄μœ ν•˜λŠ” 것이 μ•„λ‹ˆλΌ ν•΄μ‹œ κ³΅κ°„μ˜ νŠΉμ • μ’Œν‘œμ— μ‘΄μž¬ν•¨μ„ μ˜λ―Έν•œλ‹€. μ„œλ²„κ°€ ν•΄μ‹œ κ³΅κ°„μ˜ μ’Œν‘œλ₯Ό κ°–λŠ” μ½”λ“œλ₯Ό λ‚˜νƒ€λ‚΄λ©΄ μ•„λž˜μ™€ 같을 것이닀.

TreeMap<Long, Server> hashRing = new TreeMap<>();
hashRing(hash(server1.ip), server1);
hashRing(hash(server2.ip), server2);
hashRing(hash(server3.ip), server3);



그러면 이제 μš”μ²­ μ‹œ ν•΄μ‹œ ν•¨μˆ˜μ˜ 결과둜 λ‚˜μ˜¨ 값을 κΈ°μ€€μœΌλ‘œ μ‹œκ³„ λ°©ν–₯으둜 λŒλ©΄μ„œ κ°€μž₯ κ°€κΉŒμš΄ μ„œλ²„ λ…Έλ“œλ₯Ό μ°ΎλŠ”λ‹€. μ°Ύμ•˜λ‹€λ©΄, ν•΄λ‹Ή μ„œλ²„λ‘œ ν•΄λ‹Ή 킀에 λŒ€ν•œ μš”μ²­μ„ λ³΄λ‚΄λŠ” 것이닀.


그림으둜 λ‚˜νƒ€λ‚΄λ©΄ μœ„와 κ°™μ€λ°, μ‹€μ œλ‘œ μ €μž₯된 κ²ƒμ€ μ„œλ²„ λΏμ΄κ³  ν‚€ κ°’은 μ‹€μ œλ‘œ ν•΄μ‹œ κ³΅κ°„에 μ €μž₯λ˜μ§„ μ•ŠλŠ”λ‹€. κ·Έλƒ₯ λ…Όλ¦¬μ μœΌλ‘œ λ‚˜νƒ€λ‚Έ κ²ƒμΌ λΏ

μ΄λ ‡κ²Œ λ˜λ©΄ μ„œλ²„κ°€ ν•΄μ‹œ κ³΅κ°„에 κ³ λ₯΄κ²Œ λΆ„ν¬λ˜μ–΄ μžˆμ–΄ ν‚€ κ°’은 λ” μ΄μƒ μ–΄λА ν•œ μ„œλ²„λ‘œ λͺ°λ¦¬μ§€ μ•Šμ„ κ²ƒμ΄λ‹€. κ·Έλ¦¬κ³ , ν•˜λ‚˜μ˜ μ„œλ²„κ°€ μ‚¬λΌμ§€κ±°λ‚˜ μΆ”κ°€λ˜μ–΄λ„ μ˜ν–₯을 λ°›λŠ” ν‚€ κ°’μ˜ μˆ˜κ°€ μ μ–΄μ§„λ‹€!

ν•˜μ§€λ§Œ ν‚€ κ°’κ³Ό μ„œλ²„μ˜ ν•΄μ‹œ κ°’이 κ°™μœΌλ©΄ μ–΄λ–»κ²Œ λ κΉŒ? ν‚€λ₯Ό μ €μž₯ν•˜μ§„ μ•Šκ³  λΉ„κ΅ν•˜κΈ°λ§Œ ν•˜λ‹ˆ μ‚¬μ‹€ λ¬Έμ œκ°€ μ—†λ‹€. λ‹¨μ§€, κ°™μ€ κ°’μ˜ μ„œλ²„λ₯Ό ν†΅ν•΄ μš”μ²­ν• μ§€, κ°™μ€ κ°’ λ‹€μŒμ˜ κ°€κΉŒμš΄ μ„œλ²„λ₯Ό ν†΅ν•΄ μš”청할지에 λŒ€ν•œ μ „λž΅ μ°¨μ΄μΌ λΏμ΄λ‹€. μ½”λ“œλ‘œ λ³Έλ‹€λ©΄ μ•„λž˜μ™€ κ°™μ„ κ²ƒμ΄λ‹€.

TreeMap<Long, Server> ring = new TreeMap<>();
ring.put(hash(server1.ip), server1);
ring.put(hash(server2.ip), server2);
ring.put(hash(server3.ip), server3);

long keyPosition = hash(key);
Server server = ring.ceilingEntry(keyPosition).getValue();



그럼 μ΄λŸ° μ•ˆμ • ν•΄μ‹œλŠ” λ‹¨μ μ΄ μ—†μ„κΉŒ? κ·Έκ±΄ λ˜ μ•„λ‹ˆλ‹€. μœ„μ˜ μ˜ˆμ‹œμ—λŠ” μ„œλ²„μ˜ ν•΄μ‹œ κ°’이 κ³ λ₯΄κ²Œ λΆ„ν¬λœλ‹€λŠ” κ°€μ •ν•˜μ— ν•œ κ²ƒμ΄λΌ κ·Έλ ‡μ§€λ§Œ μ„œλ²„끼리 μ„œλ‘œ κ°€κΉκ²Œ ν•΄μ‹œ κ°’이 μ΄λ€„μ§€λ©΄ μ΄λŸ° μ•ˆμ • ν•΄μ‹œμ˜ μž₯점을 λˆ„릴 μˆ˜ μ—†κ²Œλœλ‹€.

κ·Έλž˜μ„œ κ°€μƒ λ…Έλ“œλ₯Ό ν™œμš©ν•˜λŠ”λ°, μ΄ κ°€μƒ λ…Έλ“œλ“€μ€ μ‹€μ œ λ…Έλ“œ λ˜λŠ” μ„œλ²„듀을 κ°€λ₯΄ν‚€λŠ” λ…Έλ“œμ΄λ‹€. κ°€μƒ λ…Έλ“œλ“€μ„ μ—¬λŸ¬ κ°œ λ°°μΉ˜ν•˜μ—¬ λ‹¨μ μ„ ν•΄μ†Œν•  μˆ˜ μžˆλ‹€. κ·Έλ¦ΌμœΌλ‘œ λ³Έλ‹€λ©΄ λ‹€μŒκ³Ό κ°™λ‹€.


ν•˜μ§€λ§Œ κ°€μƒ λ…Έλ“œλ₯Ό λ§Žμ΄ λ§Œλ“€κ²Œ λ˜λ©΄ κ·Έλ§ŒνΌ λ©”λͺ¨λ¦¬ κ³΅κ°„을 λ§Žμ΄ μ‚¬μš©ν•˜κ²Œ λ˜λ‹ˆ μ μ ˆν•œ νŠΈλ ˆμ΄λ“œ μ˜€ν”„κ°€ ν•„μš”ν•œ λ²•이닀.