البرنامج التعليمي: بيانات القطع على العقد العاملة في Azure Cosmos DB ل PostgreSQL

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

في هذا البرنامج التعليمي، يمكنك استخدام Azure Cosmos DB ل PostgreSQL لمعرفة كيفية:

  • إنشاء قطع موزعة بالتجزئة
  • انظر أين توضع قطع الجدول
  • تعرف على التوزيع المنحرف
  • إنشاء القيود على الجداول الموزعة
  • تشغيل الاستعلامات على البيانات التي تم توزيعها

المتطلبات الأساسية

يتطلب هذا البرنامج التعليمي نظام مجموعة قيد التشغيل مع عقدتين عاملتين. إذا لم يكن لديك نظام مجموعة قيد التشغيل، فاتبع البرنامج التعليمي إنشاء نظام المجموعة ثم عد إلى هذا.

البيانات الموزعة بالتجزئة

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

في قسم المتطلبات الأساسية، أنشأنا مجموعة مع عقدتين عاملتين.

coordinator and two workers

تتعقب جداول بيانات تعريف عقدة المنسق العاملين والبيانات الموزعة. يمكننا التحقق من العمال النشطاء في الجدول pg_dist_node.

select nodeid, nodename from pg_dist_node where isactive;
 nodeid | nodename
--------+-----------
      1 | 10.0.0.21
      2 | 10.0.0.23

إشعار

أسماء العقد على Azure Cosmos DB ل PostgreSQL هي عناوين IP داخلية في شبكة ظاهرية، وقد تختلف العناوين الفعلية التي تراها.

الصفوف والقطع والمواضع

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

-- create a table on the coordinator
create table users ( email text primary key, bday date not null );

-- distribute it into shards on workers
select create_distributed_table('users', 'email');

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

users table with rows pointing to shards

بشكل افتراضي، يجعل create_distributed_table()32 قطعة، كما نرى من خلال العد في جدول بيانات التعريف pg_dist_shard:

select logicalrelid, count(shardid)
  from pg_dist_shard
 group by logicalrelid;
 logicalrelid | count
--------------+-------
 users        |    32

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

-- Where would a row containing hi@test.com be stored?
-- (The value doesn't have to actually be present in users, the mapping
-- is a mathematical operation consulting pg_dist_shard.)
select get_shard_id_for_distribution_column('users', 'hi@test.com');
 get_shard_id_for_distribution_column
--------------------------------------
                               102008

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

shards assigned to workers

يمكننا إلقاء نظرة على مواضع القطع في pg_dist_placement . يوضح ربطها بجداول بيانات التعريف الأخرى التي رأيناها مكان وجود كل قطعة.

-- limit the output to the first five placements

select
	shard.logicalrelid as table,
	placement.shardid as shard,
	node.nodename as host
from
	pg_dist_placement placement,
	pg_dist_node node,
	pg_dist_shard shard
where placement.groupid = node.groupid
  and shard.shardid = placement.shardid
order by shard
limit 5;
 table | shard  |    host
-------+--------+------------
 users | 102008 | 10.0.0.21
 users | 102009 | 10.0.0.23
 users | 102010 | 10.0.0.21
 users | 102011 | 10.0.0.23
 users | 102012 | 10.0.0.21

انحراف البيانات

يعمل نظام المجموعة بفعالية أكبر عند وضع البيانات بالتساوي على العقد العاملة، وعند وضع البيانات ذات الصلة معا على نفس العمال. سنركز في هذا القسم على الجزء الأول، وهو توحيد الموضع.

للتوضيح، لنقم بإنشاء بيانات نموذجية usersلجدولنا:

-- load sample data
insert into users
select
	md5(random()::text) || '@test.com',
	date_trunc('day', now() - random()*'100 years'::interval)
from generate_series(1, 1000);

لرؤية أحجام القطع، يمكننا تشغيل وظائف حجم الجدول على القطع.

-- sizes of the first five shards
select *
from
	run_command_on_shards('users', $cmd$
	  select pg_size_pretty(pg_table_size('%1$s'));
	$cmd$)
order by shardid
limit 5;
 shardid | success | result
---------+---------+--------
  102008 | t       | 16 kB
  102009 | t       | 16 kB
  102010 | t       | 16 kB
  102011 | t       | 16 kB
  102012 | t       | 16 kB

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

الصفوف في مثالنا users موزعة بشكل متساوي بسبب خصائص عمود التوزيعemail.

  1. كان عدد عناوين البريد الإلكتروني أكبر من أو يساوي عدد القطع.
  2. كان عدد الصفوف لكل عنوان بريد إلكتروني متماثلاً (في حالتنا، صف واحد بالضبط لكل عنوان لأننا أعلنا أننا أرسلنا مفتاح عبر البريد الإلكتروني).

في أي اختيار للجدول وعمود التوزيع تفشل أي من الخاصيتين، سينتهي به الأمر مع حجم بيانات غير متساوٍ على العاملين، أي انحراف البيانات.

إضافة القيود على البيانات الموزعة

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

لنضع في الاعتبار مثال جدولنا users مع جدول ذي صلة.

-- books that users own
create table books (
	owner_email text references users (email),
	isbn text not null,
	title text not null
);

-- distribute it
select create_distributed_table('books', 'owner_email');

لتحقيق الكفاءة، نقوم بتوزيع books بنفس طريقة التوزيع users: بواسطة عنوان البريد الإلكتروني للمالك. يسمى التوزيع بواسطة قيم العمود المتماثلة colocation.

لم تكن لدينا مشكلة في توزيع الكتب بمفتاح خارجي على المستخدمين، لأن المفتاح كان في عمود التوزيع. ومع ذلك، سنواجه مشكلة في إنشاء isbn مفتاح:

-- will not work
alter table books add constraint books_isbn unique (isbn);
ERROR:  cannot create constraint on "books"
DETAIL: Distributed relations cannot have UNIQUE, EXCLUDE, or
        PRIMARY KEY constraints that do not include the partition column
        (with an equality operator if EXCLUDE).

أفضل ما يمكننا فعله في الجدول الموزع هو جعل الأعمدة نموذجاً فريداً لعمود التوزيع:

-- a weaker constraint is allowed
alter table books add constraint books_isbn unique (owner_email, isbn);

القيد أعلاه يجعل فقط isbn فريداً لكل مستخدم. هناك خيار آخر وهو إنشاء جدول مرجعي للكتب بدلاً من جدول موزع، وإنشاء جدول موزع منفصل يربط الكتب بالمستخدمين.

الاستعلامات عن الجداول الموزعة

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

على سبيل المثال، يمكننا تشغيل استعلام للعثور على متوسط أعمار المستخدمين، والتعامل مع الجدول الموزع users كما لو كان جدولاً عادياً في المنسق.

select avg(current_date - bday) as avg_days_old from users;
    avg_days_old
--------------------
 17926.348000000000

query going to shards via coordinator

خلف الكواليس، يقوم منفذ Azure Cosmos DB ل PostgreSQL بإنشاء استعلام منفصل لكل جزء، وتشغيلها على العمال، ودمج النتيجة. يمكنك رؤيته إذا كنت تستخدم أمر PostgreSQL EXPLAIN:

explain select avg(current_date - bday) from users;
                                  QUERY PLAN
----------------------------------------------------------------------------------
 Aggregate  (cost=500.00..500.02 rows=1 width=32)
   ->  Custom Scan (Citus Adaptive)  (cost=0.00..0.00 rows=100000 width=16)
     Task Count: 32
     Tasks Shown: One of 32
     ->  Task
       Node: host=10.0.0.21 port=5432 dbname=citus
       ->  Aggregate  (cost=41.75..41.76 rows=1 width=16)
         ->  Seq Scan on users_102040 users  (cost=0.00..22.70 rows=1270 width=4)

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

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

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