Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
* Properties props = new Properties();
* props.put("bootstrap.servers", "localhost:9092");
* props.put("acks", "all");
* props.put("retries", 0);
* props.put("delivery.timeout.ms", 30000);
* props.put("batch.size", 16384);
* props.put("linger.ms", 1);
* props.put("buffer.memory", 33554432);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,11 @@ public class ProducerConfig extends AbstractConfig {

/** <code>delivery.timeout.ms</code> */
public static final String DELIVERY_TIMEOUT_MS_CONFIG = "delivery.timeout.ms";
private static final String DELIVERY_TIMEOUT_MS_DOC = "An upper bound on the time to report success or failure after Producer.send() returns. "
+ "Producer may report failure to send a message earlier than this config if all the retries are exhausted or "
+ "a record is added to a batch nearing expiration. " + DELIVERY_TIMEOUT_MS_CONFIG + "should be equal to or "
+ "greater than " + REQUEST_TIMEOUT_MS_CONFIG + " + " + LINGER_MS_CONFIG;
private static final String DELIVERY_TIMEOUT_MS_DOC = "An upper bound on the time to report success or failure after "
+ "Producer.send() returns. The producer may report failure to send a record earlier than this config if all "
+ "the retries have been exhausted or a record is added to a batch nearing expiration. "

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What config is used for "batch expiration"?

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.

Urmm, delivery timeout. I found this wording a little confusing as well. I will try to rephrase.

+ "The value of this config should be equal to or greater than " + REQUEST_TIMEOUT_MS_CONFIG
+ " + " + LINGER_MS_CONFIG + ". ";

/** <code>client.id</code> */
public static final String CLIENT_ID_CONFIG = CommonClientConfigs.CLIENT_ID_CONFIG;
Expand Down Expand Up @@ -181,10 +182,14 @@ public class ProducerConfig extends AbstractConfig {
/** <code>retries</code> */
public static final String RETRIES_CONFIG = CommonClientConfigs.RETRIES_CONFIG;
private static final String RETRIES_DOC = "Setting a value greater than zero will cause the client to resend any record whose send fails with a potentially transient error."
+ " Note that this retry is no different than if the client resent the record upon receiving the error."
+ " Allowing retries without setting <code>" + MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION + "</code> to 1 will potentially change the"
+ " ordering of records because if two batches are sent to a single partition, and the first fails and is retried but the second"
+ " succeeds, then the records in the second batch may appear first.";
+ " Note that this retry is no different than if the client resent the record upon receiving the error."
+ " Allowing retries without setting <code>" + MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION + "</code> to 1 will potentially change the"
+ " ordering of records because if two batches are sent to a single partition, and the first fails and is retried but the second"
+ " succeeds, then the records in the second batch may appear first. Note that the produce requests will be"

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.

nit: Also note

+ " failed before the number of retries has been exhausted if the timeout configured by"
+ " " + DELIVERY_TIMEOUT_MS_CONFIG + " expires first before successful acknowledgement. Users should generally"
+ " prefer to leave this config unset and instead use " + DELIVERY_TIMEOUT_MS_CONFIG + " to control"
+ " retry behavior.";

/** <code>key.serializer</code> */
public static final String KEY_SERIALIZER_CLASS_CONFIG = "key.serializer";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ public Worker(
// These settings are designed to ensure there is no data loss. They *may* be overridden via configs passed to the
// worker, but this may compromise the delivery guarantees of Kafka Connect.
producerProps.put(ProducerConfig.REQUEST_TIMEOUT_MS_CONFIG, Integer.toString(Integer.MAX_VALUE));
producerProps.put(ProducerConfig.RETRIES_CONFIG, Integer.toString(Integer.MAX_VALUE));
producerProps.put(ProducerConfig.MAX_BLOCK_MS_CONFIG, Long.toString(Long.MAX_VALUE));
producerProps.put(ProducerConfig.ACKS_CONFIG, "all");
producerProps.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "1");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ KafkaBasedLog<String, byte[]> setupAndCreateKafkaBasedLog(String topic, final Wo
Map<String, Object> producerProps = new HashMap<>(originals);
producerProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
producerProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, ByteArraySerializer.class.getName());
producerProps.put(ProducerConfig.RETRIES_CONFIG, Integer.MAX_VALUE);
producerProps.put(ProducerConfig.DELIVERY_TIMEOUT_MS_CONFIG, Integer.MAX_VALUE);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@rhauch do we need to update Connect documentation?

Map<String, Object> consumerProps = new HashMap<>(originals);
consumerProps.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
consumerProps.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, ByteArrayDeserializer.class.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void configure(final WorkerConfig config) {
Map<String, Object> producerProps = new HashMap<>(originals);
producerProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, ByteArraySerializer.class.getName());
producerProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, ByteArraySerializer.class.getName());
producerProps.put(ProducerConfig.RETRIES_CONFIG, Integer.MAX_VALUE);
producerProps.put(ProducerConfig.DELIVERY_TIMEOUT_MS_CONFIG, Integer.MAX_VALUE);

Map<String, Object> consumerProps = new HashMap<>(originals);
consumerProps.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, ByteArrayDeserializer.class.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public void configure(final WorkerConfig config) {
Map<String, Object> producerProps = new HashMap<>(originals);
producerProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
producerProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, ByteArraySerializer.class.getName());
producerProps.put(ProducerConfig.RETRIES_CONFIG, 0); // we handle retries in this class
producerProps.put(ProducerConfig.DELIVERY_TIMEOUT_MS_CONFIG, 0); // we handle retries in this class

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we really want to do this? Do we ensure that we send the record at least once or could it fail in the accumulator?

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.

Actually we probably just want to leave this as it was.


Map<String, Object> consumerProps = new HashMap<>(originals);
consumerProps.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
Expand Down
10 changes: 5 additions & 5 deletions core/src/main/scala/kafka/tools/MirrorMaker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import org.apache.kafka.clients.consumer.{CommitFailedException, Consumer, Consu
import org.apache.kafka.clients.producer.internals.ErrorLoggingCallback
import org.apache.kafka.clients.producer.{KafkaProducer, ProducerConfig, ProducerRecord, RecordMetadata}
import org.apache.kafka.common.{KafkaException, TopicPartition}
import org.apache.kafka.common.serialization.ByteArrayDeserializer
import org.apache.kafka.common.serialization.{ByteArrayDeserializer, ByteArraySerializer}
import org.apache.kafka.common.utils.Utils
import org.apache.kafka.common.errors.WakeupException
import org.apache.kafka.common.record.RecordBatch
Expand All @@ -50,7 +50,7 @@ import scala.util.control.ControlThrowable
* @note For mirror maker, the following settings are set by default to make sure there is no data loss:
* 1. use producer with following settings
* acks=all
* retries=max integer
* delivery.timeout.ms=max integer
* max.block.ms=max long
* max.in.flight.requests.per.connection=1
* 2. Consumer Settings
Expand Down Expand Up @@ -193,13 +193,13 @@ object MirrorMaker extends Logging with KafkaMetricsGroup {
val sync = producerProps.getProperty("producer.type", "async").equals("sync")
producerProps.remove("producer.type")
// Defaults to no data loss settings.
maybeSetDefaultProperty(producerProps, ProducerConfig.RETRIES_CONFIG, Int.MaxValue.toString)
maybeSetDefaultProperty(producerProps, ProducerConfig.DELIVERY_TIMEOUT_MS_CONFIG, Int.MaxValue.toString)
maybeSetDefaultProperty(producerProps, ProducerConfig.MAX_BLOCK_MS_CONFIG, Long.MaxValue.toString)
maybeSetDefaultProperty(producerProps, ProducerConfig.ACKS_CONFIG, "all")
maybeSetDefaultProperty(producerProps, ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "1")
// Always set producer key and value serializer to ByteArraySerializer.
producerProps.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.ByteArraySerializer")
producerProps.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.ByteArraySerializer")
producerProps.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, classOf[ByteArraySerializer].getName)
producerProps.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, classOf[ByteArraySerializer].getName)
producer = new MirrorMakerProducer(sync, producerProps)

// Create consumers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1442,7 +1442,6 @@ class AuthorizerIntegrationTest extends BaseRequestTest {
val transactionalProperties = new Properties()
transactionalProperties.setProperty(ProducerConfig.TRANSACTIONAL_ID_CONFIG, transactionalId)
val producer = TestUtils.createProducer(TestUtils.getBrokerListStrFromServers(servers),
retries = 3,
props = Some(transactionalProperties))
producers += producer
producer
Expand All @@ -1452,7 +1451,6 @@ class AuthorizerIntegrationTest extends BaseRequestTest {
val idempotentProperties = new Properties()
idempotentProperties.setProperty(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, "true")
val producer = TestUtils.createProducer(TestUtils.getBrokerListStrFromServers(servers),
retries = 3,
props = Some(idempotentProperties))
producers += producer
producer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,11 @@ abstract class BaseProducerSendTest extends KafkaServerTestHarness {
super.tearDown()
}

protected def createProducer(brokerList: String, retries: Int = 0, lingerMs: Int = 0, props: Option[Properties] = None): KafkaProducer[Array[Byte],Array[Byte]] = {
protected def createProducer(brokerList: String,
lingerMs: Int = 0,
props: Option[Properties] = None): KafkaProducer[Array[Byte],Array[Byte]] = {
val producer = TestUtils.createProducer(brokerList, securityProtocol = securityProtocol, trustStoreFile = trustStoreFile,
saslProperties = clientSaslProperties, retries = retries, lingerMs = lingerMs, props = props)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I was thinking that it would be good to have at least one test with retries = 0. Do we have such a test?

saslProperties = clientSaslProperties, lingerMs = lingerMs, props = props)
registerProducer(producer)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,11 @@ abstract class EndToEndAuthorizationTest extends IntegrationTestHarness with Sas

override def createProducer: KafkaProducer[Array[Byte], Array[Byte]] = {
TestUtils.createProducer(brokerList,
maxBlockMs = 3000L,
securityProtocol = this.securityProtocol,
trustStoreFile = this.trustStoreFile,
saslProperties = this.clientSaslProperties,
props = Some(producerConfig))
maxBlockMs = 3000L,
securityProtocol = this.securityProtocol,
trustStoreFile = this.trustStoreFile,
saslProperties = this.clientSaslProperties,
props = Some(producerConfig))
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,19 @@ abstract class IntegrationTestHarness extends KafkaServerTestHarness {
}

def createProducer: KafkaProducer[Array[Byte], Array[Byte]] = {
TestUtils.createProducer(brokerList,
securityProtocol = this.securityProtocol,
trustStoreFile = this.trustStoreFile,
saslProperties = this.clientSaslProperties,
props = Some(producerConfig))
TestUtils.createProducer(brokerList,
securityProtocol = this.securityProtocol,
trustStoreFile = this.trustStoreFile,
saslProperties = this.clientSaslProperties,
props = Some(producerConfig))
}

def createConsumer: KafkaConsumer[Array[Byte], Array[Byte]] = {
TestUtils.createConsumer(brokerList,
securityProtocol = this.securityProtocol,
trustStoreFile = this.trustStoreFile,
saslProperties = this.clientSaslProperties,
props = Some(consumerConfig))
TestUtils.createConsumer(brokerList,
securityProtocol = this.securityProtocol,
trustStoreFile = this.trustStoreFile,
saslProperties = this.clientSaslProperties,
props = Some(consumerConfig))
}

@After
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ class PlaintextConsumerTest extends BaseConsumerTest {
producerProps.setProperty(ProducerConfig.COMPRESSION_TYPE_CONFIG, CompressionType.GZIP.name)
producerProps.setProperty(ProducerConfig.LINGER_MS_CONFIG, Int.MaxValue.toString)
val producer = TestUtils.createProducer(brokerList, securityProtocol = securityProtocol, trustStoreFile = trustStoreFile,
saslProperties = clientSaslProperties, retries = 0, lingerMs = Int.MaxValue, props = Some(producerProps))
saslProperties = clientSaslProperties, lingerMs = Int.MaxValue, props = Some(producerProps))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do you know why we were setting this to 0 previously?

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.

There was no obvious reason. As far as I can tell, we are just using this function to populate some data in order to check consumer operations.

(0 until numRecords).foreach { i =>
producer.send(new ProducerRecord(tp.topic, tp.partition, i.toLong, s"key $i".getBytes, s"value $i".getBytes))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ class PlaintextProducerSendTest extends BaseProducerSendTest {
*/
@Test
def testAutoCreateTopic() {
val producer = createProducer(brokerList, retries = 5)

val producer = createProducer(brokerList)
try {
// Send a message to auto-create the topic
val record = new ProducerRecord(topic, null, "key".getBytes, "value".getBytes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class RackAwareAutoTopicCreationTest extends KafkaServerTestHarness with RackAwa

@Test
def testAutoCreateTopic() {
val producer = TestUtils.createProducer(brokerList, retries = 5)
val producer = TestUtils.createProducer(brokerList)
try {
// Send a message to auto-create the topic
val record = new ProducerRecord(topic, null, "key".getBytes, "value".getBytes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,6 @@ class SaslClientsWithInvalidCredentialsTest extends IntegrationTestHarness with
val txProducer = TestUtils.createProducer(brokerList,
securityProtocol = this.securityProtocol,
saslProperties = this.clientSaslProperties,
retries = 1000,
acks = -1,
props = Some(producerConfig))
producers += txProducer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ class DynamicBrokerReconfigurationTest extends ZooKeeperTestHarness with SaslSet

@Test
def testLogCleanerConfig(): Unit = {
val (producerThread, consumerThread) = startProduceConsume(0)
val (producerThread, consumerThread) = startProduceConsume(retries = 0)

verifyThreads("kafka-log-cleaner-thread-", countPerBroker = 1)

Expand Down Expand Up @@ -437,7 +437,7 @@ class DynamicBrokerReconfigurationTest extends ZooKeeperTestHarness with SaslSet
def testUncleanLeaderElectionEnable(): Unit = {
val topic = "testtopic2"
TestUtils.createTopic(zkClient, topic, 1, replicationFactor = 2, servers)
val producer = ProducerBuilder().maxRetries(1000).acks(1).build()
val producer = ProducerBuilder().acks(1).build()
val consumer = ConsumerBuilder("unclean-leader-test").enableAutoCommit(false).topic(topic).build()
verifyProduceConsume(producer, consumer, numRecords = 10, topic)
consumer.commitSync()
Expand Down Expand Up @@ -543,7 +543,7 @@ class DynamicBrokerReconfigurationTest extends ZooKeeperTestHarness with SaslSet
def verifyThreadPoolResize(propName: String, currentSize: => Int, threadPrefix: String, mayReceiveDuplicates: Boolean): Unit = {
maybeVerifyThreadPoolSize(propName, currentSize, threadPrefix)
val numRetries = if (mayReceiveDuplicates) 100 else 0
val (producerThread, consumerThread) = startProduceConsume(numRetries)
val (producerThread, consumerThread) = startProduceConsume(retries = numRetries)
var threadPoolSize = currentSize
(1 to 2).foreach { _ =>
threadPoolSize = reducePoolSize(propName, threadPoolSize, threadPrefix)
Expand Down Expand Up @@ -1366,7 +1366,7 @@ class DynamicBrokerReconfigurationTest extends ZooKeeperTestHarness with SaslSet
}

private case class ProducerBuilder() extends ClientBuilder[KafkaProducer[String, String]] {
private var _retries = 0
private var _retries = Int.MaxValue

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we just want to remove this?

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.

It is being overridden in some cases.

private var _acks = -1
private var _requestTimeoutMs = 30000

Expand Down Expand Up @@ -1417,8 +1417,9 @@ class DynamicBrokerReconfigurationTest extends ZooKeeperTestHarness with SaslSet
}
}

private class ProducerThread(clientId: String, retries: Int) extends
ShutdownableThread(clientId, isInterruptible = false) {
private class ProducerThread(clientId: String, retries: Int)
extends ShutdownableThread(clientId, isInterruptible = false) {

private val producer = ProducerBuilder().maxRetries(retries).clientId(clientId).build()
val lastSent = new ConcurrentHashMap[Int, Int]()
@volatile var sent = 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ object ReplicationQuotasTestRig {
createTopic(zkClient, topicName, replicas, servers)

println("Writing Data")
val producer = TestUtils.createProducer(TestUtils.getBrokerListStrFromServers(servers), retries = 5, acks = 0)
val producer = TestUtils.createProducer(TestUtils.getBrokerListStrFromServers(servers), acks = 0)
(0 until config.msgsPerPartition).foreach { x =>
(0 until config.partitions).foreach { partition =>
producer.send(new ProducerRecord(topicName, partition, null, new Array[Byte](config.msgSize)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class FetchRequestDownConversionConfigTest extends BaseRequestTest {

private def initProducer(): Unit = {
producer = TestUtils.createProducer(TestUtils.getBrokerListStrFromServers(servers),
retries = 5, keySerializer = new StringSerializer, valueSerializer = new StringSerializer)
keySerializer = new StringSerializer, valueSerializer = new StringSerializer)
}

private def createTopics(numTopics: Int, numPartitions: Int,
Expand Down
6 changes: 3 additions & 3 deletions core/src/test/scala/unit/kafka/server/FetchRequestTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class FetchRequestTest extends BaseRequestTest {

private def initProducer(): Unit = {
producer = TestUtils.createProducer(TestUtils.getBrokerListStrFromServers(servers),
retries = 5, keySerializer = new StringSerializer, valueSerializer = new StringSerializer)
keySerializer = new StringSerializer, valueSerializer = new StringSerializer)
}

@Test
Expand Down Expand Up @@ -204,8 +204,8 @@ class FetchRequestTest extends BaseRequestTest {
val propsOverride = new Properties
propsOverride.put(ProducerConfig.BATCH_SIZE_CONFIG, batchSize.toString)
val producer = TestUtils.createProducer(TestUtils.getBrokerListStrFromServers(servers),
retries = 5, lingerMs = Int.MaxValue,
keySerializer = new StringSerializer, valueSerializer = new ByteArraySerializer, props = Some(propsOverride))
lingerMs = Int.MaxValue, keySerializer = new StringSerializer,
valueSerializer = new ByteArraySerializer, props = Some(propsOverride))
val bytes = new Array[Byte](msgValueLen)
val futures = try {
(0 to 1000).map { _ =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ class LogRecoveryTest extends ZooKeeperTestHarness {
producer.close()
producer = TestUtils.createProducer(
TestUtils.getBrokerListStrFromServers(servers),
retries = 5,
keySerializer = new IntegerSerializer,
valueSerializer = new StringSerializer
)
Expand Down
Loading