一、Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。

Kafka场景比喻

接下来我大概比喻下Kafka的使用场景

消息中间件:生产者和消费者

妈妈:生产者
你:消费者
馒头:数据流、消息
正常情况下: 生产一个  消费一个
其他情况:  
1)一直生产,你吃到某一个馒头时,你卡主(机器故障), 馒头就丢失了
2)一直生产,做馒头速度快,你吃来不及,馒头也就丢失了
为了放着其他生产情况的出现,我们可以拿个碗/篮子,馒头做好以后先放到篮子里,你要吃的时候去篮子里面取出来吃,而这篮子/框就可以为:Kafka。当篮子满了,馒头就装不下了,咋办? 多准备几个篮子 === Kafka的扩容

二、Kafka的架构和核心概念

这是张我在Kafka官网上截的图,我大概可以把Kafka的主要结构分为以下几点:

producer:生产者,就是生产馒头(老妈)
consumer:消费者,就是吃馒头的(你)
broker:篮子
topic:主题,给馒头带一个标签,topica的馒头是给你吃的,topicb的馒头是给你弟弟吃

1.Kafka可以作为集群运行在一台或者多个服务器上面;

2.Kafka集群可以分类地存储记录流,以打标签的方式,就是采用topics,每个broker可以打个topic,这样能保证消费者可以根据topic选择性消费;

3.每个记录由Key、Value、timestamp构成。

Kafka四个核心的API

1.ProducerAPI:允许一个应用向一个或多个topic里发布记录流;

2.ConsumerAPI:允许一个应用订阅一个或多个topics,处理topic里的数据流,就相当于消费;

3.StreamAPI:允许应用扮演流处理的作用,从一个或多个topic里消费数据流,然后产生输出流数据到其他一个或多个topic里,对输入流数据有效传输到输出口;

4.ConnectorAPI:允许运行和构建一个可重复利用的生产者和消费者,能将kafka的topic与其他存在的应用和数据库设备相连接,比如链接一个实时数据库,可以捕捉到每张表的变化。

这四个API,主要应用在IDEA上对应用程序的开发中,通过代码的形式管理Kafka。在第四部分将会对前两个API写个简单DEMO演示。

三、Kafka的快速使用

Kafka使用到了zookeeper,所以首先你得安装zookeeper再安装kafka。

1.单节点的broker部署

首先我们需要修改$KAFKA_HOME/config/server.properties这个配置文件,主要以下几处需要修改:
broker.id=0,每个broker的ID需要唯一
listeners:监听的端口(此处笔者设置的是默认端口9092)
host.name:当前机器
log.dirs:存储日志的文件夹

num.partitions:分区的数量
zookeeper.connect:zookeeper的地址(默认为localhost:2181)

这几处根据你自身需要进行配置,然后启动步骤如下:

1)开启zookeeper,此处需要注意的是zookeeper的conf目录下的zoo.cfg配置文件,主要修改的也是日志存储目录那块。

2)启动Kafka,命令为:kafka-server-start.sh $KAFKA_HOME/config/server.properties

3)创建topic,需要指定zookeeper,命令为:kafka-topics.sh --create --zookeeper hadoop000:2181 --replication-factor 1 --partitions 1 --topic hello_topic。 注意指定zookeeper,后面几个属性可以根据你实际情况进行定义。另外查看所有topic的命令为:
kafka-topics.sh --list --zookeeper hadoop000:2181

4)发送消息,需要指定broker,命令为:kafka-console-producer.sh --broker-list hadoop000:9092 --topic hello_topic

5)消费消息,需要指定zookeeper,命令为:kafka-console-consumer.sh --zookeeper hadoop000:2181 --topic hello_topic --from-beginning。意思就是指定zookeeper上的topic进行消费,from-beginning的设置,可以查看之前的消息。

2.单节点,多broker

主要是增加多个server.properties文件,一个配置文件就相当于一个broker,我就设置三个broker:

server-1.properties

log.dirs=/home/hadoop/app/tmp/kafka-logs-1

listeners=PLAINTEXT://:9093

broker.id=1

server-2.properties

log.dirs=/home/hadoop/app/tmp/kafka-logs-2

listeners=PLAINTEXT://:9094

broker.id=2

server-3.properties

log.dirs=/home/hadoop/app/tmp/kafka-logs-3

listeners=PLAINTEXT://:9095

broker.id=3

然后依次开启,命令如下:

kafka-server-start.sh -daemon $KAFKA_HOME/config/server-1.properties &

kafka-server-start.sh -daemon $KAFKA_HOME/config/server-2.properties &
kafka-server-start.sh -daemon $KAFKA_HOME/config/server-3.properties &

接下来就跟上面的步骤一样:

kafka-topics.sh --create --zookeeper hadoop000:2181 --replication-factor 3 --partitions 1 --topic my-replicated-topic

kafka-console-producer.sh --broker-list hadoop000:9093,hadoop000:9094,hadoop000:9095 --topic my-replicated-topic

kafka-console-consumer.sh --zookeeper hadoop000:2181 --topic my-replicated-topic

查看 topic的详细信息:

kafka-topics.sh --describe --zookeeper hadoop000:2181 --topic my-replicated-topic

要注意的是,副本中会有个leader,而多副本也实现了kafka的容错性,挂掉一个副本后,会自动在剩下副本里选出一个leader来同步操作。

根据上面步骤操作,我们在producer窗口输入,在consumer消费窗口看到相应输出。

四、Producer和Consumer API的使用

接下来展示一个简单的Demo,在生产端简单创建个线程进行循环输出,然后用消费者端对输出的内容进行展示,也就是消费。

配置文件

/**

* Kafka常用配置文件
*/

public class KafkaProperties {

  public static final String ZK = "192.168.199.111:2181";

  public static final String TOPIC = "hello_topic";

  public static final String BROKER_LIST = "192.168.199.111:9092";

  public static final String GROUP_ID = "test_group1";

}

Producer API DEMO

 
import kafka.javaapi.producer.Producer;
import kafka.producer.KeyedMessage;
import kafka.producer.ProducerConfig;

import java.util.Properties;

/**

* Kafka生产者

*/

public class KafkaProducer extends Thread{

  private String topic;

  private Producer<Integer, String> producer;

  public KafkaProducer(String topic) {

    this.topic = topic;

    Properties properties = new Properties();

    properties.put("metadata.broker.list",KafkaProperties.BROKER_LIST);

    properties.put("serializer.class","kafka.serializer.StringEncoder");

    properties.put("request.required.acks","1");

    producer = new Producer<Integer, String>(new ProducerConfig(properties));

  }

  @Override

  public void run() {

    int messageNo = 1;

    while(true) {

      String message = "message_" + messageNo;

      producer.send(new KeyedMessage<Integer, String>(topic, message));

      System.out.println("Sent: " + message);

      messageNo ++ ;

      try{

        Thread.sleep(2000);

      } catch (Exception e){

        e.printStackTrace();

      }

    }

  }

}

Consumer API DEMO

import kafka.consumer.Consumer;
import kafka.consumer.ConsumerConfig;
import kafka.consumer.ConsumerIterator;

import kafka.consumer.KafkaStream;

import kafka.javaapi.consumer.ConsumerConnector;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Properties;

/**

* Kafka消费者

*/

public class KafkaConsumer extends Thread{

  private String topic;

  public KafkaConsumer(String topic) {

    this.topic = topic;

  }

  private ConsumerConnector createConnector(){

    Properties properties = new Properties();

    properties.put("zookeeper.connect", KafkaProperties.ZK);

    properties.put("group.id",KafkaProperties.GROUP_ID);

    return Consumer.createJavaConsumerConnector(new ConsumerConfig(properties));

  }

  @Override

  public void run() {

    ConsumerConnector consumer = createConnector();

    Map<String, Integer> topicCountMap = new HashMap<String, Integer>();

    topicCountMap.put(topic, 1);

    // topicCountMap.put(topic2, 1);

    // topicCountMap.put(topic3, 1);

    // String: topic

    // List<KafkaStream<byte[], byte[]>> 对应的数据流

    Map<String, List<KafkaStream<byte[], byte[]>>> messageStream = consumer.createMessageStreams(topicCountMap);

    KafkaStream<byte[], byte[]> stream = messageStream.get(topic).get(0); //获取我们每次接收到的暑假

    ConsumerIterator<byte[], byte[]> iterator = stream.iterator();

    while (iterator.hasNext()) {

      String message = new String(iterator.next().message());

      System.out.println("rec: " + message);

    }

  }

}

最后在main函数对这两个类调用即可,结果如下:

五、搭建kafka集群

1)下载kafka0.8(http://kafka.apache.org/downloads.html),保存到服务器/home/wwb目录下kafka-0.8.0-beta1-src.tgz(kafka_2.8.0-0.8.0-beta1.tgz)

2)解压 tar -zxvf kafka-0.8.0-beta1-src.tgz,产生文件夹kafka-0.8.0-beta1-src更改为kafka01

3)配置

修改kafka01/config/server.properties,其中broker.id,log.dirs,zookeeper.connect必须根据实际情况进行修改,其他项根据需要自行斟酌。大致如下:

broker.id=1

port=9091

num.network.threads=2

num.io.threads=2

socket.send.buffer.bytes=1048576

socket.receive.buffer.bytes=1048576

socket.request.max.bytes=104857600

log.dir=./logs

num.partitions=2

log.flush.interval.messages=10000

log.flush.interval.ms=1000

log.retention.hours=168

#log.retention.bytes=1073741824

log.segment.bytes=536870912

num.replica.fetchers=2

log.cleanup.interval.mins=10

zookeeper.connect=192.168.0.1:2181,192.168.0.2:2182,192.168.0.3:2183

zookeeper.connection.timeout.ms=1000000

kafka.metrics.polling.interval.secs=5

kafka.metrics.reporters=kafka.metrics.KafkaCSVMetricsReporter

kafka.csv.metrics.dir=/tmp/kafka_metrics

kafka.csv.metrics.reporter.enabled=false

4)初始化因为kafka用scala语言编写,因此运行kafka需要首先准备scala相关环境。

> cd kafka01

> ./sbt update

> ./sbt package

> ./sbt assembly-package-dependency

在第二个命令时可能需要一定时间,由于要下载更新一些依赖包。所以请大家 耐心点。

5) 启动kafka01

>JMX_PORT=9997 bin/kafka-server-start.sh config/server.properties &

a)kafka02操作步骤与kafka01雷同,不同的地方如下

修改kafka02/config/server.properties

broker.id=2

port=9092

##其他配置和kafka-0保持一致

启动kafka02

JMX_PORT=9998 bin/kafka-server-start.shconfig/server.properties &

b)kafka03操作步骤与kafka01雷同,不同的地方如下

修改kafka03/config/server.properties

broker.id=3

port=9093

##其他配置和kafka-0保持一致

启动kafka02

JMX_PORT=9999 bin/kafka-server-start.shconfig/server.properties &

6)创建Topic(包含一个分区,三个副本)

>bin/kafka-create-topic.sh--zookeeper 192.168.0.1:2181 --replica 3 --partition 1 --topicmy-replicated-topic

7)查看topic情况

>bin/kafka-list-top.sh --zookeeper 192.168.0.1:2181

topic: my-replicated-topic  partition: 0 leader: 1  replicas: 1,2,0  isr: 1,2,0

8)创建发送者

>bin/kafka-console-producer.sh--broker-list 192.168.0.1:9091 --topic my-replicated-topic

my test message1

my test message2

^C

9)创建消费者

>bin/kafka-console-consumer.sh --zookeeper127.0.0.1:2181 --from-beginning --topic my-replicated-topic

...

my test message1

my test message2

^C

10)杀掉server1上的broker

>pkill -9 -f config/server.properties

11)查看topic

>bin/kafka-list-top.sh --zookeeper192.168.0.1:2181

topic: my-replicated-topic  partition: 0 leader: 1  replicas: 1,2,0  isr: 1,2,0

发现topic还正常的存在

11)创建消费者,看是否能查询到消息

>bin/kafka-console-consumer.sh --zookeeper192.168.0.1:2181 --from-beginning --topic my-replicated-topic

...

my test message 1

my test message 2

^C

说明一切都是正常的。

OK,以上就是对Kafka个人的理解,不对之处请大家及时指出。

补充说明:

1、public Map<String, List<KafkaStream<byte[], byte[]>>> createMessageStreams(Map<String, Integer> topicCountMap),其中该方法的参数Map的key为topic名称,value为topic对应的分区数,譬如说如果在kafka中不存在相应的topic时,则会创建一个topic,分区数为value,如果存在的话,该处的value则不起什么作用

2、关于生产者向指定的分区发送数据,通过设置partitioner.class的属性来指定向那个分区发送数据,如果自己指定必须编写相应的程序,默认是kafka.producer.DefaultPartitioner,分区程序是基于散列的键。

3、在多个消费者读取同一个topic的数据,为了保证每个消费者读取数据的唯一性,必须将这些消费者group_id定义为同一个值,这样就构建了一个类似队列的数据结构,如果定义不同,则类似一种广播结构的。

4、在consumerapi中,参数设计到数字部分,类似Map<String,Integer>,

numStream,指的都是在topic不存在的时,会创建一个topic,并且分区个数为Integer,numStream,注意如果数字大于broker的配置中num.partitions属性,会以num.partitions为依据创建分区个数的。

5、producerapi,调用send时,如果不存在topic,也会创建topic,在该方法中没有提供分区个数的参数,在这里分区个数是由服务端broker的配置中num.partitions属性决定的

关于kafka说明可以参考:http://kafka.apache.org/documentation.html

什么是kafka以及如何搭建kafka集群?的更多相关文章

  1. zookeeper集群环境搭建(使用kafka的zookeeper搭建zk集群)

    ---恢复内容开始--- 使用kafka的zookeeper来搞集群的话和单纯用zk的其实差不了多少. 0.说在前头,搭建kafka集群之前请把每个服务器的jdk搞起来. 1.安装kafka wget ...

  2. docker 搭建zookeeper集群和kafka集群

    docker 搭建zookeeper集群 安装docker-compose容器编排工具 Compose介绍 Docker Compose 是 Docker 官方编排(Orchestration)项目之 ...

  3. hadoop+yarn+hbase+storm+kafka+spark+zookeeper)高可用集群详细配置

    配置 hadoop+yarn+hbase+storm+kafka+spark+zookeeper 高可用集群,同时安装相关组建:JDK,MySQL,Hive,Flume 文章目录 环境介绍 节点介绍 ...

  4. 大数据平台搭建-zookeeper集群的搭建

    本系列文章主要阐述大数据计算平台相关框架的搭建,包括如下内容: 基础环境安装 zookeeper集群的搭建 kafka集群的搭建 hadoop/hbase集群的搭建 spark集群的搭建 flink集 ...

  5. 搭建kafaka集群

    服务器环境准备 使用vm虚拟三个linux主机 192.168.212.174 192.168.212.175 192.168.212.176 Zookeeper集群环境搭建 1.每台服务器节点上安装 ...

  6. 通过docker搭建ELK集群

    单机ELK,另外两台服务器分别有一个elasticsearch节点,这样形成一个3节点的ES集群. 可以先尝试单独搭建es集群或单机ELK https://www.cnblogs.com/lz0925 ...

  7. 使用Docker搭建Spark集群(用于实现网站流量实时分析模块)

    上一篇使用Docker搭建了Hadoop的完全分布式:使用Docker搭建Hadoop集群(伪分布式与完全分布式),本次记录搭建spark集群,使用两者同时来实现之前一直未完成的项目:网站日志流量分析 ...

  8. MongoDB 搭建分片集群

    在MongoDB(版本 3.2.9)中,分片是指将collection分散存储到不同的Server中,每个Server只存储collection的一部分,服务分片的所有服务器组成分片集群.分片集群(S ...

  9. 分布式缓存技术redis学习系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...

  10. 使用Windows Azure的VM安装和配置CDH搭建Hadoop集群

    本文主要内容是使用Windows Azure的VIRTUAL MACHINES和NETWORKS服务安装CDH (Cloudera Distribution Including Apache Hado ...

随机推荐

  1. LeetCode Majority Element Python

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  2. 移动端 元素外面使用伪类after加边框 导致其内部元素无法选中

    解决方法:给内部元素增加属性 position: relative; z-index: 3; 这样就能选中其内部元素了.

  3. Spring目前用到的知识点

    2017/7/28 目前的工作,spring用到到的地方 在当前类有下列的代码 private BookDao bookDao bookDao.调用方法 点开这个方法,声明指向的是BookDao这个接 ...

  4. 网卡驱动_WDS

    参考 cs89x0.c 1.网卡驱动程序与网络驱动程序的区别网卡驱动程序:网络驱动程序中最底层的驱动,主要工作:把上面发下来的数据发送出去,收到数据后构造一个包抛给上层.有收发能力就可以了. 2.网卡 ...

  5. PostgREST docker-compose 试用

    PostgREST 是一款很不错的直接将pg 数据库暴露为restapi ,使用了基于行级别安全访问控制, 比较全的restapi 查询以及集成了swagger openapi docker-comp ...

  6. TensorFlow笔记-06-神经网络优化-损失函数,自定义损失函数,交叉熵

    TensorFlow笔记-06-神经网络优化-损失函数,自定义损失函数,交叉熵 神经元模型:用数学公式比表示为:f(Σi xi*wi + b), f为激活函数 神经网络 是以神经元为基本单位构成的 激 ...

  7. openwrt lamp

    https://applefreak111.wordpress.com/2013/03/12/howtoopenwrt-lamp-stack%E5%AE%89%E8%A3%9D/ opkg updat ...

  8. QWidget背景(透明)问题

    一. 背景設定為成黑色,前景色設為白色. 方法一.paltette方式,經測試,該方法不會影響到其他控制元件,建議使用 QPalette bgpal = palette();bgpal.setColo ...

  9. Nginx+tomcat+redis实现session共享

    Nginx+tomcat+redis实现session共享 1,安装nginx,使用yum -y install nginx 这是epel源中的,需要安装epel源. 2,配置nginx. 在ngin ...

  10. Unity3D 中判断点与多边形的关系

    由点发出的射线与多边形边的交点个数,如果是偶数个说明在多边形的外面,交点个数为奇数个在多边形的内部,下面是代码: public bool IsPointInPolygon(Vector2 point, ...