Bu yılın başlarında şirketimizin en büyük projesine başladık.
Doğal olarak, temelinde TimescaleDB bulunan olgun bulut platformumuz Timescale'i seçtik. PostgreSQL ile çalışmaya alışkınız ve PostgreSQL'i daha hızlı ve daha ölçeklenebilir hale getirmek için TimescaleDB'yi geliştirdik; kendi örneğimize göre yaşamaktan daha iyi ne olabilir?
Bu test sürümünü denemeyi açıklamanın en kolay yolu, ölçeğini belirlemeye yardımcı olan rakamlardır. Insights oluşturmak için sürekli çalışan üretim veritabanlarından oluşan filomuz genelinde sorgu bilgileri toplamamız gerekiyordu. Platformdaki bireysel (sterilize edilmiş) sorgularla ilgili 1 trilyondan fazla kaydı hızlı bir şekilde topladık.
Insights artık üretimde yayında olduğundan, günde 10 milyardan fazla yeni kayıt alıyoruz. Tek bir Zaman Ölçeği hizmeti tarafından sunulan veri kümesi günde yaklaşık 3 TB büyüyor ve şu anda toplamı 350 TB'nin üzerine çıkıyor ve aynı veritabanı hizmeti, tüm müşterilerimizdeki gerçek zamanlı kontrol panellerini destekliyor.
Bu blog gönderisi, İçgörü oluşturma sürecine perde arkası bir bakış sunuyor. Bu ölçekte çalışmak, tek bir Zaman Ölçeği hizmetinin sınırlarını zorlamak ve yalnızca PostgreSQL'i değil aynı zamanda geliştirici empatimizi de ölçeklendirmek anlamına geliyordu. Timescale'i göreve fazlasıyla uygun bulduk, ancak geliştirmek istediğimiz alanlar da var!
Insights'ı gerçekleştirmek için veritabanı yöneticisi şapkamızı 🤠 giymemiz ve PostgreSQL'i terabaytlarca veriye ölçeklendirmek için birkaç teknik zorluğun üstesinden gelmemiz gerekiyordu. Platformumuzda barındırılan ve "özel" bir altyapıya sahip olmayan bir Timescale hizmetini merkezi veritabanımız olarak kullanmak istedik. Bu şu anlama geliyordu:
Günde milyarlarca kaydı tek bir Zaman Ölçeği hizmetine aktarabilecek bir işlem hattı oluşturmamız gerekiyordu. Zaman ölçeği, yüksek alım oranlarının üstesinden gelebilir ve bunu müşterilerimiz için düzenli olarak yapar, ancak üretim sorgu yükleri altında bu düzeydeki ölçek her zaman şüphe uyandırır.
Müşterilerimizin, Insights'ın sunduğu tüm analitikleri güçlendirecek esneklikle bu veritabanını sorgulayabilmeleri gerekiyordu ve biz de onları yanıt için dakikalarca bekletmek istemedik!
Her gün birkaç TB eklediğimiz için yüzlerce TB'yi tek bir Zaman Ölçeği hizmetinde depolamamız gerekiyordu. Daha eski verilerin (yani, birkaç haftadan daha eski olanların) erişilebilir olması gerekiyordu ancak sorgulanmasının hızlı olması gerekmiyordu.
Veri toplama açısından Timescale platformunun mimarisinden yararlandık. Zaman ölçeği Kubernetes (k8'ler) üzerinde çalışır ve farklı coğrafi bölgelerde çalışan birkaç k8 kümemiz vardır. Bu kümelerin bir veya daha fazla müşteri veritabanı hizmetini barındıran düğümleri vardır. Tüm bu veritabanlarına ilişkin sorgu yürütmelerini toplamak için, bu veritabanından bölgesel düzeye çıkıyoruz ve ardından Insights'ı destekleyen Timescale veritabanı hizmetinde kayıt gruplarını depolayan bölgesel bir yazıcıya sahibiz.
Bazı düşük seviyeli kanlı ayrıntılardan kaçınan el sallamayı bağışlayın, ancak genel anlamda işler böyle yürür: Filo genelinde çalışan her veritabanı, her sorgudan sonra bir kayıt (gizlilik ve güvenlik için sterilize edilmiş) oluşturmak üzere donatılmıştır; sorgunun kendisi ve önemsediğimiz istatistikler.
Bu kayıtlar düğüm düzeyinde toplanır, hangi veritabanı hizmetinden geldikleri ile ilişkilendirilmeleri için etiketlerle etiketlenir ve bölgesel yazara gönderilmek üzere gruplandırılır. Bölgesel yazar hizmeti, her bölgedeki yükü işlemek için gerektiği şekilde çoğaltılır. Her yazar, her kümedeki düğümlerden gruplar toplar ve daha da büyük gruplar oluşturur.
Bu büyük gruplar daha sonra önce 'KOPYALA' kullanılarak geçici bir tabloya yazılır (Önceden Yazma Günlüğü yok = hızlı). Bu geçici tablodaki girişler daha sonra gerekli tabloları güncellemek için kullanılır (aşağıya bakın). Geçici tablo, kayıtları geçici tablodan silen sonraki işlemlerle gerçekleştirilen kopyalar konusunda endişelenmeden 'KOPYALAMA'yı kullanmamıza olanak tanır.
Özetle:
Insights'ı destekleyen veritabanını yakınlaştıralım. Insights'ı "kullanıma hazır" bir Zaman Ölçeği hizmetinde çalıştırıyoruz.
Insights'ı destekleyen veritabanının pek çok bölümü var, ancak en önemlilerini vurgulamaya çalışacağız.
İlk olarak, "referans tabloları" görevi gören iki normal PostgreSQL tablomuz var. Bu tablolar bilgi veritabanı meta verilerini ve sorgu dizesi meta verilerini içerir. İşte onların (sözde) şemaları:
Veritabanı Meta Verileri
Table "insights.cloud_db" Column | Type | Collation | Nullable | Default ---------------+--------------------------+-----------+----------+-------------------------------------- id | bigint | | not null | nextval('cloud_db_id_seq'::regclass) service_id | text | | not null | project_id | text | | not null | created | timestamp with time zone | | not null | now() Indexes: "cloud_db_pkey" PRIMARY KEY, btree (id) "cloud_db_project_id_service_id_key" UNIQUE CONSTRAINT, btree (project_id, service_id)
Meta Verileri Sorgula
Table "insights.queries" Column | Type | Collation | Nullable | Default ---------------+--------------------------+-----------+----------+-------------------------------------- hash | text | | not null | normalized_query | text | | not null | created | timestamp with time zone | | not null | now() Indexes: "queries_pkey" PRIMARY KEY, btree (hash)
Yeni bir veritabanı kendisine karşı sorgu çalıştırılmaya başladığında, "insights.cloud_db" dosyasına eklenir. Yeni bir normalleştirilmiş sorgu çalıştırıldığında, bu sorgu "insights.queries"e eklenir.
(Normalleştirilmiş sorgu nedir? Tüm sabitlerin yer tutucularla değiştirildiği bir sorgudur: ilki için $1, ikincisi için $2 vb., dolayısıyla sorgunun değerlerini değil yalnızca "şeklini" görürüz. .)
Bu noktaya kadar, Timescale gizli sosu olmayan normal Postgres'i kullanıyoruz. Ancak veritabanındaki diğer önemli nesneler TimescaleDB'ye özeldir ve PostgreSQL'in başka bir seviyeye ölçeklenmesine yardımcı olur. Sihrin gerçekleştiği yer burası: hipertablolar ve sürekli kümeler.
Hipertablolar Timescale'in otomatik olarak bölümlenen tablolarıdır. Veriler alınırken otomatik olarak bir boyuta göre bölümlenirler, böylece PostgreSQL tablolarının büyük ölçeklere ölçeklendirilmesi çok daha kolay hale gelir. Hipertablolar Timescale'in yapı taşlarıdır. Daha sonra göreceğimiz gibi, sorgu istatistikleri ölçümlerimizi büyük bir hipertabloda saklıyoruz.
Sürekli toplamalar, Timescale'in PostgreSQL somutlaştırılmış görünümlerinin geliştirilmiş versiyonu olup, Insights oluşturulurken çok faydalı olduğu kanıtlanan artımlı ve otomatik materyalleştirmeye olanak tanır.
Kullanıcı tarafında hızlı analitik sorguları mümkün kılmak için bu özellikleri nasıl kullandığımızı ele alalım.
Söylediğimiz gibi, her sorgu yürütmesiyle ilgili bilgileri depolamak için büyük bir hiper tablo kullanıyoruz. Bu hiper tablo, sterilize edilmiş ham metriklerin bulunduğu ana tablomuzdur. Bir bakıma aşağıdakine benzer ve alınan verileri otomatik olarak bölümlemek için zaman damgası sütununu ( created
) kullanacak şekilde yapılandırılmıştır.
Table "insights.records" Column | Type | Collation | Nullable | Default -----------------------------+--------------------------+-----------+----------+--------- cloud_db_id | bigint | | not null | query_hash | text | | | created | timestamp with time zone | | not null | total_time | bigint | | | rows | bigint | | | ...
Bu örnekte bir sürü istatistiği atladık ama siz anladınız.
Artık kullanıcı tarafından hızlı sorgulara izin vermemiz gerekiyor; ancak bu tablo çok büyük. İşleri hızlandırmak için büyük ölçüde sürekli toplamalara güvendik (kullanarak
Sürekli toplamalar, Insights gibi gerçek zamanlı, kullanıcıya yönelik analizler sunan bir üründe çok anlamlıdır. Kullanıcılara eyleme geçirilebilir bilgiler sağlamak için ölçümleri toplamamız gerekiyor: Kullanıcılara çalıştırdıkları her sorgunun günlüğünü, yanında istatistiklerle birlikte göstermiyoruz; bazı veritabanları saniyede binlerce sorgu yapıyor, bu yüzden bulmak bir kabus olabilir. yararlı herhangi bir şey. Bunun yerine, kullanıcılara toplu olarak hizmet veriyoruz.
Dolayısıyla, ham bireysel kayıtları kullanıcılara göstermememizin avantajından faydalanabilir ve sonucu saklayabiliriz.
PostgreSQL'in somutlaştırılmış görünümlerini kullanabilirdik, ancak Timescale'in sürekli toplamalarının bizim için özellikle yararlı olan çeşitli avantajları vardır. Görünümleri sık sık yeniliyoruz ve sürekli toplamalarda otomatik yenilemeler için yerleşik politikalar bulunur ve bunlar artımlı olarak yenilenir.
Görünümleri her beş dakikada bir yeniliyoruz; dolayısıyla, somutlaştırılmış bilgilerin tamamını her beş dakikada bir yeniden oluşturmak yerine, sürekli toplamalar, orijinal tablodaki değişiklikleri izleyerek görünümü artımlı olarak günceller. Çalıştığımız ölçekte, ana hiper tablomuzu her beş dakikada bir yukarıdan aşağıya taramayı göze alamayız, dolayısıyla sürekli toplamaların bu işlevselliği bizim için temel bir "kilidini açma" işlevi gördü.
Perde arkasındaki Analizleri destekleyen bu sürekli toplamalarda, aynı zamanda ilginç istatistiklerin çoğunu da bir araya getiriyoruz.
Yine de belli bir noktada veritabanı, tüm bu ham kayıtları eklemek ve ardından bunları hizmet için hayata geçirmek için çok fazla çalışma yapmaya başladı. Ne kadar tüketebileceğimiz ve buna ayak uydurabileceğimiz konusunda bazı sınırlamalarla karşılaşıyorduk.
Alım oranımızı ihtiyacımız olan seviyeye daha da çıkarmak için UDDSketch neslini veritabanından bölge yazarlarına devrettik. Artık kayıtların bir kısmını hâlâ "ham" kayıtlar olarak saklıyoruz, ancak geri kalanını da veritabanında sakladığımız önceden oluşturulmuş taslaklara aktarıyoruz:
Table "insights.sketches" Column | Type | Collation | Nullable | Default -----------------------------+--------------------------+-----------+----------+--------- cloud_db_id | bigint | | not null | query_hash | text | | | created | timestamp with time zone | | not null | total_time_dist | uddsketch | | | rows_dist | uddsketch | | | ...
UDDSketchs'in en iyi yanı, daha büyük zaman aralıklarını desteklemek için çizimleri sürekli olarak "toplamanın" çok kolay olmasıdır. Böyle bir toplama kullanılarak, daha dar zaman aralıklarını kapsayan çizimler, hem hiyerarşik sürekli bir toplama oluşturulurken hem de sorgu zamanında geniş bir zaman aralığını kapsayan bir çizim halinde toplanabilir.
Hem hızlı alımın hem de sorguların hızlı bir şekilde alınmasını sağlamak için kullandığımız bir diğer araç da okuma kopyalarıdır. Insights'ın Timescale platformu için müşteriye yönelik önemli bir özelliği desteklediği göz önüne alındığında, çoğaltmanın kullanılması hem yüksek kullanılabilirlik hem de performans açısından çok önemlidir.
Ana veritabanı örneğimiz toplu işlerle, veri yazmayla, sürekli toplamaları gerçekleştirmeyle, sıkıştırmayı çalıştırmayla ve daha fazlasıyla oldukça meşgul. (Sıkıştırma hakkında daha fazla bilgi bir dakika içinde.) Yükünün bir kısmını hafifletmek için, çoğaltma hizmeti müşterisinin Insights konsolundan gelen istekleri okumasına izin verdik.
Son olarak yüzlerce TB'yi tek bir Zaman Ölçeği hizmetine rahatça sığdırmamız gerekiyordu. Insights veritabanı hızla ölçekleniyor: Başladığımızda 100 TB civarındaydı ve şu anda 350 TB'ın üzerinde (ve artıyor).
Bu kadar çok veriyi verimli bir şekilde depolamak için şunları etkinleştirdik:
Ana hipertablomuzda 20 kattan fazla sıkıştırma oranına tanık oluyoruz.
Çok büyük bir hiper tabloyu yönetirken elde edilen bir diğer büyük kazanç, sıkıştırılmış verilerin şemanın değişebilirliğiydi. Yaklaşık şemamızı önceki bir bölümde açıklamıştık, ancak tahmin edebileceğiniz gibi, daha fazla istatistik vb. eklemek için onu sık sık değiştiriyoruz; bunu doğrudan sıkıştırılmış hipertabloda yapabilmek çok faydalıdır.
Aynı zamanda Timescale'in veri katmanlamasının da yoğun kullanıcılarıyız. Bu özellik bu yılın başlarında erken erişime sunuldu (yakında GA haberlerini bekleyin 🔥) ve Timescale veritabanımız aracılığıyla yüzlerce TB'yi erişilebilir tutmamıza olanak tanıyor. Veri katmanlamanın da oldukça etkili olduğu kanıtlandı: Burada da inanılmaz sıkıştırma oranları görüyoruz; 130 TB, kaynak açısından yüksek verimliliğe sahip 5 TB'a küçülüyor.
Insights oluşturma süreci bize ürünümüzün gerçekte ne kadar ileri gidebileceğini gösterdi, ancak en iyisi müşterilerimizin yerinde birkaç kilometre yürümekti. PostgreSQL'i Timescale ile ölçeklendirmenin kullanıcı deneyimi hakkında çok şey öğrendik ve ürünün arkasındaki mühendisler olarak yapılacaklar listemize bazı şeyler ekledik.
Hadi hepsini gözden geçirelim: iyi ve şöyle.
Utanmazlığımızı bağışlayın ama zaman zaman ürünümüzle oldukça gurur duyduk. Halihazırda yüzlerce TB içeren tek bir PostgreSQL veritabanına her gün on milyarlarca kaydın aktarılması hafife alınacak bir şey değildir . Hızlanmaya başladığında veritabanını ayarlamak için birkaç hafta harcadık, ancak artık bebek bakıcılığı veya sürekli izleme gerektirmeden çalışıyor . (Bunun izlenmemekten farklı olduğunu unutmayın, kesinlikle izlenir!)
Bizim
Sıkıştırma bizim için çok işe yaradı. Önceki bölümde paylaştığımız gibi, basit tek bir "bölümleme" seçeneğini kullanarak etkileyici sıkıştırma oranları (20x!) elde ettik. Bizim için politikayı oluşturma ve ayarlama deneyimi zor değildi; ancak elbette bu özelliği biz geliştirdik… hafif bir avantajımız olduğu söylenebilir. 🙂 Ayrıca, sıkıştırılmış verilere sorunsuz bir şekilde yeni sütunlar ekleyebilme yeteneği, veritabanımızın esnekliğini ve uyarlanabilirliğini daha da geliştirdi. Bu yeteneği sorunsuz bir şekilde kullandık.
Sürekli toplamalar, farklı zaman aralıklarının oluşturulmasındaki mantığı basitleştirerek veri analizini ve işlemeyi kolaylaştırdı. Tonlarca hiyerarşik sürekli agrega kullandık.
Timecale'in hiperfonksiyonlarında yer alan yaklaşım algoritmaları, uygulamamızı basitleştirdi ve analizimizi büyük ölçüde ölçeklendirdi. Çizimleri kolayca toparlama yeteneği, müşteriye yönelik Insights kontrol panellerimizde farklı zaman aralıklarını ve zaman aralığı ayrıntılarını verimli bir şekilde desteklemenin de anahtarıydı.
Timescale veritabanının veri katmanlama yoluyla elinde bulundurduğu "sonsuz" sıcak depolama, büyümek için bol miktarda alanla birlikte 100'lerce TB'ye ölçeklendirme için kritik öneme sahipti. Mevcut __ veri katmanlama politikamız __ üç haftalık kayıtları sıcak depolamada tutar.
Son olarak, gözlemlenebilirliği artırmak (iş geçmişini izlemek gibi) ve deneysel yenileme stratejilerini uygulamak için özel işler oluşturma yeteneğini kullandık.
Size tüm harika şeyleri anlattıktan sonra sıra o kadar da harika olmayanları kabul etmeye geldi. Zaman Ölçeği dahil hiçbir şey mükemmel değildir. Boru hattımızı uygularken birkaç zorlukla karşılaştık ve bunları şikayet olarak kastetmiyoruz:
Veritabanının gözlemlenebilirliği, Timescale platformunda, özellikle işler ve sürekli toplamaların gerçekleştirilmesi performansı açısından geliştirilebilir.
TimescaleDB çoğunlukla anlık görüntü tabanlı görünümler sunarak zaman içindeki performansı ve eğilimleri anlamayı zorlaştırır. Örneğin, kullanıma hazır bir "iş geçmişi" tablosu mevcut değildir. Başlangıçta, sürekli toplamalarımızın aşamalı olarak hayata geçirilmesinin giderek daha uzun sürdüğünü ve sonunda bir hatanın keşfedilmesine yol açtığını fark ettik, ancak kapsamı doğrulamanın veya ölçmenin hiçbir yolu yoktu.
Daha önce de belirttiğimiz gibi, özel işleri tanımlama ve bunları Timescale'in iş çerçevesinde çalıştırma yeteneği, bunun "yeterince iyi" bir versiyonunu oluşturmamıza olanak sağladı. Zaman içinde izlemek istediğimiz görünümleri sürekli olarak sorguluyor ve değişiklikleri bir hiper tabloya ekliyorduk. Bu şimdilik Insights için işe yarıyor, ancak aynı zamanda bunlardan bazılarını yerleşik işlevlere dönüştürmek için de çalışıyoruz çünkü Zaman Ölçeği'ni her şeyin her zaman hızlı olduğu noktasını aşacak şekilde ölçeklendirdiğinizde bunların çok önemli olduğunu düşünüyoruz. .
Temel veriler büyük olduğunda sürekli toplamaların doğru şekilde elde edilmesi zor olabilir .
Sürekli toplamalar oluştururken __ VERİ YOK seçeneğini kullanmak __bir hayat kurtarıcıdır. Artımlı olarak yenilediğiniz veri miktarının yanlışlıkla çok fazla artmaması için, yenileme politikasına ilişkin dengelemeleriniz konusunda dikkatli olmanız da önemlidir.
Bu tavsiyeye uysanız bile, yenilemesi gerçekleştirmeye çalıştığınız veri miktarından daha uzun süren sürekli bir toplama elde edebilirsiniz; örneğin, 15 dakikalık veriyi gerçekleştirmek 30 dakika sürer. Bunun nedeni, bazen temel görevin sürekli toplamının belleğe sığmayacak kadar büyük olması ve diske taşmasıdır.
Bu sorunla karşılaştık ve bu sorun, sonuçta materyalizasyona hiçbir veri katkıda bulunmayacak olsalar bile ekstra parçaların sorgu planına dahil edilmesine neden olan (şimdi düzeltildi) bulduğumuz (artık düzeltilen) birer birer hata nedeniyle daha da kötüleşti. Bu hatayı bulmak aslında bir "test testi" durumuydu: Bu performans sorununu Insights'ı oluştururken kullanırken keşfettik 🤯. Insights'ta gördüğümüz zamanlama bilgileri burada bir şeylerin ters gittiğini gösteriyordu ve biz de EXPLAIN'i kullanarak ve planlara bakarak sorunu ortaya çıkardık. Yani size işe yaradığını söyleyebiliriz!
Gerçekleştirmeyi daha hızlı hale getirmek için, yenilenecek artışların boyutunu sınırlayan özel bir artımlı yenileme ilkesi oluşturduk. Bunun TimescaleDB'ye doğru şekilde genelleştirebileceğimiz bir şey olup olmadığını görmeye çalışıyoruz.
Değişim ölçekte zordur .
Verileriniz belirli bir boyuta ulaştığında TimescaleDB'deki bazı DDL (şema değişikliği) işlemleri idealden daha fazla zaman alabilir. Bunu zaten birkaç şekilde deneyimledik.
Örneğin, büyük hipertablolara yeni indeksler eklemek bir zamanlama egzersizi haline gelir. TimescaleDB şu anda 'CREATE INDEX' ile 'CONCURRENTLY' kullanımını desteklemediğinden, bir sonraki en iyi seçenek, dizini her seferinde bir parça oluşturmak için yerleşik yöntemini kullanmaktır. Bizim durumumuzda, yeni bir parça oluşturulduktan hemen sonra onu başlatmamız gerekiyor, böylece "aktif" parça üzerindeki kilitleme minimum düzeyde oluyor. Yani, bir yığın yeni olduğunda bir dizin oluşturmak, onun (neredeyse) boş olduğu ve bu nedenle hızlı bir şekilde tamamlanabileceği ve yeni eklemeleri engelleyemeyeceği anlamına gelir.
Değişimin zor olduğu başka bir yol da, yeni ölçümler (sütunlar) eklemek için sürekli toplamların güncellenmesidir. Sürekli toplamalar şu anda "ALTER"ı desteklemiyor. Dolayısıyla, yeni bir metriği kullanıcılara göstermek istediğimizde sürekli toplamanın tamamen yeni bir "versiyonunu" yaratırız, yani sürekli toplama "foo" için elimizde "foo_v2", "foo_v3" vb. bulunur. idealden daha az ama şu anda çalışıyor.
Son olarak, sıkıştırma ayarlarını değiştirmek ölçek açısından oldukça zordur. Aslına bakılırsa, sıkıştırılmış tüm parçaların sıkıştırılmış kısmının açılmasını, ayarların değiştirilmesini ve ardından yeniden sıkıştırılmasını gerektireceğinden bu şu anda bizim için fiilen mümkün değil; bu da mevcut ölçeğimizde mümkün değil.
Tüm bunlara uygulanabilir çözümler bulmak için meslektaşlarımızla beyin fırtınası yapmaya devam ediyoruz. Sadece bizim için değil, tüm Timescale kullanıcıları için.
Hepsini tek bir gönderiye sığdırmak için oldukça fazla bilgi vardı. Ama eğer ihtiyacın varsa
Building Insights ekibimiz için derin bir deneyimdi. Zaman Ölçeği'ni ne kadar ileri götürebileceğimizi, onu etkileyici ölçek rakamlarına ulaştırabileceğimizi ilk elden gördük. Süreç boyunca karşılaştığımız sıkıntılı noktalar bize çok fazla müşteri empatisi kazandırdı; test sürümünün güzelliği de budur.
Gelecek yıl, başka bir büyüklükteki veritabanını nasıl izlediğimize ve Timescale ile geniş ölçekte çalışma deneyimini nasıl geliştirmeye devam ettiğimize dair başka bir blog yazısı yazmayı umuyorum.
Sonra görüşürüz! 👋