Thuta Learning
System Design
IntermediateProgrammingintermediate

Database Sharding

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • Database Sharding concept ကို နားလည်ရှင်းပြနိုင်ရန်
  • နမူနာ diagram/code ကို ကိုယ်တိုင် လေ့လာပြီး trade-off များကို ခွဲခြမ်းစိတ်ဖြာနိုင်ရန်
  • Tutorial Platform project နှင့် production scenario တွင် မှန်ကန်စွာအသုံးချနိုင်ရန်

နားလည်ထားရမယ့် အချက်

Replication က read capacity ကို တိုးပေးပေမယ့် replica တစ်ခုစီက data ပြည့်တဲ့ copy တစ်ခုစီကို ဆက်ကိုင်ထားရပါတယ် — dataset ဟာ single machine တစ်ခု (write throughput အတွက်ဖြစ်စေ storage အတွက်ဖြစ်စေ) မကိုင်တွယ်နိုင်တော့တဲ့အထိ ကြီးလာရင် replication တစ်ခုတည်းက ကူညီမပေးနိုင်တော့ပါဘူး။ Sharding (horizontal partitioning) ကတော့ logical table တစ်ခုကို 'shard' လို့ခေါ်တဲ့ physical piece များစွာအဖြစ် ခွဲပေးပြီး shard တစ်ခုစီက database instance သီးသန့်တစ်ခုစီပေါ်မှာ နေထိုင်စေကာ shard key တစ်ခု (user ID ကို hash လုပ်တာ ဒါမှမဟုတ် ID range) သုံးပြီး row တစ်ခုစီက ဘယ် shard ပိုင်လဲဆိုတာ ဆုံးဖြတ်ပေးပါတယ်။ ဒါက total storage နဲ့ write throughput ကို shard ထပ်ပေါင်းလိုက်ရုံနဲ့ linearly နီးပါးကြီးထွားလာစေပါတယ်။ အန္တရာယ်ကတော့ shard key မှားရွေးတာပါ — sequential auto-increment ID တွေကို range နဲ့ shard ခွဲရင် write အသစ်အားလုံးက newest shard တစ်ခုတည်းဆီ ရောက်သွားပြီး shard အဟောင်းတွေက အလုပ်မရှိ ငြိမ်နေတတ်ပါတယ်၊ 'country' လို field နဲ့ shard ခွဲရင်တော့ လူကြိုက်များတဲ့ country တစ်ခုပါတဲ့ shard က overload ဖြစ်ပြီး ကျန်တာတွေက almost empty ဖြစ်တတ်ပါတယ် — ဒီနှစ်ခုစလုံးက 'hotspot' ဖြစ်စေပါတယ်၊ sharding လုပ်ခဲ့ရင်းကို ရှောင်ချင်တဲ့ bottleneck ပုံစံကို shard တစ်ခုတည်းက ပြန်ဖန်တီးလိုက်တာပါပဲ။

လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်

Tutorial Platform မှာ learner သန်းချီရောက်လာတဲ့အခါ enrollments နဲ့ activity table တွေက replica ရှိတောင် leader တစ်ခုတည်းက ကိုင်တွယ်နိုင်တာထက် ကြီးလာပါတယ်။ Team က hash(user_id) နဲ့ database instance အများစုကို shard ခွဲပါတယ် — ဒါက user တွေကို almost evenly ခွဲပေးလိုက်တဲ့အတွက် shard ဘယ်ဟာမှ overload မဖြစ်ပါဘူး။ အစပိုင်းမှာ တစ်ယောက်က course_id နဲ့ shard ခွဲကြည့်ဖို့ တင်ပြခဲ့ဖူးပါတယ် (course data က ခွဲရလွယ်ကူပုံရလို့) — ဒါပေမဲ့ learner သန်းချီက popular course အနည်းငယ် (ဥပမာ Python intro course) ထဲကို စုပြားလာရင် popular course ရဲ့ shard တွေမှာ hotspot ပြင်းထန်စွာ ဖြစ်ပြီး niche course shard တွေက almost idle ဖြစ်နေမှာဖြစ်ပါတယ်။

အတူတူ စမ်းရေးကြည့်မယ်

text
BEFORE (one giant table)              AFTER (sharded by hash(user_id) % 3)
+----------------------+               +---------+ +---------+ +---------+
| enrollments (100M)   |               | Shard 0 | | Shard 1 | | Shard 2 |
| all on ONE machine   |   ------>     | ~33M    | | ~33M    | | ~33M    |
+----------------------+               | rows    | | rows    | | rows    |
     write bottleneck                  +---------+ +---------+ +---------+
     storage ceiling                    evenly spread, no bottleneck

BAD SHARD KEY EXAMPLE (by country):
+---------+ +---------+ +---------+
| Shard 0 | | Shard 1 | | Shard 2 |
| "US"    | | "MM"    | | "NZ"    |
| 60M rows| | 35M rows| | 5M rows |  <- HOTSPOT on Shard 0
+---------+ +---------+ +---------+     (overloaded, others idle)
You should see
hash(user_id) လို shard key က data ကို ညီညာစွာ ခွဲပေးနိုင်ပေမယ့် country လို skewed key ကတော့ shard တစ်ခုကို hotspot ဖြစ်စေတယ်ဆိုတာ ပြသပါတယ်။

၅ မိနစ် စမ်းကြည့်

Tutorial Platform ရဲ့ 'quiz_attempts' table ကို shard ခွဲမယ်ဆိုပါစို့။ shard key အဖြစ် (a) auto-increment attempt_id, (b) hash(user_id) နှစ်မျိုးကို compare လုပ်ပြီး ဘယ်ဟာက hotspot ဖြစ်နိုင်ခြေပိုများသလဲ ရှင်းပြပါ။

သတိလေးတစ်ချက်

Auto-increment sequential ID ကို range shard key အဖြစ် သုံးလိုက်ရင် write အသစ်တိုင်းက newest shard တစ်ခုတည်းဆီပဲ ရောက်ပြီး ကျန် shard တွေက idle ဖြစ်နေတတ်ပါတယ်။

Shard key ရွေးတဲ့အခါ real-world data distribution (popular value တစ်ခုက data ရဲ့ ရာခိုင်နှုန်းများစွာယူထားနိုင်တာ) ကို မထည့်စဉ်းစားဘဲ 'logically clean' ဖြစ်တဲ့ field ကိုပဲ ကြည့်ရွေးတတ်ပါတယ်။

Wikipedia — Shard (database architecture)System Design

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • Auto-increment sequential ID ကို range shard key အဖြစ် သုံးလိုက်ရင် write အသစ်တိုင်းက newest shard တစ်ခုတည်းဆီပဲ ရောက်ပြီး ကျန် shard တွေက idle ဖြစ်နေတတ်ပါတယ်။
  • Shard key ရွေးတဲ့အခါ real-world data distribution (popular value တစ်ခုက data ရဲ့ ရာခိုင်နှုန်းများစွာယူထားနိုင်တာ) ကို မထည့်စဉ်းစားဘဲ 'logically clean' ဖြစ်တဲ့ field ကိုပဲ ကြည့်ရွေးတတ်ပါတယ်။
  • Design decision တစ်ခုကို production system ပေါ် တိုက်ရိုက်မကျင့်သုံးမီ load/traffic assumption များကို အရင်အတည်ပြုပါ။

လေ့ကျင့်ခန်း

Tutorial Platform ရဲ့ 'quiz_attempts' table ကို shard ခွဲမယ်ဆိုပါစို့။ shard key အဖြစ် (a) auto-increment attempt_id, (b) hash(user_id) နှစ်မျိုးကို compare လုပ်ပြီး ဘယ်ဟာက hotspot ဖြစ်နိုင်ခြေပိုများသလဲ ရှင်းပြပါ။

You'll know it worked when: hash(user_id) လို shard key က data ကို ညီညာစွာ ခွဲပေးနိုင်ပေမယ့် country လို skewed key ကတော့ shard တစ်ခုကို hotspot ဖြစ်စေတယ်ဆိုတာ ပြသပါတယ်။

Database Sharding | Thuta Learning