Go 操作kafka

Kafka介绍

Kafka是Apache软件基金会开发的一个开源流处理平台,由Java和Scala编写;Kafka是一种高吞吐、分布式、基于订阅发布的消息系统。

 

Kafka名称解释

  • Producer:生产者
  • Consumer:消费者
  • Topic:消息主题,每一类的消息称之为一个主题
  • Broker:Kafka以集群的方式运行,可以由一个或多个服务器组成,每个服务器叫做一个broker
  • Partition:物理概念上的分区,为了提供系统吞吐量,在物理上每个Topic会分为一个或多个Partition

 

Kafka架构图

一个典型的Kafka集群中包含若干Producer,若干broker(Kafka支持水平扩展,一般broker数量越多,集群吞吐率越高),若干Consumer Group,以及一个Zookeeper集群。

Kafka通过Zookeeper管理集群配置及服务协同,Producer使用push模式将消息发布到broker,Consumer通过监听使用pull模式从broker订阅并消费消息。

图上有个细节需要注意,producer给broker的过程是push,也就是有数据就推送给broker,而consumer给broker的过程是pull,是通过consumer主动去拉数据的,而不是broker把数据主动发送给consumer端的。

 

Kafka与RabbitMQ比较

  • Kafka比RabbitMQ性能要高
  • RabbitMQ比Kafka可靠性要高
  • 因此在金融支付领域使用RabbitMQ居多,而在日志处理、大数据等方面Kafka使用居多。

 

Kafka安装

第一步 下载Kafka:

  地址:

  http://kafka.apache.org/downloads

  

第二步 解压Kafka:

  

tar -zxvf kafka.tgz -C  /usr/local/kafka

  

第三步 运行Zookeeper:

   以后台方式运行

/usr/local/kafka/bin/zookeeper-server-start.sh /usr/local/kafka/config/zookeeper.properties &  zookeeper端口 2181

  

windows:

bin\windows\zookeeper-server-start.bat config\zookeeper.properties

  

第四步 运行Kafka:

     以后台方式运行

  linux

 /usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/server.properties  kafka端口 9092

  

  windows

bin\windows\kafka-server-start.bat config\server.properties

  

kafka自带的消费者读取数据

bin\windows\kafka-console-consumer.bat --bootstrap-server=127.0.0.1:9092 --topic=web_log --from-beginning

  

查看分区 情况

bin\windows\kafka-topics.bat --bootstrap-server=127.0.0.1:9092 --describe

  

 

Kafka图形管理工具

http://www.kafkatool.com/download.html 

 

1,下载安装(Windows平台请使用v1.19版本的sarama。)

go get github.com/Shopify/sarama

 

2,代码实例

生产者:

package main

import (
	"fmt"
	"github.com/Shopify/sarama"
)


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

	producer ,err := sarama.NewSyncProducer([]string{"127.0.0.1:9092"},config)
	if err !=nil{
		fmt.Println("new sync producer failed err",err)
		return
	}
	defer producer.Close()


	//可以在一个分区同时发送多分key值不同的value
	msg := &sarama.ProducerMessage{}
	msg.Topic = "test_1"
	msg.Key = sarama.StringEncoder("key_test1")
	msg.Value = sarama.StringEncoder("this is test 1 log")


	pid,offset,err := producer.SendMessage(msg)
	if err !=nil{
		fmt.Println("send message failed err:",err)
		return
	}
	fmt.Printf("partition:%v ,offset :%v\n",pid,offset)

	msg2 := &sarama.ProducerMessage{}
	msg2.Topic = "test_1"
	msg2.Key = sarama.StringEncoder("key_test2")
	msg2.Value = sarama.StringEncoder("this is test 2 log")

	pid2,offset2,err := producer.SendMessage(msg2)
	if err !=nil{
		fmt.Println("send message 2 failed err:",err)
		return
	}
	fmt.Printf("partition2:%v offset2:%v\n",pid2,offset2)


}

  

消费者代码:

  consumer

package main

import (
	"fmt"
	"github.com/Shopify/sarama"
	"sync"
)
var wg sync.WaitGroup

func main() {
	config := sarama.NewConfig()
	consumer ,err := sarama.NewConsumer([]string{"127.0.0.1:9092"},config)
	if err !=nil{
		fmt.Println("new consumer failed err:",err)
		return
	}
	defer consumer.Close()

	partitionList,err := consumer.Partitions("test_1")
	if err !=nil{
		fmt.Println("get partitons failed err:",err)
		return
	}

	for partition := range partitionList{
		pc,err := consumer.ConsumePartition("test_1",int32(partition),sarama.OffsetNewest)
		if err !=nil{
			fmt.Println("consumer partition failed err:",err)
			return
		}
		defer pc.AsyncClose()

		wg.Add(1)
		go func(pc sarama.PartitionConsumer) {
			defer wg.Done()
			for msg := range pc.Messages(){
				fmt.Printf("partition:%v offset %v key :%s value :%s \n",msg.Partition,msg.Offset,msg.Key,msg.Value)
			}
		}(pc)
	}
	wg.Wait()
}

  

 

posted @ 2021-01-22 11:52  pebblecome  阅读(425)  评论(0)    收藏  举报