في حديثه ، سيخبرك Andrey Borodin كيف أخذوا في الاعتبار تجربة تحجيم PgBouncer عند تصميم مجمّع اتصال
فيديو:
أهلاً بكم! أسمي أندرو.
في Yandex ، أقوم بتطوير قواعد بيانات مفتوحة المصدر. واليوم لدينا موضوع حول اتصالات مجمّع الاتصال.
إذا كنت تعرف كيفية الاتصال بمجمع الاتصال باللغة الروسية ، فأخبرني بذلك. أريد حقًا أن أجد مصطلحًا تقنيًا جيدًا يجب تحديده في الأدبيات الفنية.
الموضوع معقد للغاية ، لأنه في العديد من قواعد البيانات ، يكون مجمع الاتصالات مدمجًا ولا تحتاج حتى إلى معرفته. بعض الإعدادات ، بالطبع ، موجودة في كل مكان ، لكن هذا لا يعمل في Postgres. وبالتوازي مع ذلك (في HighLoad ++ 2019) يوجد تقرير من نيكولاي ساموخفالوف حول إعداد استعلامات في Postgres. وأنا أفهم أن الأشخاص قد أتوا إلى هنا والذين قاموا بالفعل بتهيئة الطلبات بشكل مثالي ، وهؤلاء هم الأشخاص الذين يواجهون مشكلات نادرة في النظام تتعلق بالشبكة واستخدام الموارد. وفي بعض الأماكن ، قد يكون الأمر صعبًا جدًا بمعنى أن المشكلات ليست واضحة.
ياندكس لديها Postgres. تعيش العديد من خدمات Yandex في Yandex.Cloud. ولدينا عدة بيتابايتات من البيانات التي تولد ما لا يقل عن مليون طلب في الثانية في Postgres.
ونحن نقدم مجموعة نموذجية إلى حد ما لجميع الخدمات - هذه هي العقدة الأساسية الرئيسية للعقدة ، النسختان المتماثلتان المعتادتان (متزامنة وغير متزامنة) ، والنسخ الاحتياطي ، وتوسيع نطاق طلبات القراءة على النسخة المتماثلة.
كل عقدة عنقود هي Postgres ، والتي ، بالإضافة إلى Postgres وأنظمة المراقبة ، يتم أيضًا تثبيت مجمّع اتصال. يستخدم مجمّع الاتصال في السياج ولغرضه الرئيسي.
ما هو الغرض الرئيسي من مجمّع الاتصال؟
تتبنى Postgres نموذج عملية للعمل مع قاعدة بيانات. هذا يعني أن الاتصال الواحد هو عملية واحدة ، وخلفية Postgres واحدة. وهناك الكثير من ذاكرات التخزين المؤقت المختلفة في هذه الواجهة الخلفية ، وهي مكلفة جدًا لعملها باختلاف التوصيلات المختلفة.
أيضًا ، هناك مصفوفة في كود Postgres تسمى procArray. يحتوي على بيانات أساسية حول اتصالات الشبكة. وجميع خوارزميات معالجة procArray تقريبًا لها تعقيد خطي ، فهي تعمل عبر مجموعة كاملة من اتصالات الشبكة. إنها دورة سريعة جدًا ، ولكن مع المزيد من اتصالات الشبكة الواردة ، تصبح الأشياء أكثر تكلفة قليلاً. وعندما تصبح الأشياء أكثر تكلفة ، ينتهي بك الأمر بدفع ثمن باهظ للغاية لعدد كبير من اتصالات الشبكة.
هناك 3 طرق ممكنة:
- على جانب التطبيق.
- على جانب قاعدة البيانات.
- وبين كل التوليفات الممكنة.
لسوء الحظ ، المجمّع المدمج قيد التطوير حاليًا. يقوم الأصدقاء في PostgreSQL Professional بهذا في الغالب. متى سيظهر من الصعب التنبؤ به. وفي الحقيقة ، لدينا حلان لاختيار المهندس المعماري. هذه هي تجمع التطبيق وتجمع الوكيل.
تجمع جانب التطبيق هو أسهل طريقة. وتوفر لك جميع برامج تشغيل العملاء تقريبًا طريقة: لتمثيل الملايين من اتصالاتك في الكود كعشرات الاتصالات بقاعدة البيانات.
هناك مشكلة في حقيقة أنك تريد في مرحلة معينة توسيع نطاق الخلفية ، فأنت تريد نشرها على العديد من الأجهزة الافتراضية.
ثم ما زلت تدرك أن لديك العديد من مناطق التوافر ، والعديد من مراكز البيانات. ويؤدي نهج التجميع من جانب العميل إلى أعداد كبيرة. الكبيرة منها حوالي 10 اتصال. هذه ميزة يمكن أن تعمل بشكل جيد.
إذا تحدثنا عن مجمعات البروكسي ، فهناك اثنان من المجمعين الذين يمكنهم القيام بالكثير من الأشياء. هم ليسوا فقط مسابح. هم مسابح + المزيد من الوظائف الرائعة. هذا
لكن لسوء الحظ ، لا يحتاج الجميع إلى هذه الوظيفة الإضافية. ويؤدي ذلك إلى حقيقة أن المجمعات يدعمون تجميع الجلسات فقط ، أي عميل وارد واحد ، وعميل صادر واحد إلى قاعدة البيانات.
هذا ليس مناسبًا جدًا لمهامنا ، لذلك نستخدم PgBouncer ، الذي ينفذ تجميع المعاملات ، أي يتم تعيين اتصالات الخادم لاتصالات العميل فقط طوال مدة المعاملة.
وعلى حمولتنا - هذا صحيح. لكن هناك العديد من المشاكل.
تبدأ المشاكل عندما تريد تشخيص جلسة ، لأن جميع الاتصالات الواردة محلية. جاء الجميع مع الاسترجاع ويصبح من الصعب بطريقة ما تتبع الجلسة.
بالطبع يمكنك استخدام application_name_add_host. هذه هي طريقة الحارس الجانبية لإضافة عنوان IP إلى اسم التطبيق. ولكن يتم تعيين اسم التطبيق من خلال اتصال إضافي.
في هذا المخطط ، حيث يمثل الخط الأصفر طلبات حقيقية ، وحيث يمثل الخط الأزرق الطلبات التي تنتقل إلى قاعدة البيانات. وهذا الاختلاف هو تحديدًا إعداد اسم التطبيق ، وهو مطلوب فقط للتتبع ، ولكنه ليس مجانيًا على الإطلاق.
بالإضافة إلى ذلك ، لا يمكن لـ Bouncer تقييد تجمع واحد ، أي عدد اتصالات قاعدة البيانات لكل مستخدم ، لكل قاعدة بيانات.
الى ماذا يؤدي هذا؟ لديك خدمة محملة مكتوبة بلغة C ++ وفي مكان قريب خدمة صغيرة على عقدة لا تفعل شيئًا خاطئًا مع القاعدة ، لكن سائقها مجنون. يفتح 20 اتصال وكل شيء آخر سينتظر. حتى التعليمات البرمجية الخاصة بك صحيحة.
بالطبع ، كتبنا تصحيحًا صغيرًا لـ Bouncer أضاف هذا الإعداد ، أي قصر العملاء على التجمع.
سيكون من الممكن القيام بذلك من جانب Postgres ، أي قصر الأدوار في قاعدة البيانات على عدد الاتصالات.
ولكن بعد ذلك تفقد القدرة على فهم سبب عدم وجود اتصالات بالخادم. لا يتسبب PgBouncer في حدوث خطأ في الاتصال ، بل يقوم دائمًا بإرجاع نفس المعلومات. ولا يمكنك فهم: ربما تم تغيير كلمة المرور الخاصة بك ، وربما تعطلت قاعدة البيانات للتو ، وربما حدث خطأ ما. لكن لا يوجد تشخيص. إذا تعذر إنشاء الجلسة ، فلن تعرف لماذا لا يمكن إجراؤها.
في مرحلة معينة ، تنظر إلى الرسوم البيانية للتطبيق وترى أن التطبيق لا يعمل.
انظر إلى الأعلى وشاهد أن الحارس ذو خيط واحد. هذه نقطة تحول في حياة الخدمة. أنت تدرك أنك كنت تستعد لتوسيع نطاق قاعدة البيانات خلال عام ونصف ، وتحتاج إلى توسيع نطاق المجمّع.
لقد توصلنا إلى استنتاج أننا بحاجة إلى المزيد من PgBouncers.
تم تصحيح الحارس قليلاً.
وقد صنعوها بحيث يمكن رفع العديد من الحراس مع إعادة استخدام منفذ TCP. وبالفعل يقوم نظام التشغيل تلقائيًا بنقل اتصالات TCP الواردة بينها عن طريق round-robin'om.
هذا واضح للعملاء ، أي يبدو أن لديك Bouncer واحدًا ، لكن لديك تجزئة للاتصالات الخاملة بين تشغيل Bouncers.
وفي مرحلة ما ، قد تلاحظ أن هؤلاء الحراس الثلاثة يأكلون قلبهم بنسبة 3٪. أنت بحاجة إلى عدد غير قليل من الحراس. لماذا؟
لأن لديك TLS. لديك اتصال مشفر. وإذا قمت بقياس Postgres باستخدام TLS وبدونه ، فستجد أن عدد الاتصالات التي تم إنشاؤها ينخفض بمقدار ضعفين تقريبًا مع تمكين التشفير ، لأن مصافحة TLS تستهلك موارد وحدة المعالجة المركزية.
وفي الجزء العلوي ، يمكنك رؤية عدد غير قليل من وظائف التشفير التي يتم تنفيذها أثناء موجة من الاتصالات الواردة. نظرًا لأننا الأساسي يمكنه التبديل بين مناطق التوفر ، فإن موجة الاتصالات الواردة هي حالة نموذجية إلى حد ما. هذا ، لسبب ما ، لم يكن الأساسي القديم متاحًا ، وتم إرسال الحمل بالكامل إلى مركز بيانات آخر. سيأتون جميعًا لإلقاء التحية على TLS في نفس الوقت.
وقد لا يستقبل عدد كبير من مصافحة TLS الحارس بالفعل ، ولكنه يضغط على حلقه. قد تصبح موجة من الاتصالات الواردة غير مخمد بسبب انتهاء المهلة. إذا قمت بإعادة المحاولة إلى القاعدة دون تراجع أسي ، فلن يعودوا مرارًا وتكرارًا في موجة متماسكة.
فيما يلي مثال على 16 PgBouncers التي تحمل 16 نواة بنسبة 100٪.
لقد وصلنا إلى PgBouncer المتتالي. هذا هو أفضل تكوين يمكننا تحقيقه في تحميل Bouncer الخاص بنا. تعمل Bouncers الخارجية الخاصة بنا لمصافحة TCP ، وتعمل الحراس الداخلية للتجميع الحقيقي ، حتى لا تؤدي إلى تفتيت الاتصالات الخارجية بشكل كبير.
في هذا التكوين ، يمكن إعادة التشغيل الناعمة. يمكنك إعادة تشغيل كل هذه الحراس الـ 18 واحدًا تلو الآخر. لكن الحفاظ على مثل هذا التكوين أمر صعب للغاية. لن يكون مسؤولو النظام و DevOps والأشخاص المسؤولون حقًا عن هذا الخادم سعداء جدًا بهذا المخطط.
يبدو أنه يمكن الترويج لجميع تحسيناتنا في المصدر المفتوح ، لكن Bouncer لا يدعم بشكل جيد. على سبيل المثال ، تم الالتزام بالقدرة على تشغيل PgBouncers متعددة على نفس المنفذ منذ شهر. تم طلب سحب هذه الميزة قبل بضع سنوات.
أو مثال آخر. في Postgres ، يمكنك إلغاء طلب قيد التشغيل عن طريق إرسال السر إلى اتصال آخر بدون المصادقة الإضافية. لكن بعض العملاء يرسلون ببساطة إعادة تعيين TCP ، أي يقطعون اتصال الشبكة. ماذا سيفعل الحارس بهذا؟ لن يفعل أي شيء. ستستمر في تنفيذ الطلب. إذا كنت قد تلقيت عددًا كبيرًا من الاتصالات التي وضعت القاعدة بطلبات صغيرة ، فلن يكون فصل الاتصال عن الحارس كافيًا ، بل تحتاج أيضًا إلى إكمال تلك الطلبات التي يتم تشغيلها في قاعدة البيانات.
تم تصحيح هذا الأمر ولم يتم دمج المشكلة بعد في المنبع في Bouncer.
وهكذا توصلنا إلى استنتاج مفاده أننا نحتاج إلى مجمّع الاتصال الخاص بنا ، والذي سيتم تطويره وتصحيحه ، حيث سيكون من الممكن إصلاح المشكلات بسرعة والتي ، بالطبع ، يجب أن تكون متعددة الخيوط.
وضعنا تعدد مؤشرات الترابط كمهمة رئيسية. نحن بحاجة إلى أن نكون قادرين على التعامل مع موجة اتصالات TLS الواردة بشكل جيد.
للقيام بذلك ، كان علينا تطوير مكتبة منفصلة تسمى Machinarium ، والتي تم تصميمها لوصف حالات الجهاز لاتصال الشبكة كرمز تسلسلي. إذا نظرت إلى شفرة مصدر libpq ، فسترى مكالمات معقدة جدًا يمكنها إرجاع نتيجة إليك وتقول ، "اتصل بي بعد قليل. لدي الآن IO في الوقت الحالي ، ولكن عندما يمر IO ، لدي عبء على المعالج. وهذا مخطط متعدد المستويات. عادة ما يتم وصف تفاعل الشبكة بواسطة آلة الحالة. هناك الكثير من القواعد مثل "إذا تلقيت سابقًا عنوان حزمة بحجم N ، فأنا الآن في انتظار N بايت" ، "إذا أرسلت حزمة SYNC ، فأنا الآن أنتظر حزمة بها بيانات وصفية للنتيجة." اتضح أنه رمز صعب غير بديهي ، كما لو تم تحويل المتاهة إلى مسح خطي. لقد صنعناها بحيث بدلاً من آلة الحالة ، يصف المبرمج مسار التفاعل الرئيسي في شكل كود أمر عادي. فقط في هذا الكود الضروري ، تحتاج إلى إدخال الأماكن التي يحتاج فيها تسلسل التنفيذ إلى مقاطعة عن طريق انتظار البيانات من الشبكة ، وتمرير سياق التنفيذ إلى coroutine آخر (مؤشر ترابط أخضر). يشبه هذا النهج حقيقة أننا نكتب المسار الأكثر توقعًا في المتاهة على التوالي ، ثم نضيف فروعًا إليه.
نتيجة لذلك ، لدينا مؤشر ترابط واحد يجعل بروتوكول TCP يقبل ويمرر round-robin اتصال TPC إلى العديد من العمال.
في هذه الحالة ، يعمل كل اتصال عميل دائمًا على معالج واحد. وهذا يسمح لك بجعله سهل التخزين المؤقت.
وإلى جانب ذلك ، قمنا بتحسين مجموعة الحزم الصغيرة بشكل طفيف في حزمة واحدة كبيرة من أجل تفريغ مكدس النظام TCP.
بالإضافة إلى ذلك ، قمنا بتحسين تجميع المعاملات بمعنى أن Odyssey ، عند تكوينه ، يمكنه إرسال CANCEL و ROLLBACK في حالة فشل اتصال الشبكة ، أي إذا لم يكن هناك أحد ينتظر الطلب ، فإن Odyssey سيخبر قاعدة البيانات بعدم محاولة الوفاء الطلب الذي يمكن أن يضيع موارد ثمينة.
وكلما أمكن ، نحافظ على اتصالات مع نفس العميل. هذا يتجنب الاضطرار إلى إعادة تثبيت application_name_add_host. إذا كان ذلك ممكنًا ، فليس لدينا إعادة تعيين إضافية للمعلمات المطلوبة للتشخيص.
نحن نعمل لصالح Yandex.Cloud. وإذا كنت تستخدم PostgreSQL المدارة وكان لديك مجمّع اتصالات مثبتًا ، فيمكنك إنشاء نسخ منطقي للخارج ، أي اتركنا إذا أردت ، باستخدام النسخ المنطقي. لن يعطي الحارس خارج تدفق النسخ المتماثل المنطقي.
هذا مثال على إعداد النسخ المتماثل المنطقي.
بالإضافة إلى ذلك ، لدينا دعم للتكرار المادي للخارج. في السحابة ، بالطبع ، هذا مستحيل ، لأن الكتلة ستعطيك بعد ذلك الكثير من المعلومات عن نفسها. ولكن في عمليات التثبيت الخاصة بك ، إذا كنت بحاجة إلى نسخ فعلي عبر مجمّع الاتصال في Odyssey ، فمن الممكن.
تتمتع Odyssey بمراقبة متوافقة تمامًا مع PgBouncer. لدينا نفس وحدة التحكم التي تنفذ جميع الأوامر تقريبًا. إذا كان هناك شيء مفقود ، أرسل طلب سحب ، أو على الأقل مشكلة على GitHub ، فسنكمل الأوامر اللازمة. لكن لدينا بالفعل الوظائف الرئيسية لوحدة التحكم PgBouncer.
وبالطبع لدينا خطأ في إعادة التوجيه. سنعود الخطأ الذي أبلغت عنه القاعدة. سوف تحصل على معلومات حول سبب عدم وجودك في القاعدة ، وليس فقط أنك لست فيها.
يتم تعطيل هذه الميزة في حالة احتياجك إلى توافق بنسبة 100٪ مع PgBouncer. يمكننا أن نتصرف مثل الحارس ، فقط في حالة.
تطوير
بضع كلمات حول كود مصدر Odyssey.
على سبيل المثال ، هناك أوامر "إيقاف مؤقت / استئناف". يتم استخدامها عادة لتحديث قاعدة البيانات. إذا كنت بحاجة إلى ترقية Postgres ، فيمكنك إيقافه مؤقتًا في مجمع الاتصال ، وإجراء pg_upgrade ، ثم استئنافه. ومن جانب العميل ، سيبدو أن قاعدة البيانات كانت تتباطأ. تم جلب هذه الوظيفة إلينا من قبل أشخاص من المجتمع. لم تمت بعد ، لكن سرعان ما سيكون كل شيء. (ميت بالفعل)
بالإضافة إلى ذلك ، فإن إحدى الميزات الجديدة في PgBouncer هي دعم مصادقة SCRAM ، والتي تم تقديمها إلينا أيضًا من قبل شخص لا يعمل في Yandex.Cloud. كلاهما وظائف معقدة وهامة.
لذلك ، أود أن أخبرك عن مكونات Odyssey ، في حال كنت تريد أيضًا كتابة بعض الرموز الآن.
لديك قاعدة Odyssey الأصلية ، والتي تعتمد على مكتبتين رئيسيتين. مكتبة Kiwi هي تطبيق لبروتوكول رسائل Postgres. أي أن proto 3 الأصلي لـ Postgres هو رسائل قياسية يمكن للواجهة الأمامية والخلفية تبادلها. يتم تنفيذها في مكتبة Kiwi.
مكتبة Machinarium هي مكتبة تنفيذ الموضوع. تمت كتابة جزء صغير من هذا الماكيناريوم في المجمع. لكن لا تقلق ، هناك 15 سطرًا فقط.
العمارة الأوديسة. هناك آلة رئيسية تعمل بنظام coroutines. تنفذ هذه الآلة قبول اتصالات TCP الواردة والتوزيع بين العمال.
داخل عامل واحد ، يمكن أن يعمل معالج لعدة عملاء. وأيضًا في الخيط الرئيسي ، تدور وحدة التحكم ومعالجة مهام crone لإزالة الاتصالات التي لم تعد ضرورية في التجمع.
تم اختبار Odyssey باستخدام مجموعة اختبارات Postgres القياسية. نحن فقط نجري فحص التثبيت من خلال Bouncer ومن خلال Odyssey ، نحصل على div فارغ. هناك العديد من الاختبارات المتعلقة بتنسيق التاريخ والتي تفشل تمامًا في Bouncer و Odyssey.
بالإضافة إلى ذلك ، هناك العديد من السائقين الذين لديهم اختباراتهم الخاصة. ونستخدم اختباراتهم لاختبار الأوديسة.
أيضًا ، نظرًا لتكويننا المتتالي ، يتعين علينا اختبار حزم مختلفة: Postgres + Odyssey و PgBouncer + Odyssey و Odyssey + Odyssey للتأكد من أنه إذا كانت Odyssey في أي جزء من أجزاء السلسلة ، فإنها لا تزال تعمل كما هو متوقع .
أشعل النار
نستخدم الأوديسة في الإنتاج. ولن يكون من العدل لو قلت إن كل شيء يعمل فقط. لا ، أي نعم ، لكن ليس دائمًا. على سبيل المثال ، في الإنتاج ، نجح كل شيء للتو ، ثم جاء أصدقاؤنا من PostgreSQL Professional وقالوا إن لدينا تسربًا في الذاكرة. لقد كانوا بالفعل ، أصلحناهم. لكنها كانت بسيطة.
ثم وجدنا أن مجمع الاتصال لديه اتصالات TLS واردة واتصالات TLS صادرة. وتحتاج الاتصالات إلى شهادات العميل وشهادات الخادم.
تتم إعادة قراءة شهادات خادم Bouncer و Odyssey بواسطة pcache ، لكن شهادات العميل لا تحتاج إلى إعادة قراءتها من pcache ، لأن أوديسي القابلة للتطوير تعتمد في النهاية على أداء النظام لقراءة هذه الشهادة. كان هذا مفاجأة لنا ، لأنه لم يرتاح على الفور. في البداية ، تم توسيع نطاقها خطيًا ، وبعد 20 اتصال متزامن وارد ، تجلت هذه المشكلة.
طريقة المصادقة القابلة للتوصيل هي القدرة على المصادقة باستخدام أدوات lunux المدمجة. في PgBouncer ، يتم تنفيذه بطريقة يوجد بها مؤشر ترابط منفصل ينتظر استجابة من PAM وهناك خيط PgBouncer رئيسي يخدم الاتصال الحالي ويمكن أن يطلب منهم العيش في مؤشر ترابط PAM.
لم ننفذ هذا لسبب واحد بسيط. لدينا العديد من الجداول. لماذا نحتاجه؟
نتيجة لذلك ، يمكن أن يؤدي ذلك إلى حدوث مشكلات في ذلك إذا كان لديك مصادقة PAM ومصادقة غير PAM ، فإن موجة كبيرة من مصادقة PAM يمكن أن تؤخر بشكل كبير مصادقة غير PAM. إنها واحدة من تلك الأشياء التي لم نصلحها. ولكن إذا كنت تريد إصلاحه ، فيمكنك القيام بذلك.
أشعل النار أخرى كانت مع حقيقة أن لدينا خيطًا واحدًا يقبل جميع الاتصالات الواردة. وبعد ذلك يتم نقلهم إلى تجمع العمال ، حيث ستتم مصافحة TLS.
نتيجة لذلك ، إذا كان لديك موجة متماسكة من 20 اتصال بالشبكة ، فسيتم قبولها جميعًا. ومن جانب العميل ، سيبدأ libpq في الإبلاغ عن المهلات. افتراضيًا ، تكون هناك 000 ثوانٍ.
إذا لم يتمكنوا جميعًا من دخول القاعدة في نفس الوقت ، فلن يتمكنوا من دخول القاعدة ، لأن كل هذا يمكن تغطيته بإعادة المحاولة غير الأسية.
انتهى بنا الأمر بنسخ مخطط PgBouncer هنا حتى نكون قد اختنقنا عدد اتصالات TCP التي نقبلها.
إذا رأينا أننا نقبل الاتصالات ، لكن ليس لديهم وقت للمصافحة في النهاية ، فإننا نضعهم في قائمة انتظار حتى لا يستهلكوا موارد وحدة المعالجة المركزية. هذا يؤدي إلى حقيقة أنه قد لا يتم إجراء المصافحة المتزامنة لجميع الاتصالات التي وصلت. لكن شخصًا ما على الأقل سيدخل قاعدة البيانات ، حتى لو كان الحمل قويًا بدرجة كافية.
خريطة الطريق
ما الذي تود رؤيته في المستقبل في Odyssey؟ ماذا نحن على استعداد لتطوير أنفسنا وماذا نتوقع من المجتمع؟
لشهر أغسطس 2019.
هذا ما بدت عليه خارطة طريق أوديسي في أغسطس:
- أردنا مصادقة SCRAM و PAM.
- أردنا إعادة توجيه طلبات القراءة إلى وضع الاستعداد.
- أود إعادة تشغيل الإنترنت.
- والقدرة على التوقف على السيرفر.
تم إنجاز نصف خارطة الطريق هذه ، وليس من جانبنا. وهذا جيد. لذلك دعونا نناقش ما تبقى ونضيف المزيد.
من حيث المبدأ ، في Postgres ، بدءًا من 10 ، من الممكن تحديد session_attrs عند الاتصال. يمكنك سرد جميع مضيفي قاعدة البيانات في الاتصال وتوضيح سبب ذهابك إلى قاعدة البيانات: الكتابة أو القراءة فقط. وسيختار السائق نفسه المضيف الأول في القائمة التي يفضلها أكثر ، والتي تفي بمتطلبات session_attrs.
لكن المشكلة في هذا النهج هو أنه لا يتحكم في تأخر النسخ المتماثل. قد يكون لديك نوع من النسخ المتماثلة يتأخر في وقت غير مقبول لخدمتك. من أجل تنفيذ كامل الميزات لطلبات القراءة على نسخة متماثلة ، في الواقع ، نحتاج إلى دعم القدرة على عدم العمل في Odyssey عندما يكون من المستحيل قراءتها.
يجب أن تذهب Odyssey إلى قاعدة البيانات من وقت لآخر وتطلب مسافة النسخ المتماثل من الأساسي. وإذا وصلت إلى الحد الأقصى ، فلا تدع الطلبات الجديدة في قاعدة البيانات ، وأخبر العميل أنك بحاجة إلى إعادة بدء الاتصالات ، وربما حدد مضيفًا آخر لتنفيذ الطلبات. سيسمح هذا لقاعدة البيانات باستعادة تأخر النسخ المتماثل بسرعة والعودة مرة أخرى للرد باستعلام.
من الصعب تسمية تواريخ التنفيذ ، لأنها مفتوحة المصدر. لكن ، آمل ، ليس 2,5 سنة مثل الزملاء من PgBouncer. هذه هي الميزة التي أود رؤيتها في أوديسي.
ولكن هناك بيان مُعد على مستوى بروتوكول الرسائل على proto3. وهذا هو المكان الذي تأتي فيه المعلومات التي يتم إنشاء البيان المُعد في شكل منظم. ويمكننا دعم الفهم بأنه في بعض اتصالات الخادم ، طلب العميل إنشاء بيانات معدة. وحتى في حالة إغلاق المعاملة ، ما زلنا بحاجة إلى إبقاء الخادم والعميل متصلين.
ولكن هنا يظهر تناقض في الحوار ، لأن أحدهم يقول أنك بحاجة إلى فهم البيانات المعدة التي أنشأها العميل ومشاركة اتصال الخادم بين جميع العملاء الذين أنشأوا اتصال الخادم هذا ، أي من أنشأ مثل هذا البيان المُعد.
قال أندريس فرويند إنه إذا جاء إليك عميل قام بالفعل بإنشاء مثل هذا البيان المُعد في اتصال خادم آخر ، فقم بإنشائه من أجله. ولكن يبدو أنه من الخطأ تنفيذ الاستعلامات في قاعدة البيانات بدلاً من العميل ، ولكن من وجهة نظر المطور الذي يكتب بروتوكولًا للتفاعل مع قاعدة البيانات ، سيكون من الملائم أن يتم منحه اتصالاً بالشبكة. التي لديها مثل هذا الطلب المعد.
وميزة أخرى نحتاج إلى تنفيذها. لدينا الآن مراقبة متوافقة مع PgBouncer. يمكننا إرجاع متوسط وقت تنفيذ الاستعلام. لكن متوسط الوقت هو متوسط درجة الحرارة في المستشفى: شخص ما بارد ، والآخر دافئ - في المتوسط يتمتع الجميع بصحة جيدة. هذا غير صحيح.
نحتاج إلى تنفيذ دعم للنسب المئوية ، مما يشير إلى أن هناك طلبات بطيئة تستهلك الموارد وتجعل المراقبة أكثر قبولًا.
أهم شيء هو أنني أريد الإصدار 1.0 (تم إصدار الإصدار 1.1 بالفعل). الحقيقة هي أن Odyssey الآن في الإصدار 1.0rc ، أي الإصدار المرشح. وجميع أشعل النار التي ذكرتها تم إصلاحها بالضبط بنفس الإصدار ، باستثناء تسرب الذاكرة.
ماذا سيعني الإصدار 1.0 بالنسبة لنا؟ نحن بصدد نشر الأوديسة في قواعدنا. إنه يعمل بالفعل على قواعد بياناتنا ، ولكن عندما يصل إلى نقطة 1 طلب في الثانية ، يمكننا القول أن هذه نسخة إصدار وهذه نسخة يمكن تسميتها 000.
طلب العديد من الأشخاص في المجتمع مزيدًا من الإيقاف المؤقت و SCRAM في الإصدار 1.0. ولكن هذا يعني أننا سنحتاج إلى طرح الإصدار التالي للإنتاج ، لأنه لم يتم دمج SCRAM ولا الإيقاف المؤقت بعد. ولكن ، على الأرجح ، سيتم حل هذه المشكلة بسرعة إلى حد ما.
أنا في انتظار طلب السحب الخاص بك. وأود أيضًا أن أسمع ما هي المشاكل التي لديك مع Bouncer. دعونا نناقشهم. ربما يمكننا تنفيذ بعض الوظائف التي تحتاجها.
بهذا أختتم من جانبي ، أود أن أسمع منك. شكرًا لك!
الأسئلة
إذا وضعت application_name الخاص بي ، فهل سيتم طرحه بشكل صحيح ، بما في ذلك في تجميع المعاملات في Odyssey؟
الأوديسة أم الحارس؟
في أوديسي. تم إلقاء الحارس.
سنقوم بعمل مجموعة.
وإذا كان اتصالي الحقيقي يقفز فوق اتصالات أخرى ، فهل سيتم نقله؟
سنقوم بعمل مجموعة من جميع المعلمات المدرجة. لا أستطيع معرفة ما إذا كان application_name في هذه القائمة. يبدو أنه رآه هناك. سنقوم بتعيين جميع المعلمات نفسها. مع طلب واحد ، ستفعل المجموعة كل ما تم تثبيته بواسطة العميل أثناء بدء التشغيل.
شكرا أندري على التقرير! تقرير جيد! أنا سعيد لأن أوديسي تتطور بشكل أسرع وأسرع كل دقيقة. أود أن أكمل نفس الشيء. لقد طلبنا منك بالفعل أن يكون لديك اتصال متعدد مصادر البيانات بحيث يمكن لـ Odyssey الاتصال بقواعد بيانات مختلفة في نفس الوقت ، أي السيد التابع ، ثم الاتصال تلقائيًا بالسيد الجديد بعد تجاوز الفشل.
نعم ، يبدو أنني أتذكر تلك المناقشة. الآن هناك العديد من المخازن. لكن لا يوجد تبديل بينهما. من جانبنا ، يجب أن نستعلم من الخادم أنه لا يزال على قيد الحياة ونفهم أن تجاوز الفشل قد حدث ، والذي سيتصل بـ pg_recovery. لدي طريقة معيارية لفهم أننا لم نصل إلى السيد. ويجب علينا أن نفهم بطريقة ما من الأخطاء أم كيف؟ أي أن الفكرة مثيرة للاهتمام ، وهي قيد المناقشة. اكتب المزيد من التعليقات. إذا كانت لديك يد عاملة تعرف لغة C ، فهذا أمر رائع بشكل عام.
إن مسألة التحجيم عبر النسخ المتماثلة تهمنا أيضًا ، لأننا نريد أن نجعل اعتماد المجموعات المنسوخة أمرًا بسيطًا قدر الإمكان لمطوري التطبيقات. لكن أود هنا المزيد من التعليقات ، أي كيفية القيام بذلك ، وكيفية القيام بذلك بشكل جيد.
السؤال هو أيضا حول النسخ المتماثلة. اتضح أن لديك نسخة رئيسية وعدة نسخ متماثلة. ومن الواضح أنهم يذهبون إلى النسخة المتماثلة في كثير من الأحيان أقل مما يذهبون إلى السيد للاتصال ، لأنه قد يكون لديهم اختلاف. لقد قلت إن الاختلاف في البيانات قد لا يرضي عملك ولن تذهب إلى هناك حتى يتم تكراره. في الوقت نفسه ، إذا لم تذهب إلى هناك لفترة طويلة ، ثم بدأت بالذهاب ، فلن تكون البيانات التي تحتاجها متاحة على الفور. أي ، إذا ذهبنا باستمرار إلى المعلم ، فسيتم تسخين ذاكرة التخزين المؤقت هناك ، وتكون ذاكرة التخزين المؤقت متخلفة قليلاً في النسخة المتماثلة.
نعم هذا صحيح. لن تكون هناك كتل بيانات في جهاز الكمبيوتر الذي تريده ، في ذاكرة التخزين المؤقت الحقيقية لن تكون هناك معلومات حول الجداول التي تريدها ، ولن تكون هناك استعلامات موزعة في الخطط ، ولا شيء على الإطلاق.
وعندما يكون لديك نوع من الكتلة ، وتضيف نسخة متماثلة جديدة هناك ، فعندما يبدأ ، يكون كل شيء سيئًا فيه ، أي أنه ينمو ذاكرة التخزين المؤقت الخاصة به.
خطرت لي الفكرة. قد يكون الأسلوب الصحيح هو تشغيل نسبة صغيرة من الاستعلامات على النسخة المتماثلة أولاً ، مما يؤدي إلى تدفئة ذاكرة التخزين المؤقت. بشكل تقريبي ، لدينا شرط ألا نتخلف أكثر من 10 ثوانٍ عن السيد. وهذا الشرط لا ينبغي أن يتم تضمينه في موجة واحدة ، ولكن بشكل سلس لبعض العملاء.
نعم ، زيادة الوزن.
هذه فكرة جيدة. لكن عليك أولاً تنفيذ هذا الإغلاق. نحتاج أولاً إلى إيقاف التشغيل ، ثم سنفكر في كيفية التشغيل. هذه ميزة رائعة لتشغيلها بسلاسة.
لدى nginx هذا الخيار slowly start
في الكتلة للخادم. وهو يزيد العبء تدريجياً.
نعم ، فكرة رائعة ، سنجربها عندما نصل إلى ذلك.
المصدر: www.habr.com