یکی از راهکارهای scaling افقی اطلاعات در پایگاههای داده، استفاده از sharding است. sharding به زبان ساده یعنی اطلاعات را در چند پایگاهداده (یا shard) تقسیم و ذخیره کنیم. هر کدام از این پایگاههای داده دارای schema مشابه با یکدیگر هستند؛ و معمولا دادهها به نحوی توزیع میشوند که هر کدام از rowها تنها در یک shard حضور داشته باشند. در واقع تجمیع rowها در تمام shardها، تشکیل یک پایگاهدادهی منطقی را خواهد داد.
رخدادهای زیر میتوانند منجر به زمان پاسخگویی طولانی و کند شدن برنامه شوند:
عمل sharding را در دو لایه میتوان پیادهسازی کرد:
در این پست منظور ما از sharding در لایهی پایگاهداده است.
پایگاهدادههای سنتی تنها روی یک نود اجرا میشدند. هر پایگاهدادهای که روی یک نود اجرا شود، محدود به ظرفیت آن نود است. این ظرفیت محدود در محیطهای ابری میتواند بدتر هم باشد؛ زیرا، پایگاهداده احتمالا روی یک سختافزار عادی و “multitenant” اجرا میشود. بنابراین باید راهی پیدا کرد که تنها محدود به ظرفیت یک نود نبود. در این بین میتوان به چندین راهکار اشاره کرد:
اما مدل sharding یک راهکار scaling افقی است، که با پخش کردن اطلاعات بین چند پایگاهداده، بر محدودیتهای ظرفیتی یک نود واحد غلبه میکند. بنابراین، به صورت خلاصه میتوان گفت که هر پایگاهداده تنها بخشی از اطلاعات را که به آن شارد گفته میشود ذخیره میکند، به طوری که تجمیع تمام شاردها تشکیل یک پایگاهدادهی منطقیِ کامل را خواهد داد، و اپلیکیشن تنها یک پایگاهداده و یک “connection string” یکتا را خواهد دید.
البته، میتوان برای هر کدام از شاردها یک replica نیز در نظر گرفت، تا قابلیت اعتماد را بالا ببریم. به این ترتیب، اگر نود اصلی (primary) به هر دلیلی پایین برود، نود replica یا secondary به عنوان نود اصلی جایگزین خواهد شد. برای مثال، شکل زیر ترکیب عمل sharding و replication را در mongoDB نشان میدهد:
در پایگاهداده یک ستون shard key باید وجود داشته باشد، که مشخص کند که کدام نود مسئول ذخیرهسازیِ یک سطر از جدول است. بنابرای برای دسترسی به دادهها به این shard key نیاز است.
به عنوان یک مثال ابتدایی این مورد را در نظر بگیرید: ستون نام کاربری به عنوان shard key خواهد بود، و حرف اول نام کاربری برای شناسایی شارد. هر نامی که با A-J شروع شود، در شارد اول، و هر نامی که با K-Z شروع شود در شارد دوم ذخیره خواهد شد. هنگامی یک کاربر بخواهد لاگین کند، به راحتی میتوان متوجه شد که اطلاعاتش در کدام شارد وجود دارد!
اگر از sharding به این دلیل استفاده میکنیم که تمام اطلاعاتمان در یک نود جا نمیشود، باید دادهها را به گونهای تقسیم کرد که هر شارد اندازهی یکسانی داشته باشد. ولی اگر از sharding بنا به دلایل کارایی استفاده میکنیم، باید دادهها را به گونهای در شاردها تقسیم کنیم که روی هر نود بار کوئری یکسانی بیافتد.
بعضی از جدولها بهتر است به جای sharding از replication استفاده کنند. این جدولها معمولا حاوی reference data و read-only هستند. برای مثال لیست zip codes. اپلیکیشن از این دادهها برای به دست آوردن نام شهر از zip code استفاده خواهد کرد. باقی جدولها معمولا شارد خواهند شد، و بر خلاف اطلاعات reference data، هر سطر جدول تنها در یک نود ذخیره خواهد شد. reference data معمولا از دادهی اصلی حجم خیلی کمتری دارد، و خیلی کم تغییر میکند.
هنگامی که از الگوی sharding استفاده میکنیم، بارِ ذخیرهسازی اطلاعات در چندین پایگاهداده تقسیم میشود. این امر کمک میکند بتوانیم بر محدودیتهای یک نود غلبه کنیم. از جملهی این محدودیتها میتوان به ظرفیت ذخیرهسازی، توانایی پاسخگویی به کوئریها، و انجام تراکنشها اشاره کرد.