繁体   English   中英

在kafka-go中阅读具有特定ID的消息

[英]Read message with specific ID in kafka-go

我正在Kafka-go库中使用消息密钥作为关联ID在Kafka中构建请求-响应设置。 我的设置可以在没有并发的情况下正常运行,但是当消息开始在单独的goroutine中发送时,阅读器部分会跳过正确的键(因为其他例程可能已经读取了它)。

考虑到连接是由不同的goroutine共享的,我如何只读取主题中的特定键?

下面的客户端示例(为简便起见,删除了错误评估):

package main

import (
    "bytes"
    "context"
    "fmt"
    "sync"
    "time"

    "github.com/google/uuid"
    kafka "github.com/segmentio/kafka-go"
)

var wg sync.WaitGroup

func requestMessage(connR *kafka.Conn, connW *kafka.Conn, body []byte, index int) {
    currentUUID := uuid.New()
    byteUUID := []byte(fmt.Sprintf("%s", currentUUID))
    connW.WriteMessages(kafka.Message{
        Key:   byteUUID,
        Value: body,
    })
    fmt.Println("Posted id " + string(byteUUID))
    for {
        m, _ := connR.ReadMessage(10e6)
        if bytes.Equal(m.Key, byteUUID) {
            break
        }
    }

    wg.Done()
    fmt.Println("Done " + string(byteUUID))

}

func main() {
    iterations := 100
    interval := 500 * time.Millisecond
    kafkaURL := "kafka:9092"
    topic := "benchmarktopic"
    partition := 0
    connW, _ := kafka.DialLeader(context.Background(), "tcp", kafkaURL, topic, partition)
    defer connW.Close()
    connR, _ := kafka.DialLeader(context.Background(), "tcp", kafkaURL, topic+"response", partition)
    defer connR.Close()
    for i := 0; i < iterations; i++ {
        <-time.After(interval)
        go requestMessage(connR, connW, []byte("body"), i)
        wg.Add(1)
    }
    wg.Wait()
}

您不能真正只从Kafka主题分区中读取特定的键。 关键是您的记录将基于键的哈希值(默认行为)被调度到特定分区。 因此,您可能在同一分区中具有不同的键。 因此,只要您拥有的键数大于分区数,就会发现一个包含不同键的分区。

我唯一想到的一种方法是为您的主题设置N个分区,其中N是您可以拥有的不同键的数量(如果使用uuid作为键,这是一个很大的数目),并为该分区分配静态映射(key ->分区)到您的生产者/消费者。

顺便说一句,您已经将第0部分分配给了您的制作人,想知道为什么吗?

亚尼克

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM