-
Notifications
You must be signed in to change notification settings - Fork 15.4k
KAFKA-2576; ConsumerPerformance hangs when SSL enabled for Multi-Partition Topic #236
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 all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,9 +24,7 @@ import kafka.common.{TopicAndPartition, ErrorMapping} | |
| import kafka.message.{MessageSet, ByteBufferMessageSet} | ||
| import kafka.api.ApiUtils._ | ||
| import org.apache.kafka.common.KafkaException | ||
| import org.apache.kafka.common.network.TransportLayer | ||
| import org.apache.kafka.common.network.Send | ||
| import org.apache.kafka.common.network.MultiSend | ||
| import org.apache.kafka.common.network.{SSLTransportLayer, TransportLayer, Send, MultiSend} | ||
|
|
||
| import scala.collection._ | ||
|
|
||
|
|
@@ -55,6 +53,7 @@ case class FetchResponsePartitionData(error: Short = ErrorMapping.NoError, hw: L | |
|
|
||
| class PartitionDataSend(val partitionId: Int, | ||
| val partitionData: FetchResponsePartitionData) extends Send { | ||
| private val emptyBuffer = ByteBuffer.allocate(0) | ||
| private val messageSize = partitionData.messages.sizeInBytes | ||
| private var messagesSentSize = 0 | ||
| private var pending = false | ||
|
|
@@ -71,15 +70,20 @@ class PartitionDataSend(val partitionId: Int, | |
|
|
||
| override def writeTo(channel: GatheringByteChannel): Long = { | ||
| var written = 0L | ||
| if(buffer.hasRemaining) | ||
| if (buffer.hasRemaining) | ||
| written += channel.write(buffer) | ||
| if (!buffer.hasRemaining && messagesSentSize < messageSize) { | ||
| val bytesSent = partitionData.messages.writeTo(channel, messagesSentSize, messageSize - messagesSentSize) | ||
| messagesSentSize += bytesSent | ||
| written += bytesSent | ||
| if (!buffer.hasRemaining) { | ||
| if (messagesSentSize < messageSize) { | ||
| val bytesSent = partitionData.messages.writeTo(channel, messagesSentSize, messageSize - messagesSentSize) | ||
| messagesSentSize += bytesSent | ||
| written += bytesSent | ||
| } | ||
| if (messagesSentSize >= messageSize && hasPendingWrites(channel)) | ||
| channel.write(emptyBuffer) | ||
| } | ||
| if (channel.isInstanceOf[TransportLayer]) | ||
| pending = channel.asInstanceOf[TransportLayer].hasPendingWrites | ||
|
|
||
| pending = hasPendingWrites(channel) | ||
|
|
||
| written | ||
| } | ||
|
|
||
|
|
@@ -112,6 +116,8 @@ case class TopicData(topic: String, partitionData: Map[Int, FetchResponsePartiti | |
|
|
||
| class TopicDataSend(val dest: String, val topicData: TopicData) extends Send { | ||
|
|
||
| private val emptyBuffer = ByteBuffer.allocate(0) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that we can just reference ErrorMapping.EmptyByteBuffer?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could do that. A few concerns: it's a bit strange that the empty buffer lives in
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok. Then what you had is fine. Did the unit tests pass?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, they passed when I ran them locally. |
||
|
|
||
| private var sent = 0L | ||
|
|
||
| private var pending = false | ||
|
|
@@ -135,14 +141,16 @@ class TopicDataSend(val dest: String, val topicData: TopicData) extends Send { | |
| throw new KafkaException("This operation cannot be completed on a complete request.") | ||
|
|
||
| var written = 0L | ||
| if(buffer.hasRemaining) | ||
| if (buffer.hasRemaining) | ||
| written += channel.write(buffer) | ||
| if(!buffer.hasRemaining && !sends.completed) { | ||
| written += sends.writeTo(channel) | ||
| if (!buffer.hasRemaining) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as above
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Explained above, mutation makes code harder to reason about, I know. :) |
||
| if (!sends.completed) | ||
| written += sends.writeTo(channel) | ||
| if (sends.completed && hasPendingWrites(channel)) | ||
| written += channel.write(emptyBuffer) | ||
| } | ||
|
|
||
| if (channel.isInstanceOf[TransportLayer]) | ||
| pending = channel.asInstanceOf[TransportLayer].hasPendingWrites | ||
| pending = hasPendingWrites(channel) | ||
|
|
||
| sent += written | ||
| written | ||
|
|
@@ -245,6 +253,9 @@ case class FetchResponse(correlationId: Int, | |
|
|
||
|
|
||
| class FetchResponseSend(val dest: String, val fetchResponse: FetchResponse) extends Send { | ||
|
|
||
| private val emptyBuffer = ByteBuffer.allocate(0) | ||
|
|
||
| private val payloadSize = fetchResponse.sizeInBytes | ||
|
|
||
| private var sent = 0L | ||
|
|
@@ -272,15 +283,18 @@ class FetchResponseSend(val dest: String, val fetchResponse: FetchResponse) exte | |
| throw new KafkaException("This operation cannot be completed on a complete request.") | ||
|
|
||
| var written = 0L | ||
| if(buffer.hasRemaining) | ||
|
|
||
| if (buffer.hasRemaining) | ||
| written += channel.write(buffer) | ||
| if(!buffer.hasRemaining && !sends.completed) { | ||
| written += sends.writeTo(channel) | ||
| if (!buffer.hasRemaining) { | ||
| if (!sends.completed) | ||
| written += sends.writeTo(channel) | ||
| if (sends.completed && hasPendingWrites(channel)) | ||
| written += channel.write(emptyBuffer) | ||
| } | ||
| sent += written | ||
|
|
||
| if (channel.isInstanceOf[TransportLayer]) | ||
| pending = channel.asInstanceOf[TransportLayer].hasPendingWrites | ||
| sent += written | ||
| pending = hasPendingWrites(channel) | ||
|
|
||
| written | ||
| } | ||
|
|
||
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.
NP: could this just be
if (buffer.hasRemaining)
written += channel.write(buffer)
else{...
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.
No, because the buffer is mutated.