3 ポイント 投稿者 GN⁺ 2026-01-30 | 1件のコメント | WhatsAppで共有
  • Oban.py は、Elixir のジョブ処理フレームワーク Oban を PostgreSQL ベースで Python に移植したバージョンで、データベースだけでジョブを投入して処理できる
  • ジョブはデータベーストランザクション内で生成・ロールバックされ、キュー管理・結果保存・cron スケジューリング など多様な機能をサポート
  • オープンソース版は 単一スレッドの asyncio 実行個別投入・確認処理 などの制約がある一方、Pro 版は 並列処理・ワークフロー・スマート並行性 を提供
  • 内部動作は Insert → Notify → Fetch → Execute → Ack の5段階で構成され、PostgreSQL の FOR UPDATE SKIP LOCKED を活用して並行性の競合を防止
  • リーダー選出、孤立ジョブの復旧、バックオフ再試行などもデータベースベースで実行され、外部ブローカーなしで安定した分散処理 を可能にする

Oban.py 概要

  • Oban.py は Elixir の Oban を Python に移植した データベースベースのジョブ処理フレームワーク
    • ジョブをデータベーストランザクション内で投入・処理し、失敗時にはトランザクション全体がロールバックされる
    • キュー制限、完了ジョブ保存、結果保持、cron スケジューリング など多様な制御機能を含む
  • 2つのバージョンを提供
    • オープンソース(OSS) : 単一スレッドの asyncio 実行、個別投入・確認、単純な復旧
    • Pro 版: プロセスプールベースの並列処理、ワークフロー・リレー・ユニークジョブ・スマート並行性 をサポート
  • OSS は個人プロジェクトや評価用途に適しており、大規模環境では Pro 版が推奨される

ジョブ処理の流れ

  • ジョブ投入後、oban_jobs テーブルに state='available' で保存され、PostgreSQL の NOTIFY によって各ノードへ通知が送られる
  • 各ノードの Stager が該当キューを検知して Producer を起こし、Producer がジョブを取得して実行する
  • ジョブ選択時には SQL の FOR UPDATE SKIP LOCKED を使い、重複実行なしの並列処理 が可能
    • すでにロックされた行はスキップするため、別の Producer が別ジョブを即座に取得できる
  • ジョブは async task としてディスパッチされ、完了時にはコールバックで acknowledgement を処理
  • Pro 版は asyncio の代わりに プロセスプールディスパッチャ を使い、マルチコア並列実行をサポート

バックグラウンドプロセス

  • リーダー選出(Leader Election)
    • PostgreSQL の INSERT ... ON CONFLICT と TTL ベースのリースでリーダーを決定
    • 別途コンセンサスプロトコルなしで単一リーダーが ジョブ整理・復旧 を担当
  • Lifeline(孤立ジョブ復旧)
    • 実行中のジョブが一定時間(rescue_after、デフォルト5分)を超えて継続すると available 状態に復旧 される
    • Pro 版は Producer の生存確認を行うが、OSS は時間ベースでのみ判断する
  • Pruner(ジョブ整理)
    • 完了・キャンセル・破棄されたジョブのうち、max_age(デフォルト1日)を超えた項目を削除
    • LIMIT で削除範囲を制限し、データベース負荷を防ぐ

再試行とバックオフ

  • ジョブが例外を発生させると Executor が再試行の可否を判断
    • 最大試行回数(max_attempts)未満なら再試行し、超過すると破棄
  • デフォルトのバックオフは ジッター(jitter) を含む 指数的増加
    • 大量失敗時の同時再試行を防ぎ、負荷急増(Thundering Herd)を緩和
    • 例: 1回目は約17秒、5回目は約47秒、10回目は約17分待機
  • ワーカークラスは backoff() メソッドで ユーザー定義のバックオフロジック を実装できる

主な特徴と評価

  • PostgreSQL が中核的な役割 を担う
    • FOR UPDATE SKIP LOCKEDLISTEN/NOTIFYON CONFLICT によって 並行性制御・シグナル伝達・リーダー選出 をすべて処理
    • Redis や外部ブローカーなしで 単一データベースによる調整レイヤー を構成
  • 並列ではないが並行性をサポート
    • asyncio ベースで I/O バウンド作業に適しており、CPU バウンド作業には Pro 版が推奨される
  • コード構造の明快さ
    • 一貫した命名と責務分離により 読みやすいコードベース を実現
  • OSS と Pro の役割分担が明確
    • OSS は実験・小規模向け、Pro は大規模・高性能環境向け
  • 結論: PostgreSQL だけで完全なジョブキューを実装した クリーンで構造的な Python 移植版 であり、Elixir ユーザーや外部インフラなしのジョブシステムを求める開発者に適している

1件のコメント

 
GN⁺ 2026-01-30
Hacker Newsの反応
  • 私は Sidekiq の作者だが、今回 Shannon と Parker がリリースしたものを祝福したい
    以前、私も同じことで悩んだ — Ruby に集中するか、それとも Sidekiq を他の言語へ広げるか。すべての言語の専門家にはなれないと気づき、その代わりに Faktory を作った。これは中央サーバーがキューのライフサイクルを管理し、各言語向けクライアントはシンプルなままにしておく構造だ。たとえば faktory-rs のようなクライアントがある。欠点は特定の言語コミュニティに集中していないので、その言語に合った例を提供しづらい点だ。
    ひとつのコミュニティに集中するアプローチのほうが、より良い結果を生むかもしれない。時間が教えてくれるだろう

    • ありがとう、Mike! あなたは本当に インスピレーションの源 です。Parker と私はそれぞれ異なる強みを持っていて、Python と Elixir の相互運用性から生まれるシナジーを信じています
    • Faktory は、私が作った言語非依存のジョブキューシステム Ocypod に大きな影響を与えました。オープンソースとして公開してくれてありがとう
    • 実際には、どちらも Resque ベースと言ったほうがより正確では?
    • 意図はなかったのかもしれないが、そのコメントは自分のプロジェクトを宣伝しようとしているように見える。そういうのはここではあまり好まれない
    • “based on” という表現は少し大げさに思える。Sidekiq は、Oban がサポートするワークフロー、cron、パーティショニング、依存ジョブ、失敗処理などと比べるとずっと単純だ
  • Oban の核心は、データベースだけでジョブの投入と処理ができる点にある。ユーザー作成トランザクションの中でメール送信ジョブも一緒に投入し、失敗したら全体がロールバックされる構造だ。
    多くの人はリレーショナル DB をジョブキューとして使うべきではないと言うが、トランザクションの重要性を見落としている。Brandur Leach の記事 Job Drain でもこの考え方がよく説明されている

    • この話には強く共感する。以前 Dual Write Problem のせいでイベントが消えるのを何年も見てきた。結局 SQL ベースのアプローチに戻したら、問題は 1 日で解決した。
      だが今では誰もその不便さを覚えていない。“トランザクショナル・アウトボックス・パターン” は必須であり、私は自分のデータと同じ ACID 保証 を受けられる方法を好む。
      DB の内部実装を知らなくても、分離レベルとコミット順序を学ぶのに 1 週間投資すれば、分散システムのデバッグ 1 年分を節約できる
    • これはまさに トランザクショナル・アウトボックス・パターン と呼ばれるものだ
    • 私もこの機能は本当に素晴らしいと思う。その代わり私は pg_timetable を使っている
    • 私たちは AI ベースのアプリビルダー を作っていて、Elixir、Phoenix、そしてもちろん OBAN を使っている。
      長い AI プロセスが多い時代において、このような 耐久性 は必須だ。他の言語エコシステムではこうした機能にお金を払うが、Oban では標準で提供されている
    • トランザクションをこんなふうに考えたことはなかったが、本当に印象的だ
  • Oban チームは Elixir エコシステムで 洗練されたエンジニアリング で知られている。だが、プロ版でプロセスプールをロックしているのは戸惑う。
    たとえば月額 135 ドルのプランには、マルチプロセス実行、ワークフロー、グローバル制限、ユニークジョブ、バルク処理、暗号化されたソース、専用サポートなどが含まれる。
    私のプロジェクト Chancy は完全に無料で、asyncio、プロセス、スレッド、サブインタープリタを自由に組み合わせられる。
    こうした機能を OSS に移して、有料は エンタープライズサポート 中心にしたほうがよいのではと思う。Python エコシステムには競合がはるかに多い

    • 関心や利用状況に応じて、一部機能を OSS に移すことはあり得る。Elixir でもそうしたことがある。
      単にサポートだけを売るモデルはうまく合わなかったが、Python では違うかもしれない。
      Python エコシステムには本当に 何でもある
    • 参考までに、Django 6.0 には Django Tasks API が追加され、バックエンドを差し替えられるが、実運用向けバックエンドはまだ存在しない。
      Chancy に Django Tasks 対応を追加するか、django-chancy パッケージを作れば、すぐに採用が進みそうだ
    • Chancy を共有してくれてありがとう。面白そうだ。API の変更を除けば、今でも本番環境で 安定的 に使えるだろうか?
  • OSS Oban は 単一スレッドの asyncio 実行 しかサポートしていないので、CPU バウンドなジョブがイベントループをブロックする。
    そのため試す価値はないと感じた。Celery のインターフェースは好きではないが慣れているし、垂直・水平の両方でいくらでもスケールできる。
    ただ、複数のワーカーノードを立ち上げられると知って少し考えが変わった

  • OSS/Pro の機能分離自体は構わないが、「Pro 版はより賢いハートビートでプロデューサーの生存を追跡する」というのは残念だ。
    信頼性に関わる機能 が有料だと、OSS プロジェクトで採用しにくくなる

    • 私も同じ印象だ。Oban は素晴らしいが、「同じ機能のより良い版」が有料なのは惜しい。
      基本版が最高であるべきで、追加機能が有料であるべきだ。境界線が少し 妙な場所 にある気がする
    • Redis や RabbitMQ ベースのキューは、予期しない停止の後にジョブを失うこともある。
      引用された文はやや不正確で、プロデューサーの生存追跡自体は同じで、違いは 孤立ジョブの復旧方法 だけだ
  • Python にある BI/ML/DS ワークフローが Elixir に移ってくれたらいいのにと思う。
    関数型・耐障害性・並行性 に優れた Elixir のほうが、こうした作業の基盤としてはずっと自然だと思う

  • うちの会社でも Celery を使っているが、あまり良くない。Temporal は重すぎるし、Oban は軽くて気に入っている。
    両方使ったことがある人の比較を聞いてみたい

    • 2 つのツールは 思想がまったく異なる
      Temporal はワークフロー保証とその複雑さを受け入れられる組織(たとえば銀行)に向いている。
      Oban は DB ベースのキューで、信頼性は自分で強化する必要がある。
      私は両方が同じシステム内に共存しているのが理想だと思う
    • 私たちは Celery から Prefect に移行して満足している。数千単位のジョブ処理には完璧だ。
      シンプルな ProcessWorker と ECS ワーカーを組み合わせて使っている
    • 久しぶりに Python の Web 開発に戻ってきたが、Celery に対する 不満 が多いことに驚いた。
      最近の Celery は以前より不安定になったり、扱いづらくなったりしているのだろうか
  • 興味深いプロジェクトだ。ただし、コア機能の一部が Pro 限定なのが目につく。
    Postgres ベースの耐久性ワークフローを OSS で実装した先行プロジェクトとしては、DBOSAbsurd がある。
    データベース中心のアプローチが増えているのは喜ばしいことだ

    • Elixir にも似た OSS プロジェクトはあったし、Oban の耐久性ワークフロー実装は DBOS より何年も先行していた。
      完全なオープンソースモデルとサポート販売だけで運営するのは 夢のようなモデル だ。いつか実現できればと思う
  • Postgres で数億件のジョブを処理できるほど 性能は十分なのか 気になる。以前 Redis + Sidekiq に移行したとき、大きな性能向上を見た

    • どれくらいの期間か気になる。私は Rails/Solid Queue + Postgres で 1 日 2,000 万件のジョブを 45 ドルの VM で処理していて、まだかなり余裕がある
  • OSS 版は長時間ジョブがあると、プロデューサーが生きていても誤って復旧されることがあるという。
    では短いジョブしか使えないということ?

    • ジョブの長さに制限はない。違いは クラッシュ後の復旧速度 だけだ。
      正常終了を待てなかった場合にのみ、復旧タイミングが変わる