كمطورين، غالبًا ما نواجه تحديات عند التعامل مع معالجة البيانات وتسليمها على نطاق واسع. في Kamero، عالجنا مؤخرًا اختناقًا كبيرًا في مسار تسليم الملفات لدينا. يتيح تطبيقنا للمستخدمين تنزيل آلاف الملفات المرتبطة بحدث معين كملف مضغوط واحد. كانت هذه الميزة، المدعومة بوظيفة Lambda المستندة إلى Node.js والمسؤولة عن جلب الملفات وضغطها من مجموعات S3، تعاني من قيود الذاكرة وأوقات التنفيذ الطويلة مع نمو قاعدة المستخدمين لدينا.
يعرض هذا المنشور تفاصيل رحلتنا من تطبيق Node.js المتعطش للموارد إلى حل Go بسيط وسريع للغاية يتعامل بكفاءة مع تنزيلات S3 الضخمة. سنستكشف كيف قمنا بتحسين نظامنا لتزويد المستخدمين بتجربة سلسة عند طلب أعداد كبيرة من الملفات من أحداث معينة، وكلها مجمعة في ملف مضغوط واحد مناسب للتنزيل.
واجهت وظيفة Lambda الأصلية العديد من المشكلات الحرجة عند معالجة مجموعات كبيرة من الملفات المستندة إلى الأحداث:
استخدم تطبيقنا الأصلي مكتبة s3-zip لإنشاء ملفات مضغوطة من كائنات S3. إليك مقتطف مبسط لكيفية معالجة الملفات:
const s3Zip = require("s3-zip"); // ... other code ... const body = s3Zip.archive( { bucket: bucketName }, eventId, files, entryData ); await uploadZipFile(Upload_Bucket, zipfileKey, body);
أثناء نجاح هذا الأسلوب، تم تحميل جميع الملفات في الذاكرة قبل إنشاء الملف المضغوط، مما أدى إلى استخدام مرتفع للذاكرة وأخطاء محتملة في نفاد الذاكرة لمجموعات الملفات الكبيرة.
قررنا إعادة كتابة وظيفة Lambda الخاصة بنا في Go، مع الاستفادة من كفاءتها وميزات التزامن المضمنة فيها. وكانت النتائج مذهلة:
لقد استخدمنا AWS SDK لـ Go v2، والذي يوفر أداءً أفضل واستخدامًا أقل للذاكرة مقارنةً بالإصدار 1:
cfg, err := config.LoadDefaultConfig(context.TODO()) s3Client = s3.NewFromConfig(cfg)
أتاحت لنا إجراءات Go معالجة ملفات متعددة في وقت واحد:
var wg sync.WaitGroup sem := make(chan struct{}, 10) // Limit concurrent operations for _, photo := range photos { wg.Add(1) go func(photo Photo) { defer wg.Done() semيسمح لنا هذا الأسلوب بمعالجة ملفات متعددة في وقت واحد مع التحكم في مستوى التزامن لمنع إرباك النظام.
3. إنشاء الرمز البريدي المتدفق
بدلاً من تحميل جميع الملفات في الذاكرة، نقوم بدفق المحتوى المضغوط مباشرةً إلى S3:
pipeReader, pipeWriter := io.Pipe() go func() { zipWriter := zip.NewWriter(pipeWriter) // Add files to zip zipWriter.Close() pipeWriter.Close() }() // Upload streaming content to S3 uploader.Upload(ctx, &s3.PutObjectInput{ Bucket: &destBucket, Key: &zipFileKey, Body: pipeReader, })يؤدي أسلوب البث هذا إلى تقليل استخدام الذاكرة بشكل كبير ويسمح لنا بالتعامل مع مجموعات ملفات أكبر بكثير.
النتائج
أدت إعادة الكتابة إلى Go إلى تحسينات مذهلة:
- استخدام الذاكرة: تم تقليله بنسبة 99% (من 10 جيجابايت إلى 100 ميجابايت)
- سرعة المعالجة: تمت زيادتها بنسبة 1000% تقريبًا
- الموثوقية: التعامل بنجاح مع 20000 ملف دون مشاكل
- فعالية التكلفة: يؤدي استخدام الذاكرة الأقل ووقت التنفيذ الأسرع إلى تقليل تكاليف AWS Lambda
الدروس المستفادة
- اختيار اللغة مهم: أحدث نموذج الكفاءة والتزامن في Go فرقًا كبيرًا في حالة الاستخدام لدينا.
- فهم الاختناقات التي تواجهك: ساعدنا تحديد وظيفة Node.js في تحديد المجالات الرئيسية للتحسين.
- الاستفادة من الحلول السحابية الأصلية: استخدام AWS SDK for Go v2 وفهم قدرات S3 يسمح بتكامل وأداء أفضل.
- التفكير في التدفقات: تعد معالجة البيانات كتدفقات بدلاً من تحميل كل شيء في الذاكرة أمرًا بالغ الأهمية للعمليات واسعة النطاق.
خاتمة
إن إعادة كتابة وظيفة Lambda الخاصة بنا في Go لم تحل مشكلات التوسع الفورية لدينا فحسب، بل قدمت أيضًا حلاً أكثر قوة وفعالية لاحتياجات معالجة الملفات لدينا. على الرغم من أن Node.js خدمنا جيدًا في البداية، إلا أن هذه التجربة سلطت الضوء على أهمية اختيار الأداة المناسبة للمهمة، خاصة عند التعامل مع المهام كثيفة الاستخدام للموارد على نطاق واسع.
تذكر أن أفضل لغة أو إطار عمل يعتمد على حالة الاستخدام المحددة لديك. في السيناريو الخاص بنا، تتوافق خصائص أداء Go تمامًا مع احتياجاتنا، مما يؤدي إلى تحسين تجربة المستخدم بشكل كبير وتقليل تكاليف التشغيل.
هل واجهت تحديات مماثلة مع الوظائف بدون خادم؟ كيف تغلبت عليهم؟ نود أن نسمع عن تجاربك في التعليقات أدناه!
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3