Spark Streaming实时流处理项目1——分布式日志收集框架Flume的学习
Spark Streaming实时流处理项目2——分布式消息队列Kafka学习
Spark Streaming实时流处理项目3——整合Flume和Kafka完成实时数据采集
Spark Streaming实时流处理项目4——实战环境搭建
Spark Streaming实时流处理项目5——Spark Streaming入门
Spark Streaming实时流处理项目6——Spark Streaming实战1
Spark Streaming实时流处理项目7——Spark Streaming实战2
Spark Streaming实时流处理项目8——Spark Streaming与Flume的整合
Spark Streaming实时流处理项目9——Spark Streaming整合Kafka实战
Spark Streaming实时流处理项目10——日志产生器开发并结合log4j完成日志的输出
Spark Streaming实时流处理项目11——综合实战
源码
Producer:生产者(生产馒头的老妈)
consumer:消费者(吃馒头的你)
broker:篮子(放馒头)
topic:主题,给馒头带上一个标签,topic A是给你吃的,topic B是给你弟弟吃的。
单节点单Broker部署
单节点多Broker部署
多节点多Broker部署
本次学习中,我们使用多节点多Broker的方式部署,最大程度上契合实际生产环境。四台虚拟机上都安装了Kafka,主机名分别是hadoop0、hadoop1、hadoop2、hadoop3.
kafak的使用依赖于zookeeper,因此安装kafka之前需要首先安装好zookeeper集群。zookeeper的安装这里不再介绍。
zookeeper启动命令:bin/zkServer.sh start
kafak下载解压之后,修改server.properties配置文件
#broker.id=0 每台服务器的broker.id都不能相同
#hostname
host.name=192.168.25.100
#日志存储的路径修改一下
log.dirs=/soft/kafka/logs
#在log.retention.hours=168 下面新增下面三项
message.max.byte=5242880
default.replication.factor=2
replica.fetch.max.bytes=5242880
#设置zookeeper的连接端口
zookeeper.connect=192.168.25.100:12181,192.168.25.101:12181,192.168.25.107:12181
kafka启动命令:
#从后台启动Kafka集群(3台都需要启动)
cd/opt/kafka/kafka_2.11-0.9.0.1//bin #进入到kafka的bin目录
./kafka-server-start.sh -daemon ../config/server.properties
1、创建Topic(要指定zookeeper)
./kafka-topics.sh --create --zookeeper 192.168.25.128:2181 --replication-factor 2 --partitions 1 --topic shuaige
#解释
--replication-factor 2 #复制两份
--partitions 1 #创建1个分区
--topic #主题为shuaige
2、在一台服务器上创建一个发布者(指定Broker)
./kafka-console-producer.sh --broker-list 192.168.25.128:9092 --topic shuaige
3、在一台服务器上创建一个订阅者(要指定zookeeper)
./kafka-console-consumer.sh --zookeeper localhost:2181 --topic shuaige --from-beginning
4、查看所有已创建的topic
./kafka-topics.sh --list --zookeeper hadoop0:2181
Kafka实际环境有可能会出现Consumer全部宕机,虽然基于Kafka的高可用特性,消费者群组中的消费者可以实现再均衡,所有Consumer不处理数据的情况很少,但是还是有可能会出现,此时就要求Consumer重启的时候能够读取在宕机期间Producer发送的数据。基于消费者订阅模式默认是无法实现的,因为只能订阅最新发送的数据。通过消费者命令行可以实现,只要在命令行中加上--from-beginning即可
查看topic状态:
/kafka-topics.sh --describe --zookeeper localhost:2181 --topic shuaige
#下面是显示信息
Topic:ssports PartitionCount:1 ReplicationFactor:2 Configs:
Topic: shuaige Partition: 0 Leader: 1 Replicas: 0,1 Isr: 1
#分区为为1 复制因子为2 他的 shuaige的分区为0
#Replicas: 0,1 复制的为0,1
partitionCount: 1 代表分区数为1 replicationFactor: 3 代表副本数为3 replicas:3 1 2 代表副本存放的brokerid
Isr : 3 1 2 代表活着的是3 1 2 leader: 3 代表broker编号为3 的是leader
理解kafka的容错性:(容错性测试)
当我们kafka有3个,随意删除其2个都不会影响kafka运行,当只剩下一个时,那么默认这个就是leader,输入jps -m 显示三个kafka 进程
我们删除俩个,kafka依然运行。
IDEA+Maven+Java语言
/**
* @author YuZhansheng
* @desc Kafka常用配置文件
* @create 2019-02-17 16:05
*/
public class KafkaProperties {
public static final String ZK = "192.168.25.128:2181";
public static final String TOPIC = "shuaige";
public static final String BROKER_LIST = "192.168.25.128:9092,192.168.25.141:9092,192.168.25.142:9092,192.168.25.143:9092";
}
/**
* @author YuZhansheng
* @desc 生产者
* @create 2019-02-17 16:10
*/
public class KafkaProducer extends Thread{
private String topic;
private Producer 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(new ProducerConfig(properties));
}
@Override
public void run() {
int messageNo = 1;
while (true){
String message = "message_" + messageNo;
producer.send(new KeyedMessage(topic,message));
System.out.println("sent: " + message);
messageNo++;
try {
Thread.sleep(2000);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
/**
* @author YuZhansheng
* @desc Kafka Java API测试
* @create 2019-02-17 16:32
*/
public class KafkaClientApp {
public static void main(String[] args) {
new KafkaProducer(KafkaProperties.TOPIC).start();
new KafkaConsumer(KafkaProperties.TOPIC).start();
}
}
/**
* @author YuZhansheng
* @desc 消费者
* @create 2019-02-17 16:39
*/
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 topicCountMap = new HashMap();
topicCountMap.put(topic,1);
//第一个String就是传的topic;List>> messageStream = consumer.createMessageStreams(topicCountMap);
//get(0)就是获取每次接收到的数据
KafkaStream stream = messageStream.get(topic).get(0);
ConsumerIterator iterator = stream.iterator();
while (iterator.hasNext()){
String message = new String(iterator.next().message());
System.out.println("rec: " + message);
}
}
}