نواجه أحمال معاملات ضخمة على تخزيننا من وقت لآخر. لم نتمكن من العثور على أي جدول زمني أو نمط زمني لهذا الحدث، لكنه يحدث مرة واحدة على الأقل يوميًا. حتى أن المدة تتراوح بين 10 دقائق وعدة ساعات.
أثناء هذه الأحمال، يتصرف نظامنا بالكامل بشكل غريب قليلاً، على سبيل المثال، لا يتم التعرف على قراءة المواضيع، لذا لا تزال تظهر في “جديدة” و/أو “غير مقروءة”.
يبدو أن Discourse ينقل كميات هائلة من الملفات. خاصة عمليات READ تزداد بشكل ملحوظ. لقد تحققنا بالفعل مما إذا كان هناك زيادة في حركة المرور الخارجية أيضًا، لكن لا. فقط حركة المرور بين Discourse والتخزين هي المتأثرة.
لاحظنا هذا السلوك لأول مرة بعد الترقية من Discourse 2.4.0.beta9 إلى 2.4.0.beta10، لكننا لسنا متأكدين مما إذا كان قد حدث من قبل. نحن الآن نعمل بالإصدار 2.5.0.beta4.
يعمل تثبيت Discourse لدينا في بيئة Azure مع تخزين Premium متصل عبر SMBv3، والذي يعمل بشكل جيد عادةً.
هل يمكن لأحد شرح ما يحدث؟ في البداية اشتبهنا في مهمة sidekiq المسماة MigrateUploadScheme، لكن إذا كانت هذه المهمة مسؤولة عن هذه المعاملات، فيجب أن نرى هذه الأحمال العالية بشكل متكرر أكثر مما نراه. بالإضافة إلى ذلك، لم نجد أي مهمة أخرى يمكن أن تكون مسؤولة.
بسبب “انفجار IOPS”، يمكنك رؤية هذه الذروة عند حوالي 800 ألف معاملة/30 دقيقة. بعد استنفاد هذه الرصيد، يتم تقليلها إلى حوالي 250 ألف معاملة/30 دقيقة. لذا، يرجى عدم الانتباه إلى هذه الذروة لأنها مجرد مكافأة محدودة/مرخصة من طبقة تخزين Azure.
عادةً ما يكون لدينا 5 آلاف - 40 ألف معاملة كل 30 دقيقة.
في هذه المرحلة، لا نعرف أين ننظر، وأي فكرة أو تلميح مُقدَّر.
WITH x AS (SELECT
u.id user_id,
SUM(CASE WHEN p.id IS NOT NULL AND t.id IS NOT NULL AND ua.action_type = 2 THEN 1 ELSE 0 END) likes_received,
SUM(CASE WHEN p.id IS NOT NULL AND t.id IS NOT NULL AND ua.action_type = 1 THEN 1 ELSE 0 END) likes_given,
COALESCE((SELECT COUNT(topic_id) FROM topic_views AS v WHERE v.user_id = u.id AND v.viewed_at > '2019-10-28 23:52:24.911261'), 0) topics_entered,
COALESCE((SELECT COUNT(id) FROM user_visits AS uv WHERE uv.user_id = u.id AND uv.visited_at > '2019-10-28 23:52:24.911261'), 0) days_visited,
COALESCE((SELECT SUM(posts_read) FROM user_visits AS uv2 WHERE uv2.user_id = u.id AND uv2.visited_at > '2019-10-28 23:52:24.911261'), 0) posts_read,
SUM(CASE WHEN t2.id IS NOT NULL AND ua.action_type = 4 THEN 1 ELSE 0 END) topic_count,
SUM(CASE WHEN p.id IS NOT NULL AND t.id IS NOT NULL AND ua.action_type = 5 THEN 1 ELSE 0 END) post_count
FROM users AS u
LEFT OUTER JOIN user_actions AS ua ON ua.user_id = u.id AND COALESCE(ua.created_at, '2019-10-28 23:52:24.911261') > '2019-10-28 23:52:24.911261'
LEFT OUTER JOIN posts AS p ON ua.target_post_id = p.id AND p.deleted_at IS NULL AND p.post_type = 1 AND NOT p.hidden
LEFT OUTER JOIN topics AS t ON p.topic_id = t.id AND t.archetype = 'regular' AND t.deleted_at IS NULL AND t.visible
LEFT OUTER JOIN topics AS t2 ON t2.id = ua.target_topic_id AND t2.archetype = 'regular' AND t2.deleted_at IS NULL AND t2.visible
LEFT OUTER JOIN categories AS c ON t.category_id = c.id
WHERE u.active
AND u.silenced_till IS NULL
AND u.id > 0
GROUP BY u.id)
UPDATE directory_items di SET
likes_received = x.likes_received,
likes_given = x.likes_given,
topics_entered = x.topics_entered,
days_visited = x.days_visited,
posts_read = x.posts_read,
topic_count = x.topic_count,
post_count = x.post_count
FROM x
WHERE
x.user_id = di.user_id AND
di.period_type = 5 AND (
di.likes_received <> x.likes_received OR
di.likes_given <> x.likes_given OR
di.topics_entered <> x.topics_entered OR
di.days_visited <> x.days_visited OR
di.posts_read <> x.posts_read OR
di.topic_count <> x.topic_count OR
di.post_count <> x.post_count )
هل يمكنني تقديم بعض السياق لتتمكن من تقييمه بشكل أفضل:
لدينا حوالي 430 ألف مستخدم، و1.6 مليون موضوع (بدون المحذوف منها) مع 8.4 مليون منشور (بدون المحذوف منها) في 241 فئة و12 مليون user_actions.
لكنني لا أفهم بعد لماذا يجب أن تتسبب الاستعلامات البطيئة في هذا العدد الكبير من عمليات القراءة على وحدة التخزين (/uploads). هل يمكن أن أكون قد فاتني شيء ما؟
هذا لا يبدو صحيحًا. أنا مشوش، إذا كنت تستخدم Azure، فكيف تقوم بتخزين الملفات؟ هل هذه إعدادة حاوية واحدة؟ وكيف تم إعداد عمليات الرفع؟
تحديث الدليل بطيء جدًا. إذا لم تتمكن من تحمل تكلفة تحديثه، فيمكنك تعطيل الدليل https://meta.discourse.org/u. لدينا بعض الخطط المحددة لإضافة بحث المستخدمين إلى بحث الصفحة الكاملة، حتى تتمكن من الاستغناء عن الدليل.
نعتذر عن أي لبس. سأحاول شرح كيفية إعدادنا لـ Discourse.
أولاً، ليس لدينا إعداد حاوية واحدة. لقد قمنا بتقسيمه لاستخدام خدمات Azure الخاصة بـ Redis و PostgreSQL والتخزين.
هناك 3 آلات افتراضية (VMs) تشغل Discourse + Nginx. تم تركيب Azure File Share منفصل عبر SMBv3 على هذه الآلات الافتراضية الثلاث، وتم ربط نقطة التثبيت هذه بحاويات Discourse كحجم تخزين (volume).
هنا سيتم تخزين /public/uploads و /tmp/javascript-cache و /tmp/stylesheet-cache.
أقراص الآلات الافتراضية والتخزين وقاعدة البيانات مفصولة عن بعضها البعض. لذلك، لن يؤثر حمل قاعدة البيانات (أو لا ينبغي أن يؤثر) على التخزين أو أداء الآلات الافتراضية، ويمكننا الاستفادة من مزايا هذه الخدمات (مثل إحصائيات قاعدة البيانات على مثيل PostgreSQL الذي ذكرته سابقًا وتوصيات الأداء).
يسمح لنا هذا الإعداد أيضًا بمراقبة كل خدمة/جزء على حدة، وقد لاحظنا أن Azure File Share، حيث يتم تخزين uploads، يستقبل عددًا كبيرًا جدًا من المعاملات (كما يمكنك رؤية ذلك في منشوري الأول). تتكون هذه المعاملات في الغالب من عمليات قراءة.
وبما أن هذا التخزين (Azure File Share) يُستخدم فقط بواسطة Discourse نفسه، فقد حاولنا معرفة العملية/العمل المسؤول عن هذه الأحداث التي تحدث 1-2 مرة يوميًا وتستمر من بضع دقائق إلى عدة ساعات.
إلى جانب هذه الأعداد الهائلة من المعاملات، يعمل هذا الإعداد بشكل جيد جدًا باستثناء بعض الاستعلامات البطيئة التي تؤثر على الأداء فقط في حالات قليلة (على سبيل المثال، قد تستغرق صفحات ملخص نشاط عدد قليل من المستخدمين ما يصل إلى 15 ثانية للتحميل).
آمل أن أكون قد شرحت سبب دهشتي من كيف يمكن لأداء قاعدة البيانات أن يؤثر على عدد معاملات الملفات الثابتة.
مع أطيب التحيات وشكرًا لجهودكم حتى الآن
ساسا
ملاحظة:
نحن نستخدم صورة Docker مخصصة في إعدادنا، وأنا أفهم تمامًا أنك لا تستطيع/لا ترغب في تقديم دعم للحلول المخصصة.
الشيء الوحيد الذي نود معرفته هو العملية/العمل/الإعداد الذي قد يتسبب في هذه الأعداد من معاملات التخزين والتي تبطئ جزئيًا الإعداد بأكمله، وما يمكننا فعله لتجنب ذلك.
أعتقد أن أفضل خيار لك من حيث الأداء هو التبديل إلى تخزين S3 أو محرك تخزين متوافق مع S3 بالإضافة إلى CDN. استخدام مشاركة SMB للuploads ليس شيئًا اختبرناه من قبل. أظن أننا نتحقق من حجم الuploads يوميًا، وهو أمر سريع جدًا على النظام المحلي، ولكنه بطيء جدًا على SMB.
شكرًا للتوضيح ونصيحتك. في الواقع، يمكن أن يكون بروتوكول SMB بطيئًا جدًا عند الوصول إلى عدد كبير من الملفات. في معظم الأحيان، لا يحدث فرق لأن الملفات التي يتم الوصول إليها بشكل متكرر يتم تخزينها مؤقتًا بواسطة nginx (نطبق بشكل متكرر التغييرات المطبقة على ملف إعداد nginx النموذجي الخاص بـ Discourse). لكن عند التعامل مع عمليات الفحص هذه، ينخفض الأداء.
نحن نبحث عن حلول تخزين أخرى منذ فترة. قد يؤدي استخدام تخزين خارجي متوافق مع S3 إلى كسر أجزاء من مفهوم الأمان الخاص بنا. كل مثيل/خدمة مشاركة (قاعدة البيانات، الآلة الافتراضية، التخزين، إلخ) مرتبط بشبكة خاصة وغير قابل للوصول من الإنترنت العام. يتم إدارة جميع حركة المرور العامة بواسطة Azure Application Gateway.
لسوء الحظ، ليس تخزين Azure Blob متوافقًا مع S3، لكن قد ينبغي علينا استثمار بعض الوقت للاستفادة منه. الحلول الممكنة الحالية هي إضافة تخزين Blob الخاصة بـ Discourse أو استخدام blobfuse مباشرة داخل الحاوية.
على أي حال، شكرًا لوقتك ومساعدتك. هل هناك سبب لفحص حجم التحميل يوميًا، وهل هناك طريقة لإيقاف ذلك؟
شكرًا جزيلاً لك، هذا سيساعد كثيرًا. ستكون أداة du مكلفة جدًا عند استخدامها مع مشاركة SMB، خاصة أننا نستضيف حوالي 800 ألف ملف (38 جيجابايت) على هذه المشاركة.
لقد قمنا بتعطيل pulling_hotlinked_images بالفعل بسبب المخاوف القانونية/حقوق النشر المحتملة.
أعتقد أن إنشاء اختصار (alias) لـ du قد يكون تدخلاً كبيرًا بعض الشيء، بينما يُعد إصلاحه باستخدام إضافة فكرة جيدة. هل يمكننا ببساطة تطبيق git-patch أثناء بناء الصورة باستخدام شيء مثل: