Skip to content

[#825][followup] fix(spark): Apply a thread safety way to track the blocks sending result - #1260

Merged
roryqi merged 5 commits into
apache:masterfrom
summaryzb:fix_concurrency
Oct 25, 2023
Merged

[#825][followup] fix(spark): Apply a thread safety way to track the blocks sending result#1260
roryqi merged 5 commits into
apache:masterfrom
summaryzb:fix_concurrency

Conversation

@summaryzb

@summaryzb summaryzb commented Oct 24, 2023

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

As title

Why are the changes needed?

[INFO] Running org.apache.uniffle.test.ContinuousSelectPartitionStrategyTest
Error:  Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 59.195 s <<< FAILURE! - in org.apache.uniffle.test.ContinuousSelectPartitionStrategyTest
Error:  resultCompareTest  Time elapsed: 55.751 s  <<< ERROR!
org.apache.spark.SparkException: 
Job aborted due to stage failure: Task 6 in stage 1.0 failed 1 times, most recent failure: Lost task 6.0 in stage 1.0 (TID 16) (fv-az391-410.nf14wd45lyte3l5gjbhk121dmd.jx.internal.cloudapp.net executor driver): org.apache.uniffle.common.exception.RssException: Timeout: Task[16_0] failed because 9 blocks can't be sent to shuffle server in 30000 ms.
	at org.apache.spark.shuffle.writer.RssShuffleWriter.checkBlockSendResult(RssShuffleWriter.java:350)
	at org.apache.spark.shuffle.writer.RssShuffleWriter.writeImpl(RssShuffleWriter.java:246)
	at org.apache.spark.shuffle.writer.RssShuffleWriter.write(RssShuffleWriter.java:209)
	at org.apache.spark.shuffle.ShuffleWriteProcessor.write(ShuffleWriteProcessor.scala:59)
	at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:99)
	at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:52)

ActionLink
I debug the local test and find that all blocks are successfully send, but some blocks are not in the block tracker

Does this PR introduce any user-facing change?

No.

How was this patch tested?

Integration test
Especially run below test in a loop of many times without a fail

mvn -B -fae test -Dtest=org.apache.uniffle.test.ContinuousSelectPartitionStrategyTest -Pspark3

@summaryzb

Copy link
Copy Markdown
Contributor Author

@yl09099 @jerqi PTAL

blockId ->
blockIdsSendFailTracker
.computeIfAbsent(blockId, id -> Lists.newArrayList())
.computeIfAbsent(blockId, id -> new CopyOnWriteArrayList())

@roryqi roryqi Oct 24, 2023

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CopyOnWriteArrayList is suitable for the situation that we have more read operations than write operations. But we have more write operations than read operations now. Maybe it will give us performance regression. If we want to use thread safe collection, maybe queue will be better.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ur right, replace it with BlockingQueue. Besides I revert the blockIdsSendSuccessTracker to the earlier code, since we don't track the success server.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@summaryzb summaryzb changed the title [#825][part-2][followup] fix(writer): use safety list to track the blocks sending result [#825][part-2][followup] fix(writer): Apply a thread safety way to track the blocks sending result Oct 24, 2023
@codecov-commenter

codecov-commenter commented Oct 24, 2023

Copy link
Copy Markdown

Codecov Report

Merging #1260 (6eaeabd) into master (49effee) will increase coverage by 1.13%.
The diff coverage is 91.30%.

@@             Coverage Diff              @@
##             master    #1260      +/-   ##
============================================
+ Coverage     53.93%   55.06%   +1.13%     
- Complexity     2647     2653       +6     
============================================
  Files           396      376      -20     
  Lines         23036    20687    -2349     
  Branches       1970     1970              
============================================
- Hits          12424    11391    -1033     
+ Misses         9845     8600    -1245     
+ Partials        767      696      -71     
Files Coverage Δ
...va/org/apache/spark/shuffle/writer/DataPusher.java 62.26% <ø> (ø)
...uniffle/client/response/SendShuffleDataResult.java 46.15% <100.00%> (ø)
...he/uniffle/client/impl/ShuffleWriteClientImpl.java 35.69% <90.90%> (+1.72%) ⬆️

... and 21 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

// we assume that most of the blocks can be sent successfully
// so initialize the map at first without concurrency insurance
// AtomicInteger is enough to reflect value changes in other threads
Map<Long, AtomicInteger> blockIdsSendSuccessTracker = Maps.newHashMap();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initialize With all blockIds to reduce the condition race, eliminate the scenario that no existing blockId while tracking the sending result

// we assume that most of the blocks can be sent successfully
// so initialize the map at first without concurrency insurance
// AtomicInteger is enough to reflect value changes in other threads
Map<Long, AtomicInteger> blockIdsSendSuccessTracker = Maps.newHashMap();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BlockIdsSendSuccessTracker object should have concurrency issues? Use concurrentMap?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No concurrency issues, since blockIdsSendSuccessTracker is already initialize with all blockIds, it will not be modified in other thread.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of put the blockId in blockIdsSendSuccessTracker when get a response in multi threads, We just put all blockIds in the beginning before concurrency execute. This is helpful to reduce condition race, and we can be optimistically that no space will be wasted since most of the blockIds will be sent successfully.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK,I get it,LGTM~

@roryqi roryqi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks @summaryzb @yl09099

@roryqi
roryqi merged commit ec7f85c into apache:master Oct 25, 2023
@roryqi roryqi changed the title [#825][part-2][followup] fix(writer): Apply a thread safety way to track the blocks sending result [#825][followup] fix(spark): Apply a thread safety way to track the blocks sending result Oct 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants