كيف تغلبت على مشكلة الـ CPU = 100% مع سيرفر MySQL؟

في عندي داتا بيز MySQL حجمها تقريباً 12 غيغا بايت, هي الداتا بتستخدم InnoDB لحفظ الداتا. الـ IO ع هي الداتا بيز عالي كتير, ممكن يوصل لـ 5000 بالثانية ببعض الأحيان. الداتا بيز موجودة ع Dedicated server عليه معالج Intel i9 octa-core مع 128 GB DDR4 Ram.

الداتا بيز عم تكبر كل يوم و الترافيك ع الـ Front end  للتطبيق الي عم تشغله  الداتا بيز عم يزيد, هالشي خلاني انقلها من سيرفر لسيرفر اكبر مؤخراً لحتى تقدر تلحق الـ Load.

من فترة قررت انو ما عاد فيني ضل هيك، خصوصي انو في عندي Replica و الاهتمام بسيرفرين بالشكل و بالحجم هاد عم ياخد وقت و جهد كتير, فقررت انتقل للكلاود و استخدم IaaS لتشغل الـ MySQL, الخيار كان كارثي مادياً, الكلفة ارتفعت ع الأقل 4 اضعاف, و هالشي دفعني اني ارجع للسيرفرات المعدنية.

قضيت فترة منيحة و انا عم اعمل Debug  للداتا بيز لحتى افهم تماماً شو الي عم يخلي الـ CPU = 100%  طول الوقت, و شفت انو فكرة توسعة الـ Hardware resources  لهالداتا بيز كـ حل ابداً مانو خيار جيد و مستقر, المهم قضيت أيام عم اشتغل ع الموضوع و قدرت نزل الـ CPU load  لـ 10% عبر اتباع الطريقة التالية:

  1. راقب الداتا بيز تبعك عن طريق SHOW PROCESSLIST لفترة منيحة, أي ضل عم تكبس الكوماند و تشوف الـ Output و تحلله, لحتى تقدر تحدد شو هو اكتر Table عم يكون شغال, و شو طبيعة الـ Queries  الي عم يتم تنفيذها, و شو طبيعة الداتا الي عم تنحفظ, راح تتفاجئ  بكمية الزبالة الي عم يتم حفظها بالداتا بيز تبعك, و السبب بسيط (الكود تبعك زبالة :D) و كودي كان زبالة بكتير نواحي, مثلاً كودي كان عم يخزن داتا بالداتا بيز تبعي متعلقة بـ User behavior هي الداتا لسا ما عندي أي استخدام الها, و ما في أي سبب يخليني خزنها عندي, فبلشت اني غير من الكود و خزن كمية داتا اقل, و خلي حصراً الداتا الي بحاجتها انا.
  2. كود غيري كان زبالة! كان في 3rd party libraries عم استخدمها بالكود تبعي, و هي الإضافات للسيستم كانت عم تخزن داتا مؤقتة و ما كانت عم تحذفها بعد ما تستخدمها. طبعاً كان عندي مشكلة مع طبيعة الداتا الي عم يتم تخزينها، و مع طريقة تخزينها و عمر هي الداتا. اضطريت اني اتخلى عن بعض هي المكتبات او لاقي بدائل احسن.
  3. كان عندي داتا بيز مركزية لكل شي. هي المشكلة كانت كارثية بشكل, يعني داتا بيز وحدة بتقدم الخدمات الرئيسية للتطبيق الي عم تخدمه, و بنفس الداتا بيز بجمع داتا عن اليوزر مثلاً او Statistics بتخص المستخدمين, المفاجئة كانت انو المهام الرئيسية للداتا بيز (تشغيل التطبيق) كانت بتاخد Resources اقل بكتير من الحباشات التانية. ع هالأساس عملت اكثر من داتا بيز و رتبت أولوية كل داتا بيز من ناحية أهميتها لتشغيل التطبيق, و حددت الـ Max resources لكل داتا بيز بحسب أهميتها.
  4. عملت Offloading لداتا قديمة ما كتير مضطر عليها فوراً، و عملتلها Replica offline. يعني تخيل عندك جدول فيه داتا بتخص اليوزر تبعك, يمكن تكون مضطر انو يكون عندك اكسس ع داتا عمرها 3 اشهر مثلاً مو اكثر, بس حتماً ما بدك داتا عمرها 5 سنين, لهيك الأفضل تفرغ الداتا بيز و تعيد بناء الـ Indexes  تبعك ع هاد الأساس.
  5. ماكنت مختار architecture صحيحة للنظام عندي. كنت عامل Replica يعني البايت الي بينكتب ع الداتا بيز الأولى, بينكتب نسخة منو ع الداتا بيزا لتانية, و هاد البروسس كان عم يستخدم Resources  تبع سيرفرين, بس فعلياً الـ Operational database كانت واحدة فقط, ماعدا انو فعل الـ Replication  نفسو كان بحدو ذاتو بياخد Double resources  لحتى يتم, لهيك انتقلت من الـ Replica based architecture  لـ MySQL Cluster و الي بتوزع الداتا ع اكتر من سيرفر. صحيح هاد الخيار ممكن يكلفني في حال وقف سيرفر عن العمل و يسبب Down time, بس حله بسيط انو عبر اني اعمل Replica between 2 clusters و هاد عم جهز اني اعملو عن طريق سيرفرات اصغر و ارخص.
Share Button

,

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.