خب سلام دوباره در ادامه مجموعه پست های دیتابیس تو این یکی قراره با معماری Vitess اشنا بشیم و متوجه بشیم یوتوب چگونه 2.49 میلیارد کاربر خودش رو با MySQL هندل میکنه.
توجه این پست بر اساس تحقیق هستش و ممکنه با پیادهسازی واقعی فرق داشته باشه.
روزی روزگاری، سه نفر که تو PayPal کار میکردن، تصمیم گرفتن یه سایت دوستیابی درست کنن. اما مدل کسبوکارشون شکست خورد. برای همین ایدهشون رو عوض کردن و یه سایت اشتراکگذاری ویدئو درست کردن و اسمش رو گذاشتن یوتیوب.
اونا عناوین ویدئوها، توضیحات و اطلاعات کاربران رو تو MySQL ذخیره کردن. وقتی کاربرهای بیشتری به سایت پیوستن، اونا MySQL رو به حالت رهبر-دنبالکننده (leader-follower replication topology) تنظیم کردن تا بتونن بهتر مقیاسپذیری کنن. اما تکرار در MySQL تکنخی (single-threaded) است. بنابراین دنبالکنندهها نمیتونستن در عملیات نوشتن شدید به رهبر برسند و دادههای جدید رو بهروز کنن. با این حال، نرخ رشدشون خیلی زیاد بود و به یک میلیارد کاربر رسیدن و به دومین سایت پربازدید در جهان تبدیل شدن.
بنابراین با اضافه کردن یه حافظه نهان (cache) مقیاسپذیری کردن و همه رویدادها رو از لاگ باینری MySQL (binary log) بارگذاری کردن. این یعنی تکرار به حافظه وابسته شد و سرعت بیشتری پیدا کرد. اگرچه این کار به طور موقت مشکل مقیاسپذیری اونا رو حل کرد، مشکلات جدیدی به وجود اومد.
در اینجا به برخی از اونا اشاره میکنم:
1. پارتیشنبندی (Sharding):
اولین کاری که باید کرد این که MySQL باید پارتیشنبندی بشه تا نیازهای ذخیرهسازی رو مدیریت کنه. اما بعد از پارتیشنبندی، معاملات (transactions) و پیوستن جداول (joins) سخت میشه. بنابراین منطق برنامه (application logic) باید این رو مدیریت کنه. این یعنی منطق برنامه باید بفهمه که کدوم پارتیشنها رو باید پرسوجو کنه و این باعث افزایش احتمال زمان خرابی (downtime) میشه.
2. عملکرد (Performance):
و(leader-follower replication topology) باعث میشه که دادههای قدیمی از دنبالکنندهها خونده بشه. بنابراین منطق برنامه باید خوندن دادهها رو به رهبر هدایت کنه اگر دادههای جدید لازم باشه. و این نیاز به پیادهسازی منطق اضافی داره.
3. حفاظت (Protection):
ریسک اینکه برخی پرسوجوها خیلی طول بکشه تا دادهها رو برگردونن وجود داره. همچنین تعداد زیادی از اتصالات MySQL به طور همزمان میتونه مشکلساز بشه و ممکنه دیتابیس رو از کار بندازه.
اونا میخواستن یه لایه انتزاعی روی MySQL برای سادگی و مقیاسپذیری ایجاد کنند. بنابراین Vitess رو ساختن. در اینجا نحوه ارائه مقیاسپذیری بالا توسط Vitess رو توضیح میدم:
1. تعامل با پایگاه داده:(Interacting with Database)
اونا یه سرور جانبی (sidecar server) جلو هر نمونه MySQL نصب کردن و اسمش رو گذاشتند VTTablet.
این سرور جانبی به اونا اجازه میداد:
- کنترل سرور MySQL و مدیریت پشتیبانگیری از پایگاه داده
- بازنویسی کوئریهای سنگین با اضافه کردن محدودیت (limit clause)
- کش کردن دادههای پر دسترس برای جلوگیری از مشکل Thundering Herd
2. مسیریابی کوئریها(Routing SQL Queries):
یه سرور پراکسی بدون حالت (stateless proxy server) برای مسیریابی کوئریها تنظیم کردند و اسمش رو گذاشتند VTGate.
این سرور پراکسی بهشون اجازه میداد:
- پیدا کردن VTTablet صحیح برای مسیریابی کوئری بر اساس اسکیما و طرح پارتیشنبندی
- پایین نگه داشتن تعداد اتصالات MySQL از طریق تجمیع اتصالات (connection pooling)
- صحبت با لایه کاربردی به پروتکل MySQL
- عمل کردن مانند یه سرور MySQL یکپارچه برای سادگی
- محدود کردن تعداد معاملات در یک زمان برای عملکرد بهتر
همچنین برای مقیاسپذیری بیشتر، سرورهای VTGate متعددی راهاندازی کردند.
3. اطلاعات حالت:
تصویر چهارم در کامنت ها
یه پایگاه داده توزیعشده کلید-مقدار (distributed key-value database) راهاندازی کردند تا اطلاعات مربوط به اسکیما، طرحهای پارتیشنبندی و نقشها رو ذخیره کنه.
این پایگاه داده همچنین روابط بین پایگاههای داده مثل رهبر و دنبالکنندهها رو مدیریت میکنه.
در ادمه از Zookeeper برای پیادهسازی این پایگاه داده کلید-مقدار استفاده کرندند.
علاوه بر این، این دادهها رو در VTGate برای عملکرد بهتر کش میکردند.
برای بهروزرسانی پایگاه داده کلید-مقدار، یه سرور HTTP راهاندازی کردند و اسمش رو گذاشتند VTctld. این سرور فهرست کامل سرورها و روابطشون رو میگیره و سپس پایگاه داده کلید-مقدار رو بهروزرسانی میکنه.
#database
#postgresql
توجه این پست بر اساس تحقیق هستش و ممکنه با پیادهسازی واقعی فرق داشته باشه.
روزی روزگاری، سه نفر که تو PayPal کار میکردن، تصمیم گرفتن یه سایت دوستیابی درست کنن. اما مدل کسبوکارشون شکست خورد. برای همین ایدهشون رو عوض کردن و یه سایت اشتراکگذاری ویدئو درست کردن و اسمش رو گذاشتن یوتیوب.
اونا عناوین ویدئوها، توضیحات و اطلاعات کاربران رو تو MySQL ذخیره کردن. وقتی کاربرهای بیشتری به سایت پیوستن، اونا MySQL رو به حالت رهبر-دنبالکننده (leader-follower replication topology) تنظیم کردن تا بتونن بهتر مقیاسپذیری کنن. اما تکرار در MySQL تکنخی (single-threaded) است. بنابراین دنبالکنندهها نمیتونستن در عملیات نوشتن شدید به رهبر برسند و دادههای جدید رو بهروز کنن. با این حال، نرخ رشدشون خیلی زیاد بود و به یک میلیارد کاربر رسیدن و به دومین سایت پربازدید در جهان تبدیل شدن.
بنابراین با اضافه کردن یه حافظه نهان (cache) مقیاسپذیری کردن و همه رویدادها رو از لاگ باینری MySQL (binary log) بارگذاری کردن. این یعنی تکرار به حافظه وابسته شد و سرعت بیشتری پیدا کرد. اگرچه این کار به طور موقت مشکل مقیاسپذیری اونا رو حل کرد، مشکلات جدیدی به وجود اومد.
در اینجا به برخی از اونا اشاره میکنم:
1. پارتیشنبندی (Sharding):
اولین کاری که باید کرد این که MySQL باید پارتیشنبندی بشه تا نیازهای ذخیرهسازی رو مدیریت کنه. اما بعد از پارتیشنبندی، معاملات (transactions) و پیوستن جداول (joins) سخت میشه. بنابراین منطق برنامه (application logic) باید این رو مدیریت کنه. این یعنی منطق برنامه باید بفهمه که کدوم پارتیشنها رو باید پرسوجو کنه و این باعث افزایش احتمال زمان خرابی (downtime) میشه.
2. عملکرد (Performance):
و(leader-follower replication topology) باعث میشه که دادههای قدیمی از دنبالکنندهها خونده بشه. بنابراین منطق برنامه باید خوندن دادهها رو به رهبر هدایت کنه اگر دادههای جدید لازم باشه. و این نیاز به پیادهسازی منطق اضافی داره.
3. حفاظت (Protection):
ریسک اینکه برخی پرسوجوها خیلی طول بکشه تا دادهها رو برگردونن وجود داره. همچنین تعداد زیادی از اتصالات MySQL به طور همزمان میتونه مشکلساز بشه و ممکنه دیتابیس رو از کار بندازه.
اونا میخواستن یه لایه انتزاعی روی MySQL برای سادگی و مقیاسپذیری ایجاد کنند. بنابراین Vitess رو ساختن. در اینجا نحوه ارائه مقیاسپذیری بالا توسط Vitess رو توضیح میدم:
1. تعامل با پایگاه داده:(Interacting with Database)
اونا یه سرور جانبی (sidecar server) جلو هر نمونه MySQL نصب کردن و اسمش رو گذاشتند VTTablet.
این سرور جانبی به اونا اجازه میداد:
- کنترل سرور MySQL و مدیریت پشتیبانگیری از پایگاه داده
- بازنویسی کوئریهای سنگین با اضافه کردن محدودیت (limit clause)
- کش کردن دادههای پر دسترس برای جلوگیری از مشکل Thundering Herd
2. مسیریابی کوئریها(Routing SQL Queries):
یه سرور پراکسی بدون حالت (stateless proxy server) برای مسیریابی کوئریها تنظیم کردند و اسمش رو گذاشتند VTGate.
این سرور پراکسی بهشون اجازه میداد:
- پیدا کردن VTTablet صحیح برای مسیریابی کوئری بر اساس اسکیما و طرح پارتیشنبندی
- پایین نگه داشتن تعداد اتصالات MySQL از طریق تجمیع اتصالات (connection pooling)
- صحبت با لایه کاربردی به پروتکل MySQL
- عمل کردن مانند یه سرور MySQL یکپارچه برای سادگی
- محدود کردن تعداد معاملات در یک زمان برای عملکرد بهتر
همچنین برای مقیاسپذیری بیشتر، سرورهای VTGate متعددی راهاندازی کردند.
3. اطلاعات حالت:
تصویر چهارم در کامنت ها
یه پایگاه داده توزیعشده کلید-مقدار (distributed key-value database) راهاندازی کردند تا اطلاعات مربوط به اسکیما، طرحهای پارتیشنبندی و نقشها رو ذخیره کنه.
این پایگاه داده همچنین روابط بین پایگاههای داده مثل رهبر و دنبالکنندهها رو مدیریت میکنه.
در ادمه از Zookeeper برای پیادهسازی این پایگاه داده کلید-مقدار استفاده کرندند.
علاوه بر این، این دادهها رو در VTGate برای عملکرد بهتر کش میکردند.
برای بهروزرسانی پایگاه داده کلید-مقدار، یه سرور HTTP راهاندازی کردند و اسمش رو گذاشتند VTctld. این سرور فهرست کامل سرورها و روابطشون رو میگیره و سپس پایگاه داده کلید-مقدار رو بهروزرسانی میکنه.
#database
#postgresql