1.核心概念
broker: 进程
producer: 生产者
consumer: 消费者
topic: 主题
partitions: 分区 (副本数)
consumergroup:
1.容错性的消费机制
2.一个组内,共享一个公共的ID groupid
3.组内的所有消费者协调在一起,去消费topic的所有的分区
4.每个分区只能由同一个消费组的一个消费者来消费
副本数:每个分区有几个副本,以3为例:
发送123--> 0分区 在2,3机器上面也有个0分区,会备份123.
offset: 每个partition的数据的id
kafka中的offset
segment:
1.分为log和index文件
2.通过配置以下参数设置回滚
log.segment.bytes
log.roll.hours
3.命名规则: 上一个segment分组log文件的最大offset
2.消费语义
at most once: 最多消费一次 消费可能丢失 但是不会重复消费 ?-->适用于不重要的log,丢几条没事
at least once: 至少消费一次 消费不可能丢失 但是会重复消费 ?-->不用担心丢失,但数据会重复,需考虑去重
exactly once: 正好一次 消息不会丢失 也不会重复(这才是我们想要的)
但0.10.0.1 不支持不能实现 0.11官方已支持
数据去重:1.HBase的put操作,MySQL的update insert操作。2.把数据放到redis,在redis中去重
consumer offset:
数据:1,2,3,4,5
传到:1,2,3consumer挂了,offset没有维护
那么重启后从上一次的更新的offset的位置去消费(断点还原)
0.10版本的offset是存在kafka自己本身
topic: test
内嵌一个topic:如 ![]()
3.Flume-->Kafka-->Spark streaming 经典案例
Pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ruozedata</groupId>
<artifactId>DSHS</artifactId>
<version>1.0-SNAPSHOT</version>
<inceptionYear>2008</inceptionYear>
<repositories>
<repository>
<id>scala-tools.org</id>
<name>Scala-Tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</repository>
</repositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<scala.version>2.11.8</scala.version>
<kafka.version>0.10.0.0</kafka.version>
<spark.version>2.1.1</spark.version>
</properties>
<dependencies>
<!-- scala-->
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
<!-- spark-->
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.11</artifactId>
<version>${spark.version}</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming_2.11</artifactId>
<version>${spark.version}</version>
</dependency>
<!-- spark-streaming-kafka -->
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming-kafka-0-10_2.11</artifactId>
<version>${spark.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>2.15.2</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
源码:
import java.util.Date
import org.apache.commons.lang3.time.FastDateFormat
import org.apache.kafka.common.serialization.StringDeserializer
import org.apache.spark.sql.SparkSession
import org.apache.spark.streaming.kafka010.ConsumerStrategies.Subscribe
import org.apache.spark.streaming.kafka010.LocationStrategies.PreferConsistent
import org.apache.spark.streaming.kafka010.{CanCommitOffsets, HasOffsetRanges, KafkaUtils}
import org.apache.spark.streaming.{Seconds, StreamingContext}
/**
* By ruozedata-J 20180826
*/
object DSHS {
def main(args: Array[String]): Unit = {
//定义变量
val timeFormat = FastDateFormat.getInstance("yyyy/MM/dd HH:mm:ss.SSS")
println("启动时间:" + timeFormat.format(new Date()))
//流间隔 batch的时间
var slide_interval = Seconds(1) //默认 1秒
if (args.length==1){
slide_interval = Seconds(args(0).toLong) //自定义
}
val bootstrap_servers = "***.***.*.**:9092,***.***.*.**:9092,***.***.*.**:9092" //kakfa地址
try {
//1. Create context with 2 second batch interval
val ss = SparkSession.builder()
.appName("DSHS-0.1")
.master("local[2]")
.getOrCreate()
val sc = ss.sparkContext
val scc = new StreamingContext(sc, slide_interval)
//2.设置kafka的map参数
val kafkaParams = Map[String, Object](
"bootstrap.servers" -> bootstrap_servers
, "key.deserializer" -> classOf[StringDeserializer]
, "value.deserializer" -> classOf[StringDeserializer]
, "group.id" -> "use_a_separate_group_id_for_each_stream"
, "auto.offset.reset" -> "latest"
, "enable.auto.commit" -> (false: java.lang.Boolean)
, "max.partition.fetch.bytes" -> (2621440: java.lang.Integer) //default: 1048576
, "request.timeout.ms" -> (90000: java.lang.Integer) //default: 60000
, "session.timeout.ms" -> (60000: java.lang.Integer) //default: 30000
)
//3.创建要从kafka去读取的topic的集合对象
val topics = Array("onlinelogs")
//4.输入流
val directKafkaStream = KafkaUtils.createDirectStream[String, String](
scc,
PreferConsistent,
Subscribe[String, String](topics, kafkaParams)
)
//坑 order window
directKafkaStream.foreachRDD(
rdd => {
val offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges //RDD的offset
//rdd-->DF -->sql
rdd.foreachPartition(rows => {
rows.foreach { row =>
println(row.toString) //打印
//TODO 业务处理
}
})
//该RDD异步提交offset
directKafkaStream.asInstanceOf[CanCommitOffsets].commitAsync(offsetRanges)
}
)
scc.start()
scc.awaitTermination()
scc.stop()
} catch {
case e: Exception =>
println(e.getMessage)
}
}
}
auto.offset.reset:
latest 断点还原从最新的偏移量开始
earliest 断点还原从头开始=重新执行任务
none
enable.auto.commit: 一般设为false,如果设为true,易引发数据丢失
若设为true:
enable.auto.commit: true
auto.commit.interval.ms:5000 每个5s自动维护偏移量
生产:断批还原 +put 保证数据零丢失
举例:一个批次10000条数据,发送2000条后挂了。于是我们开始断批还原,从头传这个批次。那2000条数据,由于put命令的底层操作不会导致重复,后面的数据无缝对接传完。
4.监控 & 心得
1.Kafka eagle:Kafka 消息监控 - Kafka Eagle
2.CDH
通过以下语句构建图标实时监控:
SELECT total_kafka_bytes_received_rate_across_kafka_broker_topics ,total_kafka_bytes_fetched_rate_across_kafka_broker_topics
WHERE entityName = "kafka:onlinelogs" AND category = KAFKA_TOPIC
图:
1.生产者和消费者的速度是一样嘛?
由于趋势度吻合,所以速度一样的
2.为什么消费者的曲线和生产者的曲线趋势度吻合?
可以及时消费,消费目前的数据量没有压力
3.为什么消费者的曲线和生产者的曲线要高?
本文深入讲解Kafka的核心概念,包括broker、producer、consumer、topic和partition。详细阐述其容错性消费机制,消费者组的工作原理以及副本数的作用。还探讨了Kafka的offset管理和segment机制,并介绍了不同消费语义的特点与数据去重的方法。同时,提到了监控工具Kafka Eagle和CDH在监控Kafka中的应用,以及如何理解生产者和消费者的速度关系。
6636

被折叠的 条评论
为什么被折叠?



