Uh oh!
There was an error while loading. Please reload this page.
[SPARK-21527][CORE] Use buffer limit in order to use JAVA NIO Util's buffercache - #18730
[SPARK-21527][CORE] Use buffer limit in order to use JAVA NIO Util's buffercache#18730caneGuy wants to merge 19 commits into
Conversation
cloud-fan
commented
Aug 23, 2017
ok to test |
cloud-fan
commented
Aug 23, 2017
looks reasonable, do you have some performance numbers? |
| /** | ||
| * Write this buffer to a channel with slice. | ||
| */ |
There was a problem hiding this comment.
can we use this one to replace writeFully?
SparkQA
commented
Aug 23, 2017
Test build #81018 has finished for PR 18730 at commit
|
SparkQA
commented
Aug 23, 2017
Test build #81020 has finished for PR 18730 at commit
|
cloud-fan
commented
Aug 23, 2017
retest this please |
@cloud-fan Thanks for your time to review this pr.Actually,there is an application in our cluster always failed with direct memory oom.I have not measured performance with some benchmark test,but this feature has run in our cluster for a long time(since last year) and i observed this has not caused any performance issue.By the way, application with direct memory issue caused by 'BufferCache' out of control has not occur since then. |
SparkQA
commented
Aug 23, 2017
Test build #81023 has finished for PR 18730 at commit
|
jiangxb1987
commented
Aug 23, 2017
It would be great to benchmark this improvement, otherwise we are not sure there is no regression. |
| def writeWithSlice(channel: WritableByteChannel): Unit = { | ||
| for (bytes <- getChunks()) { | ||
| val capacity = bytes.limit() | ||
| while (bytes.position() < capacity) { |
There was a problem hiding this comment.
Should we replace Math.min(...) with Math.min(capacity, bytes.position + NIO_BUFFER_LIMIT.toLong)? I am afraid about int underflow. For example, if capacity = 0x7FFFFFF0 and bytes.position = 0x7FFFFF00, the result of bytes.position + NIO_BUFFER_LIMIT.toInt is negative (i.e. greater than 0x80000000).
To avoid this underflow, it would be good to compare them by using long.
There was a problem hiding this comment.
Good review.I refactor the code.
caneGuy
commented
Aug 24, 2017
@jiangxb1987 Ok,i will try to do some benchmark tesing. |
caneGuy
commented
Aug 24, 2017
I mock some local test for two different api. From the simple test result, we can see slice will not affect the performance of write bytes.Test result below: Test code below: |
SparkQA
commented
Aug 24, 2017
Test build #81068 has finished for PR 18730 at commit
|
SparkQA
commented
Aug 24, 2017
Test build #81061 has finished for PR 18730 at commit
|
SparkQA
commented
Aug 24, 2017
Test build #81064 has finished for PR 18730 at commit
|
SparkQA
commented
Aug 24, 2017
Test build #81069 has finished for PR 18730 at commit
|
kiszk
commented
Aug 24, 2017
Thank you for preparing a benchmark. Could you please write a benchmark using Benchmark class? |
caneGuy
commented
Aug 24, 2017
|
| private[spark] val BUFFER_WRITE_CHUNK_SIZE = | ||
| ConfigBuilder("spark.buffer.write.chunkSize") | ||
| .internal() | ||
| .doc("The block size limit when use ChunkedByteBuffer to writeFully bytes.") |
There was a problem hiding this comment.
The chunk size during writing out the bytes of ChunkedByteBuffer
SparkQA
commented
Aug 24, 2017
Test build #81085 has finished for PR 18730 at commit
|
cloud-fan
commented
Aug 24, 2017
LGTM, pending jenkins |
caneGuy
commented
Aug 24, 2017
Thanks for your time @cloud-fan |
SparkQA
commented
Aug 24, 2017
Test build #81087 has finished for PR 18730 at commit
|
SparkQA
commented
Aug 24, 2017
Test build #81086 has finished for PR 18730 at commit
|
SparkQA
commented
Aug 24, 2017
Test build #81089 has finished for PR 18730 at commit
|
SparkQA
commented
Aug 24, 2017
Test build #81091 has finished for PR 18730 at commit
|
SparkQA
commented
Aug 24, 2017
Test build #81080 has finished for PR 18730 at commit
|
SparkQA
commented
Aug 24, 2017
Test build #81081 has finished for PR 18730 at commit
|
SparkQA
commented
Aug 24, 2017
Test build #81082 has finished for PR 18730 at commit
|
SparkQA
commented
Aug 24, 2017
Test build #81083 has finished for PR 18730 at commit
|
SparkQA
commented
Aug 25, 2017
Test build #81112 has finished for PR 18730 at commit
|
caneGuy
commented
Aug 25, 2017
@cloud-fan can we retest this?Thanks |
cloud-fan
commented
Aug 25, 2017
retest this please |
| while (bytes.remaining > 0) { | ||
| while (bytes.remaining() > 0) { | ||
| val ioSize = Math.min(bytes.remaining(), bufferWriteChunkSize) | ||
| bytes.limit(bytes.position + ioSize.toInt) |
There was a problem hiding this comment.
let's avoid this per-loop type cast, we can make bufferWriteChunkSize an int.
| .internal() | ||
| .doc("The chunk size during writing out the bytes of ChunkedByteBuffer.") | ||
| .bytesConf(ByteUnit.BYTE) | ||
| .createWithDefault(64 * 1024 * 1024) |
There was a problem hiding this comment.
add a checkValue to make sure the value is smaller than Int.Max
SparkQA
commented
Aug 25, 2017
Test build #81125 has finished for PR 18730 at commit
|
SparkQA
commented
Aug 25, 2017
Test build #81128 has finished for PR 18730 at commit
|
caneGuy
commented
Aug 25, 2017
@cloud-fan Jekins done! |
cloud-fan
commented
Aug 25, 2017
thanks, merging to master! |
What changes were proposed in this pull request?
Right now, ChunkedByteBuffer#writeFully do not slice bytes first.We observe code in java nio Util#getTemporaryDirectBuffer below:
If we slice first with a fixed size, we can use buffer cache and only need to allocate at the first write call.
Since we allocate new buffer, we can not control the free time of this buffer.This once cause memory issue in our production cluster.
In this patch, i supply a new api which will slice with fixed size for buffer writing.
How was this patch tested?
Unit test and test in production.