You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Update databricks provider to use TriggerOperator #18999
The databricks provider can be updated to a deferrable task introduced in airflow 2.2.0. This will significnatly reduce cpu usage, memory usage on LocalExecutor and improve reliability since state is stored in the airflow metastore.
Use case/motivation
Currently the databricks operators works by calling the databricks REST API to submit a spark job and polling it every 20 secs to check when it is done. This creates the following inefficiencies:
If the airflow executor process crashes, a duplicate job can be created in databricks since airflow doesn't save the databricks job run id.
Each task instance of the databricks operators run its own process, however 95% of the time the process is idle and waiting to repoll the databricks API. If you want to 50 jobs in parallel, you will use a non trivial amount of memory / CPU just to poll a rest API.
That would be very interesting to work on this issue, using the new Airflow functionality, i.e. implementing the polling in async. I'd be happy to contribute to that.
@chinwobble thank you so much, it's a good base to start working on! 👍
Regarding the task duration - I haven't checked yet, but I thought it's implemented so that execution time counted over total time, so an operator might fail even while it's deferred.
@chinwobble thank you so much, it's a good base to start working on! 👍
Regarding the task duration - I haven't checked yet, but I thought it's implemented so that execution time counted over total time, so an operator might fail even while it's deferred.
@ekarimov I've checked the task duration.
If your task defers, that deferral time is not considered as part of the task duration.
@chinwobble you're right, I see the same behaviour... I've spotted though when I don't pass timeout argument to self.defer(), a deferred task will fail if its runtime more than execution_timeout set for the Operator calling it.
I.e. timeout for a deferred task is equal to execution timeout for an Operator in this case. Here is the code behind
Also, we might found a a bug, because I see a code part in TaskInstance trying to check for timeout and re-calculate it, when task executed after deferred state. The issue is that self.start_date is changing every time when a task is continued after the deferred state.
We are using localExecutor and it seems like the deferral consumes an unnecessary amount of tasks.
When implementing deferral, it looks like this is what is happening:
schedulerJob decides a task is ready to be queued
Queued jobs run on a local executor and start a new job consuming 1 worker slot.
The execute method is started, it takes 1 sec to submit the job to databricks
self.defer() is run and queues a trigger.
This throws an exception and causes the task job to terminate and the worker slot is returned to the pool
The triggerer is a separate process that can asynchronously process triggers and determine when to a resume a task
The trigger yields a result causing the scheduler to requeue the original databricks task possibly on a different method
A new executor worker process (second job start) is started (consuming 1 worker slot), when complete it marks the task as succeeded or failed
The task is complete and all workers are returned to the pool.
FYI just wanted to share that I'm still willing to introduce deferrable operators for Databricks, and working on the code.
Hope to create a PR later this week.
There're a couple of moments I'd like to discuss with someone more experienced than me, @chinwobble I'd be very happy if you review the code, will add you to the reviewers list if you don't mind.
Regarding the timeout - I've created a separate issue #19382 to investigate and fix it, shared the findings there. @chinwobble could I add your comment above there into the issue description? It's a nice summary on how it works internally
Activity
boring-cyborg commentedon Oct 15, 2021
Thanks for opening your first issue here! Be sure to follow the issue template!
eskarimov commentedon Oct 26, 2021
That would be very interesting to work on this issue, using the new Airflow functionality, i.e. implementing the polling in async. I'd be happy to contribute to that.
chinwobble commentedon Oct 27, 2021
@eskarimov I have implemented a prototype like this:
One issue i have with the above limitation is that the task duration does not count the time the task was deferred.
I'm sure many improvements could be made but this should work.
eskarimov commentedon Oct 30, 2021
@chinwobble thank you so much, it's a good base to start working on! 👍
Regarding the task duration - I haven't checked yet, but I thought it's implemented so that execution time counted over total time, so an operator might fail even while it's deferred.
chinwobble commentedon Oct 31, 2021
@ekarimov I've checked the task duration.
If your task defers, that deferral time is not considered as part of the task duration.
eskarimov commentedon Nov 1, 2021
@chinwobble you're right, I see the same behaviour... I've spotted though when I don't pass
timeoutargument toself.defer(), a deferred task will fail if its runtime more thanexecution_timeoutset for the Operator calling it.I.e. timeout for a deferred task is equal to execution timeout for an Operator in this case. Here is the code behind
Also, we might found a a bug, because I see a code part in
TaskInstancetrying to check for timeout and re-calculate it, when task executed after deferred state. The issue is thatself.start_dateis changing every time when a task is continued after the deferred state.chinwobble commentedon Nov 2, 2021
We are using localExecutor and it seems like the deferral consumes an unnecessary amount of tasks.
When implementing deferral, it looks like this is what is happening:
eskarimov commentedon Nov 17, 2021
FYI just wanted to share that I'm still willing to introduce deferrable operators for Databricks, and working on the code.
Hope to create a PR later this week.
There're a couple of moments I'd like to discuss with someone more experienced than me, @chinwobble I'd be very happy if you review the code, will add you to the reviewers list if you don't mind.
Regarding the timeout - I've created a separate issue #19382 to investigate and fix it, shared the findings there.
@chinwobble could I add your comment above there into the issue description? It's a nice summary on how it works internally
chinwobble commentedon Nov 18, 2021
@eskarimov Happy to review your code. I'm not the best python dev, so I think I could learn a thing or two from you.
#18999 (comment)
These deferrable operators are a good first step in making airflow more scalable.
However, there are a few issues that make me feel its not ready yet:
chinwobble commentedon May 29, 2022
@eskarimov nice work getting this one merged!