TreasureDataで多重実行を排除するdomain keyがサポートされました


これまでの問題

td queryコマンドではPOSTリクエストを発行して、その返り値にJOB IDが返却されます。
しかし、稀にジョブは発行したけれども、返り値がネットワークの問題などによって取得できないエラーが発生することがありました。
POSTリクエストの場合にはリトライすると多重にジョブが登録されてしまう可能性があり、簡単にリトライすることができません。
そうすると、JOB IDがわからないので、自分が実行したジョブが本当に発行されたかどうかを調べることが難しいという問題がありました。
特にINSERT INTOやクエリ結果書き出しなどを実行していると、多重実行されてしまうと困ってしまうケースもありました。

それを解決するために、--domain-keyがサポートされました。
https://github.com/treasure-data/td/pull/157

domain keyとは

ジョブにユニーク名をつけることができるオプションになります。
これを使うことで、このdomain keyが登録されていて、かつジョブが発行されていれば、再度このdomain keyを元に処理を実行しても、既にジョブが登録されているから、受付拒否するよ。ということができるようになっており、多重実行を防ぐことができます。

例:

まずはジョブを発行します。

$ td query -d sample_datasets --domain-key batch1-20160926 -T presto "select * from www_access"
Job 92034375 is queued.
Use 'td job:show 92034375' to show the status.

正常にジョブIDを取得できてますが、仮にこれが失敗してjob idがわからなかったときは、再度このkeyを元に発行します。

$ td query -d sample_datasets --domain-key batch1-20160926 -T presto "select * from www_access"
Error: Query failed: ["Domain key has already been taken"]: conflicts_with job:92034375

すると、上記のエラーが発生し、これによってjob idが取得できます。
つまり従来は、

query -> job id取得 -> job status -> SUCCESSまでリトライ -> done

という処理しかできず、job id取得に問題があるとこまってしまったのですが、

query (+ domain key) -> job id取得できるまでquery -> job status -> SUCCESSまでリトライ -> done

という流れに変えることができるようになり、よりロバストなバッチ処理を実現できるようになっています。

補足

DigdagのTDオペレータでは、内部的にこれを利用するようになっており、リトライなどがロバストに行えるようになっています。