تحسين الحمل في مشروع Highload مع ElasticSearch

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

كيف يتم ترتيب المشروع


في الواجهة الخلفية ، نقوم بإنشاء خدمات تضمن أداء المواقع والتطبيقات المحمولة لعملائنا. يمكن رؤية الهيكل العام في الرسم التخطيطي:

صورة

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

هناك أيضًا عمليات عكسية عندما نتلقى بيانات من عميل ونرسلها إلى المستخدم. بالإضافة إلى ذلك ، لا تزال هناك عمليات للعمل مع برامج المدفوعات والمكافآت.

خلفية قصيرة


في البداية ، استخدمنا PostgreSQL كمخزن البيانات الوحيد. مزاياها القياسية لنظام إدارة قواعد البيانات: توفر المعاملات ، لغة متطورة لأخذ عينات البيانات ، أدوات واسعة للتكامل ؛ إلى جانب الأداء الجيد ، فإن الأشخاص الراضين قد استوفوا احتياجاتنا لفترة طويلة.

قمنا بتخزين جميع البيانات على الإطلاق في Postgres: من المعاملات إلى الأخبار. لكن عدد المستخدمين زاد ومعه عدد الطلبات.

من أجل الفهم ، يبلغ العدد السنوي للجلسات في عام 2017 على موقع سطح المكتب وحده 131 مليونًا. وفي عام 2018 ، أصبح 125 مليون 2019 مرة أخرى 130 مليونًا. أضف 100-200 مليون أخرى من إصدار الهاتف المحمول للموقع وتطبيق الهاتف المحمول ، وستحصل على عدد كبير من الطلبات.

مع نمو المشروع ، توقفت Postgres عن التعامل مع الحمل ، لم يكن لدينا الوقت - ظهر عدد كبير من الاستفسارات المختلفة ، والتي لم نتمكن بموجبها من إنشاء عدد كاف من الفهارس.

لقد أدركنا أن هناك حاجة إلى مستودعات بيانات أخرى توفر احتياجاتنا وتنزيل العبء من PostgreSQL. اعتبرت Elasticsearch و MongoDB كخيارين محتملين. خسر الأخير في النقاط التالية:

  1. سرعة فهرسة بطيئة مع زيادة حجم البيانات في الفهارس. في مطاطا ، لا تعتمد السرعة على كمية البيانات.
  2. لا يوجد بحث النص الكامل

لذلك اخترنا المرونة لأنفسنا واستعدنا للانتقال.

التبديل إلى مرونة


1. بدأنا عملية النقل من خلال خدمة البحث عن نقاط البيع. يمتلك عميلنا ما مجموعه حوالي 70،000 نقطة بيع ، ويتطلب عدة أنواع من عمليات البحث على الموقع وفي التطبيق:

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

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

2. التالي في الخط كان قسم الأخبار. كل يوم ، تظهر المنشورات على الموقع بحيث لا يضيع المستخدم في تدفق المعلومات ، يجب فرز البيانات قبل إصدارها. لهذا ، تحتاج إلى بحث: على الموقع يمكنك البحث عن طريق مطابقة النص ، وفي الوقت نفسه توصيل فلاتر إضافية ، حيث يتم إجراؤها أيضًا من خلال مطاط.

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

وفي الوقت نفسه ، يجب معالجة البيانات في الحد الأدنى من الوقت - لا يحب المستخدمون انتظار نتيجة لعدة أيام. لن تحقق مثل هذه المواعيد النهائية من خلال Postgres - غالبًا ما نحصل على أقفال ، وبينما نعالج جميع الطلبات ، لا يمكن للمستخدمين التحقق مما إذا كانوا قد تلقوا جوائز أم لا. هذا ليس ممتعا جدا للعمل ، لذلك قمنا بنقل المعالجة إلى Elasticsearch.

دورية


الآن يتم تكوين التحديثات حسب الحدث ، في ظل الظروف التالية:

  1. نقطة البيع. بمجرد أن تصل إلينا البيانات من مصدر خارجي ، نبدأ التحديث على الفور.
  2. أخبار. بمجرد تحرير أي أخبار على الموقع ، يتم إرسالها تلقائيًا إلى Elastic.

هنا مرة أخرى ، تجدر الإشارة إلى مزايا المرونة. في Postgres ، عند إرسال طلب ، عليك الانتظار حتى يعالج بصدق جميع السجلات. يمكنك إرسال 10 آلاف سجل إلى Elastic ، والبدء في العمل فورًا ، دون انتظار حتى يتم توزيع السجلات عبر جميع Shards. بالطبع ، قد لا يرى بعض Shard أو Replica البيانات على الفور ، ولكن قريبًا سيكون كل شيء متاحًا.

طرق التكامل


هناك طريقتان للتكامل مع المرونة:

  1. من خلال العميل الأصلي عبر TCP. يموت السائق الأصلي تدريجيًا: لم يعد مدعومًا ، ولديه بناء جملة غير مريح للغاية. لذلك ، نحن لا نستخدمها عمليًا ونحاول التخلي عنها تمامًا.
  2. عبر واجهة HTTP يمكنك من خلالها استخدام كل من طلبات JSON وبناء جملة Lucene. هذا الأخير هو محرك نص يستخدم المرن. في هذا الخيار ، نحصل على إمكانية الحزم من خلال طلبات JSON عبر HTTP. هذا هو الخيار الذي نحاول استخدامه.

بفضل واجهة HTTP ، يمكننا استخدام المكتبات التي توفر تطبيقًا غير متزامن لعميل HTTP. يمكننا الاستفادة من Batch و API غير المتزامن ، والتي تعطي في النهاية أداءً عاليًا ، مما ساعد كثيرًا خلال أيام إجراء كبير (المزيد عن ذلك أدناه)

بعض الأرقام للمقارنة:

  • إنقاذ المستخدمين الذين حصلوا على جوائز في Postgres في 20 بثًا بدون مجموعات: 460.713 مُدخلاً في 42 ثانية
  • عميل مرن + متفاعل لـ 10 خيوط + مجموعة لـ 1000 عنصر: 596749 تسجيل في 11 ثانية
  • عميل مرن + تفاعلي لـ 10 خيوط + مجموعة لـ 1000 عنصر: 23801684 تسجيل في 4 دقائق

الآن قمنا بكتابة مدير طلب HTTP الذي يقوم بإنشاء JSON كدفعة / ليس دفعة وإرساله من خلال أي عميل HTTP ، بغض النظر عن المكتبة. يمكنك أيضًا اختيار إرسال الطلبات بشكل متزامن أو غير متزامن.

في بعض عمليات الدمج ، ما زلنا نستخدم عميل النقل الرسمي ، ولكن هذه ليست سوى مسألة إعادة الهيكلة القادمة. في الوقت نفسه ، يتم استخدام عميل مخصص مبني على أساس Spring WebClient للمعالجة.

صورة

ترقية كبيرة


مرة واحدة في السنة ، تجري حملة كبيرة للمستخدمين في المشروع - وهذا هو نفس الحمل المرتفع ، حيث نعمل في الوقت الحالي مع عشرات الملايين من المستخدمين في نفس الوقت.

عادة ما تحدث أحمال الذروة خلال العطلات ، ولكن هذا العرض الترويجي مختلف تمامًا. في العام السابق ، في يوم العرض الترويجي ، قمنا ببيع 27،580،890 وحدة من البضائع. تمت معالجة البيانات لأكثر من نصف ساعة ، مما تسبب في إزعاج للمستخدمين. حصل المستخدمون على جوائز للمشاركة ، ولكن أصبح من الواضح أنه يجب تسريع العملية.

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

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

الخلاصة / الاستنتاجات


في الوقت الحالي ، قمنا بنقل جميع الخدمات التي أردناها والتي أوقفناها مؤقتًا إلى مرونة. الآن نقوم ببناء فهرس في مطاط على رأس التخزين الثابت الرئيسي في Postgres ، والذي يأخذ على حمل المستخدم.

في المستقبل ، نخطط لنقل الخدمات إذا فهمنا أن طلب البيانات يصبح متنوعًا للغاية ويتم البحث فيه بواسطة عدد غير محدود من الأعمدة. لم تعد هذه مهمة Postgres.

إذا كنا بحاجة إلى البحث عن نص كامل في الوظيفة ، أو إذا كان لدينا الكثير من معايير البحث المختلفة ، فإننا نعلم بالفعل أن هذا يحتاج إلى ترجمته إلى مطاط.

⌘⌘⌘


شكرا للقراءة. إذا كانت شركتك تستخدم أيضًا البحث المرن ولديها حالات تنفيذ خاصة بها ، فأخبرنا بذلك. سيكون من المثير للاهتمام معرفة كيف لدى الآخرين :-)

All Articles