موقع الجدول في Azure Cosmos DB ل PostgreSQL

ينطبق على: Azure Cosmos DB ل PostgreSQL (مدعوم بملحق قاعدة بيانات Citus إلى PostgreSQL)

تقصد لفظة «Colocation» تخزين المعلومات ذات الصلة معًا على نفس العقد. يمكن أن تسير الاستعلامات بسرعة عندما تتوفر جميع البيانات الضرورية دون أي نسبة استخدام للشبكة. يسمح تجميع البيانات ذات الصلة على عقد مختلفة بتشغيل الاستعلامات بكفاءة بالتوازي على كل عقدة.

تجميع البيانات للجداول الموزعة على شفرة التجزئة

في Azure Cosmos DB ل PostgreSQL، يتم تخزين صف في جزء إذا كانت تجزئة القيمة في عمود التوزيع تقع ضمن نطاق التجزئة للجزء. يتم دائماً وضع القطع ذات نطاق التجزئة نفسه على نفس العقدة. الصفوف ذات قيم عمود التوزيع المتساوي موجودة دائمًا على نفس العقدة عبر الجداول. يعرف مفهوم الجداول الموزعة على التجزئة أيضا باسم التقسيم المستند إلى الصف. في التقسيم المستند إلى المخطط، يتم دائما تجميع الجداول داخل مخطط موزع.

يُظهر الرسم التخطيطي الأجزاء التي لها نفس نطاق التجزئة الموضوعة على نفس العقدة لأجزاء الأحداث وأجزاء الصفحات.

مثال عملي على تخزين المعلومات ذات الصلة معًا على نفس العقد

ضع في اعتبارك الجداول التالية التي قد تكون جزءا من SaaS لتحليلات الويب متعددة المستأجرين:

CREATE TABLE event (
  tenant_id int,
  event_id bigint,
  page_id int,
  payload jsonb,
  primary key (tenant_id, event_id)
);

CREATE TABLE page (
  tenant_id int,
  page_id int,
  path text,
  primary key (tenant_id, page_id)
);

الآن نريد الرد على الاستعلامات التي قد يتم إصدارها بواسطة لوحة معلومات مخصصة للعملاء. وكمثال على الاستعلام هو "إرجاع عدد الزيارات في الأسبوع الماضي لجميع الصفحات التي تبدأ بـ '/blog' في المستأجر السادس."

إذا كانت بياناتنا في خادم PostgreSQL واحد، يمكننا بسهولة التعبير عن استعلامنا باستخدام مجموعة غنية من العمليات العلائقية التي تقدمها SQL:

SELECT page_id, count(event_id)
FROM
  page
LEFT JOIN  (
  SELECT * FROM event
  WHERE (payload->>'time')::timestamptz >= now() - interval '1 week'
) recent
USING (tenant_id, page_id)
WHERE tenant_id = 6 AND path LIKE '/blog%'
GROUP BY page_id;

طالما أن مجموعة العمل لهذا الاستعلام تناسب الذاكرة، فإن جدول الخادم الواحد هو الحل المناسب. دعونا ننظر في فرص تحجيم نموذج البيانات باستخدام Azure Cosmos DB ل PostgreSQL.

توزيع الجداول حسب المعرف

تبدأ استعلامات الخادم الواحد في التباطؤ مع زيادة عدد المستأجرين والبيانات المخزنة لكل مستأجر. تتوقف مجموعة العمل عن ملاءمة الذاكرة وتصبح وحدة CPU مزدحمة.

في هذه الحالة، يمكننا تقسيم البيانات عبر العديد من العقد باستخدام Azure Cosmos DB ل PostgreSQL. الخيار الأول والأكثر أهمية الذي نحتاج إلى اتخاذه عندما نقرر التقسيم هو عمود التوزيع. لنبدأ باختيار سهل لاستخدام event_id في جدول الحدث وpage_id للجدول page:

-- naively use event_id and page_id as distribution columns

SELECT create_distributed_table('event', 'event_id');
SELECT create_distributed_table('page', 'page_id');

عندما توزع البيانات عبر عمال مختلفين، لا يمكننا إجراء عملية ربط كما نفعل على عقدة PostgreSQL واحدة. بدلاً من ذلك، نحتاج إلى إصدار استعلامين:

-- (Q1) get the relevant page_ids
SELECT page_id FROM page WHERE path LIKE '/blog%' AND tenant_id = 6;

-- (Q2) get the counts
SELECT page_id, count(*) AS count
FROM event
WHERE page_id IN (/*…page IDs from first query…*/)
  AND tenant_id = 6
  AND (payload->>'time')::date >= now() - interval '1 week'
GROUP BY page_id ORDER BY count DESC LIMIT 10;

بعد ذلك، يجب دمج النتائج من الخطوتين بواسطة التطبيق.

يجب أن يراجع تشغيل الاستعلامات البيانات الموجودة في الأجزاء المتناثرة عبر العقد.

يُظهر الرسم التخطيطي نهجًا غير فعال يستخدم استعلامات متعددة مقابل الحدث وجداول الصفحات في عقدتين.

في هذه الحالة، يحدث توزيع البيانات عيوبًا كبيرة:

  • زيادة الاستعلامات عن كل جزء وتشغيل استعلامات متعددة.
  • زيادة Q1 لإرجاع العديد من الصفوف إلى العميل.
  • تصبح Q2 كبيرة.
  • تتطلب الحاجة إلى كتابة الاستعلامات في خطوات متعددة إجراء تغييرات في التطبيق.

يتم توزيع البيانات، بحيث يمكن موازاة الاستعلامات. لن يكون مقدار العمل الذي يقوم به الاستعلام مفيدًا إلا إذا كان أكبر بكثير من الحمل الزائد للاستعلام عن العديد من المقاطع.

توزيع الجداول حسب المستأجر

في Azure Cosmos DB ل PostgreSQL، تضمن الصفوف التي لها نفس قيمة عمود التوزيع أن تكون على نفس العقدة. بدءًا من جديد، يمكننا إنشاء جداولنا باستخدام tenant_id كعمود التوزيع.

-- co-locate tables by using a common distribution column
SELECT create_distributed_table('event', 'tenant_id');
SELECT create_distributed_table('page', 'tenant_id', colocate_with => 'event');

الآن يمكن ل Azure Cosmos DB ل PostgreSQL الإجابة عن استعلام الخادم الفردي الأصلي دون تعديل (Q1):

SELECT page_id, count(event_id)
FROM
  page
LEFT JOIN  (
  SELECT * FROM event
  WHERE (payload->>'time')::timestamptz >= now() - interval '1 week'
) recent
USING (tenant_id, page_id)
WHERE tenant_id = 6 AND path LIKE '/blog%'
GROUP BY page_id;

بسبب التصفية والانضمام على tenant_id، يعرف Azure Cosmos DB ل PostgreSQL أنه يمكن الرد على الاستعلام بأكمله باستخدام مجموعة الأجزاء المجمعة التي تحتوي على بيانات لهذا المستأجر المحدد. يمكن أن تجيب عقدة PostgreSQL واحدة عن الاستعلام في خطوة واحدة.

يُظهر الرسم التخطيطي استعلامًا منفردًا لعقدة واحدة، وهو نهج أكثر فاعلية

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

الخطوات التالية