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

بالنسبة لمقدمي العروض المحترفين ، تعتبر المعلمات مثل زمن الاستجابة واستقرار توزيع الوقت (الارتعاش) وموثوقية المجمع بالكامل من الأمور الحاسمة. حاليًا ، نعالج عشرات الملايين من المعاملات يوميًا. تستغرق معالجة كل معاملة بواسطة النظام الأساسي عشرات من مايكروثانية. بطبيعة الحال ، مع مشغلي شبكات الهاتف النقال في السنة الجديدة أو مع محركات البحث ، يكون الحمل نفسه أعلى من حملنا ، ولكن من حيث التحميل ، إلى جانب الخصائص المذكورة أعلاه ، يمكن أن يقارن عدد قليل منا ، كما يبدو لي. في الوقت نفسه ، من المهم بالنسبة لنا ألا يتباطأ النظام لفترة ثانية ، ويعمل بشكل ثابت تمامًا ، وأن جميع المستخدمين على قدم المساواة.
قليلا من التاريخ
في عام 1994 ، تم إطلاق نظام ASTS الأسترالي في بورصة موسكو بين البنوك (MICEX) ، ومن هذه اللحظة يمكنك حساب التاريخ الروسي للتجارة الإلكترونية. في عام 1998 ، تم تحديث بنية البورصة لإدخال التداول عبر الإنترنت. منذ ذلك الحين ، تكتسب سرعة تقديم حلول جديدة وتغييرات معمارية في جميع الأنظمة والأنظمة الفرعية قوة دفع فقط.
في تلك السنوات ، كان نظام التبادل يعمل على أجهزة عالية الجودة - خوادم HP Superdome 9000 الموثوقة للغاية (المبنية على
بنية PA-RISC ) ، والتي تكرر كل شيء على الإطلاق: أنظمة الإدخال / الإخراج الفرعية ، والشبكة ، وذاكرة الوصول العشوائي (في الواقع ، كانت هناك مجموعة RAID من RAM ) ، المعالجات (تبادل الساخنة معتمدة). كان من الممكن تغيير أي مكون من مكونات الخادم دون إيقاف تشغيل الجهاز. اعتمدنا على هذه الأجهزة ، اعتبرناها خالية من المتاعب فعليًا. كان نظام التشغيل يشبه يونيكس HP UX.
ولكن منذ حوالي عام 2010 ، نشأت ظاهرة مثل التداول عالي التردد (HFT) ، أو التداول عالي التردد ، ببساطة ، تبادل الروبوتات. في 2.5 سنة فقط ، زاد الحمل على خوادمنا 140 مرة.

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

من الناحية التخطيطية ، يمكن تقسيم جوهر النظام إلى ثلاثة مستويات:
- مستوى العميل الذي يعمل فيه الوسطاء والعملاء. كلهم يتفاعلون مع خوادم الوصول.
- خوادم الوصول (Gateways) هي خوادم تخزين مؤقت تقوم بمعالجة جميع طلبات المعلومات محليًا. تريد أن تعرف بأي سعر يتم تداول أسهم سبيربنك الآن؟ يذهب الطلب إلى خادم الوصول.
- ولكن إذا كنت ترغب في شراء الأسهم ، فإن الطلب موجود بالفعل على الخادم المركزي (Trade Engine). هناك خادم واحد لكل نوع من أنواع السوق ، يلعبون دوراً حاسماً ، وقد أنشأنا هذا النظام لهم.
جوهر نظام التداول هو قاعدة بيانات صعبة في الذاكرة تكون فيها جميع المعاملات معاملات تبادل. تمت كتابة القاعدة باللغة C ، أما التبعيات الخارجية فلم يكن هناك سوى مكتبة libc ولم يتم تخصيص ذاكرة ديناميكية بالكامل. لتقليل وقت المعالجة ، يبدأ النظام بمجموعة ثابتة من المصفوفات وبنقل ثابت للبيانات: أولاً ، يتم تحميل جميع البيانات الخاصة باليوم الحالي في الذاكرة ، ثم لا يتم الوصول إلى القرص ، تتم جميع الأعمال فقط في الذاكرة. عند بدء تشغيل النظام ، يتم فرز جميع البيانات المرجعية بالفعل ، وبالتالي فإن البحث يعمل بكفاءة عالية ويستغرق وقتًا طويلاً في وقت التشغيل. تصنع جميع الجداول بقوائم وأشجار متطفلة لهياكل البيانات الديناميكية بحيث لا تتطلب تخصيص ذاكرة في وقت التشغيل.
دعنا نذهب لفترة وجيزة إلى تاريخ تطوير نظام التداول والمقاصة الخاص بنا.
تم بناء الإصدار الأول من بنية نظام التداول والمقاصة على ما يسمى بتفاعل يونكس: تم استخدام الذاكرة المشتركة والإشارة والصفوف ، وكانت كل عملية تتألف من مؤشر ترابط واحد. كان هذا النهج واسع الانتشار في أوائل التسعينيات.
احتوى الإصدار الأول من النظام على مستويين من Gateway وخادم مركزي للنظام التجاري. مخطط العمل كان على النحو التالي:
- يرسل العميل طلبًا يصل إلى Gateway. إنه يتحقق من صحة التنسيق (ولكن ليس البيانات نفسها) ويرفض المعاملة الخاطئة.
- إذا تم إرسال طلب معلومات ، فسيتم تنفيذه محليًا ؛ إذا كانت هذه معاملة ، فسيتم إعادة توجيهها إلى الخادم المركزي.
- ثم يعالج محرك التداول المعاملة ، ويغير الذاكرة المحلية ويرسل ردًا على المعاملة ، وهو نفسه - للنسخ المتماثل باستخدام آلية نسخ متماثل منفصلة.
- يستقبل Gateway استجابة من العقدة المركزية ويعيد توجيهها إلى العميل.
- بعد فترة من الزمن ، تستقبل البوابة المعاملة باستخدام آلية النسخ المتماثل ، وتقوم هذه المرة بتنفيذها محليًا ، وتغيير بنيات البيانات الخاصة بها بحيث تعرض طلبات المعلومات التالية البيانات الفعلية.
في الواقع ، يتم وصف نموذج النسخ المتماثل هنا ، حيث تكرر Gateway تمامًا الإجراءات التي يتم تنفيذها في نظام التداول. قدمت قناة النسخ المتماثل منفصلة نفس ترتيب تنفيذ المعاملة على عقد وصول متعددة.
نظرًا لأن الشفرة كانت ذات سلاسل مفردة ، تم استخدام مخطط كلاسيكي بعمليات متشعبة لخدمة العديد من العملاء. ومع ذلك ، كان إنشاء شوكة لقاعدة البيانات بأكملها مكلفًا للغاية ، لذلك تم استخدام عمليات خدمة خفيفة الوزن تجمع الحزم من جلسات TCP ونقلتها إلى قائمة انتظار واحدة (قائمة انتظار رسائل SystemV). عملت Gateway and Trade Engine فقط مع قائمة الانتظار هذه ، مع أخذ المعاملات للتنفيذ من هناك. كان من المستحيل بالفعل إرسال إجابة عليه ، لأنه ليس من الواضح أي عملية خدمة يجب قراءتها. لذلك لجأنا إلى خدعة: كل عملية متشعبة تنشئ قائمة انتظار استجابة لنفسها ، وعندما يتم تقديم طلب في قائمة الانتظار الواردة ، تمت إضافة علامة قائمة انتظار الاستجابة على الفور إلى ذلك.
إنشاء نسخ ثابتة من قائمة الانتظار إلى قائمة انتظار كميات كبيرة من البيانات مشاكل ، خاصةً خصائص طلبات المعلومات. لذلك ، استفدنا من خدعة أخرى: بالإضافة إلى قائمة انتظار الاستجابة ، قامت كل عملية أيضًا بإنشاء ذاكرة مشتركة (ذاكرة النظام المشتركة للنظام). تم وضع الحزم نفسها فيها ، وتم حفظ العلامة فقط في قائمة الانتظار ، مما يتيح لك العثور على الحزمة المصدر. ساعد هذا في تخزين البيانات في ذاكرة التخزين المؤقت للمعالج.
يتضمن SystemV IPC أدوات مساعدة لعرض حالة قائمة الانتظار والذاكرة وكائنات الإشارة. استخدمنا هذا بنشاط من أجل فهم ما يحدث في النظام في لحظة معينة ، حيث تتراكم الحزم ، والتي يتم حظرها ، إلخ.
التحديث الأول
بادئ ذي بدء ، تخلصنا من بوابة العملية الواحدة. كان العيب الكبير هو أنه يمكن معالجة معاملة النسخ متماثل واحد أو طلب معلومات واحد من عميل. ومع زيادة التحميل ، ستقوم البوابة بمعالجة الطلبات لفترة أطول ولن تتمكن من معالجة دفق النسخ المتماثل. بالإضافة إلى ذلك ، إذا أرسل العميل معاملة ، فأنت بحاجة فقط إلى التحقق من صلاحيتها وإعادة توجيهها. لذلك ، استبدلنا إحدى عمليات Gateway بعدة مكونات يمكن أن تعمل بشكل متوازٍ: المعلومات متعددة العمليات وعمليات المعاملات التي تعمل بشكل مستقل عن بعضها البعض مع منطقة ذاكرة مشتركة باستخدام RW-lock. وفي الوقت نفسه قدمنا عمليات الجدولة والنسخ المتماثل.
تأثير التداول عالي التردد
استمرت النسخة أعلاه من العمارة حتى عام 2010. وفي الوقت نفسه ، لم نعد راضين عن أداء خوادم HP Superdome. بالإضافة إلى ذلك ، توفي هيكل PA-RISC بالفعل ؛ لم يقدم البائع أي تحديثات مهمة. نتيجة لذلك ، بدأنا في التحول من HP UX / PA RISC إلى Linux / x86. بدأ الانتقال مع تكييف خوادم الوصول.
لماذا يتعين علينا تغيير الهيكل مرة أخرى؟ والحقيقة هي أن التداول عالي التردد قد غيّر بشكل كبير من ملف تعريف تحميل النظام الأساسي.
لنفترض أن لدينا معاملة صغيرة تسببت في تغيير كبير في السعر - اشترى شخص ما نصف مليار دولار. بعد بضع ميلي ثانية ، يلاحظ جميع المشاركين في السوق هذا ويبدأون في التصحيح. وبطبيعة الحال ، تصطف الطلبات في طابور كبير ، والذي سيشعله النظام لفترة طويلة.

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

جولة جديدة من التطور
بعد إجراء اختبارات وبحوث مستفيضة ، تحولنا إلى نواة نظام التشغيل في الوقت الفعلي. للقيام بذلك ، اختاروا RedHat Enterprise MRG Linux ، حيث يرمز MRG إلى شبكة الرسائل في الوقت الحقيقي. تتمثل ميزة التصحيحات في الوقت الفعلي في أنها تقوم بتحسين النظام لتحقيق أسرع تنفيذ ممكن: يتم ترتيب جميع العمليات في طابور FIFO ، يمكنك عزل النواة ، لا قطرات ، تتم معالجة جميع المعاملات في تسلسل صارم.
أحمر - العمل مع قائمة انتظار في نواة عادية ، أخضر - العمل في نواة في الوقت الحقيقي.لكن تحقيق الكمون المنخفض على الخوادم العادية ليس بالأمر السهل:
- يتداخل وضع SMI ، الذي يقع في بنية x86 ، في قلب العمل مع الأجهزة الطرفية الهامة ، بشكل كبير. تتم معالجة الأحداث المختلفة للأجهزة وإدارة المكونات والأجهزة بواسطة البرامج الثابتة في ما يسمى بوضع SMI الشفاف ، حيث لا يرى نظام التشغيل ما الذي تفعله البرامج الثابتة على الإطلاق. وكقاعدة عامة ، يقدم جميع البائعين الرئيسيين ملحقات خاصة لخوادم البرامج الثابتة ، مما يسمح بتقليل مقدار معالجة SMI.
- يجب ألا يكون هناك تحكم ديناميكي في تردد المعالج ، وهذا يؤدي إلى توقف إضافي.
- عند إعادة تعيين سجل نظام الملفات ، تحدث عمليات معينة في النواة تؤدي إلى تأخير غير متوقع.
- تحتاج إلى الانتباه إلى أشياء مثل وحدة المعالجة المركزية تقارب ، تقارب المقاطعة ، NUMA.
يجب أن أقول أن موضوع تكوين أجهزة Linux و kernel للمعالجة الفعلية يستحق مقالة منفصلة. قضينا الكثير من الوقت في التجارب والأبحاث قبل أن نحقق نتيجة جيدة.
عند التبديل من خوادم PA-RISC إلى x86 ، لم يكن لدينا عملياً تغيير رمز النظام كثيرًا ، بل قمنا فقط بتكييفه وإعادة تكوينه. في الوقت نفسه ، تم إصلاح العديد من الأخطاء. على سبيل المثال ، ظهرت النتائج بسرعة أن PA RISC كان نظام endian كبير و x86 نظام endian صغير: على سبيل المثال ، لم تتم قراءة البيانات بشكل صحيح. كان الخلل الأكثر صعوبة هو أن PA RISC يستخدم الوصول
المتسق للذاكرة ، في حين أن x86 يمكنه إعادة ترتيب عمليات القراءة ، وبالتالي فإن الشفرة الصالحة تمامًا على منصة واحدة تصبح غير صالحة للعمل على نظام آخر.
بعد التبديل إلى x86 ، زادت الإنتاجية ثلاث مرات تقريبًا ، انخفض متوسط وقت معالجة المعاملات إلى 60 ميكرون.
دعونا الآن نلقي نظرة فاحصة على التغييرات الرئيسية التي تم إجراؤها على بنية النظام.
ملحمة الاستعداد الساخنة
بالانتقال إلى خوادم السلع ، كنا ندرك أنها أقل موثوقية. لذلك ، عند إنشاء بنية جديدة ، افترضنا سلفًا احتمال فشل عقد أو أكثر. لذلك ، كنا بحاجة إلى نظام الاستعداد الساخن قادر على التبديل بسرعة كبيرة إلى آلات النسخ الاحتياطي.
بالإضافة إلى ذلك ، كانت هناك متطلبات أخرى:
- في أي حال من الأحوال يجب أن تفقد المعاملات المعالجة.
- يجب أن يكون النظام شفافًا تمامًا في البنية التحتية لدينا.
- يجب ألا يرى العملاء فواصل الاتصال.
- لا ينبغي أن يؤدي الحجز إلى تأخير كبير ، لأن هذا عامل حاسم في التبادل.
عند إنشاء نظام الاستعداد السريع ، لم نعتبر هذه السيناريوهات بمثابة فشل مزدوج (على سبيل المثال ، توقفت الشبكة الموجودة على خادم واحد عن العمل وتعلق الخادم الرئيسي) ؛ لم يأخذ في الاعتبار احتمال وجود أخطاء في البرنامج ، لأنه يتم اكتشافها أثناء الاختبار ؛ ولم ينظر في خلل الحديد.
نتيجة لذلك ، توصلنا إلى المخطط التالي:

- تفاعل الخادم الرئيسي مباشرة مع خوادم Gateway.
- تم نسخ جميع المعاملات المستلمة على الخادم الرئيسي على الفور إلى خادم النسخ الاحتياطي عبر قناة منفصلة. قام الحكم (الحاكم) بتنسيق التبديل عند حدوث أي مشاكل.

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

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