Kafka使用调研

章节导航

  • Kafka是什么?
  • Kafka使用场景及特性
  • Kafka架构
  • Kafka配置
  • 使用Kafka的两种方式:命令行和API

Kafka是什么?

试想一下我们现在有一个分布式的网站流量分析系统,我们有多台用于记录用户行为的服务器,前端经过负载均衡将用户行为记录在这些服务器上,每台服务器拥有一部分纪录。
然后问题来了,如何做到实时分析?不可能在每台机上部署一个分析程序,这样会存在数据同步和容错问题,所以我们有了kafka+storm/spark,kafka作为数据管道(Data pipline)的角色,从收数端向storm/spark发送数据,kafka保证数据同步,除此之外还会将数据持久化到磁盘。kafka用zookeeper来实现数据同步和宕机切换。
kafka is a distributed streaming platform, a streaming platform has three key capabilities:

  1. 发布和订阅数据流,在这方面它类似于消息队列或企业消息系统
  2. 以容错的方式处理数据流
  3. 在数据流发生处处理它

Kafka使用场景及特性

使用场景:

  1. 在收数端和实时计算或批处理计算框架之间做数据通道
  2. 作为处理流式数据的应用

特性:

  • 支持多订阅,同一份数据集能被消费多次
  • 保存数据到磁盘,能同时传送消息到实时和批处理消费者
  • 内置数据冗余,保证高可用性
  • 支持水平扩展,容错

Kafka架构

先了解一下kafka中的一些概念:
1. topic和partition
Kafka提供的对流式数据的抽象,即一个topic代表一个数据流。对每个topic,kafka集群持有分区日志(partitioned log),这些分区组成更高级的topic抽象,每个分区是一个有序的、可变的数据序列,kafka源源不断地向分区末端添加数据,读取时则通过一个offset来记录读取的位置,offset由consumer持有,consumer可以随意改变offset。
在设定的时长之内,Kafka为我们保存所有的数据,直到超时后才扔掉它们。
出于容错的考虑,Kafka会为每个分区在不同的服务器上建立副本(副本切换应该是由zookeeper实现),每个分区都有一个”leader”服务器和0到多个”followers”服务器,leader服务器承担处理读写请求的责任,如果leader宕机,则从其他followers中选出一个leader。每个服务器都是某一个分区的leader和其他分区的followers,以此实现负载均衡。

2.Producers
Produers向它们选择的topics生产数据,并且负责选择与数据绑定的分区,即哪些数据应该传到哪个partition。选择分区的过程可以由round-robin来简单地负载均衡,或由语义分区函数完成。大多数情况下用语义分区函数。

3.Consumers和Consumer group
与我们对订阅者下意识的印象不同的是,对数据的消费以consumer group为单位,每个group持有一个group.id,拥有相同group.id的consumer属于同一个consumer group,每个consumer可以来自于单独的进程或者单独的服务器。
每个consumer选择它们想要消费的topic,然后一旦用户使用API或者命令行发生拉取操作,consumer group就从注册了这个topic的consumer中选择一个来消费数据。具体的分配逻辑是:组内有一个consumer来负责负载均衡,consumer group将会通过周期性地刷新元数据来探测新分区,并把新分区分配给组内的consumer,每个consumer只消费这个分区,如果有一个consumer挂了,它持有的分区就会被分发给还存活的其他consumer。
由于kafka不保证分区的全局有序,只保证分区内有序,所以同一个组内的consumer不能并行读取数据。

Kafka对有序性的保证:
1. 保证同一个producer向同个partition生产的数据是有序的,即如果producer先发M1再发M2,则partition log里的顺序也是M1在M2之前,M1拥有更低的offset。
2. consumer看到的数据顺序和它们在partition log中存储的顺序相同

4.brokers
kafka消息中心,负责持有topic并为topic划分分区,每个broker可以持有多个topic。

Kafka在zookeeper中建立的znode:
这里写图片描述

Kafka配置

  1. 先配zookeeper,我选择用standalone模式,所以用默认配置即可;也可以用伪分布式,只要在zookeeper中配置server.x=本机IP:随便一个端口,一般是2888:随便一个端口,x和data文件夹下的myid相同。
    由于默认配置dataDir是在tmp目录,关机即清零,还应该改一下dataDir。

  2. 启动一下 zookeeper,查看zookeeper服务状态:

    [root@localhost zookeeper-3.4.9]# bin/zkServer.sh start
    ZooKeeper JMX enabled by default
    Using config: /usr/local/zookeeper-3.4.9/bin/../conf/zoo.cfg
    Starting zookeeper ... STARTED
    [root@localhost zookeeper-3.4.9]# bin/zkServer.sh status
    ZooKeeper JMX enabled by default
    Using config: /usr/local/zookeeper-3.4.9/bin/../conf/zoo.cfg
    Mode: standalone
    [root@localhost zookeeper-3.4.9]# 
  1. 再来改kafka的配置,以下是基本配置:

    1. broker config,修改server.properties

      
      #如果要在一台机上配置多个代理,只要多复制几份配置文件,并且给broker.id设置不同的值,然后启动时在命令行后面写上配置文件路径(相对或绝对都行)
      
      broker.id=1          
      log.dirs=/data/kafka/logs
      zookeeper.connect=localhost:2181      #zookeeper host列表,格式是host:clientPort,多个host用“,”分隔
    2. 对于producer和consumer,还有相应的配置

  2. 从命令行启动kafka:bin/kafka-server-start.sh config/server.properties &,控制台打印出来的信息里下面这几行说明了kafka在zookeeper中创建znode的情况:

        [2017-03-25 09:35:05,666] INFO zookeeper state changed (SyncConnected) (org.I0Itec.zkclient.ZkClient)
    [2017-03-25 09:35:05,678] INFO Creating /controller (is it secure? false) (kafka.utils.ZKCheckedEphemeral)
    [2017-03-25 09:35:05,684] INFO Result of znode creation is: OK (kafka.utils.ZKCheckedEphemeral)
    [2017-03-25 09:35:05,684] INFO 0 successfully elected as leader (kafka.server.ZookeeperLeaderElector)
    [2017-03-25 09:35:05,745] INFO re-registering broker info in ZK for broker 0 (kafka.server.KafkaHealthcheck$SessionExpireListener)
    [2017-03-25 09:35:05,745] INFO Creating /brokers/ids/0 (is it secure? false) (kafka.utils.ZKCheckedEphemeral)
    [2017-03-25 09:35:05,750] INFO Result of znode creation is: OK (kafka.utils.ZKCheckedEphemeral)
    [2017-03-25 09:35:05,750] INFO Registered broker 0 at path /brokers/ids/0 with addresses: PLAINTEXT -> EndPoint(localhost,9092,PLAINTEXT) (kafka.utils.ZkUtils)
    [2017-03-25 09:35:05,751] INFO done re-registering broker (kafka.server.KafkaHealthcheck$SessionExpireListener)
    [2017-03-25 09:35:05,751] INFO Subscribing to /brokers/topics path to watch for new topics (kafka.server.KafkaHealthcheck$SessionExpireListener)
    [2017-03-25 09:35:05,804] INFO New leader is 0 (kafka.server.ZookeeperLeaderElector$LeaderChangeListener)

命令行和API

命令行脚本
  • 创建/修改/删除 topic
    bin/kafka-topics.sh --zookeeper zk_host:port[/topicsrootpath] --create/--alter/--delete --topic topic\_name --partitions pnum --replication-factor rnum --config x=y

    • partitions选项指定topic被分成几个分区,分区数决定了consumers的并行数
    • replication-factor是副本数
    • bin/kafka-topics.sh –help可以查看options手册

      [root@localhost kafka_2.10-0.10.1.0]# bin/kafka-topics.sh --create --zookeeper localhost:2181 --topic testTopic --partitions 2 --replication-factor 1
      [zk: localhost:2181(CONNECTED) 0] ls /brokers/topics
      [testTopic]
  • 命令行producer和consumer工具

    • bin/kafka-console-producer.sh --broker-list localhost:9092 --topic streams-file-input <然后从linux标准输入获得数据>
    • bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 \
      --topic streams-wordcount-output \
      --from-beginning \
      --formatter kafka.tools.DefaultMessageFormatter \
      --property print.key=true \
      --property print.value=true \
      --property key.deserializer=org.apache.kafka.common.serialization.StringDeserializer \
      --property value.deserializer=org.apache.kafka.common.serialization.LongDeserializer
  • 执行调用了kafka API的java程序
    bin/kafka-run-class.sh org.apache.kafka.streams.examples.wordcount.WordCountDemo

  • 均衡leadership
    当一个broker停止后,其作为leader持有的partitions将会在follower里面重新选一个leader把leadership转移过去,因此当这个broker重启后它将是它的所有partitions的follower,这样会导致leadership的不均匀分布,可以使用bin/kafka-preferred-replica-election.sh --zookeeper zk_host:port[/topicsrootpath]来尝试修复不均衡的leadership,也可以通过配置auto.leader.rebalance.enable=true让kafka定时自动修复。

  • 查看consumers的位置
    bin/kafka-run-class.sh kafka.tools.ConsumerOffsetChecker --zookeeper localhost:2181 --group test

  • list,describe,delete consumer groups:
    bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list [--describe --group groupname]

  • 扩展集群,把原有节点上的分区转移到新节点
    bin/kafka-reassign-partitions.sh ...

JAVA API

consumer API
producer API
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值