الجدول colocation في قاعدة بيانات Azure ل PostgreSQL – Hyperscale (Citus)
التجميع يعني تخزين المعلومات ذات الصلة معا على نفس العقد. يمكن أن تسير الاستعلامات بسرعة عندما تتوفر جميع البيانات الضرورية دون أي حركة مرور على الشبكة. يسمح تجميع البيانات ذات الصلة على عقد مختلفة بتشغيل الاستعلامات بكفاءة بالتوازي على كل عقدة.
الموقع المشترك للبيانات للجداول الموزعة بالتجزئة
في قاعدة بيانات Azure ل PostgreSQL – Hyperscale (Citus)، يتم تخزين صف في شظية إذا كانت تجزئة القيمة في عمود التوزيع تقع ضمن نطاق تجزئة الشظية. يتم دائما وضع الشظايا ذات نطاق التجزئة نفسه على نفس العقدة. تكون الصفوف ذات قيم أعمدة التوزيع المتساوية دائما على نفس العقدة عبر الجداول.
مثال عملي على التوطين المشترك
ضع في اعتبارك الجداول التالية التي قد تكون جزءا من 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" في المستأجر ستة".
إذا كانت بياناتنا في خيار النشر Single-Server، فيمكننا بسهولة التعبير عن استعلامنا باستخدام المجموعة الغنية من العمليات العلائقية التي تقدمها 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;
طالما أن مجموعة العمل لهذا الاستعلام تتناسب مع الذاكرة، فإن جدول خادم واحد هو الحل المناسب. دعونا ننظر في فرص توسيع نطاق نموذج البيانات باستخدام خيار نشر Hyperscale (Citus).
توزيع الجداول حسب المعرف
تبدأ استعلامات الخادم الواحد في التباطؤ مع نمو عدد المستأجرين والبيانات المخزنة لكل مستأجر. تتوقف مجموعة العمل عن التركيب في الذاكرة وتصبح وحدة المعالجة المركزية عنق الزجاجة.
في هذه الحالة ، يمكننا قطع البيانات عبر العديد من العقد باستخدام Hyperscale (Citus). الخيار الأول والأكثر أهمية الذي نحتاج إلى اتخاذه عندما نقرر أن نقطع هو عمود التوزيع. لنبدأ باختيار ساذج للاستخدام event_id لجدول الأحداث والجدول page_idpage :
-- 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 يصبح كبيرا.
- تتطلب الحاجة إلى كتابة الاستعلامات في خطوات متعددة تغييرات في التطبيق.
يتم تشتيت البيانات ، بحيث يمكن موازاة الاستعلامات. إنه مفيد فقط إذا كان مقدار العمل الذي يقوم به الاستعلام أكبر بكثير من النفقات العامة للاستعلام عن العديد من الشظايا.
توزيع الجداول حسب المستأجر
في Hyperscale (Citus)، يتم ضمان أن تكون الصفوف التي لها نفس قيمة عمود التوزيع على نفس العقدة. بدءا من جديد ، يمكننا إنشاء جداولنا كعمود 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');
الآن يمكن ل Hyperscale (Citus) الإجابة على استعلام الخادم الفردي الأصلي دون تعديل (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، يعرف Hyperscale (Citus) أنه يمكن الإجابة على الاستعلام بأكمله باستخدام مجموعة من الشظايا المتداخلة التي تحتوي على بيانات هذا المستأجر المحدد. يمكن لعقدة PostgreSQL واحدة الإجابة على الاستعلام في خطوة واحدة.
في بعض الحالات، يجب تغيير الاستعلامات ومخططات الجداول لتضمين معرف المستأجر في قيود فريدة وشروط الانضمام. عادة ما يكون هذا التغيير واضحا.
الخطوات التالية
- تعرف على كيفية مشاركة بيانات المستأجر في البرنامج التعليمي متعدد المستأجرين.