paint-brush
Postgres TOAST: Veri Sıkıştırma Mekanizmasını ve Sınırlamalarını Anlamakile@timescale
6,869 okumalar
6,869 okumalar

Postgres TOAST: Veri Sıkıştırma Mekanizmasını ve Sınırlamalarını Anlamak

ile Timescale11m2023/11/03
Read on Terminal Reader

Çok uzun; Okumak

Bu makalede, orijinal olarak bir PostgreSQL sayfasındaki büyük değerleri yönetmek için tasarlanan PostgreSQL'in TOAST mekanizmasının veri sıkıştırma sınırlamaları tartışılmaktadır. TOAST'ın avantajları olmasına rağmen, büyük veri kümelerine sahip modern uygulamalar için depolama verimliliğini optimize etme konusunda yetersiz kalıyor. Makale, sorgu performansını artırırken veritabanı boyutunu önemli ölçüde azaltan bir çözüm olarak TimescaleDB'nin sütunlu sıkıştırma işlevini tanıtmaktadır. Bu yaklaşım, daha verimli depolamaya olanak tanıyarak PostgreSQL'i çağdaş uygulamalarda veri yönetimi için daha zorlu bir seçim haline getiriyor.
featured image - Postgres TOAST: Veri Sıkıştırma Mekanizmasını ve Sınırlamalarını Anlamak
Timescale HackerNoon profile picture


Postgres'te büyük veritabanlarıyla çalışıyorsanız bu hikaye tanıdık gelecektir. Postgres veritabanınız büyümeye devam ettikçe performansınız düşmeye başlar ve depolama alanı konusunda, daha doğrusu, bunun için ne kadar ödeyeceğiniz konusunda endişelenmeye başlarsınız. PostgreSQL'i seviyorsunuz ama sahip olmayı dilediğiniz bir şey var: son derece etkili bir veri sıkıştırma mekanizması.


PostgreSQL'in bir çeşit sıkıştırma mekanizması vardır: KIZARMIŞ EKMEK 🍞. Bu yazıda size Postgres TOAST'ın nasıl çalıştığını ve farklı TOAST stratejilerini anlatacağız. İyi bir TOAST'tan ne kadar keyif alsak da, bunun neden modern büyük veritabanlarının depolama alanını azaltmak için ihtiyaç duyduğunuz türden bir sıkıştırma özelliği olmadığını ve Timescale'de burada olduğumuz PostgreSQL meraklıları olarak nasıl karar verdiğimizi tartışacağız. NoSQL veritabanlarının sütunlu tasarımından esinlenerek PostgreSQL için daha uygun bir sıkıştırma mekanizması oluşturmak.


Postgres TOAST Nedir?

Veri kümelerinin boyutunu azaltsa bile TOAST (Büyük Boyutlu Öznitelik Depolama Tekniği), geleneksel veri sıkıştırma mekanizmanız değildir. TOAST'ın ne olduğunu anlamak için konuşarak başlamalıyız. PostgreSQL'de veriler nasıl depolanır? .


Postgres'in depolama birimlerine sayfalar denir ve bunların sabit bir boyutu vardır (varsayılan olarak 8 kB). Sabit bir sayfa boyutuna sahip olmak Postgres'e veri yönetimi basitliği, verimliliği ve tutarlılığı gibi birçok avantaj sağlar, ancak bunun bir dezavantajı da vardır: bazı veri değerleri o sayfaya sığmayabilir.


TOAST burada devreye giriyor. TOAST, PostgreSQL'in Postgres'te bir sayfaya sığmayan değerleri verimli bir şekilde depolamak ve yönetmek için kullandığı otomatik mekanizmayı ifade eder. Bu tür değerleri işlemek için Postgres TOAST, varsayılan olarak bunları dahili bir algoritma kullanarak sıkıştırır. Sıkıştırma sonrasında değerler hala çok büyükse, Postgres bunları ayrı bir tabloya (TOAST tablosu adı verilen) taşıyacak ve işaretçileri orijinal tabloda bırakacaktır.


Bu makalenin ilerleyen kısımlarında göreceğimiz gibi, kullanıcı olarak bu stratejiyi, örneğin Postgres'e belirli bir sütundaki verileri sıkıştırmaktan kaçınmasını söyleyerek değiştirebilirsiniz.


TOAST'a Uygun Veri Türleri

TOAST'a tabi tutulabilecek veri türleri, öncelikle standart bir PostgreSQL sayfasının boyut sınırlarını aşma potansiyeline sahip değişken uzunluktaki veri türleridir. Öte yandan, integer , float veya timestamp gibi sabit uzunluktaki veri türleri, bir sayfaya rahatça sığdıkları için TOAST'a tabi değildir.


TOAST'a tabi tutulabilecek veri türlerinin bazı örnekleri şunlardır:


  • json ve jsonb

  • Büyük text dizeleri

  • varchar ve varchar(n) ( varchar(n) 'de belirtilen uzunluk yeterince küçükse, o sütunun değerleri her zaman TOAST eşiğinin altında kalabilir.)

  • bytea ikili verileri saklıyor

  • path ve polygon gibi geometrik veriler ve geometry veya geography gibi PostGIS türleri


Postgres TOAST Nasıl Çalışır?

TOAST'ı anlamak yalnızca sayfa boyutu kavramıyla değil aynı zamanda başka bir Postgres depolama konseptiyle de ilgilidir: tuple'lar. Tuple'lar PostgreSQL tablosundaki satırlardır. Tipik olarak TOAST mekanizması, bir demet içindeki tüm alanların toplam boyutu yaklaşık 2 kB'nin üzerindeyse devreye girer.


Eğer dikkat ettiyseniz, "Durun ama sayfa boyutu 8 kB civarında, neden bu ek yük?" diye merak ediyor olabilirsiniz. Bunun nedeni, PostgreSQL'in tek bir sayfada birden fazla tuple depolayabilmesini sağlamayı sevmesidir: eğer demetler çok büyükse, her sayfaya daha az tuple sığar, bu da G/Ç işlemlerinin artmasına ve performansın düşmesine neden olur.


Postgres'in ayrıca ek operasyonel verileri sığdırmak için boş alan tutması gerekir: her sayfa yalnızca demet verilerini değil aynı zamanda öğe tanımlayıcıları, başlıklar ve işlem bilgileri gibi verileri yönetmek için ek bilgileri de depolar.


Bu nedenle, bir demetteki tüm alanların toplam boyutu yaklaşık 2 kB'yi (veya daha sonra göreceğimiz gibi TOAST eşik parametresini) aştığında PostgreSQL, verilerin verimli bir şekilde saklanmasını sağlamak için harekete geçer. TOAST bunu iki temel yolla ele alır:


  1. Sıkıştırma. PostgreSQL, bu makalenin ilerleyen kısımlarında ele alacağımız bir sıkıştırma algoritmasını kullanarak, demet içindeki büyük alan değerlerini sıkıştırarak boyutlarını küçültebilir. Varsayılan olarak, sıkıştırma, demetin toplam boyutunu eşiğin altına getirmeye yeterliyse, veriler sıkıştırılmış formatta da olsa ana tabloda kalacaktır.


  2. Hat dışı depolama. Sıkıştırma tek başına büyük alan değerlerinin boyutunu küçültecek kadar etkili değilse Postgres bunları ayrı bir TOAST tablosuna taşır. Bu işlem "hat dışı" depolama olarak bilinir çünkü ana tablodaki orijinal demet artık büyük alan değerlerini tutmaz. Bunun yerine, TOAST tablosundaki büyük verilerin konumuna ilişkin bir "işaretçi" veya referans içerir.


Bu makale için işleri biraz basitleştiriyoruz— Tam ayrıntılı görünüm için PostgreSQL belgelerini okuyun.


Postgres Sıkıştırma Algoritması: pglz

TOAST'ın PostgreSQL'de büyük değerleri sıkıştırabildiğinden bahsetmiştik. Peki PostgreSQL hangi sıkıştırma algoritmasını kullanıyor ve ne kadar etkili?


pglz (PostgreSQL Lempel-Ziv), özellikle TOAST için uyarlanmış PostgreSQL tarafından kullanılan varsayılan dahili sıkıştırma algoritmasıdır.


Çok basit bir ifadeyle şu şekilde çalışır:


  • pglz tekrarlanan verilerden kaçınmaya çalışır. Tekrarlanan verileri gördüğünde aynı şeyi tekrar yazmak yerine sadece daha önce yazdığı yere işaret eder. Bu "tekrardan kaçınma" yerden tasarruf etmenize yardımcı olur.


  • pglz verileri okurken, gördüğü son verilerin bir kısmını hatırlar. Bu son anıya "kayan pencere" adı veriliyor.


  • Yeni veriler geldikçe pglz , bu verileri yakın zamanda (kayan pencerede) görüp görmediğini kontrol eder. Cevabınız evet ise verileri tekrarlamak yerine kısa bir referans yazar.


  • Veriler yeniyse veya referansı gerçek verilerden daha kısa hale getirecek kadar tekrarlanmadıysa, pglz onu olduğu gibi yazar.


  • Sıkıştırılmış verileri okuma zamanı geldiğinde pglz , orijinal verileri getirmek için referanslarını kullanır. Bu süreç, atıfta bulunulan verileri arayıp ait olduğu yere yerleştirdiği için oldukça doğrudandır.


  • pglz belleği için ayrı bir depolamaya ihtiyacı yoktur (kayan pencere); hareket halindeyken sıkıştırırken onu oluşturur ve sıkıştırmayı açarken de aynısını yapar.


Bu uygulama, TOAST mekanizması içindeki sıkıştırma verimliliği ve hız arasında bir denge sağlamak üzere tasarlanmıştır. Sıkıştırma oranı açısından pglz etkinliği büyük ölçüde verinin doğasına bağlı olacaktır.


Örneğin, yüksek oranda tekrarlanan veriler, yüksek entropili verilerden (rastgele veriler gibi) çok daha iyi sıkıştırılacaktır. Sıkıştırma oranlarının yüzde 25 ila 50 aralığında olduğunu görebilirsiniz, ancak bu çok genel bir tahmindir; sonuçlar, verinin kesin doğasına bağlı olarak büyük ölçüde farklılık gösterecektir.


TOAST'ı Yapılandırma

TOAST stratejileri

Varsayılan olarak PostgreSQL, daha önce açıklanan prosedüre göre TOAST mekanizmasından geçecektir (sıkıştırma yeterli değilse önce sıkıştırma ve ardından hat dışı depolama). Yine de bu davranışa sütun başına ince ayar yapmak isteyebileceğiniz senaryolar olabilir. PostgreSQL bunu TOAST stratejilerini PLAIN , EXTERNAL , EXTENDED ve MAIN kullanarak yapmanıza olanak sağlar.


  • EXTENDED : Bu varsayılan stratejidir. Bu, normal bir tablo sayfası için çok büyükse verilerin ayrı bir TOAST tablosunda sıra dışı olarak saklanacağı anlamına gelir. Veriler TOAST tablosuna taşınmadan önce yerden tasarruf sağlamak için sıkıştırılacaktır.


  • EXTERNAL : Bu strateji, eğer veriler normal bir tablo sayfasına sığmayacak kadar büyükse, PostgreSQL'e bu sütuna ait verileri satır dışında saklamasını söyler ve biz de PostgreSQL'den verileri sıkıştırmamasını isteriz; değer yalnızca tablo sayfasına taşınacaktır. TOAST masası olduğu gibi.


  • MAIN : Bu strateji bir orta yoldur. Sıkıştırma yoluyla verileri ana tabloda aynı hizada tutmaya çalışır; eğer veri kesinlikle çok büyükse, hatayı önlemek için veriyi TOAST tablosuna taşıyacaktır, ancak PostgreSQL sıkıştırılmış veriyi taşımayacaktır. Bunun yerine, değeri TOAST tablosunda orijinal biçiminde saklar.


  • PLAIN : Bir sütunda PLAIN kullanmak, PostgreSQL'e sütunun verilerini her zaman ana tablodaki satırda saklamasını söyler, böylece satır dışı TOAST tablosuna taşınmamasını sağlar. Veriler sayfa boyutunu aşarsa veriler sığmayacağından INSERT başarısız olacağını göz önünde bulundurun.


Belirli bir tablonun mevcut stratejilerini incelemek istiyorsanız aşağıdakileri çalıştırabilirsiniz:


 \d+ your_table_name


Bunun gibi bir çıktı alacaksınız:

 => \d+ example_table                     Table "public.example_table" Column |    Data Type  | Modifiers | Storage | Stats target | Description ---------+------------------+-----------+----------+--------------+-------------  bar  | varchar(100000) |      | extended |       |


Depolama ayarını değiştirmek isterseniz bunu aşağıdaki komutu kullanarak yapabilirsiniz:

 -- Sets EXTENDED as the TOAST strategy for bar_column ALTER TABLE example_blob ALTER COLUMN bar_column SET STORAGE EXTENDED;

Anahtar parametreler

Yukarıdaki stratejilerin dışında, bu iki parametre de TOAST davranışını kontrol etmek için önemlidir:


TOAST_TUPLE_THRESHOLD


Bu, büyük boyutlu tuple'lar için TOASTing işlemlerinin (sıkıştırma ve hat dışı depolama) dikkate alındığı durumlar için boyut eşiğini ayarlayan parametredir.


Daha önce de belirttiğimiz gibi, varsayılan olarak TOAST_TUPLE_THRESHOLD yaklaşık 2 kB'ye ayarlıdır.


TOAST_COMPRESSION_THRESHOLD


Bu, Postgres'in TOAST işlemi sırasında onu sıkıştırmayı düşünmesinden önce bir değerin minimum boyutunu belirten parametredir.


Bir değer bu eşiği aşarsa PostgreSQL onu sıkıştırmaya çalışacaktır. Bununla birlikte, bir değerin sıkıştırma eşiğinin üzerinde olması, otomatik olarak sıkıştırılacağı anlamına gelmez: TOAST stratejileri, PostgreSQL'e, sıkıştırılıp sıkıştırılmadığına ve sonuç boyutuna bağlı olarak verinin nasıl işleneceği konusunda rehberlik edecektir. Bir sonraki bölümde göreceğimiz gibi sayfa sınırları.


Hepsini bir araya getirmek

TOAST_TUPLE_THRESHOLD tetikleme noktasıdır. Bir demetin veri alanlarının toplam boyutu bu eşiği aştığında PostgreSQL, sıkıştırma ve hat dışı depolamayı göz önünde bulundurarak sütunları için belirlenmiş TOAST stratejisine dayalı olarak bunun nasıl yönetileceğini değerlendirecektir. Gerçekleştirilen kesin işlemler aynı zamanda sütun verilerinin TOAST_COMPRESSION_THRESHOLD değerini aşıp aşmadığına da bağlı olacaktır:


  • EXTENDED (varsayılan strateji): Bir demetin boyutu TOAST_TUPLE_THRESHOLD değerini aşarsa, PostgreSQL ilk önce büyük boyutlu sütunları, ayrıca TOAST_COMPRESSION_THRESHOLD değerini de aşmaları durumunda sıkıştırmayı deneyecektir. Sıkıştırma demet boyutunu eşiğin altına getirirse ana tabloda kalacaktır. Aksi takdirde veriler, hat dışı TOAST tablosuna taşınacak ve ana tablo, bu harici verilere yönelik işaretçiler içerecektir.


  • MAIN : Eğer demet boyutu TOAST_TUPLE_THRESHOLD değerini aşarsa, PostgreSQL büyük boyutlu sütunları sıkıştırmaya çalışacaktır ( TOAST_COMPRESSION_THRESHOLD değerinin üzerinde olmaları şartıyla). Sıkıştırma, demetin ana tablonun demetinin içine sığmasına izin veriyorsa, orada kalır. Değilse, veriler sıkıştırılmamış haliyle TOAST tablosuna taşınır.


  • EXTERNAL : PostgreSQL, TOAST_COMPRESSION_THRESHOLD değerine bakılmaksızın sıkıştırmayı atlar. Demetin boyutu TOAST_TUPLE_THRESHOLD değerinin ötesindeyse, büyük boyutlu sütunlar TOAST tablosunda satır dışı olarak depolanacaktır.


  • PLAIN : Veriler her zaman ana tabloda saklanır. Bir demetin boyutu sayfa boyutunu aşarsa (sütunların çok büyük olması nedeniyle), bir hata ortaya çıkar.


Strateji

Tuple > TOAST_COMPRESSION_THRESHOLD ise sıkıştır

Tuple > TOAST_TUPLE_THRESHOLD ise hat dışında depolayın

Tanım

UZATILMIŞ

Evet

Evet

Varsayılan strateji. Önce sıkıştırır, ardından hat dışı depolamanın gerekli olup olmadığını kontrol eder.

ANA

Evet

Yalnızca sıkıştırılmamış biçimde

İlk önce sıkıştırılır ve eğer hala büyükse, sıkıştırma olmadan TOAST tablosuna taşınır.

HARİCİ

HAYIR

Evet

Büyük boyutluysa, sıkıştırma olmadan her zaman TOAST'a geçer.

OVA

HAYIR

HAYIR

Veriler her zaman ana tabloda kalır. Bir demet sayfa boyutunu aşarsa bir hata oluşur.


PostgreSQL'de Veri Sıkıştırma Mekanizması Olarak TOAST Neden Yeterli Değil?

Şimdiye kadar muhtemelen TOAST'ın neden PostgreSQL'de olmasını istediğiniz veri sıkıştırma mekanizması olmadığını anlayacaksınız. Modern uygulamalar, her gün büyük miktarda verinin alınmasını gerektirir; bu da veritabanlarının hızla (aşırı) büyümesi anlamına gelir.


Sevgili Postgres'imiz onlarca yıl önce geliştirildiğinde bu tür bir sorun bu kadar belirgin değildi, ancak günümüzün geliştiricileri, veri kümelerinin depolama alanını azaltmak için sıkıştırma çözümlerine ihtiyaç duyuyor.


TOAST, sıkıştırmayı tekniklerinden biri olarak dahil etse de, birincil rolünün geleneksel anlamda bir veritabanı sıkıştırma mekanizması olarak hizmet etmek olmadığını anlamak çok önemlidir. TOAST temel olarak tek bir soruna çözüm sunar: Postgres sayfasının yapısal sınırları içinde büyük değerleri yönetmek.


Bu yaklaşım, belirli büyük değerlerin sıkıştırılması nedeniyle bir miktar depolama alanı tasarrufuna yol açsa da, asıl amacı, depolama alanını genel olarak optimize etmek değildir.


Örneğin, küçük demetlerden oluşan 5 TB'lık bir veritabanınız varsa, TOAST bu 5 TB'yi 1 TB'ye dönüştürmenize yardımcı olmaz. TOAST'ta ayarlanabilen parametreler olsa da bu, TOAST'ı genelleştirilmiş, depolama tasarrufu sağlayan bir çözüme dönüştürmez.


Ayrıca TOAST'ı PostgreSQL'de geleneksel bir sıkıştırma mekanizması olarak kullanmanın doğasında olan başka sorunlar da vardır, örneğin:


  • TOAST'lanmış verilere erişim, özellikle veriler hat dışında depolandığında ek yük oluşturabilir. Bu, birçok büyük metin veya diğer TOAST özellikli veri türlerine sıklıkla erişildiğinde daha belirgin hale gelir.


  • TOAST, sıkıştırma politikalarını dikte etmek için üst düzey, kullanıcı dostu bir mekanizmadan yoksundur. Depolama maliyetlerini optimize etmek veya depolama yönetimini kolaylaştırmak için tasarlanmamıştır.


  • TOAST'ın sıkıştırması özellikle yüksek sıkıştırma oranları sağlayacak şekilde tasarlanmamıştır. Tipik olarak yüzde 25-50 arasında değişen sıkıştırma oranlarına sahip yalnızca bir algoritma ( pglz ) kullanır.

Zaman Ölçeğiyle PostgreSQL'e Sütun Sıkıştırması Ekleme

TimescaleDB uzantısı aracılığıyla , PostgreSQL kullanıcılarının daha iyi bir alternatifi var. NoSQL veritabanlarının sıkıştırma tasarımından ilham alan, PostgreSQL'e sütunlu sıkıştırma işlevi ekledik . Bu dönüştürücü yaklaşım, PostgreSQL'in geleneksel satır tabanlı depolama paradigmasını aşarak sütunlu depolamanın verimliliğini ve performansını sunar.


Büyük tablolarınıza sıkıştırma politikası ekleyerek, PostgreSQL veritabanı boyutunuzu 10 kata kadar azaltabilirsiniz (yüzde +90 sıkıştırma oranlarına ulaşarak) .


Zamana dayalı bir sıkıştırma ilkesi tanımlayarak verilerin ne zaman sıkıştırılması gerektiğini belirtirsiniz. Örneğin yedi (7) günden eski verileri otomatik olarak sıkıştırmayı seçebilirsiniz:


 -- Compress data older than 7 days SELECT add_compression_policy('my_hypertable', INTERVAL '7 days');


Bu sıkıştırma politikası aracılığıyla Timescale tabloyu dönüştürecek bölümler ( Zaman Ölçeğinde de otomatik olarak oluşturulanlar ) birçok satırı (1.000) bir dizide birleştirerek sahne arkasında sütunlu bir formata dönüştürür. Sıkıştırılabilirliği artırmak için Timescale, veri türüne bağlı olarak farklı sıkıştırma algoritmaları uygulayacaktır:


  • Şamandıralar için Goril sıkıştırması

  • Delta-of-delta + Basit-8b ile çalışma uzunluğu kodlaması zaman damgaları ve diğer tam sayı benzeri türler için sıkıştırma

  • Birkaç yinelenen değere sahip sütunlar için tam satır sözlük sıkıştırması (üstte + LZ sıkıştırması)

  • Diğer tüm türler için LZ tabanlı dizi sıkıştırma


Bu sütunlu sıkıştırma tasarımı, PostgreSQL'deki büyük veri kümeleri sorununa etkili ve ölçeklenebilir bir çözüm sunar. Sorgu performansınıza zarar vermeden daha fazla veri depolamak için daha az depolama alanı kullanmanıza olanak tanır (iyileştirir). Ayrıca TimescaleDB'nin en son sürümlerinde, doğrudan sıkıştırılmış veriler üzerinden INSERT , DELETE ve UPDATE işlemlerini de gerçekleştirebilirsiniz.

Sarmak

Bu makalenin, TOAST'ın bir PostgreSQL sayfasındaki büyük değerleri yönetmek için iyi düşünülmüş bir mekanizma olmasına rağmen, modern uygulamalar alanında veritabanı depolama kullanımını optimize etmede etkili olmadığını anlamanıza yardımcı olacağını umuyoruz.


Depolama tasarruflarınızda ilerleme kaydedebilecek etkili veri sıkıştırma arıyorsanız Timescale'i bir deneyin. PostgreSQL'i yeni performans seviyelerine taşıyan, onu daha hızlı ve daha güçlü hale getiren bulut platformumuzu deneyebilirsiniz. ücretsizdir ve kredi kartı gerekmez —veya ekleyebilirsiniz TimescaleDB uzantısı kendi barındırdığınız PostgreSQL veritabanınıza.


Carlota Soto'nun yazdığı.