Kafka简介 | 青训营笔记

193 阅读3分钟

这是我参与「 第五届青训营 」伴学笔记创作活动的第 13 天 Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据,具有高性能、持久化、多副本备份、横向扩展等特点。本文介绍了Kafka的特点、架构以及如何使用Go语言发送和接收kafka消息。

安装使用

Go语言中连接kafka使用第三方库:github.com/Shopify/sarama

go get github.com/Shopify/sarama

Kafka功能

发布订阅:生产者(producer)生产消息(数据流), 将消息发送到到kafka指定的主题队列(topic)中,也可以发送到topic中的指定分区(partition)中,消费者(consumer)从kafka的指定队列中获取消息,然后来处理消息。 流处理(Stream Process): 将输入topic转换数据流到输出topic。 连接器(Connector) : 将数据从应用程序(源系统)中导入到kafka,或者从kafka导出数据到应用程序(宿主系统sink system), 例如:将文件中的数据导入到kafka,从kafka中将数据导出到文件中。

主流消息队列

  • Kafka:分布式的、分区的、多副本的日志提交服务,在高吞吐场景下发挥较为出色
  • RocketMQ:低延迟、强一致、高性能、高可靠、万亿级容量和灵活的可扩展性,在一些实时场景中运用较广
  • Pulsar:是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体,采用存算分离的架构设计
  • BMQ:和Pulsar架构类似,存算分离,初期定位是承接高吞吐的离线业务场景,逐步替换掉对应的Kafka集群

Kafka

Kafka架构

image.png

基础使用

func sendMsg() {
    config := sarama.NewConfig()
    config.Producer.RequiredAcks = sarama.WaitForAll
    config.Producer.Partitioner = sarama.NewRandomPartitioner
    config.Producer.Return.Successes = true

    msg := &sarama.ProducerMessage{
            Topic: "test_log",
            Value: sarama.StringEncoder("this is a test log"),
    }
    client, err := sarama.NewSyncProducer([]string{"127.0.0.1:9092"}, config)
    if err != nil {
            fmt.Println("send msg failed, err:", err)
            return
    }
    defer client.Close()

    pid, offset, err := client.SendMessage(msg)
    if err != nil {
            fmt.Println("send msg failed, err:", err)
            return
    }

    fmt.Printf("pid: %v offset:%v\n", pid, offset)
}

func consumerMsg() {
    consumer, err := sarama.NewConsumer([]string{"127.0.0.1:9092"}, nil)
    if err != nil {
            fmt.Printf("fail to start consumer, err:%v\n", err)
            return
    }
    partitionList, err := consumer.Partitions("web_log") // 根据topic取到所有的分区
    if err != nil {
            fmt.Printf("fail to get list of partition:err%v\n", err)
            return
    }
    fmt.Println(partitionList)
    for partition := range partitionList { // 遍历所有的分区
            // 针对每个分区创建一个对应的分区消费者
            pc, err := consumer.ConsumePartition("test_log", int32(partition), sarama.OffsetNewest)
            if err != nil {
                    fmt.Printf("failed to start consumer for partition %d,err:%v\n", partition, err)
                    return
            }
            defer pc.AsyncClose()
            // 异步从每个分区消费信息
            go func(sarama.PartitionConsumer) {
                    for msg := range pc.Messages() {
                            fmt.Printf("Partition:%d Offset:%d Key:%v Value:%v", msg.Partition, msg.Offset, msg.Key, msg.Value)
                    }
            }(pc)
	}
}

相关概念

image.png

Topic: Kakfa中的逻辑队列,可以理解成每一 个不同的业务场景就是一 个不同的topic, 对于这个业务说,所有的数据都存储在这个topic中 Cluster: Kafka的物理集群, 每个集群中可以新建多个不同的topic Producer:顾名思义,也就是消息的生产端,负责将业务消息发送到Topic当中 Consumer:消息的消费端,负责消费已经发送到topic中的消息 Partition:通常topic会有多 个分片,不同分片直接消息是可以并发来处理的,这样提高单个Topic的吞吐

Offset image.png

Replica image.png