Skip to content
Snippets Groups Projects
Commit 90f73fcc authored by Aaron Davidson's avatar Aaron Davidson Committed by Reynold Xin
Browse files

[SPARK-3889] Attempt to avoid SIGBUS by not mmapping files in ConnectionManager

In general, individual shuffle blocks are frequently small, so mmapping them often creates a lot of waste. It may not be bad to mmap the larger ones, but it is pretty inconvenient to get configuration into ManagedBuffer, and besides it is unlikely to help all that much.

Author: Aaron Davidson <aaron@databricks.com>

Closes #2742 from aarondav/mmap and squashes the following commits:

a152065 [Aaron Davidson] Add other pathway back
52b6cd2 [Aaron Davidson] [SPARK-3889] Attempt to avoid SIGBUS by not mmapping files in ConnectionManager
parent 411cf29f
No related branches found
No related tags found
No related merge requests found
...@@ -66,13 +66,27 @@ sealed abstract class ManagedBuffer { ...@@ -66,13 +66,27 @@ sealed abstract class ManagedBuffer {
final class FileSegmentManagedBuffer(val file: File, val offset: Long, val length: Long) final class FileSegmentManagedBuffer(val file: File, val offset: Long, val length: Long)
extends ManagedBuffer { extends ManagedBuffer {
/**
* Memory mapping is expensive and can destabilize the JVM (SPARK-1145, SPARK-3889).
* Avoid unless there's a good reason not to.
*/
private val MIN_MEMORY_MAP_BYTES = 2 * 1024 * 1024;
override def size: Long = length override def size: Long = length
override def nioByteBuffer(): ByteBuffer = { override def nioByteBuffer(): ByteBuffer = {
var channel: FileChannel = null var channel: FileChannel = null
try { try {
channel = new RandomAccessFile(file, "r").getChannel channel = new RandomAccessFile(file, "r").getChannel
channel.map(MapMode.READ_ONLY, offset, length) // Just copy the buffer if it's sufficiently small, as memory mapping has a high overhead.
if (length < MIN_MEMORY_MAP_BYTES) {
val buf = ByteBuffer.allocate(length.toInt)
channel.read(buf, offset)
buf.flip()
buf
} else {
channel.map(MapMode.READ_ONLY, offset, length)
}
} catch { } catch {
case e: IOException => case e: IOException =>
Try(channel.size).toOption match { Try(channel.size).toOption match {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment