PHP ، YII2 وتشكيل ملفات إكسل كبيرة

ابدأ


بدأ نظام واحد للمحاسبة والإبلاغ تدعمه شركتنا ينمو بسرعة كبيرة في كمية البيانات المخزنة. النظام مكتوب بلغة PHP باستخدام إطار عمل Yii2. في البداية ، تم بناء التقارير من خلال مكتبة PhpSpreadsheet ، والتي حلت محل PhpExcel المهجور منذ فترة طويلة.

من بين أنواع التقارير المختلفة ، كان هناك تقرير واحد كبير جدًا - في الواقع ، يجب تحميل المجموعة الكاملة لجميع البيانات المخزنة في قاعدة البيانات إلى جدول excel واحد. في المرحلة الأولية ، لم تكن هناك مشاكل ، ولكن عندما بدأ المجلد يتجاوز مئات الآلاف من السجلات ، بدأ سيناريو تشكيل التفريغ في التراجع عند حد المهلة. بادئ ذي بدء ، رفعنا هذا الحد وبدأنا في البحث عن طرق لحل المشكلة. لكن الحل المؤقت لم يدم طويلاً - تحولت مشكلة الحد الزمني إلى مشكلة تتعلق بحد الذاكرة. لقد ألقوا "ذاكرة الوصول العشوائي" إلى الخادم وأزالوا ذاكرة الذاكرة لهذه العملية بالذات. بعد فترة وجيزة ، بدأ المستخدمون يشكون من أخطاء وقت التشغيل مرة أخرى. اضطررت إلى إزالة الحد الزمني للتقرير الكامل. لكن الجلوس ومشاهدة اثني عشر دقيقة على الشاشة مع مؤشر تحميل ليست ممتعة للغاية. علاوة على ذلك ، في بعض الأحيان كانت هناك حاجة إلى تقرير "هنا والآن" ، وتبين أن كل دقيقة تمضية في تشكيلها كانت حاسمة. تم إيقاف التجارب مع إعدادات البيئة ، وخدش الجزء الخلفي من الرأس وبدأ تحسين الرمز.

ابحث عن حل


أول شيء تم القيام به هو وضع البرنامج النصي لإعداد التقارير في عملية الخلفية ، ويراقب المستخدم التقدم من خلال "شريط التقدم". تم تنفيذ تنفيذ المهمة في الخلفية من خلال آلية قائمة الانتظار باستخدام Redis للتخزين. لا يتوقف العمل في النظام ، يمكنك القيام بمهام أخرى والعودة بشكل دوري إلى صفحة التقرير لمعرفة ما إذا كان الملف جاهزًا. بمجرد تشكيل الملف ، يتم عرض رابط تنزيل على المستخدم. ولكن ، كما ذكر أعلاه ، في بعض الأحيان كان الملف مطلوبًا "على الفور" ، ولم تؤدي زيادة قابلية الاستخدام إلى حل هذه المشكلة. في غضون ذلك ، استمر حجم البيانات في النمو والوقت الذي استغرقه إنشاء الملف بلغ 79 دقيقة! هذا أمر غير مقبول على الإطلاق ، خاصة بالنظر إلى أن إعداد التقارير هو أحد أسس وظائف هذا النظام. لا ، عملت جميع الأجزاء الأخرى كالساعة ، لكن هذه الذبابة في المرهم أفسدت الانطباع العام.

النتائج الأولى


جلسنا مرة أخرى لتحليل التعليمات البرمجية. أول شيء تم اختباره كان عملية اختيار البيانات من قاعدة البيانات. ولكن تم تحسين الاستعلامات بالفعل بأقصى طريقة ممكنة. على الرغم من أن أطول طلب كان عينة رهيبة مع خمس أو ست مكالمات إلى FIAS البشعة ، إلا أنها نجحت في 2-5 ثوان. نقطة ضعفه لم يكن هو بل تشكيل ملف "exelnik". بدأت المحاولات لتحسين هذه العملية. بدءًا من التخزين المؤقت في redis ، إلى الانحرافات ، مثل تشكيل "excels" الصغير المنفصل في تيارات متوازية ، يليه اللصق في ملف واحد. لكن النتيجة كانت دائمًا هي نفسها: تحولت المشكلة بمرور الوقت إلى مشكلة في الذاكرة والعكس بالعكس. لم يكن هناك حل وسط ، يتدفق فقط من طرف إلى آخر. بعد كمية معينة من البيانات ، بدأ استهلاك الموارد في المكتبة ينمو بشكل كبير ولم يكن من الممكن إلحاق الهزيمة بها. PhpSpreadsheet - غير مناسب للملفات الكبيرة. ونتيجة لذلك ، تقرر تغيير المكتبة. كخيار - كتابة التناظرية الخاصة بك لتشكيل الملفات السابقة.

التحليل واختيار الأداة


لم يتسرعوا في كتابة الدراجات ، ولكن في البداية حللوا الحلول الحالية. من بين الخيارات الممكنة ، كان الصندوق / صنبور فقط من الفائدة. أعد كتابة الوحدة بسرعة باستخدام هذه المكتبة. ونتيجة لذلك ، تم الحصول على تقرير كامل في 145 ثانية. دعني أذكرك بأن أحدث الاختبارات باستخدام PhpSpreadsheet هي 79 دقيقة ، وهنا 2.5 دقيقة! إجراء الاختبار: زيادة كمية البيانات مرتين. تم إنشاء التقرير في 172 ثانية. الفرق مذهل. بالطبع ، لا تحتوي المكتبة على نفس الوظائف مثل PhpSpreadsheet ، ولكن في هذه الحالة يكون الحد الأدنى من مجموعة الأدوات كافيًا ، لأن السرعة أمر بالغ الأهمية.

ملحق Yii2


تم تأطير القرار النهائي كامتداد لـ Yii2. ربما يأتي شخص في متناول اليدين. تسمح لك الإضافة بتحميل أي مجموعة بيانات من GridView إلى التفوق مع الحفاظ على التصفية والفرز. يستخدم yii / queue و box / spout كتبعيات. من المنطقي استخدام الامتداد لتكوين ملفات كبيرة حقًا ، حسنًا ، على الأقل 50000 سطر =) في الوقت الحالي ، تتعامل الوحدة ، التي أصبحت أساسًا للإضافة ، بشكل مشهور مع حمولة من 600000 سطر تقريبًا.

رابط إلى github: ملحق Yii2 ExcelReport

شكرا لكم على اهتمامكم!

Source: https://habr.com/ru/post/ar420393/


All Articles