-
Notifications
You must be signed in to change notification settings - Fork 29k
[SPARK-3151] [Block Manager] DiskStore.getBytes fails for files larger than 2GB #18855
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
fc3f1d7
8468738
1580449
c5028f5
908c786
67f4259
8338b4e
4a320e6
5a5c344
6cbe8d0
f6fb9e9
0e3cd82
a911c85
c877dcf
8be899f
732073c
d0c98a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -180,9 +180,9 @@ private class DiskBlockData( | |
| } | ||
|
|
||
| override def toByteBuffer(): ByteBuffer = { | ||
| require( blockSize < Int.MaxValue | ||
| , s"can't create a byte buffer of size $blockSize" | ||
| + s" since it exceeds Int.MaxValue ${Int.MaxValue}.") | ||
| require(blockSize < Int.MaxValue, | ||
| s"can't create a byte buffer of size $blockSize" + | ||
| s" since it exceeds Int.MaxValue ${Int.MaxValue}.") | ||
|
||
| Utils.tryWithResource(open()) { channel => | ||
| if (blockSize < minMemoryMapBytes) { | ||
| // For small files, directly read rather than memory map. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1438,7 +1438,7 @@ class BlockManagerSuite extends SparkFunSuite with Matchers with BeforeAndAfterE | |
| case (a, b) => | ||
|
||
| a != null && | ||
| b != null && | ||
| a.asInstanceOf[Array[Byte]].seq == b.asInstanceOf[Array[Byte]].seq | ||
| a.asInstanceOf[Array[Byte]].seq === b.asInstanceOf[Array[Byte]].seq | ||
| }) | ||
| } | ||
| val getResult = store.get(RDDBlockId(42, 0)) | ||
|
|
@@ -1448,7 +1448,7 @@ class BlockManagerSuite extends SparkFunSuite with Matchers with BeforeAndAfterE | |
| case (a, b) => | ||
| a != null && | ||
| b != null && | ||
| a.asInstanceOf[Array[Byte]].seq == b.asInstanceOf[Array[Byte]].seq | ||
| a.asInstanceOf[Array[Byte]].seq === b.asInstanceOf[Array[Byte]].seq | ||
| }) | ||
| } | ||
| val getBlockRes = store.getBlockData(RDDBlockId(42, 0)) | ||
|
|
@@ -1464,7 +1464,7 @@ class BlockManagerSuite extends SparkFunSuite with Matchers with BeforeAndAfterE | |
| case (a, b) => | ||
| a != null && | ||
| b != null && | ||
| a.asInstanceOf[Array[Byte]].seq == b.asInstanceOf[Array[Byte]].seq | ||
| a.asInstanceOf[Array[Byte]].seq === b.asInstanceOf[Array[Byte]].seq | ||
| }) | ||
| } | ||
| } finally { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we will still hit the 2g limitation here, I'm wondering which end-to-end use cases are affected by it.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indeed.
I chose to postpone the failure from
DiskStroe.getBytesto this place as I believe it introduces no regression while still allowing the more common 'streaming' like use-case.further more, I think this plays well with the comment about future deprecation of
org.apache.spark.network.buffer.ManagedBuffer#nioByteBufferwhich seems to be the main reason forBlockDataexposing thetoByteBuffermethod.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cloud-fan
it took me roughly 4 hours, but I looked both at the shuffle cod path and at
BlockManager.getRemoteBytes:it seems the first is robust to large blocks by using Netty's stream capabilities,
the later seems to be broken as it's not using the Netty's streaming capabilities and actually tries to copy the result buffer into a heap based buffer. I think this deserves its own JIRA/PR.
I think these two places plus the external shuffle server cover most of the relevant use cases (aside from local caching which i believe this PR completes in terms of being 2GB proof).