محسن میرزانیا
محسن میرزانیا
خواندن ۵ دقیقه·۵ سال پیش

برنامه‌های "cloud-native" - قسمت پنجم Sharding

الگوی Sharding در پایگاه داده

یکی از راهکارهای scaling افقی اطلاعات در پایگاه‌های داده، استفاده از sharding است. sharding به زبان ساده یعنی اطلاعات را در چند پایگاه‌داده (یا shard) تقسیم و ذخیره کنیم. هر کدام از این پایگاه‌های داده دارای schema مشابه با یکدیگر هستند؛ و معمولا داده‌ها به نحوی توزیع می‌شوند که هر کدام از rowها تنها در یک shard حضور داشته باشند. در واقع تجمیع rowها در تمام shardها، تشکیل یک پایگاه‌داده‌ی منطقی را خواهد داد.

چرا از sharding استفاده می‌شود؟

رخدادهای زیر می‌توانند منجر به زمان پاسخگویی طولانی و کند شدن برنامه شوند:

  • حجم کوئری‌هایی که اپلیکیشن برای پایگاه‌داده ارسال می‌کند، از توان پاسخگویی یک نود پایگاه‌داده فراتر می‌رود.
  • حجم آپدیت‌هایی که اپلیکیشن برای پایگاه‌داده ارسال می‌کند،‌ از توان انجام تراکنش‌های یک نود پایگاه‌داده فراتر می‌رود.
  • پهنای‌باند شبکه‌ی مورد نیاز اپلیکیشن در ارتباط با پایگاه‌داده، از پهنای‌باند موجود در یک نود پایگاه‌داده فراتر می‌رود، و منجر به timeout خواهد شد.
  • نیازمندی‌های فضای ذخیره‌سازی اطلاعات اپلیکیشن، از ظرفیت ذخیره‌سازی یک نود پایگاه‌داده فراتر می‌رود.

عمل sharding را در دو لایه می‌توان پیاده‌سازی کرد:

  • در پایگاه‌داده، که مستلزم این است که پایگاه‌داده این قابلیت را به صورت ذاتی ارائه کند، برای مثال mongoDB.
  • در لایه‌ی اپلیکیشن. پایگاه‌داده درگیر نیست و پیاده‌سازی پیچیده‌تر خواهد شد.

در این پست منظور ما از sharding در لایه‌ی پایگاه‌داده است.

پیاده‌سازی

پایگاه‌داده‌های سنتی تنها روی یک نود اجرا می‌شدند. هر پایگاه‌داده‌ای که روی یک نود اجرا شود، محدود به ظرفیت آن نود است. این ظرفیت محدود در محیط‌های ابری می‌تواند بدتر هم باشد؛ زیرا، پایگاه‌داده احتمالا روی یک سخت‌افزار عادی و “multitenant” اجرا می‌شود. بنابراین باید راهی پیدا کرد که تنها محدود به ظرفیت یک نود نبود. در این بین می‌توان به چندین راهکار اشاره کرد:

  • پخش کردن بار پاسخ دادن به کوئری‌ها با استفاده از نودهای slave. از نودهای slave که replicaهای نود master هستند، فقط برای پاسخ‌دادن به کوئری‌ها می‌توان استفاده کرد، و نه عملیات write یا update. این نودها معمولا read-only هستند و از مدل “eventually consistent” پیروی می‌کنند.
  • ذخیره‌ کردن داده‌های مختلف در چند پایگاه‌داده.
  • روش scale کردن عمودی پایگاه‌داده.

اما مدل sharding یک راهکار scaling افقی است، که با پخش کردن اطلاعات بین چند پایگاه‌داده، بر محدودیت‌های ظرفیتی یک نود واحد غلبه می‌کند. بنابراین، به صورت خلاصه می‌توان گفت که هر پایگاه‌داده تنها بخشی از اطلاعات را که به آن شارد گفته می‌شود ذخیره می‌کند، به طوری که تجمیع تمام شاردها تشکیل یک پایگاه‌داده‌ی منطقیِ کامل را خواهد داد، و اپلیکیشن تنها یک پایگاه‌داده و یک “connection string” یکتا را خواهد دید.

البته، می‌توان برای هر کدام از شاردها یک replica نیز در نظر گرفت، تا قابلیت اعتماد را بالا ببریم. به این ترتیب، اگر نود اصلی (primary) به هر دلیلی پایین برود، نود replica یا secondary به عنوان نود اصلی جایگزین خواهد شد. برای مثال، شکل زیر ترکیب عمل sharding و replication را در mongoDB نشان می‌دهد:

شناسایی شاردها

در پایگاه‌داده یک ستون shard key باید وجود داشته باشد، که مشخص کند که کدام نود مسئول ذخیره‌سازیِ یک سطر از جدول است. بنابرای برای دسترسی به داده‌ها به این shard key نیاز است.

به عنوان یک مثال ابتدایی این مورد را در نظر بگیرید: ستون نام کاربری به عنوان shard key خواهد بود، و حرف اول نام کاربری برای شناسایی شارد. هر نامی که با A-J شروع شود، در شارد اول، و هر نامی که با K-Z شروع شود در شارد دوم ذخیره خواهد شد. هنگامی یک کاربر بخواهد لاگین کند، به راحتی می‌توان متوجه شد که اطلاعاتش در کدام شارد وجود دارد!

اگر از sharding به این دلیل استفاده می‌کنیم که تمام اطلاعاتمان در یک نود جا نمی‌شود، باید داده‌ها را به گونه‌ای تقسیم کرد که هر شارد اندازه‌ی یکسانی داشته باشد. ولی اگر از sharding بنا به دلایل کارایی استفاده می‌کنیم، باید داده‌ها را به گونه‌ای در شاردها تقسیم کنیم که روی هر نود بار کوئری یکسانی بیافتد.

چه زمانی از sharding استفاده نکنیم؟

بعضی از جدول‌ها بهتر است به جای sharding از replication استفاده کنند. این جدول‌ها معمولا حاوی reference data و read-only هستند. برای مثال لیست zip codes. اپلیکیشن از این داده‌ها برای به دست آوردن نام‌ شهر از zip code استفاده خواهد کرد. باقی جدول‌ها معمولا شارد خواهند شد، و بر خلاف اطلاعات reference data، هر سطر جدول تنها در یک نود ذخیره خواهد شد. reference data معمولا از داده‌ی اصلی حجم خیلی کمتری دارد، و خیلی کم تغییر می‌کند.

نتیجه‌گیری

هنگامی که از الگوی sharding استفاده می‌کنیم، بارِ ذخیره‌سازی اطلاعات در چندین پایگاه‌داده تقسیم می‌شود. این امر کمک می‌کند بتوانیم بر محدودیت‌های یک نود غلبه کنیم. از جمله‌ی این محدودیت‌ها می‌توان به ظرفیت ذخیره‌سازی، توانایی پاسخگویی به کوئری‌ها، و انجام تراکنش‌ها اشاره کرد.

shardingmongodbreplicationdatabase
شاید از این پست‌ها خوشتان بیاید