Postgres kuyruk teknolojisi seçimi
(adriano.fyi)- Ayrı bir kuyruk sistemi getirmeden önce, zaten kullandığınız Postgres ile arka plan iş kuyruğu kurabiliyorsanız operasyonel basitlikten ve ekibin aşinalığından büyük ölçüde yararlanabilirsiniz
- Postgres 9.5 sonrası
NOTIFY/LISTENveFOR UPDATE SKIP LOCKED, yeni iş bildirimini ve çalışanlar arasında mükerrer işlemeyi önlemeyi birlikte çözer - Redis, Kafka, RabbitMQ ve Amazon SQS güçlü seçeneklerdir; ancak yeni bağımlılıklar geliştirme, test ve operasyon ortamlarına hata modları ve öğrenme maliyeti ekler
- Postgres kuyruğu da her derde deva değildir: push/pop işlemleri Redis’ten yavaş olabilir; ayrı bir kuyruk veritabanı veya sunucu, daha sık
VACUUMgibi operasyonel bedeller doğabilir - Arka plan iş kodunu kuyruk backend’ine bağlı kalmayacak şekilde soyutlamak ve yalnızca aşina olunan teknoloji gereksinimleri karşılamadığında başka kuyruk teknolojilerini değerlendirmek daha güvenlidir
Postgres kuyruğu nasıl çalışır
- Postgres kuyruk teknolojisi iki unsurdan oluşur
- Yeni işleri bildiren ve alan pub/sub
- Birden fazla çalışanın aynı işi işlemesini engelleyen satır kilitleme
- İki özellik de 2016’da yayımlanan Postgres 9.5’ten beri yerleşik olarak sunulur
NOTIFYveLISTENbirlikte kullanıldığında uygulamaya pub/sub eklenebilirFOR UPDATE SKIP LOCKED, koşullara uyan kayıtlarda satır kilidi alır ve zaten kilitli olan kayıtları atlar- İş kayıtlarına uygulandığında
SELECT * FROM jobs ORDER BY created_at FOR UPDATE SKIP LOCKED LIMIT 1gibi bir kuyruk işleme sorgusu oluşturulabilir
- İş kayıtlarına uygulandığında
SKIP LOCKED, verinin “tutarsız” bir görünümünü sunar; ancak kuyruklarda bu özellik yararlıdır- Zaten işlenmekte olan işler, satır kilidi nedeniyle diğer çalışanlara görünmez
- Bu davranış dağıtık karşılıklı dışlamayı mümkün kılar
NOTIFYileLISTENyapan çalışanlara yeni işler bildirildiğinde hem periyodik toplu işleme hem de gerçek zamanlı iş işleme kurulabilir
Redis’in arka plan işleri için varsayılan haline gelişi
- Uzun süre çalışan işlerin nasıl ele alınacağı, birçok ödünleşim içeren bir teknoloji seçimidir
- Yaygın kullanılan kuyruk ve mesaj aracısı seçenekleri şunlardır
- Redis: Bellek içi veri deposu ve birçok arka plan iş kütüphanesinin backend’i
- Apache Kafka: Apache Foundation tarafından yönetilen dağıtık olay akışı platformu
- RabbitMQ: Yaygın biçimde dağıtılmış bir mesaj aracısı olarak tanıtılır
- Amazon SQS: Yüksek ölçeklenebilir kuyruklar sağlayan Amazon SaaS’i
- GitHub’daki background jobs topic içinde en popüler ilk 5 kütüphanenin tamamı Redis tabanlıdır
- Redis verileri bellekte sakladığı için ekleme ve okuma hızlıdır; pub/sub API’si ile
list,setveri yapılarını sunduğundan kuyruk uygulamaları için iyi uyum sağlar - Redis’in ölçeklenebilirliği birçok geliştirici için varsayılan seçenek olmasını sağlar; varsayılanlar teknoloji seçiminde güçlü bir etkiye sahiptir
Ölçeklenebilirlikten önce bakılması gereken ölçütler
- Teknoloji sektörünün “scale” takıntısı basitliği, bakım kolaylığını ve geliştiricilerin bilişsel yükünü azaltmayı geri plana itebilir
- Birçok uygulama Google, Facebook veya Uber seviyesinde ölçeklenme gerektirmez
- Bir projeye veya işe başlarken, en baştan yalnızca ölçeklenebilirliği optimize etmek yerine önce şu ölçütlere bakmak gerekir
- Ekibin iyi bildiği teknoloji
- Kullanıcı ihtiyaçlarını karşılayan yeterince iyi teknoloji
- Ekip yetkinliklerine uygun ve en az zahmetli çözüm
- Postgres pratikte iyi ölçeklenir; ancak kuyruk kullanım senaryosunda en çok ölçeklenen uzmanlaşmış kuyruk sistemi değildir
- Genel amaçlı bir yazılım olan Postgres birçok işi oldukça iyi yapar; kuyruk da bunlardan biri olarak ele alınabilir
“Sıkıcı teknoloji” ile karar vermek
- Kuyruk teknolojisi seçerken en önemli soru, şu anda hangi teknolojiyi kullandığınız ve iyi anladığınızdır
- Zaten kullanılan ve iyi bilinen teknolojinin yazılım yığınına eklediği yük daha küçüktür
- Halihazırda ilişkisel veritabanı kullanıyorsanız ve bu veritabanı Postgres ise, diğer yazılımlardan önce Postgres kuyruğunu değerlendirebilirsiniz
- “Sıkıcı teknoloji” sabit bir liste değildir; şu anda kullanılan teknolojiye göre değişir
- Mesaj iletimi merkezli uygulamalarda RabbitMQ sıkıcı teknoloji olabilir
- Önbellekleme merkezli uygulamalarda Redis sıkıcı teknoloji olabilir
- İlişkisel verisi yoğun uygulamalarda Postgres sıkıcı teknoloji olabilir
- Redis, Kafka, RabbitMQ veya SQS’yi yalnızca arka plan işleri için yeni devreye almak maliyeti artırır
- Geliştirme, test ve production ortamlarına yeni bir sistem bağımlılığı eklenir
- Gelecekte Developer, DBA ve SRE’lerin yeni sistemin hata modlarını ve yapılandırmasını bilmesi gerekir
- Felaket kurtarma, sorun tanılama ve performans izleme bilgisi gerekir
- Ekibin henüz bilmediği unknown unknowns risk olarak kalır
Postgres kuyruğunun bedelleri ve seçim ölçütleri
- Sıkıcı teknoloji her derde deva değildir; Postgres de istisna değildir
- Postgres kuyruğunu seçtiğinizde aşinalık, bilinen hata modları ve maliyeti dağıtma avantajları elde ederken şu bedellerle karşılaşabilirsiniz
- Postgres kuyruğunda push/pop, Redis’e göre kayda değer ölçüde yavaştır
- Tek bir ilişkisel veritabanı yerine uygulama veritabanı ve kuyruk veritabanı gerekebilir
- Arka plan işlerini bağımsız ölçeklendirmek için ayrı bir veritabanı sunucusu gerekebilir
- Daha sık
VACUUMgerekebilir ve bu da performans yükü oluşturabilir
- Postgres, Redis, Kafka, RabbitMQ veya SQS’den hiçbiri otomatik varsayılan olmamalıdır
- Teknoloji seçimi süregiden bir ödünleşimdir; ekip ve uygulama gereksinimlerine göre değerlendirilmelidir
- Emin olunmadığında “alternatifleri yalnızca sıkıcı teknolojinin gereksinimleri karşılamadığının kanıtlandığı durumda değerlendirmek” ölçütü uygulanabilir
Kuyruğu değiştirebilen arka plan iş yapısı
- Arka plan iş işleme kodu belirli bir kuyruk teknolojisine bağımlı olmamalıdır
- Uygulama büyüdükçe ihtiyaca göre memcached veya Redis gibi teknolojiler eklenebilir; zamanla bu teknolojiler de ekip için aşina olunan “sıkıcı teknoloji” haline gelebilir
- Kuyruk teknolojisi soyutlanırsa kullanıcılar işe uygun kuyruğu seçebilir
- GitHub’da en popüler arka plan iş kütüphaneleri arasında Hangfire dışında hiçbiri Redis dışı kuyruk teknolojisine çıkış yolu sunmaz
- Bu yapıda kuyruğu değiştirmek için uygulama kodunu yeniden yazmak gerekir
- Neoq, bu felsefeyle geliştirilmiş Go kütüphanesidir
- Kuyruk backend’i olarak bellek içi, Postgres ve Redis kullanılabilir
- Kullanıcılar uygulama kodunu değiştirmeden farklı bir kuyruk backend’i ile başlatabilir
- Bellek içi ve Postgres uygulamaları birinci elden sunulur; Redis uygulaması asynq kullanır
- Redis, Kafka, RabbitMQ ve SQS harika teknolojiler olabilir; ancak her zaman ilgili iş için doğru kuyruk veya uygun karmaşıklık düzeyi olmayabilir
1 yorum
Hacker News yorumları
Şimdiye kadar üç kez dağıtık iş sistemi kurdum ve yıllardır önerdiğim pratik kural şu: “mevcut ölçeğin 10 katına göre tasarla.”
Saniyede 70 istekse 700 isteği, 20 batch iş sunucusu gerekiyorsa 200 sunucuyu baz almak gibi. Yılda %100 büyüyen bir startup bile 3 yıl sonra 8 kat ölçeğe ulaşır; yani büyürken yeniden yazacak zamanınız olur.
İlk yaptığım sistemde “ölçeklenebilirlik” yüzünden SQL’den kaçınmıştım; ama işlem bütünlüğü gerektiren çok sayıda istisnai durumla karşılaşınca epey zorlandım.
Sonraki iki dağıtık iş sisteminde PostgreSQL’i koordinatör olarak kullandım ve kelimenin tam anlamıyla
SELECT FOR UPDATE SKIP LOCKEDetrafında kurguladım. Biri normalde 350 worker’ı yönetiyor, diğeri ise binlerce işe karmaşık önceliklendirme uyguluyor.İkisi de yıllık geliri milyonlarca dolar seviyesine çıkana kadar sorunsuz dayanacaktır; örneğin 350 worker’lık olan, az bir düzenlemeyle yaklaşık 2.000 CPU’ya kadar ölçeklenebilir.
Ultra büyük ölçek teknolojileri, transaction gerektiğini fark edene kadar oldukça ucuz görünür. Ama o andan itibaren nihai tutarlılığa sahip bir depolama katmanının üstünde transaction semantiğini taklit etmek mühendislik kâbusuna dönüşür.
Bu yüzden oturup hesap yapmak gerekir. Şirket yıllık 100 milyon dolar kazanırsa dağıtık sistemin ne kadar büyümesi gerekeceğini, bu yükü kaldıracak bir PostgreSQL instance’ının kolayca bulunup bulunamayacağını ya da istemci bazlı sharding’in yeterli olup olmayacağını değerlendirin; mümkünse PostgreSQL’i ciddi şekilde düşünmeye değer. Yüz tane küçük şey kolaylaşır.
SQL çözümleri genelde daha basit, daha az hesaplama kaynağı tüketen ve operasyonel olarak desteklemesi daha kolay çözümler oluyor.
Ancak çalıştırmak için,
SELECT FOR UPDATE SKIP LOCKEDgibi özelliklerin baştan var olduğunu bilecek kadar veritabanını iyi bilmek gerekiyor. Günümüzde birçok mühendis, DBMS’in gerçek gücünü ağır ORM’lerin perdelediği ortamlarda yetiştiği için bu tür bilgi epey nadirleşiyor.Sistem tepe yükü kaldırmak zorunda; tepe yükü bilmiyorsanız güvenlik payı bırakmalı ya da gerektiğinde işleri atmanın veya ertelemenin bir yolunu koymalısınız.
Her şey bir ödünleşimdir; yalnızca optimize edilmesi gerekenleri optimize etmek gerekir ve neyin buna dahil olduğunu ayırt edebilmek iyi bir mühendisin özelliğidir.
Bu sizin için yeniyse, mesai saatinde bir hafta HN okumanın karşılığını az önce almış oldunuz; bunu bir kâğıda yazıp ATM kartınıza yapıştırmaya değer.
Birçok projede daha basit bir yaklaşımı seçtim: tüm dillerdeki ORM/sorgu DSL framework’lerinde doğrudan çalışan sıradan tablolar ve
SELECT FOR UPDATE SKIP LOCKEDkullanmak.https://www.pgcasts.com/episodes/the-skip-locked-feature-in-...
“Web ölçeği” değil ama benim deneyimime göre binlerce arka plan işine kadar kolayca ölçekleniyor.
Bu yöntemi büyük bir kuruluşun işlerinde de sorunsuz kullandık. Özel bir dağıtım ya da yeni altyapı gerekmiyor; uygulamanın içinde birkaç worker thread başlatmak yeterli. Terk edilmiş işleri sıfırlayan bir thread de koyabilirsiniz.
Ancak 3 yıl boyunca pratikte böyle bir durum yaşanmadı; her şey
try/catchiçindeydi, başarısız olursa kuyruğa geri koyuyorduk ve Java uygulaması da çok kararlıydı.delete from taskwhere task_id in( select task_idfrom taskorder by random() -- use tablesample for better performancefor updateskip lockedlimit 1)returning task_id, task_type, params::jsonb as params[1] https://taylor.town/pg-task
“Binlerce arka plan işi” dediniz ama kuyruklara genelde Little yasası açısından bakmak gerekir; saniyedeki ortalama iş giriş oranı ve ortalama iş süresi gibi oranlardan söz etmek gerekir. Ham sayıların tek başına pek anlamı yoktur.
Başta saf bir
UPDATE ... SETile de olur, ama çok fazla kilit alır.UPDATEiçindeSELECTalt sorgusu kullanarak ya daSELECT FOR UPDATE SKIP LOCKEDile çekme kilidini daha verimli hale getirmek mümkündür; ama sonunda çekme sorguları birbirlerinin kilitlerini engelleyip kuyruğu durdurabilir.O noktada DB’ye nefes aldırmak için iş girişini kapatabilirsiniz, ama kaybedilen girişler yüzünden veri kaybı oluşur ve çoğu zaman asıl sorun çekme işlemlerinin birbirini engellemesidir.
İş tablosunu aceleyle shard’layıp kilitlerden kaçınabilirsiniz; ancak bunu birden çok worker’a dağıtmak kırılgandır ve veri kaybına yol açabilir. Rastgele işlerin bir kısmını atabilirsiniz ama bu da doğal olarak veri kaybıdır.
Bu seçenekler üretimde aşırı streslidir ve baştan aşağı yeniden tasarlamadan toparlanması da çok zordur. Yalnızca birkaç müşteriniz varsa ve sonsuza kadar saniyede birkaç düzine iş seviyesinde kalacağınızdan eminseniz başka; ama bunu bizzat yaşadıktan sonra, mümkün olduğunda veritabanı yerine gerçek bir kuyruk teknolojisi seçiyorum.
“Mühendisler kendi ihtiyaçlarından tamamen farklı olmasına rağmen havalı görünmek için FAANG altyapısını kopyalıyor” tarzı eleştirileri sık görüyorum, ama bunun büyük ölçüde bilgi ve dokümantasyon meselesi olduğunu düşünüyorum.
FAANG’i ya da başka startup’ları izleyip sonsuz ölçeklenebilir kuyruk tabanlı bir mimari kurmak istiyorsanız, Redis, SQS gibi ölçeklenebilir çözümleri birkaç saat içinde kurmanızı sağlayan düzinelerce kaliteli rehber, eğitim ve teknik doküman var.
Bakım maliyeti daha yüksek, ama itibarlı kaynaklardaki komutları, kodları ve ayarları kopyalayıp yapıştırarak başlayabiliyorsunuz.
Buna karşılık PostgreSQL’in
NOTIFYözelliğini kullanmak isteyip “SQLALchemy notify listen postgres” diye aradığınızda, birkaç yanıtsız Stack Overflow sorusu ve bağlamdan yoksun GitHub Gist’lerinden başka pek bir şey çıkmıyor.Bir yan projede bu yöntemi gerçekten denemek istiyorum, ama tek başıma 2-3 gün ayırıp çözmeye vaktim yok.
Dışarıdan bakınca seçim “basit ama ölçeklenmez, yani yalnızca PostgreSQL kullanmak” ile “karmaşık ama ölçeklenir, yani Redis/SQS vb.” arasında gibi görünüyor; böyle olunca da sanki parlak teknolojilere ve FAANG’e kapılıp ihtiyacım olmayan ölçeklenebilirliği seçmişim gibi oluyor.
Ama rehberleri ve kaynakları da hesaba katınca gerçek seçenekler daha çok “karmaşık ve ölçeklenebilirliği de öngörülemez, çünkü uygulama yöntemini ve tuzakları bilmiyorum” ile “basit ve ölçeklenebilir, herkesin pratikte yaptığı yol” arasında oluyor. Bu durumda FAANG’i izleyen mühendisin tercihi çok daha makul görünüyor.
NOTIFYkullanmak istiyorsanız sadece https://www.postgresql.org/docs/current/sql-notify.html adresini okumanız yeterli; arama becerisine gerek yok.Örneğin düşük yük altında PostgreSQL kullanırsanız şema migration’ları, yeni kısıtlar ekleme, analiz vb. neredeyse önemsiz işler hâline gelir.
SQS, Cassandra vb. kullanırsanız ölçeklenebilirlik/erişilebilirlik kazanırsınız, ama asıl tasarımın uymadığını fark ettiğinizde değiştirmek çok daha uzun sürer. İş tarafı “foo tipindeki kullanıcılar bar değerlerini aynı anda birleştiremesin” gibi bir kısıt eklenmesini istediğinde bu böyledir.
PostgreSQL olmadan da uygulanabilir, ama özellikle değişiklik gerekiyorsa kolay ya da basit değildir.
Bu yüzden esnekliği korumak için PostgreSQL kullanmak, değişmeyeceğini bildiğinizde ise PostgreSQL’in üstüne başka bir şey eklemek daha iyi görünüyor. Elbette bu durumda altyapı ve bakım ek yükü de eklenir.
Sonuçta bu her zaman bir ödünleşimdir; neyi, ne zaman, neyle takas edeceğinizi bilmeniz gerekir.
Herkesin kendi uygulaması içinde PostgreSQL backend’i ya da başka bir kuyrukla özel bir arka plan iş worker’ı yazmasının ideal olduğunu düşünmüyorum.
Arka plan işlerinde yanılması kolay ince noktalar ve uygulama ayrıntıları çoktur; genellikle bunları daha kapsamlı, bu işe özel bir kütüphane ya da framework’ün üstlenmesi daha iyidir.
Her Rails uygulamasında Sidekiq/Active Jobs olmasaydı ve herkes kendi özel arka plan worker’ını yazsaydı, Rails uygulamalarının güvenilirlik açısından bugünkünden çok daha kötü bir itibarı olması muhtemeldi.
Ana hedeften çok uzaklaşmadan en büyük faydayı sağlayan çözümü seçmek gerekir.
Geliştiricilerinin zamanının yaklaşık %80’ini araçlar ve altyapıyla boğuşarak geçirdiği bir startup görmüştüm. Runway’i 3 aydı; şimdi o pistin sonunda sadece büyük bir çukur kaldı. Düşününce hâlâ ürperiyorum.
Karmaşıklığa yeterince saygı gösterilmiyor gibi geliyor.
PostgreSQL’i bir yayınla/abone ol veri yolu olarak
LISTEN/NOTIFYile kullanırken en büyük dezavantaj,LISTENin oturum düzeyinde bir özellik olması ve bu yüzden ifade düzeyinde connection pooling ile uyumsuz olmasıdır.Bu yöntemi kullanacaksanız advisory lock kullanmak iyi olur. Diğer açık kilitler veritabanına daha fazla yük bindirir, ama advisory lock’lar özellikle çok hafif olacak şekilde tasarlanmıştır.
Sevdiğim uygulama örneği, birçok dile port edilmiş olan que’dur.
NOTIFY/LISTENi sevmeme nedenlerimden biri, sorun çıktığında tanı koymanın zor olmasıdır.Yakın zamanda da bir süre geçtikten sonra tüm
NOTIFY/LISTENlerin durduğu ve ancak veritabanını yeniden başlatınca çözülen bir sorun yüzünden kullanmayı bırakmak zorunda kaldım https://dba.stackexchange.com/questions/325104/error-could-n...Skype yıllar önce tüm CDR’leri işlemek için küçük bir eklentiyle birlikte PostgreSQL’i kuyruk olarak kullanmıştı. Hâlâ kullanıyorlar mı bilmiyorum ama 10 yıl önceki ölçütlere göre “web ölçeği” idi ve internette veritabanını kuyruk olarak kullanmanın anti-pattern olup olmadığı tartışılırken gayet sorunsuz çalışıyordu
Transaction olması epey kullanışlı
https://wiki.postgresql.org/wiki/SkyTools
İşte oldukça fazla kullandığım için Sydpy’de bu konuda birkaç kez sunum da yaptım. PostgreSQL’i zaten iyi işletiyor ve destekliyorsanız kullanışlı
Ama bugün olsa özel bir kuyruk kullanırdım; RabbitMQ’dan ise özellikle kaçınırdım
Vendor lock-in’den endişe etseniz bile kuyrukların temel işlemleri fiilen push/pop düzeyinde küçük olduğu için, gerekirse taşınması kolay olacak şekilde yazmak da nispeten kolay
Zaten veritabanını işletiyorsunuz diye kuyruğu da veritabanına koyduysanız, bu mantık iki ucu keskin bir kılıç. Kutlanacak bir şey değil ama kuyruk karmaşası artık ana veri deposunu da aşağı çekebilir
PostgreSQL’i uygulama kuyruğu olarak kullanırken en büyük avantajlardan biri, zamanlanan tüm asenkron işlerin transactional olmanın avantajından yararlanması
Örneğin kayıt sonrası e-posta gönderen karmaşık bir backend değişikliği var; e-posta gönderme işini ekledikten sonra aynı transaction’ın daha sonraki bir kısmında hata olup rollback olursa, o e-posta işi en baştan kuyruğa hiç girmemiş olur
E-posta için gönderim onayını beklerken hata olursa, transaction’ı başarısız kılıp e-postanın yinelenmesi ihtimalini mi göze alacaksınız, yoksa devam edip e-postanın kaybolması ihtimalini mi; bunu seçmeniz gerekir
Büyük avantaj, DB’yi asenkron olarak değiştiren kod yollarından geliyor. İşin tüketilmesi ve DB güncellemesi aynı transaction içinde olduğundan exactly-once semantiğini tamamen transaction ile işleyebilirsiniz
PostgreSQL’de tetiklenen olayı ve ilgili transaction’ın
pg_current_xact_id()değerini içeren bir transaction log tablosu tutuyorum. Satırın yerleşikxmindeğeri de kullanılabilir ama transaction wraparound’u düşünmek gerekir. Bu satıra insert yapıldığındaNOTIFYoluşurBir arka plan süreci tekrar tekrar çalışır; önceki çalıştırmanın
xmindeğeri ile mevcutpg_snapshot_xmin(pg_current_snapshot())arasındaki transaction ID’lerine sahip tüm satırları transaction tablosundan seçer. Bu olayları işlere eşleyip SQS’e gönderir,xmindeğerini kaydeder ve sonra bir sonrakiNOTIFYiçinLISTENile beklerPostgreSQL kuyruğunda e-posta gönderme işini ekledikten sonra transaction daha sonra başarısız olursa e-postanın kuyruğa girmediği doğru
Tamamen ayrı olması gereken veritabanı kodunu farklı transaction’lara ayırmaya değer. Tersine, kullanıcı DB’de oluşturulmadıysa kayıt e-postasını da göndermek istemeyebilirsiniz; duruma bağlı
Redis tabanlı kuyruklarda ya da aslında başka hemen her kuyrukta, transaction commit edilmeden önce veritabanı kaydının var olduğunu varsayan bir işin çalıştığı durumla kısa sürede karşılaşırsınız. Bunu düzelten kod genellikle garip ve karmaşık olur
Kafka’da sevdiğim şey, onun sadece append-only log olması ve istemcilerin özünde yalnızca offset tutması
Kavramsal olarak anlaması çok basit; kalıcı ve arızalara karşı da oldukça dayanıklı. Çünkü herhangi bir offset’e dönüp yeniden okuyabilirsiniz
Ne yazık ki Kafka, dağıtık yapısı nedeniyle yeterince karmaşıklık getiriyor ve çoğu kullanım senaryosunda sonunda buna değmez hâle geliyor
Kişisel olarak işletmesi daha kolay benzer bir şey olmasını isterdim. Tek bir node’da saniyede yüzlerce, hatta belki binlerce event işleyebilirdi; dağıtık karmaşıklık olmasa epey iyi olurdu
Teorik olarak PostgreSQL ile de yapılabilir; satırları hiç silmezsiniz. Belki cevap bu olabilir
Consumer group, partition gibi tüm özelliklere ihtiyacınız yoksa consumer yapılandırması da çok daha basit olur
Windmill’de tam olarak bu yaklaşım kullanılıyor. Windmill açık kaynaklı bir Retool alternatifi ve modern Airflow’a yakın bir araç; her gün benchmark çalıştırıyor
Makul bir GitHub CI instance’ında bir Windmill worker’ı ve PostgreSQL’i container olarak çalıştırınca benchmark saniyede 1.200 iş işliyor. Worker ekleyince saniyede 5.000 işe kadar stabil şekilde ölçekleniyor
Multi-tenant instance’ta saniyede 5.000 iş bariyerini aşmak için Citus kullanmayı değerlendiriyoruz
https://github.com/windmill-labs/windmill/tree/benchmarks
Saniyede yaklaşık 10 mesaj düzeyinde olduğumuz zamanlarda bazı kuyruklar için PostgreSQL kullandık ve fena sayılmayacak şekilde ölçeklendi. Ama açıkçası AWS, GCP, Azure üzerinde SQS ya da başka bir kuyruk yığını kurmak çok kolay; bunlar zaten bu amaç için yapılmış ve DLQ gibi şeyler de yerleşik geliyor
Sırf bu sistem çöker de veritabanının geri kalan durumunu da etkiler mi diye kaygılanarak neden bu yolu seçeyim, bilmiyorum
“En basit aracı kullan” ilkesini seviyorum ama bazen mühendisler işi fazla ileri götürüp, ana akım alternatifler görece ucuz ve basitken bile, geriye yalnızca belirsiz uyarıları olan en aptal aracı bırakıyor gibi geliyor
İş durumunu veritabanında saklayınca durumu düzgünce sorgulayabiliyorsunuz. Gerçek durumu birebir göstermese bile, üretimdeki arızaları analiz ederken yardımcı oluyor. Özellikle çoğu iş kuyruğu işlenen kayıtları doğrudan silip atıyor
Ayrıca tüm arka plan işlerini idempotent hâle getirirseniz, “bu işi işlemesi için iş kuyruğuna mesaj gönderme” gibi bir yaklaşım neredeyse her zaman güvenli oluyor
Yalnızca mesaj kuyruğuna bel bağlarsanız, performans sorunu çıktığında ne olup bittiğini anlamak çoğu zaman zor. Örneğin RabbitMQ kuyruk boyutunu söyleyebilir ama iç verileri inceleme işlevleri yok denecek kadar azdır ya da çok sınırlıdır
Bazı yazılımların PostgreSQL’in kapasitesini asla aşmayacağı öngörülebilir; aşsa bile başka bir servise taşınması kolay olacak şekilde tasarlanabilir
Ayrıca transaction’lı bir iş sistemini PostgreSQL içinde basitçe kurmak isteyebilirsiniz
Biz Elixir’in Oban’ını kullanarak PostgreSQL içinde her gün yüz binlerce ila milyonlarca işi işliyoruz
Transaction başarılı olduğunda e-postayı planlamak gibi, arka plan işleri etrafında transaction semantiğinin olması inanılmaz derecede kullanışlı
autovacuumiçin biraz ayar yapmak gerekiyor ama toparladıktan sonra bizim için çok iyi çalıştı