-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
KIP-392: Allow consumers to fetch from closest replica #1696
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 |
---|---|---|
|
@@ -299,6 +299,9 @@ type partitionConsumer struct { | |
errors chan *ConsumerError | ||
feeder chan *FetchResponse | ||
|
||
replicaInited bool | ||
preferredReadReplica int32 | ||
|
||
trigger, dying chan none | ||
closeOnce sync.Once | ||
topic string | ||
|
@@ -359,21 +362,29 @@ func (child *partitionConsumer) dispatcher() { | |
close(child.feeder) | ||
} | ||
|
||
func (child *partitionConsumer) preferedBroker() (*Broker, error) { | ||
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. preferred, not prefered. |
||
if child.replicaInited { | ||
broker, err := child.consumer.client.Broker(child.preferredReadReplica) | ||
if err == nil { | ||
return broker, nil | ||
} | ||
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. does the error not important? could we log it? 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. Not important at all..but could log it. |
||
} | ||
|
||
// if prefered replica cannot be found fallback to leader | ||
return child.consumer.client.Leader(child.topic, child.partition) | ||
} | ||
|
||
func (child *partitionConsumer) dispatch() error { | ||
if err := child.consumer.client.RefreshMetadata(child.topic); err != nil { | ||
return err | ||
} | ||
|
||
var leader *Broker | ||
var node *Broker | ||
var err error | ||
if leader, err = child.consumer.client.Leader(child.topic, child.partition); err != nil { | ||
if node, err = child.preferedBroker(); err != nil { | ||
return err | ||
} | ||
|
||
child.broker = child.consumer.refBrokerConsumer(leader) | ||
|
||
child.broker = child.consumer.refBrokerConsumer(node) | ||
child.broker.input <- child | ||
|
||
return nil | ||
} | ||
|
||
|
@@ -445,7 +456,6 @@ func (child *partitionConsumer) responseFeeder() { | |
feederLoop: | ||
for response := range child.feeder { | ||
msgs, child.responseResult = child.parseResponse(response) | ||
|
||
if child.responseResult == nil { | ||
atomic.StoreInt32(&child.retries, 0) | ||
} | ||
|
@@ -480,7 +490,6 @@ feederLoop: | |
} | ||
} | ||
} | ||
|
||
child.broker.acks.Done() | ||
} | ||
|
||
|
@@ -617,6 +626,12 @@ func (child *partitionConsumer) parseResponse(response *FetchResponse) ([]*Consu | |
child.fetchSize = child.conf.Consumer.Fetch.Default | ||
atomic.StoreInt64(&child.highWaterMarkOffset, block.HighWaterMarkOffset) | ||
|
||
if response.Version == 11 && len(child.consumer.conf.RackID) > 0 { | ||
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. I accidently removed my suggestion. Doing it again. To support additional Fetch protocol changes, the comparison with version 11 should allow this. |
||
// we got a valid response with messages. update child's preferredReadReplica from the FetchResponseBlock | ||
child.replicaInited = true | ||
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. this name is not descriptive enough; suggest |
||
child.preferredReadReplica = block.PreferredReadReplica | ||
} | ||
|
||
// abortedProducerIDs contains producerID which message should be ignored as uncommitted | ||
// - producerID are added when the partitionConsumer iterate over the offset at which an aborted transaction begins (abortedTransaction.FirstOffset) | ||
// - producerID are removed when partitionConsumer iterate over an aborted controlRecord, meaning the aborted transaction for this producer is over | ||
|
@@ -815,10 +830,16 @@ func (bc *brokerConsumer) handleResponses() { | |
for child := range bc.subscriptions { | ||
result := child.responseResult | ||
child.responseResult = nil | ||
|
||
switch result { | ||
case nil: | ||
// no-op | ||
if !child.replicaInited { | ||
return | ||
} | ||
if bc.broker.ID() != child.preferredReadReplica { | ||
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. I think this would also do the same: if child.replicaInited && bc.broker.ID() != child.preferredReadReplica not need to do the return there also the 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. Ack. will do this |
||
// not an error but needs redispatching to consume from prefered replica | ||
child.trigger <- none{} | ||
delete(bc.subscriptions, child) | ||
} | ||
case errTimedOut: | ||
Logger.Printf("consumer/broker/%d abandoned subscription to %s/%d because consuming was taking too long\n", | ||
bc.broker.ID(), child.topic, child.partition) | ||
|
@@ -834,6 +855,7 @@ func (bc *brokerConsumer) handleResponses() { | |
// not an error, but does need redispatching | ||
Logger.Printf("consumer/broker/%d abandoned subscription to %s/%d because %s\n", | ||
bc.broker.ID(), child.topic, child.partition, result) | ||
child.replicaInited = false | ||
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. I wonder if this needs a locking mechanism? seems unsafe 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. Checked. it it's fine to be accessed like this. |
||
child.trigger <- none{} | ||
delete(bc.subscriptions, child) | ||
default: | ||
|
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.
initiated? what is this going to be used for?
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.
I will rename it...its used to fetch from read replica instead of master.