Uh oh!
There was an error while loading. Please reload this page.
[SPARK-28709][DSTREAMS] Fix StreamingContext leak through Streaming - #25439
[SPARK-28709][DSTREAMS] Fix StreamingContext leak through Streaming#25439choojoyq wants to merge 1 commit into
Conversation
dongjoon-hyun
commented
Aug 13, 2019
ok to test |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| try { | ||
| validate() | ||
| registerProgressListener() |
There was a problem hiding this comment.
I understand you are suggesting that the unregister is important, but do we need this? This seems to be a behavior change.
There was a problem hiding this comment.
I think so. I believeStreamingTab shouldn't be responsible for registering/unregistering the listener as it could be and even already used in other place (metrics). Moreover seems there is also a bug that if ui is disabled, listener isn't registered and metrics aren't reported.
There was a problem hiding this comment.
Yes I tend to agree. The behavior change is registering listeners when when the UI is disabled, but that seems like possibly a fix (we'd have to look deeper to figure out whether something else registers it in this case, like StreamingSource). This seems like a better place to manage it, certainly unregistering, and if it's unregistered here it should be registered here.
| // Set up the streaming context and input streams | ||
| withStreamingContext(new StreamingContext(conf, batchDuration)) { ssc => | ||
| ssc.addStreamingListener(ssc.progressListener) | ||
There was a problem hiding this comment.
If you remove the behavior change here( https://github.com/apache/spark/pull/25439/files#r313624949 ), it seems that we don't need to change this, right?
dongjoon-hyun
commented
Aug 13, 2019
SparkQA
commented
Aug 13, 2019
Test build #109063 has finished for PR 25439 at commit
|
75935cd to
fbfabb0Compare…JobProgressListener on stop
fbfabb0 to
4d5965eCompareSparkQA
commented
Aug 14, 2019
Test build #109088 has finished for PR 25439 at commit
|
choojoyq
commented
Aug 14, 2019
@dongjoon-hyun thanks for the so fast review. |
dongjoon-hyun
commented
Aug 16, 2019
Retest this please. |
SparkQA
commented
Aug 16, 2019
Test build #109232 has finished for PR 25439 at commit
|
choojoyq
commented
Aug 20, 2019
Hi @zsxwing, could you please take a look ? |
| try { | ||
| validate() | ||
| registerProgressListener() |
There was a problem hiding this comment.
Yes I tend to agree. The behavior change is registering listeners when when the UI is disabled, but that seems like possibly a fix (we'd have to look deeper to figure out whether something else registers it in this case, like StreamingSource). This seems like a better place to manage it, certainly unregistering, and if it's unregistered here it should be registered here.
Uh oh!
There was an error while loading. Please reload this page.
| attachHandler(renderJsonHandler) | ||
| val handlers = pageToHandlers.getOrElseUpdate(page, ArrayBuffer[ServletContextHandler]()) | ||
| handlers += renderHandler | ||
| handlers += renderJsonHandler |
There was a problem hiding this comment.
Yes, handlers store reference to streaming and batch pages which store reference to StreamingJobProgressListener which stores reference to StreamingContext. So all the handlers should be unregistered.
There was a problem hiding this comment.
I see so that's kind of an additional bug fix, that this never recorded the handler in the list?
There was a problem hiding this comment.
I think so, seems that it wasn't an issue in past cause other tabs can't be detached in runtime.
dongjoon-hyun
commented
Aug 24, 2019
Retest this please. |
SparkQA
commented
Aug 24, 2019
Test build #109670 has finished for PR 25439 at commit
|
srowen
commented
Aug 26, 2019
Merged to master |
zzcclp
commented
Aug 27, 2019
srowen
commented
Aug 27, 2019
Yes I think that's OK. We're in a 'code freeze' for the 2.4.4 release at the moment, so I hesitate to merge anything but critical fixes until it's finalized. But it could go in for 2.4.5. |
zzcclp
commented
Aug 27, 2019
OK, thanks. |
dongjoon-hyun
commented
Aug 27, 2019
Thank you all. Yes. This is a good backport candidate for |
zzcclp
commented
Sep 3, 2019
@choojoyq@srowen@dongjoon-hyun 2.4.4 was released, do you plan to merge this pr into branch-2.4? |
In my application spark streaming is restarted programmatically by stopping StreamingContext without stopping of SparkContext and creating/starting a new one. I use it for automatic detection of Kafka topic/partition changes and automatic failover in case of non fatal exceptions. However i notice that after multiple restarts driver fails with OOM. During investigation of heap dump i figured out that StreamingContext object isn't cleared by GC after stopping. <img width="1901" alt="Screen Shot 2019-08-14 at 12 23 33" src="https://user-images.githubusercontent.com/13151161/63010149-83f4c200-be8e-11e9-9f48-12b6e97839f4.png"> There are several places which holds reference to it : 1. StreamingTab registers StreamingJobProgressListener which holds reference to Streaming Context directly to LiveListenerBus shared queue via ssc.sc.addSparkListener(listener) method invocation. However this listener isn't unregistered at stop method. 2. json handlers (/streaming/json and /streaming/batch/json) aren't unregistered in SparkUI, while they hold reference to StreamingJobProgressListener. Basically the same issue affects all the pages, i assume that renderJsonHandler should be added to pageToHandlers cache on attachPage method invocation in order to unregistered it as well on detachPage. 3. SparkUi holds reference to StreamingJobProgressListener in the corresponding local variable which isn't cleared after stopping of StreamingContext. Added tests to existing test suites. After i applied these changes via reflection in my app OOM on driver side gone. Closes#25439 from choojoyq/SPARK-28709-fix-streaming-context-leak-on-stop. Authored-by: Nikita Gorbachevsky <nikitag@playtika.com> Signed-off-by: Sean Owen <sean.owen@databricks.com>
srowen
commented
Sep 3, 2019
Also backported to 2.4. I resolved a minor merge conflict carefully and think I got it right. |
zzcclp
commented
Sep 4, 2019
Thank @srowen |
… avoid CCE ### What changes were proposed in this pull request? [SPARK-27122](#24088) fixes `ClassCastException` at `yarn` module by introducing `DelegatingServletContextHandler`. Initially, this was discovered with JDK9+, but the class path issues affected JDK8 environment, too. After [SPARK-28709](#25439), I also hit the similar issue at `streaming` module. This PR aims to fix `streaming` module by adding `getContextPath` to `DelegatingServletContextHandler` and using it. ### Why are the changes needed? Currently, when we test `streaming` module independently, it fails like the following. ``` $ build/mvn test -pl streaming ... UISeleniumSuite: - attaching and detaching a Streaming tab *** FAILED *** java.lang.ClassCastException: org.sparkproject.jetty.servlet.ServletContextHandler cannot be cast to org.eclipse.jetty.servlet.ServletContextHandler ... Tests: succeeded 337, failed 1, canceled 0, ignored 1, pending 0 *** 1 TEST FAILED *** [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ ``` ### Does this PR introduce any user-facing change? No. ### How was this patch tested? Pass the Jenkins with the modified tests. And do the following manually. Since you can observe this when you run `streaming` module test only (instead of running all), you need to install the changed `core` module and use it. ``` $ java -version openjdk version "1.8.0_222" OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_222-b10) OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.222-b10, mixed mode) $ build/mvn install -DskipTests $ build/mvn test -pl streaming ``` Closes#25791 from dongjoon-hyun/SPARK-29087. Authored-by: Dongjoon Hyun <dhyun@apple.com> Signed-off-by: Dongjoon Hyun <dhyun@apple.com>
… avoid CCE ### What changes were proposed in this pull request? [SPARK-27122](#24088) fixes `ClassCastException` at `yarn` module by introducing `DelegatingServletContextHandler`. Initially, this was discovered with JDK9+, but the class path issues affected JDK8 environment, too. After [SPARK-28709](#25439), I also hit the similar issue at `streaming` module. This PR aims to fix `streaming` module by adding `getContextPath` to `DelegatingServletContextHandler` and using it. ### Why are the changes needed? Currently, when we test `streaming` module independently, it fails like the following. ``` $ build/mvn test -pl streaming ... UISeleniumSuite: - attaching and detaching a Streaming tab *** FAILED *** java.lang.ClassCastException: org.sparkproject.jetty.servlet.ServletContextHandler cannot be cast to org.eclipse.jetty.servlet.ServletContextHandler ... Tests: succeeded 337, failed 1, canceled 0, ignored 1, pending 0 *** 1 TEST FAILED *** [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ ``` ### Does this PR introduce any user-facing change? No. ### How was this patch tested? Pass the Jenkins with the modified tests. And do the following manually. Since you can observe this when you run `streaming` module test only (instead of running all), you need to install the changed `core` module and use it. ``` $ java -version openjdk version "1.8.0_222" OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_222-b10) OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.222-b10, mixed mode) $ build/mvn install -DskipTests $ build/mvn test -pl streaming ``` Closes#25791 from dongjoon-hyun/SPARK-29087. Authored-by: Dongjoon Hyun <dhyun@apple.com> Signed-off-by: Dongjoon Hyun <dhyun@apple.com> (cherry picked from commit 729b318) Signed-off-by: Dongjoon Hyun <dhyun@apple.com>
In my application spark streaming is restarted programmatically by stopping StreamingContext without stopping of SparkContext and creating/starting a new one. I use it for automatic detection of Kafka topic/partition changes and automatic failover in case of non fatal exceptions. However i notice that after multiple restarts driver fails with OOM. During investigation of heap dump i figured out that StreamingContext object isn't cleared by GC after stopping. <img width="1901" alt="Screen Shot 2019-08-14 at 12 23 33" src="https://user-images.githubusercontent.com/13151161/63010149-83f4c200-be8e-11e9-9f48-12b6e97839f4.png"> There are several places which holds reference to it : 1. StreamingTab registers StreamingJobProgressListener which holds reference to Streaming Context directly to LiveListenerBus shared queue via ssc.sc.addSparkListener(listener) method invocation. However this listener isn't unregistered at stop method. 2. json handlers (/streaming/json and /streaming/batch/json) aren't unregistered in SparkUI, while they hold reference to StreamingJobProgressListener. Basically the same issue affects all the pages, i assume that renderJsonHandler should be added to pageToHandlers cache on attachPage method invocation in order to unregistered it as well on detachPage. 3. SparkUi holds reference to StreamingJobProgressListener in the corresponding local variable which isn't cleared after stopping of StreamingContext. Added tests to existing test suites. After i applied these changes via reflection in my app OOM on driver side gone. Closesapache#25439 from choojoyq/SPARK-28709-fix-streaming-context-leak-on-stop. Authored-by: Nikita Gorbachevsky <nikitag@playtika.com> Signed-off-by: Sean Owen <sean.owen@databricks.com>
What changes were proposed in this pull request?
In my application spark streaming is restarted programmatically by stopping StreamingContext without stopping of SparkContext and creating/starting a new one. I use it for automatic detection of Kafka topic/partition changes and automatic failover in case of non fatal exceptions.
However i notice that after multiple restarts driver fails with OOM. During investigation of heap dump i figured out that StreamingContext object isn't cleared by GC after stopping.
There are several places which holds reference to it :
How was this patch tested?
Added tests to existing test suites.
After i applied these changes via reflection in my app OOM on driver side gone.