نجمع أكثر من ملياري حدث تحليلي في اليوم. بفضل هذا ، يمكننا اكتشاف مجموعة من الأشياء الضرورية: سواء كانوا ينقرون على القلوب أكثر من النجوم ، ما الساعات التي يكتبون فيها أوصافًا أكثر تفصيلاً ، وفي المناطق التي غالبًا ما يفوتون فيها الأزرار الخضراء.
يمكن أن يسمى نظام جمع الأحداث وتحليلها بشكل عام clickstream. سأخبرك عن الجانب الفني من مجرى النقر في Avito: ترتيب الأحداث وإرسالها وتسليمها والتحليلات والتقارير. لماذا تريد خاصتك ، إذا كان هناك Google Analytics و Yandex.Metrica ، الذين يفسدون مطوري clickstream الحياة ولماذا لا يستطيع المبرمجون أن ينسوا php.

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

مثال 2

أدوات منتهية
نحن نعرف عن Yandex Metric و Google Analytics ، نستخدمه لبعض المهام. بمساعدتهم ، من الجيد والسريع جمع البيانات التحليلية من الواجهات الأمامية. ولكن لتصدير البيانات من الخلفيات إلى الأنظمة التحليلية الخارجية ، عليك القيام بعمليات تكامل صعبة.
باستخدام الأدوات الخارجية ، يجب عليك حل مشكلة تقسيم تدفق الأحداث بشكل مستقل.
المعلومات التحليلية قيمة للغاية. لقد تم جمعها لسنوات ، فهي تتيح لنا أن نعرف بالتفصيل كيف يتصرف مستخدمونا. لا أريد مشاركة هذه المعرفة مع العالم الخارجي.
يُلزم التشريع بتخزين البيانات على أراضي روسيا.
كانت هذه الأسباب كافية تمامًا لتطوير حلنا الخاص كأداة رئيسية لجمع ومعالجة البيانات التحليلية.
الحل
يتم إرسال الأحداث من خلال النقل عالي الأداء (معالجة دفق الأحداث ، ESP) في التخزين (مستودع البيانات ، DWH). استنادًا إلى البيانات الموجودة في المستودع ، يتم إنشاء التقارير التحليلية.
حدث
كيان مركزي. في حد ذاته ، هذا يعني الحقيقة. حدث شيء ملموس في الوحدة الزمنية المعينة.
من الضروري التمييز بين حدث وآخر. هذا هو المعرف الفريد للحدث.
مهتم أيضا بوقت وقوع الأحداث. ننقله في كل حدث بدقة ميكروثانية. في الأحداث القادمة من الواجهات الأمامية ، نقوم أيضًا بإصلاح الوقت على جهاز العميل من أجل استعادة تسلسل الإجراءات بشكل أكثر دقة.
المجال
يتكون الحدث من الحقول. الحقل هو أصغر وحدة دلالية في النظام التحليلي. في الفقرة السابقة هناك أمثلة للحقول: معرف الحدث ، ووقت الإرسال.
سمات الحقل: النوع (سلسلة ، رقم ، صفيف) ، إلزامي.
البيئة
يمكن أن يحدث نفس الحدث في أجزاء مختلفة من النظام: على سبيل المثال ، التفويض ممكن على الموقع أو في تطبيق الهاتف المحمول. في هذه الحالة ، نرسل نفس الحدث ، ولكن نضيف دائمًا المعرف الفريد لمصدر الحدث بالداخل.
تختلف المصادر بشكل ملحوظ عن بعضها البعض. يمكن أن تكون الشياطين الداخلية والتيجان ، خدمة الواجهة الأمامية أو الخلفية ، تطبيق محمول. يجب إرسال جزء من الحقول مع كل حدث من مصدر معين.
هناك مفهوم "البيئة". هذا هو تجميع منطقي للأحداث حسب المصدر مع القدرة على تعيين الحقول المشتركة لجميع أحداث المصدر.
أمثلة على البيئات: "الواجهة الخلفية للخدمة A" و "الواجهة الأمامية للخدمة A" و "تطبيق ios للخدمة A".
دليل الأحداث
يتم وصف جميع الأحداث الموجودة في دليل يمكن للمطورين والمحللين تعديله. يتم تجميع الأحداث منطقياً حسب البيئة ، ولكل حدث مالك ، ويتم الاحتفاظ بسجل التغييرات في الدليل.
في الوقت الحالي ، يصف الدليل عدة مئات من الحقول وعشرات البيئات وأكثر من ألف حدث.
لانغ باك
لقد رفضنا التعذيب ، ولم نعد نجبر المطورين على كتابة كود إرسال الحدث يدويًا. بدلاً من ذلك ، وبناءً على الدليل ، نقوم بإنشاء مجموعة من الملفات لكل لغة خادم تدعمها الشركة: php أو go أو python. يسمى هذا الكود المولد "langpack".
الملفات الموجودة في langpack بسيطة قدر الإمكان ، ولا يعرفون عن منطق الأعمال في المشاريع. هذه مجموعة من الحروف والأساسات الميدانية لكل حدث وكود لإرسال الحدث.
يتم إنشاء حزمة langpack واحدة لكل بيئة. يتحلل إلى مستودع الحزمة (satis for php ، pypi for python). يتم تحديثه تلقائيًا عند إجراء تغييرات على الدليل.
لا يمكنك التوقف عن الكتابة في PHP. رمز الخدمة التي تولد langpacks مكتوب في Go. لدى الشركة ما يكفي من مشاريع PHP ، لذلك كان علي أن أتذكر لغة البرمجة المفضلة المكونة من ثلاثة أحرف وإنشاء رمز PHP على Go. إذا ابتعدت قليلاً ، يمكنك أيضًا إنشاء اختبارات لاختبار الرمز الذي تم إنشاؤه باستخدام هذه الاختبارات.
تعيين الإصدار
يمكن تحرير المرجع. لا يمكن كسر الرمز في المعركة. نقوم بإنشاء رمز القتال على أساس الدليل. بشكل خطير.
بعد كل تغيير للحدث ، يتم إنشاء نسخة جديدة في الدليل. جميع إصدارات الأحداث التي تم إنشاؤها من أي وقت مضى تعيش إلى الأبد في الدليل. لذا نحل مشكلة الثبات لأحداث معينة. تشير المشاريع دائمًا إلى إصدار الحدث الذي نعمل معه.
إذا تغير رمز langpack (على سبيل المثال ، لم يكن هناك سوى مستوطنين ، ولكننا قررنا الآن أيضًا إضافة رسائل) ، فقم بإنشاء إصدار جديد من langpack. ستعيش أيضًا إلى الأبد. تطلب المشاريع دائمًا إصدارًا محددًا من langpack لبيئتها. لذا نحل مشكلة ثبات واجهة langpack.
نستخدم semver. يتكون إصدار كل langpack من ثلاثة أرقام. الأول دائمًا صفر ، والثاني هو إصدار رمز langpack ، والثالث هو الزيادة. يتغير الرقم الثالث في أغلب الأحيان ، بعد كل تغيير للأحداث.
تسمح لك الإصدارات ذات المستويين بتحرير الدليل دون كسر الشفرة في المعركة. يقوم على مبدأين: لا يمكنك حذف أي شيء. لا يمكنك تحرير الكيانات المنشأة ، فقط قم بإنشاء نسخ معدلة جنبًا إلى جنب.
النقل
على عكس اللاعبين من Badoo على LSD ، لم نتعلم أبدًا كتابة الملفات بشكل جميل . ونعتقد أن NSQ ليس فقط خادم انتظار ، ولكنه أيضًا وسيلة نقل للأحداث.
قاموا بإخفاء NSQ خلف طبقة صغيرة من كود go ، ووضعوا جامعي لكل عقدة في مجموعة Kubernetes باستخدام مجموعات خفية ، وكتبوا مستهلكين يمكنهم إضافة أحداث إلى مصادر مختلفة.
في الوقت الحالي ، يقدم النقل حوالي ملياري حدث في اليوم. تحت هذا الحمل ، يعمل ثلاثون جامعًا مع بعض الهامش. كل منها يستهلك المزيد من نواة المعالج وأكثر من غيغابايت من الذاكرة.
توجيه الأحداث
يمكن أن يكون مرسلو الأحداث مشاريع تعيش داخل مجموعتنا أو خارجها. داخل التجمعات ، هذه هي الواجهة الخلفية للخدمة ، والتيجان ، والشياطين ، ومشاريع البنية التحتية ، وإنترانت. في الخارج ، تأتي الأحداث من واجهة المشاريع العامة ، من تطبيقات الهاتف المحمول والمشاريع الشريكة.
لتلقي الأحداث خارج الكتلة ، نستخدم وكيل. نقطة دخول مشتركة مع تصفية صغيرة لتدفق الأحداث ، مع إمكانية إثرائها. مزيد من النقل للنقل حسب المخطط العام.
مخطط التوجيه العام: يمكن أن يكون لكل حدث مجموعة من المستلمين. يشمل المستلمون المحتملون مستودعًا تحليليًا مشتركًا (DWH) أو مشاريع إعادة بناء أو مشاريع مونغا مهتمة ببعض الأحداث. يتم استخدام الحالة الأخيرة ، على سبيل المثال ، لإعادة تدريب نماذج الإشراف التلقائي للإعلانات. تستمع النماذج إلى أحداث معينة ، والحصول على الملاحظات اللازمة.
من جانب المشاريع لا توجد معرفة حول التوجيه. يرسلون الأحداث باستخدام langpacks حيث يتم خياطة عناوين هواة الجمع الشائعة.
التخزين
مستودع الأحداث الرئيسي هو HP Vertica ، بضع عشرات تيرابايت. قاعدة عمود بميزات مناسبة لمحللينا. واجهة - تابلوه لإعداد التقارير.
إنه أكثر كفاءة لتسجيل الأحداث في تخزيننا على دفعات كبيرة. أمام التخزين عازلة على شكل مونغو. مجموعات الحذف التلقائي التي تم إنشاؤها تلقائيًا لكل ساعة. يتم تخزين المجموعات لعدة أيام حتى تتمكن من إعادة تشغيل التدقيق اللغوي في Vertica إذا حدث خطأ ما.
قراءات من العازلة مونغو على مخطوطات الحيوانات الأليفة. يتم توجيه البرامج النصية بمرجع ، ونحن نحاول عدم الاحتفاظ بمنطق الأعمال هنا. في هذه المرحلة ، من الممكن إثراء الحدث.
التطور
الرقص اليد في الظلام
نشأت الحاجة إلى تسجيل الأحداث في وقت أبكر بكثير من الوعي بالحاجة إلى الحفاظ على دليل. توصل المطورون في كل مشروع إلى طريقة لإرسال الأحداث ، يبحثون عن النقل. أدى ذلك إلى توليد الكثير من التعليمات البرمجية بلغات مختلفة ، والكذب في مشاريع مختلفة ، ولكن حل مشكلة واحدة.
في كثير من الأحيان داخل رمز إرسال الحدث ، عاشت أجزاء من منطق الأعمال. لا يمكن نقل التعليمات البرمجية بهذه المعرفة إلى مشاريع أخرى. عند إعادة الهيكلة ، يجب إعادة منطق الأعمال إلى المشروع ، تاركًا في رمز الحدث الامتثال فقط لتنسيق البيانات المحدد.
في هذه المرحلة ، لم يكن هناك دليل للأحداث. لفهم الأحداث التي تم تسجيلها بالفعل ، وما هي الحقول التي كانت موجودة بها الأحداث ، كان ذلك ممكنًا فقط من خلال النظر في الرمز. لتعلم أن المطور توقف عن طريق الخطأ عن كتابة البيانات في الحقل المطلوب ، كان من الممكن عند إنشاء التقرير ، إذا كنت تولي اهتمامًا خاصًا لذلك.
لم تكن هناك أحداث كثيرة. تم إضافة مجموعات عازلة في النمس حسب الحاجة. مع نمو عدد الأحداث ، كان من الضروري إعادة توجيه الأحداث يدويًا إلى مجموعات أخرى ، لإنشاء المجموعات اللازمة. تم اتخاذ قرار بوضع الحدث في مجموعة عازلة معينة في وقت الإرسال ، على جانب المشروع. كان النقل بطلاقة ، العميل لأنه كان td-agent.
علم غير متزامن
تقرر إنشاء دليل لجميع الأحداث الموجودة. قمنا بتحليل رمز الخلفية ، وسحبنا بعض المعلومات من هناك. لقد ألزمنا المطورين بتدوين ذلك في الدليل مع كل تغيير في رمز الحدث.
تم وصف الأحداث القادمة من الواجهات الأمامية والتطبيقات المحمولة يدويًا ، وأحيانًا يتم التقاط المعلومات اللازمة من دفق الأحداث على مستوى النقل.
المطورين يعرفون كيف ينسون. أدى هذا إلى عدم تزامن الدليل والكود ، لكن الدليل أظهر الصورة العامة.
ازداد عدد المجموعات العازلة بشكل ملحوظ ، وزاد العمل اليدوي للحفاظ عليها بشكل ملحوظ. ظهر شخص لا غنى عنه مع مجموعة من المعرفة السرية حول التخزين المؤقت.
النقل الجديد
قاموا بإنشاء وسيلة نقل مشتركة ، ESP ، على علم بجميع نقاط تسليم الحدث. لقد جعلوها نقطة استقبال واحدة. هذا جعل من الممكن التحكم في جميع تدفقات الأحداث. توقفت المشاريع مباشرة عن الوصول إلى التخزين المؤقت.
Clickstreamism المستنير
بناء على الدليل ، تم إنشاء langpacks. أنها لا تسمح بإنشاء أحداث غير صالحة.
أدخلت فحوصات تلقائية لصحة الأحداث القادمة من الواجهات والتطبيقات المحمولة. في هذه الحالة ، لا نتوقف عن كتابة الأحداث حتى لا نفقد البيانات ، ولكننا نسجل الأخطاء ونشير إلى المطورين.
يتم التحقق من الأحداث النادرة في الخلفية التي يصعب إعادة هيكلها والتي لم يتم إرسالها بعد من خلال langpacks بواسطة مكتبة منفصلة وفقًا للقواعد من الدليل. في الأخطاء ، قم برمي استثناء يمنع الطرح.
حصلت على نظام يميل إلى مطابقة الدليل. المكافآت: الشفافية ، الإدارة ، سرعة الإنشاء وتغيير الأحداث.
خاتمة
كانت الصعوبات والدروس الرئيسية التنظيمية. من الصعب ربط المبادرات التي تضم عدة فرق. ليس من السهل تغيير رمز مشروع قديم كبير. مهارات التواصل مع الفرق الأخرى ، وتقسيم المهام إلى تكامل مستقل نسبيًا ومدروس مسبقًا مع إمكانية تقديم المساعدة المستقلة. لم يعد مطورو Clickstream يحبون فرق المنتج عندما تبدأ مرحلة التكامل لحل جديد. إذا تغيرت الواجهات ، يتم إضافة العمل إلى الجميع.
كان إنشاء دليل فكرة جيدة للغاية. أصبح المصدر الوحيد للحقيقة ، يمكنك دائمًا مناشدته في حالة وجود اختلافات في المدونة. يرتبط الكثير من الأتمتة بالدليل: الشيكات ، وتوجيه الأحداث ، وإنشاء التعليمات البرمجية.
البنية التحتية لا تحتاج إلى معرفة منطق الأعمال. علامات ظهور منطق الأعمال: تتغير الأحداث على طول الطريق من المشروع إلى المستودع ؛ تغيير النقل دون تغيير المشاريع يصبح مستحيلا. على جانب البنية التحتية ، يجب أن يكون هناك معرفة حول تكوين الأحداث وأنواع الحقول وإلزامها. من ناحية المنتج ، المعنى المنطقي لهذه الحقول.
هناك دائما مجال للنمو. من الناحية الفنية ، هذه زيادة في عدد الأحداث ، انخفاض في الوقت من إنشاء الحدث إلى بداية تسجيل البيانات ، والقضاء على العمل اليدوي في جميع المراحل.
هناك بضعة أفكار جريئة. الحصول على رسم بياني مفصل لانتقالات المستخدم ، وتكوين الأحداث بسرعة دون طرح الخدمة. ولكن المزيد عن ذلك في المقالات التالية.
PS لقد تحدثت عن هذا الموضوع في اجتماع Backend United # 1. صلصة الخل. يمكن أن يرى
عرض أو فيديو من الاجتماع.