تخزين مئات الملايين من الملفات الصغيرة بكفاءة. حل مستضاف ذاتيا

تخزين مئات الملايين من الملفات الصغيرة بكفاءة. حل مستضاف ذاتيا

عزيزي المجتمع، ستركز هذه المقالة على تخزين واسترجاع مئات الملايين من الملفات الصغيرة بكفاءة. في هذه المرحلة، يُقترح الحل النهائي لأنظمة الملفات المتوافقة مع POSIX مع الدعم الكامل للأقفال، بما في ذلك الأقفال العنقودية، وحتى بدون عكازات على ما يبدو.

لذلك كتبت خادمي المخصص لهذا الغرض.
في سياق تنفيذ هذه المهمة، تمكنا من حل المشكلة الرئيسية، وفي الوقت نفسه تحقيق وفورات في مساحة القرص وذاكرة الوصول العشوائي، والتي كان نظام الملفات العنقودية لدينا يستهلكها بلا رحمة. في الواقع، مثل هذا العدد من الملفات ضار لأي نظام ملفات متفاوت المسافات.

الفكرة هي كالتالي:

بكلمات بسيطة، يتم تحميل الملفات الصغيرة من خلال الخادم، ويتم حفظها مباشرة في الأرشيف، والقراءة منه أيضًا، ويتم وضع الملفات الكبيرة جنبًا إلى جنب. المخطط: مجلد واحد = أرشيف واحد، في المجموع لدينا عدة ملايين من الأرشيفات التي تحتوي على ملفات صغيرة، وليس عدة مئات من ملايين الملفات. ويتم تنفيذ كل هذا بالكامل، دون أي نصوص برمجية أو وضع ملفات في أرشيفات tar/zip.

سأحاول أن أختصر، وأعتذر مقدمًا إذا كان المقال طويلًا.

بدأ كل شيء بحقيقة أنني لم أتمكن من العثور على خادم مناسب في العالم يمكنه حفظ البيانات المستلمة عبر بروتوكول HTTP مباشرة في الأرشيف، دون العيوب الكامنة في الأرشيفات التقليدية وتخزين الكائنات. وكان سبب البحث هو مجموعة Origin المكونة من 10 خوادم والتي نمت على نطاق واسع، حيث تراكمت بالفعل 250,000,000 ملف صغير، ولم يتوقف اتجاه النمو.

بالنسبة لأولئك الذين لا يحبون قراءة المقالات، فإن القليل من التوثيق أسهل:

هنا и هنا.

وعامل الإرساء في نفس الوقت، يوجد الآن خيار فقط مع nginx بالداخل فقط في حالة:

docker run -d --restart=always -e host=localhost -e root=/var/storage 
-v /var/storage:/var/storage --name wzd -p 80:80 eltaline/wzd

المقبل:

إذا كان هناك الكثير من الملفات، فستكون هناك حاجة إلى موارد كبيرة، وأسوأ ما في الأمر هو إهدار بعضها. على سبيل المثال، عند استخدام نظام ملفات متفاوت المسافات (في هذه الحالة، MooseFS)، فإن الملف، بغض النظر عن حجمه الفعلي، يستهلك دائمًا 64 كيلو بايت على الأقل. أي أنه بالنسبة للملفات التي يبلغ حجمها 3 أو 10 أو 30 كيلو بايت، يلزم وجود 64 كيلو بايت على القرص. فإذا كان هناك ربع مليار ملف، فإننا نخسر من 2 إلى 10 تيرابايت. لن يكون من الممكن إنشاء ملفات جديدة لأجل غير مسمى، حيث أن MooseFS لديه قيود: لا يزيد عن مليار مع نسخة طبق الأصل واحدة من كل ملف.

مع زيادة عدد الملفات، هناك حاجة إلى قدر كبير من ذاكرة الوصول العشوائي (RAM) للبيانات التعريفية. تساهم عمليات تفريغ البيانات التعريفية الكبيرة والمتكررة أيضًا في تآكل محركات أقراص SSD.

خادم WZD. نحن نرتب الأشياء على الأقراص.

الخادم مكتوب باللغة Go. بادئ ذي بدء، كنت بحاجة لتقليل عدد الملفات. كيف افعلها؟ بسبب الأرشفة، ولكن في هذه الحالة بدون ضغط، لأن ملفاتي مجرد صور مضغوطة. جاء BoltDB إلى الإنقاذ، والذي لا يزال يتعين القضاء عليه من عيوبه، وهذا ينعكس في الوثائق.

في المجمل، بدلاً من ربع مليار ملف، لم يتبق في حالتي سوى 10 ملايين أرشيف بولت. إذا أتيحت لي الفرصة لتغيير بنية ملف الدليل الحالي، فسيكون من الممكن تقليله إلى ما يقرب من مليون ملف.

يتم تعبئة جميع الملفات الصغيرة في أرشيفات بولت، والتي تتلقى تلقائيًا أسماء الدلائل التي توجد بها، وتبقى جميع الملفات الكبيرة بجوار الأرشيفات، ولا فائدة من تعبئتها، فهذا قابل للتخصيص. تتم أرشفة الصغيرة، وتترك الكبيرة دون تغيير. يعمل الخادم بشفافية مع كليهما.

بنية وميزات خادم wZD.

تخزين مئات الملايين من الملفات الصغيرة بكفاءة. حل مستضاف ذاتيا

يعمل الخادم تحت أنظمة التشغيل Linux وBSD وSolaris وOSX. لقد اختبرت بنية AMD64 فقط في نظام التشغيل Linux، ولكن من المفترض أن تعمل مع ARM64 وPPC64 وMIPS64.

الخصائص الرئيسية:

  • تعدد الخيوط؛
  • خادم متعدد، يوفر التسامح مع الأخطاء وموازنة التحميل؛
  • أقصى قدر من الشفافية للمستخدم أو المطور؛
  • طرق HTTP المدعومة: GET وHEAD وPUT وDELETE؛
  • إدارة سلوك القراءة والكتابة من خلال الرؤوس من جانب العميل؛
  • دعم المضيفين الظاهريين القابلين للتكوين بشكل كبير؛
  • دعم سلامة بيانات اتفاقية حقوق الطفل عند الكتابة/القراءة؛
  • مخازن مؤقتة شبه ديناميكية لتقليل استهلاك الذاكرة إلى الحد الأدنى وضبط أداء الشبكة بشكل مثالي؛
  • ضغط البيانات المؤجلة؛
  • بالإضافة إلى ذلك، يتم تقديم أرشيفي متعدد الخيوط wZA لترحيل الملفات دون إيقاف الخدمة.

تجربة حقيقية:

لقد قمت بتطوير واختبار الخادم والأرشيف على البيانات الحية لفترة طويلة، والآن يعمل بنجاح على مجموعة تتضمن 250,000,000 ملف صغير (صور) موجودة في 15,000,000 دليل على محركات أقراص SATA منفصلة. مجموعة مكونة من 10 خوادم هي خادم Origin مثبت خلف شبكة CDN. لخدمتها، يتم استخدام 2 خادم Nginx + 2 خادم wZD.

بالنسبة لأولئك الذين يقررون استخدام هذا الخادم، سيكون من الحكمة تخطيط بنية الدليل، إن أمكن، قبل الاستخدام. اسمحوا لي أن أحجز على الفور أن الخادم ليس المقصود منه حشر كل شيء في أرشيف 1 Bolt.

اختبار أداء:

كلما كان حجم الملف المضغوط أصغر، كلما تم تنفيذ عمليات GET وPUT عليه بشكل أسرع. دعونا نقارن إجمالي الوقت الذي يستغرقه عميل HTTP في الكتابة بالملفات العادية وأرشيفات Bolt، بالإضافة إلى القراءة. تتم مقارنة العمل مع الملفات ذات الأحجام 32 كيلو بايت و256 كيلو بايت و1024 كيلو بايت و4096 كيلو بايت و32768 كيلو بايت.

عند العمل مع أرشيفات Bolt، يتم التحقق من سلامة البيانات لكل ملف (يتم استخدام CRC)، قبل التسجيل وأيضًا بعد التسجيل، تحدث القراءة وإعادة الحساب أثناء التنقل، وهذا يؤدي بطبيعة الحال إلى تأخيرات، ولكن الشيء الرئيسي هو أمان البيانات.

لقد أجريت اختبارات الأداء على محركات أقراص SSD، نظرًا لأن الاختبارات على محركات أقراص SATA لم تظهر فرقًا واضحًا.

الرسوم البيانية على أساس نتائج الاختبار:

تخزين مئات الملايين من الملفات الصغيرة بكفاءة. حل مستضاف ذاتيا
تخزين مئات الملايين من الملفات الصغيرة بكفاءة. حل مستضاف ذاتيا

كما ترون، بالنسبة للملفات الصغيرة، يكون الفرق في أوقات القراءة والكتابة بين الملفات المؤرشفة وغير المؤرشفة صغيرًا.

نحصل على صورة مختلفة تمامًا عند اختبار قراءة وكتابة ملفات بحجم 32 ميجابايت:

تخزين مئات الملايين من الملفات الصغيرة بكفاءة. حل مستضاف ذاتيا

الفارق الزمني بين قراءة الملفات هو في حدود 5-25 مللي ثانية. مع التسجيل، الأمور أسوأ، والفرق حوالي 150 مللي ثانية. ولكن في هذه الحالة ليست هناك حاجة لتحميل ملفات كبيرة، ببساطة لا يوجد أي معنى للقيام بذلك، يمكن أن تعيش بشكل منفصل عن الأرشيف.

*من الناحية الفنية، يمكنك استخدام هذا الخادم للمهام التي تتطلب NoSQL.

الطرق الأساسية للعمل مع خادم wZD:

تحميل ملف عادي:

curl -X PUT --data-binary @test.jpg http://localhost/test/test.jpg

تحميل ملف إلى أرشيف بولت (إذا لم يتم تجاوز معلمة الخادم fmaxsize، التي تحدد الحد الأقصى لحجم الملف الذي يمكن تضمينه في الأرشيف؛ إذا تم تجاوزه، فسيتم تحميل الملف كالمعتاد بجانب الأرشيف):

curl -X PUT -H "Archive: 1" --data-binary @test.jpg http://localhost/test/test.jpg

تنزيل ملف (إذا كانت هناك ملفات بنفس الأسماء على القرص وفي الأرشيف، فعند التنزيل، يتم إعطاء الأولوية افتراضيًا للملف غير المؤرشف):

curl -o test.jpg http://localhost/test/test.jpg

تنزيل ملف من أرشيف بولت (قسري):

curl -o test.jpg -H "FromArchive: 1" http://localhost/test/test.jpg

أوصاف الطرق الأخرى موجودة في الوثائق.

وثائق دبليو زي دي
وثائق WZA

يدعم الخادم حاليًا بروتوكول HTTP فقط، ولا يعمل مع HTTPS حتى الآن. طريقة POST غير مدعومة أيضًا (لم يتم تحديد ما إذا كانت مطلوبة أم لا).

من يبحث في الكود المصدري سيجد الحلوى هناك، لا يحبها الجميع، لكنني لم أربط الكود الرئيسي بوظائف إطار عمل الويب، باستثناء معالج المقاطعة، لذلك في المستقبل يمكنني إعادة كتابته بسرعة لأي شيء تقريبًا محرك.

تودو:

  • تطوير النسخ المتماثل والموزع الخاص بك + Geo لإمكانية استخدامه في الأنظمة الكبيرة بدون أنظمة الملفات العنقودية (كل شيء للكبار)
  • إمكانية الاسترداد العكسي الكامل للبيانات الوصفية في حالة فقدانها بالكامل (في حالة استخدام موزع)
  • بروتوكول أصلي للقدرة على استخدام اتصالات الشبكة المستمرة وبرامج التشغيل للغات البرمجة المختلفة
  • إمكانيات متقدمة لاستخدام مكون NoSQL
  • ضغطات بأنواع مختلفة (gzip, zstd, snappy) للملفات أو القيم الموجودة داخل أرشيفات بولت وللملفات العادية
  • التشفير بأنواعه المختلفة للملفات أو القيم داخل أرشيفات بولت وللملفات العادية
  • تأخر تحويل الفيديو من جانب الخادم، بما في ذلك على وحدة معالجة الرسومات

لدي كل شيء، آمل أن يكون هذا الخادم مفيدًا لشخص ما، ترخيص BSD-3، حقوق الطبع والنشر المزدوجة، لأنه إذا لم تكن هناك شركة أعمل فيها، فلن يتم كتابة الخادم. أنا المطور الوحيد. سأكون ممتنًا لأية أخطاء وطلبات ميزات تجدها.

المصدر: www.habr.com

إضافة تعليق