PostgreSQL için Azure Cosmos DB'de tablo birlikte bulundurma
ŞUNLAR IÇIN GEÇERLIDIR: PostgreSQL için Azure Cosmos DB (PostgreSQL'e citus veritabanı uzantısıyla desteklenir)
Birlikte bulundurma, ilgili bilgileri aynı düğümlerde birlikte depolama anlamına gelir. Gerekli tüm veriler herhangi bir ağ trafiği olmadan kullanılabilir olduğunda sorgular hızla gerçekleştirilir. Farklı düğümlerde ilgili verilerin birlikte bulunması, sorguların her düğümde paralel olarak verimli bir şekilde çalışmasını sağlar.
Karma dağıtılmış tablolar için veri birlikte bulundurma
PostgreSQL için Azure Cosmos DB'de, dağıtım sütunundaki değerin karması parçanın karma aralığı içindeyse bir satır parçada depolanır. Aynı karma aralığına sahip parçalar her zaman aynı düğüme yerleştirilir. Eşit dağıtım sütunu değerlerine sahip satırlar her zaman tablolar arasında aynı düğümdedir. Karma dağıtılmış tablolar kavramı satır tabanlı parçalama olarak da bilinir. Şema tabanlı parçalamada, dağıtılmış şema içindeki tablolar her zaman birlikte bulunur.
Birlikte bulundurmanın pratik bir örneği
Çok kiracılı bir web analizi SaaS'sinin parçası olabilecek aşağıdaki tabloları göz önünde bulundurun:
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)
);
Şimdi müşteriye yönelik bir pano tarafından verilebilen sorguları yanıtlamak istiyoruz. Örnek bir sorgu: "Kiracı altıda '/blog' ile başlayan tüm sayfalar için geçen haftaki ziyaret sayısını döndür."
Verilerimiz tek bir PostgreSQL sunucusundaysa SQL tarafından sunulan zengin ilişkisel işlemleri kullanarak sorgumuzu kolayca ifade edebiliriz:
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;
Bu sorgunun çalışma kümesi belleğe sığdıkça, tek sunuculu bir tablo uygun bir çözümdür. PostgreSQL için Azure Cosmos DB ile veri modelini ölçeklendirme fırsatlarını ele alalım.
Tabloları kimliklerine göre dağıtma
Kiracı sayısı ve her kiracı için depolanan veriler arttıkça tek sunuculu sorgular yavaşlamaya başlar. Çalışma kümesi belleğe uyum sağlamayı durdurur ve CPU bir performans sorununa dönüşür.
Bu durumda, PostgreSQL için Azure Cosmos DB'yi kullanarak verileri birçok düğüm arasında parçalayabiliriz. Parçaya karar vermek için yapmamız gereken ilk ve en önemli seçim dağıtım sütunudur. Olay tablosu ve page_id
page
tablo için kullanmak event_id
üzere basit bir seçimle başlayalım:
-- naively use event_id and page_id as distribution columns
SELECT create_distributed_table('event', 'event_id');
SELECT create_distributed_table('page', 'page_id');
Veriler farklı çalışanlara dağıtıldığında, tek bir PostgreSQL düğümünde yaptığımız gibi birleştirme gerçekleştiremiyoruz. Bunun yerine iki sorgu yayınlamamız gerekir:
-- (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;
Daha sonra, iki adımda elde edilen sonuçların uygulama tarafından birleştirilmesi gerekir.
Sorguları çalıştırmak, düğümlere dağılmış parçalardaki verilere başvurmalıdır.
Bu durumda, veri dağıtımı önemli dezavantajlar oluşturur:
- Her bir parçanın sorgulanması ve birden çok sorgu çalıştırılmasının yükü.
- Q1'in istemciye birçok satır döndürmesi yükü.
- Q2 büyük hale gelir.
- Birden çok adımda sorgu yazma gereksinimi, uygulamada değişiklik yapılmasını gerektirir.
Veriler dağıtıldığından sorgular paralel hale getirilebilir. Bu, yalnızca sorgunun yaptığı iş miktarının birçok parçanın sorgulanmasından önemli ölçüde fazla olması durumunda faydalıdır.
Tabloları kiracıya göre dağıtma
PostgreSQL için Azure Cosmos DB'de, aynı dağıtım sütunu değerine sahip satırların aynı düğümde olması garanti edilir. Baştan başlayarak tablolarımızı tenant_id
dağıtım sütunu olarak oluşturabiliriz.
-- 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');
Artık PostgreSQL için Azure Cosmos DB, özgün tek sunuculu sorguyu değiştirmeden yanıtlayabilir (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 filtreleme ve birleştirme nedeniyle PostgreSQL için Azure Cosmos DB, söz konusu kiracının verilerini içeren birlikte konumlandırılmış parça kümesi kullanılarak sorgunun tamamının yanıtlanabileceğini bilir. Tek bir PostgreSQL düğümü sorguyu tek bir adımda yanıtlayabilir.
Bazı durumlarda, sorguların ve tablo şemalarının kiracı kimliğini benzersiz kısıtlamalara ve birleştirme koşullarına dahil etmek için değiştirilmesi gerekir. Bu değişiklik genellikle basittir.
Sonraki adımlar
- Çok kiracılı öğreticide kiracı verilerinin nasıl bir arada bulunduğuna bakın.