البحث بسرعة 1 تيرابايت / ثانية

TL;DR: منذ أربع سنوات، تركت Google ولدي فكرة عن أداة جديدة لمراقبة الخادم. وكانت الفكرة هي الجمع بين الوظائف المعزولة عادة في خدمة واحدة مجموعة وتحليل السجل، وجمع المقاييس، التنبيهات ولوحات المعلومات. أحد المبادئ هو أن الخدمة يجب أن تكون حقيقية سريع، مما يوفر للمطورين تجربة سهلة وتفاعلية وممتعة. ويتطلب ذلك معالجة مجموعات بيانات متعددة الجيجابايت في أجزاء من الثانية مع البقاء في حدود الميزانية. غالبًا ما تكون أدوات إدارة السجل الحالية بطيئة ومعقدة، لذلك واجهنا تحديًا جيدًا: التصميم الذكي لأداة لمنح المستخدمين تجربة جديدة.

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

قوة المدرسة القديمة

يبدأ تحليل السجل عادةً بالبحث: ابحث عن جميع الرسائل التي تطابق نمطًا معينًا. في Scalyr، هناك عشرات أو مئات الجيجابايت من السجلات من العديد من الخوادم. تتضمن الأساليب الحديثة، كقاعدة عامة، إنشاء بعض هياكل البيانات المعقدة المُحسّنة للبحث. لقد رأيت هذا بالتأكيد على Google، حيث أنهم جيدون جدًا في هذا النوع من الأشياء. لكننا استقرينا على نهج أكثر بدائية: المسح الخطي للسجلات. وقد نجح الأمر - فنحن نوفر واجهة قابلة للبحث وهي أسرع بكثير من منافسينا (انظر الرسوم المتحركة في النهاية).

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

الوجبات الرئيسية من هذه المقالة:

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

(تصف هذه المقالة البحث عن البيانات في الذاكرة. في معظم الحالات، عندما يقوم مستخدم بإجراء بحث في السجل، تكون خوادم Scalyr قد قامت بتخزينه مؤقتًا بالفعل. ستناقش المقالة التالية البحث عن السجلات غير المخزنة مؤقتًا. تنطبق نفس المبادئ: التعليمات البرمجية الفعالة، والقوة الغاشمة بموارد حسابية كبيرة).

طريقة القوة الغاشمة

تقليديًا، يتم البحث في مجموعة كبيرة من البيانات باستخدام فهرس الكلمات الرئيسية. عند تطبيقه على سجلات الخادم، فهذا يعني البحث عن كل كلمة فريدة في السجل. لكل كلمة، تحتاج إلى تقديم قائمة بجميع الادراج. وهذا يجعل من السهل العثور على جميع الرسائل التي تحتوي على هذه الكلمة، على سبيل المثال "خطأ" أو "فايرفوكس" أو "معاملة_16851951" - ما عليك سوى البحث في الفهرس.

لقد استخدمت هذا النهج في Google وقد نجح بشكل جيد. لكن في Scalyr نقوم بالبحث في السجلات بايتًا بايت.

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

الفهارس رائعة، لكن لها حدود. من السهل العثور على كلمة واحدة. لكن البحث عن الرسائل التي تحتوي على كلمات متعددة، مثل "googlebot" و"404"، يعد أكثر صعوبة. يتطلب البحث عن عبارة مثل "استثناء غير معلوم" فهرسًا أكثر تعقيدًا لا يسجل جميع الرسائل التي تحتوي على تلك الكلمة فحسب، بل يسجل أيضًا الموقع المحدد للكلمة.

الصعوبة الحقيقية تأتي عندما لا تبحث عن الكلمات. لنفترض أنك تريد معرفة مقدار حركة المرور القادمة من الروبوتات. الفكرة الأولى هي البحث في السجلات عن كلمة "bot". هذه هي الطريقة التي ستجد بها بعض الروبوتات: Googlebot وBingbot وغيرها الكثير. لكن كلمة "bot" هنا ليست كلمة، ولكنها جزء منها. إذا بحثنا عن "bot" في الفهرس، فلن نجد أي مشاركات تحتوي على كلمة "Googlebot". إذا قمت بفحص كل كلمة في الفهرس ثم قمت بمسح الفهرس بحثًا عن الكلمات الرئيسية التي تم العثور عليها، فسوف يتباطأ البحث بشكل كبير. ونتيجة لذلك، فإن بعض برامج السجل لا تسمح بالبحث عن جزء من الكلمة أو (في أحسن الأحوال) تسمح ببناء جملة خاص بأداء أقل. نريد تجنب هذا.

مشكلة أخرى هي علامات الترقيم. هل تريد العثور على كافة الطلبات من 50.168.29.7؟ ماذا عن سجلات التصحيح التي تحتوي على [error]؟ عادةً ما يتخطى المشتركون علامات الترقيم.

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

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

تشغل فهارس الكلمات الرئيسية أيضًا مساحة كبيرة، ويعد التخزين تكلفة كبيرة في نظام إدارة السجلات.

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

تعمل القوة الغاشمة إذا كانت لديك مشكلة غاشمة (والكثير من القوة)

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

كان رمز البحث الخاص بنا يحتوي في الأصل على حلقة داخلية كبيرة إلى حد ما. نقوم بتخزين الرسائل على الصفحات بدقة 4K؛ تحتوي كل صفحة على بعض الرسائل (بتنسيق UTF-8) والبيانات الوصفية لكل رسالة. بيانات التعريف هي بنية تقوم بترميز طول القيمة ومعرف الرسالة الداخلي والحقول الأخرى. تبدو دورة البحث كما يلي:

البحث بسرعة 1 تيرابايت / ثانية

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

(قد تتساءل لماذا نقوم بتخزين الرسائل بهذا التنسيق مع صفحات ونصوص وبيانات تعريف بدقة 4K، بدلاً من العمل مع السجلات مباشرة. هناك العديد من الأسباب، والتي تتلخص في حقيقة أن محرك Scalyr داخليًا يشبه قاعدة بيانات موزعة أكثر من كونه قاعدة بيانات موزعة. نظام الملفات. غالبًا ما يتم دمج البحث النصي مع مرشحات نمط DBMS في الهوامش بعد تحليل السجل. يمكننا البحث في عدة آلاف من السجلات في وقت واحد، والملفات النصية البسيطة ليست مناسبة لإدارة البيانات الخاصة بالمعاملات والمكررة والموزعة).

في البداية، بدا أن هذا الكود لم يكن مناسبًا جدًا لتحسين القوة الغاشمة. "العمل الحقيقي" في String.indexOf() لم يهيمن حتى على ملف تعريف وحدة المعالجة المركزية. أي أن تحسين هذه الطريقة وحدها لن يكون له تأثير كبير.

يحدث أننا نقوم بتخزين البيانات الوصفية في بداية كل صفحة، ويتم تعبئة نص جميع الرسائل بتنسيق UTF-8 في الطرف الآخر. وللاستفادة من هذا، قمنا بإعادة كتابة الحلقة للبحث في الصفحة بأكملها مرة واحدة:

البحث بسرعة 1 تيرابايت / ثانية

هذا الإصدار يعمل مباشرة على طريقة العرض raw byte[] ويبحث في جميع الرسائل مرة واحدة عبر صفحة 4K بأكملها.

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

تعتمد خوارزمية البحث الفعلية لدينا على فكرة عظيمة ليونيد فولنيتسكي. وهي تشبه خوارزمية Boyer-Moore، حيث يتم تخطي طول سلسلة البحث تقريبًا في كل خطوة. والفرق الرئيسي هو أنه يتحقق من وحدتي بايت في المرة الواحدة لتقليل التطابقات الخاطئة.

يتطلب تنفيذنا إنشاء جدول بحث بحجم 64 كيلو بايت لكل عملية بحث، ولكن هذا لا يقارن بالغيغابايت من البيانات التي نبحث فيها. تعالج الحلقة الداخلية عدة غيغابايت في الثانية على قلب واحد. من الناحية العملية، يبلغ الأداء المستقر حوالي 1,25 جيجابايت في الثانية لكل نواة، وهناك مجال للتحسين. من الممكن التخلص من بعض الحمل خارج الحلقة الداخلية، ونحن نخطط لتجربة حلقة داخلية في لغة C بدلاً من Java.

نحن نستخدم القوة

لقد ناقشنا إمكانية تنفيذ البحث في السجل "بشكل تقريبي"، ولكن ما مقدار "القوة" التي لدينا؟ كثيرا نوعا ما.

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

8 نوى: نحن نعمل حاليًا على خوادم Amazon hi1.4xlarge وi2.4xlarge SSD، كل منها يحتوي على 8 مراكز (16 موضوعًا). كما ذكرنا سابقًا، عادةً ما تكون هذه النوى مشغولة بعمليات الخلفية. عندما يقوم المستخدم بإجراء بحث، يتم تعليق عمليات الخلفية، مما يحرر جميع النوى الثمانية للبحث. يكتمل البحث عادةً في جزء من الثانية، وبعد ذلك يُستأنف العمل في الخلفية (يضمن برنامج الاختناق أن وابل استعلامات البحث لا يتداخل مع العمل المهم في الخلفية).

16 نوى: من أجل الموثوقية، نقوم بتنظيم الخوادم في مجموعات رئيسية/تابعة. كل سيد لديه SSD واحد وخادم EBS واحد تحت إمرته. إذا تعطل الخادم الرئيسي، فسيأخذ خادم SSD مكانه على الفور. في جميع الأوقات تقريبًا، يعمل السيد والعبد بشكل جيد، بحيث تكون كل كتلة بيانات قابلة للبحث على خادمين مختلفين (يحتوي خادم EBS التابع على معالج ضعيف، لذلك لا نعتبره). نقوم بتقسيم المهمة بينهما، بحيث يكون لدينا إجمالي 16 مركزًا متاحًا.

العديد من النوى: في المستقبل القريب، سنقوم بتوزيع البيانات عبر الخوادم بحيث تشارك جميعها في معالجة كل طلب غير تافه. كل جوهر سوف يعمل. [ملحوظة: قمنا بتنفيذ الخطة وقمنا بزيادة سرعة البحث إلى 1 تيرابايت/ثانية، راجع الملاحظة في نهاية المقالة].

البساطة تضمن الموثوقية

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

يُنتج فهرس الكلمات الرئيسية أحيانًا نتائج سريعة بشكل لا يصدق، وفي أحيان أخرى لا يحدث ذلك. لنفترض أن لديك 50 غيغابايت من السجلات التي يظهر فيها المصطلح "customer_5987235982" ثلاث مرات بالضبط. يقوم البحث عن هذا المصطلح باحتساب ثلاثة مواقع مباشرة من الفهرس وسيكتمل على الفور. لكن عمليات البحث المعقدة بأحرف البدل يمكن أن تفحص آلاف الكلمات الرئيسية وتستغرق وقتًا طويلاً.

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

إن بساطة طريقة القوة الغاشمة تعني أن أدائها قريب من الحد الأقصى النظري. هناك خيارات أقل للتحميل الزائد غير المتوقع على القرص، والتنافس على القفل، ومطاردة المؤشر، وآلاف الأسباب الأخرى للفشل. لقد ألقيت نظرة للتو على الطلبات التي قدمها مستخدمو Scalyr الأسبوع الماضي على خادمنا الأكثر ازدحامًا. كان هناك 14 طلب. ثمانية منهم بالضبط استغرقوا أكثر من ثانية واحدة؛ اكتمل 000% خلال 99 مللي ثانية (إذا لم تستخدم أدوات تحليل السجل، ثق بي: إنه سريع).

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

سجل البحث قيد التنفيذ

إليك رسم متحرك قصير يوضح عملية بحث Scalyr أثناء العمل. لدينا حساب تجريبي حيث نقوم باستيراد كل حدث في كل مستودع Github العام. في هذا العرض التوضيحي، قمت بفحص بيانات أسبوع كامل: ما يقرب من 600 ميجابايت من السجلات الأولية.

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

البحث بسرعة 1 تيرابايت / ثانية

في الختام

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

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

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

равка: تم تغيير العنوان والنص من "البحث بسرعة 20 جيجابايت في الثانية" إلى "البحث بسرعة 1 تيرابايت في الثانية" ليعكس زيادة الأداء خلال السنوات القليلة الماضية. ترجع هذه الزيادة في السرعة في المقام الأول إلى التغييرات في نوع وعدد خوادم EC2 التي نطرحها اليوم لخدمة قاعدة عملائنا المتزايدة. هناك تغييرات قادمة قريبًا ستوفر دفعة كبيرة أخرى في الكفاءة التشغيلية، ولا يمكننا الانتظار لمشاركتها.

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

إضافة تعليق