一 基本环境信息
1.1 服务器信息
ip
hostname
OS
已经安装的服务器
172.16.56.101
bd01.yiyong.info
centOS7
zookepper, spark3.0.1(master,worker),hadoop3.2.1
172.16.56.102
bd02.yiyong.info
centOS7
zookepper, spark3.0.1(master,worker),hadoop3.2.1
172.16.56.103
bd03.yiyong.info
centOS7
zookepper, spark3.0.1(worker),hadoop3.2.1
1.2 基本软件
jdk:1.8
1.3 其他说明
本次使用的zookeepr是外置的zookeeper,版本是3.5.8.
具体集群安装配置请参考: http://www.yiyong.info/article/162
安装kafka的位置:/opt/hadoop 下面。
二 kafka安装
2.1 下载安装包
下载:国内镜像:https://mirrors.tuna.tsinghua.edu.cn/apache/kafka/2.6.0/
下载kafka_2.12-2.6.0.tgz 文件
2.2 上传并配置
1)把安装kafka_2.12-2.6.0.tgz上传到/opt/hadoop
2)解压:tar zxvf kafka_2.12-2.6.0.tgz
3) 进入kafka. cd kafka_2.12-2.6.0
4) 配置config/server.properties
使用vi config/server.properties
# kafka 名称,每个节点都是一个不同的数字(主要,必须是数字) line 21
broker.id=1
# kafak保存数据的路径,建议这个文件夹不要放着kafka目录里面,避免后续升级误删除 line 60
log.dir=/opt/hadoop/hddata/kafka
# 配置zokkeeper的地址,有多个配置多个节点,使用逗号分开,line 123
zookeeper.connect=bd01.yiyong.info:2181,bd02.yiyong.info:2181,bd03.yiyong.info:2181
2.3 分发并配置每个broker的id
使用: scp -r 命令分发到其他服务对应的
比如: scp -r kafka_2.12-2.6.0 bd02.yiyog.info:PWD
修改各个分发的服务器server.properties里面的broker.id的值分别是2,3 等。
2.4 配置系统环境变量
在/etc/profile.d 下面建立文件并配置: vi 28_kafka.sh
export KAFKA_HOME=/opt/hadoop/kafka_2.12-2.6.0
export PATH=$PATH:$KAFKA_HOME/bin
分发到其他服务器相同的位置,使用soure/profile 或者使用客户端重新连接,使得环境变量生效。
2.5 启动
1)启动前的,需要启动zookeeper集群
具体请参考 Zookeeper 集群配置搭建:http://www.yiyong.info/article/162
2)前台启动:
$ kafka-server-start.sh $KAFKA_HOME/config/server.properties
3)后台启动: 增加 -daemon 参数
$ kafka-server-start.sh -daemon $KAFKA_HOME/config/server.properties
注意,上述启动,需要在三台机器上都进行启动。
4) 后台停止:
$ kafka-server-stop.sh
5) 编写批量启动脚本
在kafka 的bin目录下面创建文件 vi kafka-server-start-all.sh
#!/bin/bash
echo “Starting kafka cluster ......”
for i in {1..3}
do
ssh bd0$i.yiyong.info "source /etc/profile;kafka-server-start.sh -daemon $KAFKA_HOME/config/server.properties"
echo "started bd0$i.yiyong.info kafka server."
done
tips: 这个脚本建立2.4 的环境变量配置完成,并且每个服务器都生效的情况下,否则会出现文件找到的情况
6)编写批量停止脚本
在kafka 的bin目录下面创建文件 vi kafka-server-stop-all.sh
#!/bin/bash
echo “Stopping kafka cluster ......”
for i in {1..3}
do
ssh bd0$i.yiyong.info "source /etc/profile;kafka-server-stop.sh"
echo "Stopped bd0$i.yiyong.info kafka server."
done
7) 把上述的批量启动和停止的脚本分发到各个kafka的服务器上
三 kafka测试
3.1 创建topic
$ kafka-topics.sh --create --zookeeper bd01.yiyong.info:2181,bd02.yiyong.info:2181,bd03.yiyong.info:2181 --replication-factor 3 --partitions 3 --topic searchlog
参数名称
说明
--ceate
创建topic
--zookeeper
所有zookeeper的地址,逗号分开
--replication-factor
重复副本数(最大值不能超过kafka的节点数)
--partitions
分区数,可以是多个,最大值不受kafka节点数大小
--topic
top的名字,会存储在zookeeper里面
3.2 查询topic
查询topic 列表
$ kafka-topics.sh --list --zookeeper bd01.yiyong.info:2181,bd02.yiyong.info:2181,bd03.yiyong.info:2181
tips: 前面和最后都不要有空格,否则报错
查询具体topic信息
$ kafka-topics.sh --describe --zookeeper bd01.yiyong.info:2181,bd02.yiyong.info:2181,bd03.yiyong.info:2181 --topic searchlog
[yiyong@bd02 kafka_2.12-2.6.0]$ bin/kafka-topics.sh --describe --zookeeper bd01.yiyong.info:2181,bd02.yiyong.info:2181,bd03.yiyong.info:2181 --topic searchlog
Topic: searchlog PartitionCount: 3 ReplicationFactor: 3 Configs:
Topic: searchlog Partition: 0 Leader: 3 Replicas: 3,1,2 Isr: 2,1,3
Topic: searchlog Partition: 1 Leader: 1 Replicas: 1,2,3 Isr: 2,1,3
Topic: searchlog Partition: 2 Leader: 2 Replicas: 2,3,1 Isr: 2,1,3
tips: 每个Partition都会有一个Leader 节点。
3.3 写数据
往topic写入数据(命令行):
启动生产者命令行:(需要在三台kafka的任意机器上执行)
$ kafka-console-producer.sh --broker-list bd01.yiyong.info:9092,bd02.yiyong.info:9092,bd03.yiyong.info:9092 --topic searchlog
在命令行里面,可以输入文本内容
启动消费命令行:
$ kafka-console-consumer.sh --bootstrap-server bd01.yiyong.info:9092,bd02.yiyong.info:9092,bd03.yiyong.info:9092 --from-beginning --topic searchlog
( --from-beginning 从第一条开始消费)
tips: 左边窗口是producer, 右边窗口是consumer窗口
四 java调用
https://zhuanlan.zhihu.com/p/81047459
4.1 pom依赖包
org.apache.kafka
kafka_2.12
2.6.0
log4j
log4j
1.2.12
org.slf4j
slf4j-api
1.7.25
org.slf4j
slf4j-log4j12
1.7.25
4.2 生产者代码
package info.yiyong.kafka.demo;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;
/**
* @Author: David Yi
* @Create: 2020-10-17 18:08:38
* @Version: 1.0
* @Desc: 生产者,异步发送
*/
public class T1_ProducerDemo {
public static void main(String[] args) {
Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "bd01.yiyong.info:9092,bd02.yiyong.info:9092,bd03.yiyong.info:9092");
props.put(ProducerConfig.ACKS_CONFIG,"all");
props.put(ProducerConfig.RETRIES_CONFIG,0);
props.put(ProducerConfig.BATCH_SIZE_CONFIG, 16384);
props.put(ProducerConfig.LINGER_MS_CONFIG, 1);
props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, 33554432);
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer");
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer");
Producer producer = new KafkaProducer(props);
for (int i = 1001; i <= 1100 ; i++) {
producer.send(new ProducerRecord("searchlog", "test kafka data"+i));
System.out.println("test kafka data"+i);
}
producer.close();
}
}
4.3 消费者代码
package info.yiyong.kafka.demo;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.serialization.StringDeserializer;
import java.time.Duration;
import java.util.Arrays;
import java.util.Properties;
/**
* @Author: David Yi
* @Create: 2020-10-17 18:40:38
* @Version: 1.0
* @Desc: 自动提交offset, 异步消费
* 其他方式;https://zhuanlan.zhihu.com/p/81047459
*/
public class T2_ConsumerDemo {
public static void main(String[] args) {
Properties props = new Properties();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "bd01.yiyong.info:9092,bd02.yiyong.info:9092,bd03.yiyong.info:9092");
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
props.put(ConsumerConfig.GROUP_ID_CONFIG, "vvvvv");
// latest, earliest, none
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
props.put(ConsumerConfig.GROUP_ID_CONFIG, "test");
KafkaConsumer consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("searchlog"));
while (true) {
ConsumerRecords poll = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord record : poll) {
System.out.println("topic " + record.topic() + "offset=" + record.offset()
+"key and value" + record.key()+"-" + record.value());
}
}
}
}
四 和spark 集成 (TBD)