1 poin oleh GN⁺ 7 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • Workflow durable melakukan checkpoint status eksekusi ke database sehingga dapat dipulihkan dari langkah terakhir yang selesai setelah crash
  • Orkestrasi eksternal ala Temporal, Airflow, dan AWS Step Functions menambah orkestrator pusat dan penyimpanan sehingga kompleksitas meningkat
  • Arsitektur berbasis Postgres memungkinkan server aplikasi mem-polling tabel workflow dan menyimpan output langkah secara langsung agar bisa dipulihkan
  • Banyak server mencegah eksekusi ganda dengan lock dan integrity constraint, serta menangani masalah skalabilitas, ketersediaan, dan observabilitas dengan solusi Postgres
  • Satu instance Postgres dapat diskalakan secara vertikal hingga puluhan ribu workflow per detik, sambil tetap memanfaatkan replikasi, multi-AZ, dan analisis SQL

Model dasar workflow durable

  • Workflow durable adalah pendekatan yang secara berkala menyimpan status kemajuan selama eksekusi program sebagai checkpoint di database, sehingga setelah crash atau kegagalan dapat dipulihkan dari langkah terakhir yang selesai
  • Seperti save dan load dalam video game, ini bisa dilihat sebagai model yang secara berkala “menyimpan” progres program lalu “memuatnya” kembali dari checkpoint terakhir setelah crash
  • Implementasi yang umum adalah sistem orkestrasi eksternal seperti Temporal, Airflow, dan AWS Step Functions
  • Dalam orkestrasi eksternal, program durable ditulis sebagai workflow yang terdiri dari beberapa langkah, lalu orkestrator pusat mengoordinasikan eksekusinya

Cara kerja orkestrasi eksternal

  • Saat klien mengirim workflow, orkestrator membuat record di data store lalu mendistribusikannya ke worker untuk dieksekusi
  • Setiap kali worker menyelesaikan suatu langkah, hasilnya dikirim ke orkestrator, lalu orkestrator melakukan checkpoint output tersebut ke data store sebelum mendistribusikan langkah berikutnya
  • Jika worker crash atau gagal, orkestrator mengirim ulang workflow itu ke worker lain dan memulainya dari langkah checkpoint terakhir
  • Struktur ini menambah server orkestrator terpisah ke ide inti menyimpan status workflow di database, sehingga kompleksitas meningkat

Arsitektur yang menggunakan Postgres sebagai orkestrator

  • Jika inti dari workflow durable adalah melakukan checkpoint status program ke database, maka menggunakan database itu sendiri sebagai orkestrator tanpa server orkestrator terpisah lebih sederhana dan efisien
  • Postgres adalah pilihan yang cocok untuk membangun workflow durable karena popularitasnya, skalabilitasnya, dan ekosistemnya yang kaya
  • Dalam sistem workflow durable berbasis Postgres, server aplikasi berkomunikasi langsung dengan Postgres tanpa melalui orkestrator pusat untuk menjalankan workflow
  • Klien mengirim eksekusi dengan membuat entri di tabel workflow Postgres, lalu server aplikasi mem-polling tabel tersebut untuk dequeue dan mengeksekusi workflow
  • Saat menjalankan workflow, server melakukan checkpoint output tiap langkah ke Postgres, dan jika server yang sedang berjalan crash atau gagal, server lain memulihkan workflow dari checkpoint

Mengapa orkestrator pusat menjadi tidak diperlukan

  • Server aplikasi dapat berkoordinasi melalui Postgres, sehingga orkestrator pusat tidak perlu mendistribusikan workflow ke worker
  • Server dapat secara kooperatif dequeue workflow dari tabel Postgres, dan dengan mekanisme seperti klausa lock dapat menjamin setiap workflow hanya di-dequeue oleh tepat satu worker
  • Checkpoint output langkah juga ditulis langsung ke Postgres oleh worker, bukan oleh orkestrator
  • Jika beberapa worker mencoba menjalankan workflow yang sama secara bersamaan, integrity constraint Postgres dapat mendeteksi pekerjaan duplikat pada saat checkpoint dan memaksa salah satunya mundur
  • Dengan mengganti orkestrator pusat menggunakan Postgres atau database lain, masalah seperti skalabilitas, ketersediaan, observabilitas, dan keamanan dapat ditangani dengan solusi native Postgres yang sudah mapan

Skalabilitas dan ketersediaan

  • Skalabilitas dan ketersediaan sistem workflow durable berbasis database pada dasarnya ditentukan oleh database yang mendasarinya
  • Karena server worker dapat ditambah untuk scale out secara horizontal, kapasitas maksimum bergantung pada seberapa cepat database dapat memproses workflow
  • Worker dapat saling menggantikan dan memulihkan status satu sama lain, sehingga sistem tetap tersedia selama database yang mendasarinya tersedia
  • Saat menggunakan Postgres, keunggulannya adalah skalabilitas dan ketersediaan merupakan masalah yang sudah lama diteliti dan memiliki solusi yang kuat
  • Satu server Postgres dapat diskalakan secara vertikal untuk menangani puluhan ribu workflow per detik
  • Skalabilitas tambahan dapat dicapai dengan menggunakan Postgres terdistribusi seperti CockroachDB atau Postgres yang di-shard
  • Postgres mendukung streaming replication dengan failover otomatis, dan layanan terkelola menyediakan deployment multi-AZ serta SLA high availability secara bawaan
  • Rekayasa dan riset selama puluhan tahun yang terakumulasi untuk mengoperasikan Postgres dalam skala besar juga dapat langsung dimanfaatkan untuk mengoperasikan workflow durable

Observabilitas

  • Dalam eksekusi durable berbasis Postgres, workflow dan langkah di-checkpoint ke tabel Postgres, sehingga checkpoint tersebut dapat dipindai untuk memantau workflow secara real time dan memvisualisasikan eksekusi
  • Postgres unggul karena hampir semua query observabilitas workflow dapat diekspresikan dengan SQL
  • Tugas analisis dan filtering yang kompleks, seperti query untuk menemukan semua workflow yang mengalami error selama sebulan terakhir, dapat dinyatakan secara deklaratif dengan SQL
  • Hal ini dimungkinkan karena memanfaatkan model relasional Postgres dan puluhan tahun riset optimisasi query
  • Banyak sistem dengan model data yang lebih sederhana, seperti key-value store yang digunakan oleh orkestrator eksternal populer, tidak dapat memberikan dukungan analisis berbasis SQL pada tingkat yang sama
  • Dengan menyimpan data workflow dan langkah di tabel Postgres serta menambahkan indeks sekunder untuk query analisis yang cepat, kita bisa memperoleh observabilitas yang efisien dalam eksekusi durable

Keandalan dan keamanan

  • Dalam eksekusi durable yang menggunakan orkestrator eksternal, orkestrator dan data store-nya sama-sama menjadi single point of failure
  • Karena orkestrator dan data store langsung mengoordinasikan eksekusi workflow, jika salah satunya down maka seluruh aplikasi menjadi tidak dapat digunakan
  • Keduanya juga menangani dan menyimpan workflow serta checkpoint langkah, sehingga berpotensi mengakses data aplikasi yang sensitif dan perlu diperkeras, dikontrol aksesnya, serta diaudit seperti infrastruktur sensitif lainnya
  • Dalam eksekusi durable berbasis Postgres, satu-satunya titik kegagalan adalah Postgres itu sendiri, dan semua data workflow disimpan langsung di Postgres tanpa melewati sistem lain
  • Jika aplikasi sudah bergantung pada Postgres, maka mengadopsi eksekusi durable tidak menambah titik kegagalan baru maupun menciptakan permukaan serangan baru yang perlu dilindungi
  • Karena database sudah menjadi infrastruktur inti, lebih masuk akal untuk menggunakan kembali database yang ada daripada menambahkan infrastruktur inti baru khusus untuk orkestrasi

Pelajari lebih lanjut

1 komentar

 
GN⁺ 7 jam lalu
Komentar Hacker News
  • absurd karya Armin Ronacher adalah implementasi workflow tahan lama untuk Postgres
    https://lucumr.pocoo.org/2025/11/3/absurd-workflows/
    https://github.com/earendil-works/absurd
    https://earendil-works.github.io/absurd/
    Saya belum mencobanya sendiri, tetapi ini layak dibandingkan dengan opsi lain

    • Jika tidak membutuhkan throughput yang sangat tinggi, absurd dan turunan implementasi Rust bernama durable menurut saya adalah pilihan bagus yang menjaga sisi klien tetap sangat sederhana
      Karena ringan, agen coding bisa dengan mudah memahami seluruh strukturnya, dan bila perlu statusnya bisa dicek lewat query
  • Saya memakai dbos.dev, restate.dev, dan cf workflows, dan di Agents.md kami tertulis seperti ini
    Restate.dev dipakai untuk integrasi pembayaran northflank. Lebih cepat daripada cf workflows, independen dari Cloudflare dan gangguannya, serta bisa self-hosted sehingga tidak ada vendor lock-in
    Cloudflare workflows dipakai untuk tugas yang kurang penting seperti pembuatan laporan CSV/PDF. Alasannya karena sangat murah
    DBOS.dev dipakai untuk workflow yang butuh messaging atomik yang terikat dengan transaksi Postgres, sehingga memerlukan keandalan/daya tahan 100%. Contohnya mengisi materialized row atau mengirim email/push penting ke merchant
    DBOS dan Restate terlihat mirip di permukaan, tetapi Restate memerlukan “orchestrator” terpusat, yang punya plus minus tersendiri dan membuatnya lebih mudah dibangun bersama worker serverless cf/vercel
    Selain itu ada VirtualObject, jadi ini lumayan sebagai alternatif open-source tanpa vendor lock-in untuk DurableObject single-threaded milik Cloudflare
    Ada dua hal yang benar-benar menonjol dari DBOS. 1) Dengan dbos.enqueue_workflow, kita bisa melakukan messaging atomik di dalam transaksi DB yang sama dengan logika bisnis. Bagian ini sering kali menjadi titik paling rapuh di berbagai solusi, jadi jika bisa ditangani secara atomik dan tahan lama di transaksi yang sama dengan eksekusi logika bisnis, kompleksitasnya jauh berkurang
    2) DBOS menyimpan status workflow di DB, jadi sepertinya mudah membuat dashboard observabilitas dengan metabase/looker. Akan bagus juga kalau Restate mengekspor instance rocksdb agar bisa dihubungkan ke metabase

    • Saya penasaran bagaimana mereka menangani pembaruan skema. Apakah job-nya dimigrasikan, atau deployment worker ditangani dengan cara tertentu?
  • Saya penasaran dengan pengalaman nyata orang-orang yang pernah memakai DBOS dan Temporal
    Saya pernah memakai Temporal sebelumnya dan itu bekerja cukup baik, tetapi saya sempat merasa tidak nyaman saat membangun solusi karena batas ukuran payload request atau event
    Memang ada kelebihan karena ia memaksa praktik engineering yang baik, tetapi saya juga tidak selalu ingin memakai logika khusus berupa mengunggah file CSV ke S3 lalu meneruskan tautannya dan mengunduhnya kembali di workflow hanya karena file CSV itu lebih besar dari 2MB
    Saya ingin tahu seperti apa pengalaman dengan DBOS, dan bagaimana perbandingannya dengan Temporal dari sisi kompleksitas operasional maupun kesetaraan fitur

    • Saya belum pernah memakai DBOS, tetapi saya sudah memakai Temporal di pekerjaan sekarang dan pekerjaan sebelumnya, total sekitar 1,5 tahun
      Di rumah pun saya menjalankannya untuk menangani tugas otomasi rumah yang tidak terlalu sensitif terhadap waktu. Latensi workflow-nya tidak terlalu buruk, tetapi saya rasa saya tidak akan memakainya untuk trigger yang harus merespons seketika seperti event deteksi gerakan di rumah, sedangkan untuk timeout seperti mematikan sesuatu setelah periode tidak aktif, itu masih cocok
      Saya cukup menyukai pendekatan menaruh REST API tipis di depan Temporal di dalam VPC atau klaster Kubernetes. Dengan begitu trigger berbasis event tidak perlu memikirkan autentikasi Temporal atau pemeriksaan status workflow, dan ini membantu menjaga event sebisa mungkin tetap tanpa logika
      Misalnya trigger DB berjalan langsung atau memasukkan event ke antrean, lalu handler memanggil REST API tipis dengan detail event yang diperlukan. REST API dapat memutuskan apakah ini harus memulai workflow, mengirim signal ke workflow yang sudah ada, atau mengabaikannya. Polanya berbeda-beda tergantung situasi, tetapi dalam kasus saya saya sering memakai SignalWithStart, atau jika tidak layak memulai dan memang tidak ada workflow yang sudah ada, ya dibuang saja
      Selain itu, saat perlu mengorkestrasi aksi-aksi yang saling independen dalam siklus hidup satu objek, fitur parent/child workflow sangat berguna, dan saya juga suka karena ia bisa dibatalkan ketika faktor eksternal mengubah jalur progres objek tersebut
      Kalau dijelaskan secara panjang dan agak samar, ini sangat kuat, mudah dipakai, dan sangat membantu memindahkan logika siklus hidup ke luar API. Jika diletakkan di dalam API, utang teknis mudah menumpuk dan pengelolaannya jadi rapuh. Saya setuju bahwa memaksa kita mengikuti praktik terbaik itu lebih baik daripada melempar logika ke tempat yang terlihat mudah lalu belakangan menjadi jebakan tersembunyi
    • Saya merasa Temporal terlalu rumit, tetapi seperti yang disebutkan, bagian terbaiknya adalah ia memaksa praktik engineering yang baik
      Namun saya sempat mencoba produk Cloud-nya dan kaget dengan harganya. Bahkan sebelum naik ke produksi, kredit gratis sebesar 1.000 dolar sudah habis. Saya juga tidak ingin mengoperasikan Temporal lokal sendiri
      Menurut saya pribadi, yang terbaik adalah mengambil idenya dari arsitekturnya lalu mengimplementasikannya sendiri dengan Postgres
    • Kami baru saja merilis pendekatan penyimpanan eksternal untuk mengatasi masalah payload besar
      Saya tidak 100% puas dengannya. Rasanya seperti tambahan, bukan bagian yang esensial, dan ini juga masih rilis awal. Tetapi setidaknya sekarang masalah itu pada dasarnya sudah teratasi
    • Saya mengoperasikan deployment Temporal on-premise skala besar, dan akun ini akun sementara karena takut ketahuan
      Setelah menjalankannya di produksi selama lebih dari setahun, menurut saya Temporal didesain dengan buruk, lambat, dan dari sisi infrastruktur benar-benar terlalu berat
      Untuk pekerjaan yang tidak sepele, misalnya lebih dari 200 event per workflow dan hanya beberapa ratus yang berjalan bersamaan sepanjang hari, Anda bisa saja menghabiskan jutaan dolar untuk biaya infrastruktur, dan hasilnya tetap saja kurang bagus
      Jika menjalankan benchmark sendiri, angkanya buruk
      Tim sales-nya juga benar-benar buruk dan terlihat putus asa
      Dari sudut pandang developer, SDK-nya cukup bagus
      Jangan sampai terkunci di nexus, dan kalau tim sales menelepon, pastikan tim legal ikut ada di ruangan
    • Kami memakai dbos untuk workflow yang dihasilkan AI dan pemrosesan file video
      Butuh waktu untuk memahami cara migrasi dari Celery, tetapi untuk kasus kami itu sepadan
  • Conductor OSS juga melakukan ini dengan cukup baik https://docs.conductor-oss.org/devguide/ai/index.html
    https://github.com/agentspan-ai/agentspan pada dasarnya adalah lapisan SDK agen untuk Conductor, yang bisa membuat agen langgraph, OpenAI, vercel, dan ADK menjadi durable serta menambahkan orkestrasi tanpa perubahan kode

    • Di produksi kami memakai Redis sebagai antrean, tetapi saya juga pernah melihat pengguna yang memakai Postgres dan MySQL sebagai antrean
  • Daripada memisahkan penyimpanan data, state machine, constraint status yang valid, dan logika untuk berpindah antarstatus yang valid, akan bagus kalau semua itu bisa disatukan ke semacam kernel dari status aplikasi
    Sejujurnya Postgres sudah punya banyak kemampuan seperti ini, tetapi saya masih belum melihat gambaran yang jelas di level aplikasi atau produk yang menyediakan himpunan status yang dapat dibuktikan untuk transisi aplikasi, lalu otomatis mengeksposnya ke klien dengan cara yang bermanfaat. Misalnya, pengguna ini boleh memberi like pada postingan ini tetapi tidak boleh mengeditnya
    Di mata saya ini terlihat seperti bentuk colored Petri net, tetapi saya masih belum melihat paradigma status aplikasi yang sederhana seperti database yang punya batas keberhasilan yang jelas

    • Temporal.io agak mendekati ini dengan fitur query, signal, dan update
      Hanya saja saya tidak yakin apakah itu benar-benar integrasi penuh
    • Sudah ada upaya ke arah ini, tetapi stored procedure seribu baris benar-benar mimpi buruk
    • Ini terdengar seperti convex.dev atau https://spacetimedb.com/. Saya tidak memakai keduanya secara langsung
  • Karena DBOS tidak mendukung Rust, saya mengimplementasikan versi Rust yang sangat minimal dan mirip ini di https://github.com/tensorzero/durable
    Ini cukup stabil dan bisa diskalakan, tetapi tentu saja Anda harus sangat berhati-hati dengan implementasi SQL. Semoga ini menarik bagi para pembaca di sini

  • Saya sepenuhnya memahami dan setuju dengan konsepnya. Ini cara yang bagus untuk memasukkan jenis durabilitas seperti ini ke dalam sistem workflow
    Hanya saja, dengan otak gamer, saya ingin menyebut ini sebagai save scumming skala besar. Banyak orang mungkin sudah tahu bahwa pendekatan ini berhasil, tetapi mungkin belum mengaitkannya dengan konsep ilmu komputer yang abstrak
    Strategi lain untuk meningkatkan ketahanan adalah menyusun workflow dari operasi-operasi idempoten. Ini bisa berguna saat status workflow terlalu besar untuk dicadangkan dengan mudah. Sebagai gantinya, jika tugas dijalankan ulang dari awal, semua langkah hingga titik kemajuan terakhir hanya akan menjadi no-op

  • Saya terus dibuat takjub oleh banyaknya hal yang bisa dilakukan dengan sedikit alat selama Postgres ada di dalam kotak peralatan
    Baru-baru ini saya mengembangkan distributed queue dan hasilnya bekerja sangat baik, benchmark-nya juga bagus, serta tidak ada race condition maupun konflik. Saya memakai SKIP LOCKED agar para worker bisa bersaing dengan aman
    Jika ingin membuat worker di beberapa node menghindari benturan, Anda juga bisa memakai mutex berskala sesi, yaitu pg advisory lock

    • Bagaimanapun, untuk kasus seperti ini advisory lock memang biasanya lebih disukai. Menahan banyak SELECT FOR UPDATE tidak akan berskala dengan baik
      Edit: setelah saya cek lagi, sepertinya sekarang sarannya justru berubah menjadi kebalikannya
    • Cukup pasang reservasi pada record dengan actor ID
  • Di Rails ada beberapa backend pekerjaan berbasis database, tetapi menurut konvensi, sebuah job harus selalu hanya melakukan satu hal dan, kalau bisa, selesai dengan sangat cepat
    Karena itu, membangun workflow terasa agak dipaksakan. Baris terakhir job pertama akan memasukkan job kedua ke queue, lalu baris terakhir job kedua akan memasukkan job ketiga ke queue, dan seterusnya
    Backend job tidak menampilkan semuanya sebagai workflow yang saling terhubung, melainkan memperlakukannya sebagai job independen, dan jika ingin memahami workflow pada level tinggi, kita harus membaca beberapa class job
    Rails baru-baru ini memperkenalkan konsep continuable yang memungkinkan checkpoint per langkah dan melanjutkan eksekusi di dalam job, tetapi konvensi untuk menjaga job tetap memiliki tanggung jawab tunggal masih sangat kuat, jadi rasanya canggung untuk workflow sungguhan
    Saya penasaran apakah orang lain juga mengalami hal seperti ini, dan apakah mereka menemukan solusinya

  • Ini pola yang sangat bagus. Sebaiknya lakukan sebanyak mungkin pekerjaan di dalam database
    Spanner eksternal menyediakan change streams. Spanner internal berbeda; terutama karena dalam beberapa kasus ada kebutuhan skalabilitas yang ekstrem, dan juga campuran alasan "sudah berjalan dengan baik" serta "change stream arbitrer itu menakutkan"
    Spanner internal memungkinkan transaksi apa pun menulis entri queue. Di sini queue kurang lebih adalah tabel khusus dengan kesadaran waktu. Anda bisa menjadwalkan pengiriman, dan entri akan didorong dari queue ke handler, sementara handler juga bisa melakukan penulisan ke DB di dalam transaksi dequeue. Dan semua skalabilitas yang sama tetap terjaga