Design Real-time Game Leaderboard
μꡬμ¬ν
μμ νλ μ΄μ΄μ μμ μ€μκ° μ 곡
νΉμ μ¬μ©μμ μΌμ λ²μμ μμ μ 곡
DAU 500λ§ λͺ , MAU 2,500λ§ λͺ
ν루 νκ· 10 κ²μ νλ μ΄
μμ λ°μμ κ°λ₯ν μ€μκ°μ κ°κΉκ² μ²λ¦¬
μ μꡬ μ¬νμ λ§μ‘±νκΈ° μν΄ λ€μκ³Ό κ°μ κ°λ΅μ μΈ κ·λͺ¨λ₯Ό μΆμ ν μ μλ€.
μ΄λΉ νκ· μ μ : 500λ§ λͺ / 24 / 3600 = 57.87 (24μκ° κ³ λ₯΄κ² λΆν¬λμ΄ μλ€κ³ κ°μ )
μ§ν κ²μ: 57.87 * 10 = 578.7 (ν루 νκ· 10κ²μ νλ μ΄νλ€κ³ κ°μ )
μ¬μ©μ μ μ νλ QPS: 578.7 * 5 = 2,893.5 (νΌν¬ μκ°μ 5λ°°μ νΈλν½μ΄ λ°μνλ€κ³ κ°μ )
μμ μ‘°ν QPS: 57.87 (μ΅μ΄ μ μ μ μ‘°ννλ€κ³ κ°μ )
API λ¨μ κΈ°λ₯ μ μ
POST /scores
: κ²μ νλ μ΄ ν μ μλ₯Ό κΈ°λ‘νλ APIGET /scores
: μμ νλ μ΄μ΄μ μμλ₯Ό μ‘°ννλ APIGET /scores/{user_id}
: νΉμ μ¬μ©μμ μμλ₯Ό μ‘°ννλ API
κ°λ΅μ μ€κ³μ
κ²μ μλΉμ€μ μμν μλΉμ€λ‘ λλμ΄ μλμ κ°μ νλ¦μΌλ‘ μ€κ³ν μ μλ€.
μ¬μ©μκ° κ²μμ νλ μ΄νκ³ μ μλ₯Ό νλ ν κ²μ μλΉμ€μ μμ²
κ²μ μλΉμ€λ μ μκ° μ ν¨νμ§ νμΈ ν μμν μλΉμ€μ μ μ κΈ°λ‘ μμ²
μμν μλΉμ€λ μ μλ₯Ό κΈ°λ‘νκ³ , ν΄λΉ μ¬μ©μμ μμλ₯Ό κ°±μ
μμ κ°±μ μ Redisμ Sorted Setμ μ¬μ©νμ¬ μ μλ₯Ό λ΄λ¦Όμ°¨μμΌλ‘ μ λ ¬
μ¬μ©μλ μ§μμ μΌλ‘ μμν μλΉμ€μ νλ μ΄μ΄μ μμλ₯Ό μ‘°ν
κ²μ μλΉμ€μ μμν μλΉμ€ κ° ν΅μ μλ μν©μ λ°λΌ REST API λλ λ©μμ§ νλ₯Ό μ¬μ©ν μ μλ€.
μ μ₯μ μꡬμ¬ν - Redis Sorted Set μ¬μ©
μμ μ 보λ₯Ό Redisμ Sorted Setμ μ¬μ©νμ¬ μ μ₯νλ€κ³ κ°μ νκ³ , λ€μκ³Ό κ°μ μꡬ μ¬νμ΄ μλ€κ³ κ°μ νμ.
μ¬μ©μ ID - μ μ ννλ‘ μ μ₯
μκ° νμ± μ¬μ©μ 2,500λ§ λͺ λͺ¨λ μμμ ν¬ν¨
ID 24 character λ¬Έμμ΄ / μ μ 16λΉνΈ μ μ = 26λ°μ΄νΈ
26λ°μ΄νΈ * 2,500λ§ λͺ = μ½ 650MB
650MBλ μ€λ²ν€λμ μ λ ¬ μ§ν© ν΄μλ₯Ό κ³ λ €ν΄ λ λ°°λ₯Ό μ¬μ©νλ€κ³ κ°μ νλλΌλ, ν λμ Redis μΈμ€ν΄μ€μ μΆ©λΆν μ μ₯ν μ μμΌλ©°, 2,900 QPSλ ν λμ Redisμμ μ²λ¦¬ν μ μλ λ²μμ΄λ€.
Redis Sorted Set λμ λ°©μ
Redisμ Sorted Setμ ν΄μ ν μ΄λΈκ³Ό μ€ν΅ 리μ€νΈ λ κ°μ§ μλ£κ΅¬μ‘°λ₯Ό μ¬μ©νμ¬ κ΅¬νλλ€.
ν΄μ ν μ΄λΈ: μ¬μ©μμ μ μ μ μ₯
μ€ν΅ 리μ€νΈ: νΉμ μ μλ₯Ό λ΄ μ¬μ©μλ€μ λͺ©λ‘μ μ μ₯
μ΄ μ€ μ€ν΅λ¦¬μ€νΈλ λΉ λ₯Έ κ²μμ κ°λ₯νκ² νλ μλ£ κ΅¬μ‘°λ‘, μ λ ¬λ μ°κ²° 리μ€νΈμ λ€λ¨κ³ μμΈμ λμ΄ κ²μ μλλ₯Ό λμΈλ€.
1 -------------- 15 ---------------- 60
| | |
1 ----- 8 ------ 15 ------ 36 ------ 60
| | | | |
1 - 4 - 8 - 10 - 15 - 26 - 36 - 45 - 60 - 68
μ΄μ§ κ²μ νΈλ¦¬μ²λΌ μ€κ° μ§μ μ λ 빨리 λλ¬ν μ μλλ‘ nμ°¨μ μμΈμ μΆκ°νμ¬, κ²μ μλλ₯Ό O(log n)μΌλ‘ μ€μΌ μ μλ€.
Redis Sorted Set λͺ
λ Ήμ΄
Redis Sorted Setμμ μ¬μ©νκ² λλ λͺ λ Ήμ΄λ, λ€μκ³Ό κ°μ΄ νμ©ν μ μλ€.
ZADD
: κΈ°μ‘΄μ μλ μ¬μ©μλ₯Ό μ§ν©μ μΆκ°νκ±°λ, κΈ°μ‘΄ μ¬μ©μ μ μλ₯Ό κ°±μZINCRBY
: κΈ°μ‘΄ μ¬μ©μ μ μ μ¦κ°ZRANGE
/ZREVRANGE
: νΉμ λ²μμ μλ μ¬μ©μ μ‘°νZRANK
/ZREVRANK
: νΉμ μ¬μ©μμ μμ μ‘°ν
μμΈ μ€κ³
ν΄λΌμ°λ μλΉμ€ μ¬μ©
μ체 μλΉμ€λ₯Ό ꡬμΆνλ κ²½μ°, Redisμ MySQLλ₯Ό μ§μ μ¬μ©νμ¬ κ΅¬νν μ μμ§λ§, ν΄λΌμ°λ μλΉμ€λ₯Ό μ¬μ©νλ€κ³ κ°μ νλ©΄ API Gatewayμ AWS λλ€ κΈ°μ μ μ¬μ©ν΄λ³Ό μ μλ€.
API Gatewayλ₯Ό νΈμΆνκ³ , ν΄λΉ κ²μ΄νΈμ¨μ΄λ μ μ ν AWS λλ€ ν¨μλ₯Ό νΈμΆ
λλ€ ν¨μλ μ€ν λ¦¬μ§ κ³μΈ΅μ λͺ λ Ήμ νΈμΆνμ¬ μ»μ κ²°κ³Όλ₯Ό API Gatewayμ λ°ν
API Gatewayλ λλ€ ν¨μμ μλ΅μ ν΄λΌμ΄μΈνΈμ λ°ν
μ΄λ κ² νλ©΄, μλ² μΈμ€ν΄μ€λ₯Ό λ§λ€μ§ μμλ APIλ₯Ό μ 곡ν μ μμΌλ©°, μλ² κ΄λ¦¬μ λΆλ΄μ μ€μΌ μ μλ€.
λ λμ€ κ·λͺ¨ νμ₯
κΈ°μ‘΄ κ·λͺ¨λ³΄λ€ λ ν° κ·λͺ¨λ‘ νμ₯νκΈ° μν΄μ μ€λ©μ΄ νμνλ°, κ³ μ νν°μ κ³Ό ν΄μ νν°μ λ κ°μ§ λ°©λ²μ΄ μλ€.
κ³ μ νν°μ : μ μ λ²μμ λ°λΌ νν°μ μ λλλ λ°©λ²
0
100μ μ νν°μ A, 101200μ μ νν°μ B λ±ν΄λΉ μ¬μ©μκ° μ΄λ νν°μ μ μνλμ§ μμμΌ ν¨(μ¬μ©μID-μ μλ₯Ό μ μ₯νλ 2μ°¨ μΊμλ₯Ό ν΅ν΄ μ±λ₯μ λμΌ μ μμ)
μ μκ° κ³ λ₯΄κ² λΆν¬λμ΄ μμ΄μΌ κΈ°λνλ μ±λ₯μ λΌ μ μμ
ν΄μ νν°μ : λ λμ€ ν΄λ¬μ€ν°κ° μλμΌλ‘ μ€λ©
κ°κ°μ ν€κ° νΉμ ν ν΄μ μ¬λ‘―μ μνλλ‘ νλ μ€λ© κΈ°λ² μ¬μ©
16,384κ°μ ν΄μ μ¬λ‘―μ΄ μμΌλ©°,
CRC16(key) % 16384
λ‘ ν΄μ μ¬λ‘―μ κ³μ°λ Έλ λ³λ‘ ν΄μ μ¬λ‘― λ²μλ₯Ό ν λΉ(0 - 5500μ λ Έλ A, 5501 - 11000μ λ Έλ B λ±)
ν΄λΉ μ¬λ‘―μ μνλ λ λμ€ λ Έλλ‘ μμ²μ μ λ¬
μ μ λΆν¬κ° κ³ λ₯΄μ§ μμλ μ±λ₯μ μ μ§ν μ μμ
μμ Nλͺ μ μ¬μ©μ μ‘°ν μ, λͺ¨λ λ Έλμ μμ²μ 보λ΄κ³ μλ΅μ ν©μ³μΌ νλ―λ‘ μ±λ₯μ΄ μ νλ μ μμ
μλΉμ€ νΉμ±μ μμ Nλͺ μ μ¬μ©μ μ‘°νκ° λΉλ²νκ² λ°μνκΈ° λλ¬Έμ, κ³ μ νν°μ μ μ¬μ©νλ κ²μ΄ λ μ ν©ν μ μλ€.
μΆκ° κ³ λ €μ¬ν
λ λΉ λ₯Έ μ‘°ν λ° λμ μ μμ νμ
λ λμ€ ν΄μλ₯Ό μ¬μ©νλ©΄ λ¬Έμμ΄ νλμ κ° μμ λμκ΄κ³λ₯Ό μ μ₯νμ¬ νμ©ν μ μλ€.
μμνμ νμν μ¬μ©μ IDμ μ¬μ©μ κ°μ²΄ μ¬μ΄μ λμ κ΄κ³λ₯Ό μ μ₯
λ°μ΄ν°λ² μ΄μ€μ μ§μ νμ§ μκ³ , λΉ λ₯΄κ² μ¬μ©μ μ 보λ₯Ό μ‘°νν μ μμ
λ μ¬μ©μ μ μκ° κ°μ κ²½μ° λκ° λ¨Όμ μ μλ₯Ό νλνλμ§ νλ³νκΈ° μν΄, μ¬μ©μ IDμ μ μ νλ μκ°μ ν¨κ» μ μ₯
λμ μ μμ νλ³μ μν΄ μκ° μ 보λ₯Ό μΆκ°νμ¬, λμΌ μ μμ μ¬μ©μ μ€ λ¨Όμ μ μλ₯Ό νλν μ¬μ©μκ° μμ μμλ₯Ό μ°¨μ§νλλ‘ ν¨
μμ€ν
μ₯μ 볡ꡬ
μμ€ν μ₯μ κ° λ°μνμ λ, λ€μκ³Ό κ°μ 볡ꡬ λ°©λ²μ κ³ λ €ν μ μλ€.
RDB μ€λ μ· / AOF(Append Only File) λ‘κ·Έλ₯Ό μ¬μ©νμ¬ Redis λ°μ΄ν°λ₯Ό 볡ꡬ
MySQLμ μ μ μ¦κ° μ΄λ ₯μ μ μ₯νμ¬, ZADD / ZINCRBY λͺ λ Ήμ΄λ₯Ό μ¬μ©ν΄ μ μλ₯Ό 볡ꡬ
μ°Έκ³ μλ£
Last updated
Was this helpful?