kafka 顺序消费, spark streaming exactly-once以及零丢失的一些总结

Kafka:定义:

消息中间件 –>分布式流式平台

生产者   source
Broker channel
消费者 sink 

正常部署的是:

 Broker进程(一个机器一个(分布式),一个机器多个(伪分布式))

使用场景:

Flume-->Kafka-->Spark streaming 实时流式Kafka Streaming

特点:

发布/订阅
实时app
分布式  副本数 一个
SCALA编写

部署: kafka_2.11-0.10.0.0.tgz
scala version:2.11

准备环境:

1.JDK
   java -version
2.Scala 
   scala -version
3.Zookeeper
[root@node85 software]# ln -s zookeeper-3.4.6 zookeeper
[root@node85 software]# ll
total 462992  
lrwxrwxrwx   1 hdfs hdfs        33 Jan 

命令解释:

 软连接:ln -s   物理文件夹/文件 快捷的文件夹/文件 
 1.删除 快捷的文件夹/文件 ,增加安全系数
 2.多版本管理
 3.硬连接

常用命令:kafka-topics.sh

bin/kafka-topics.sh --create \--zookeeper node85:2181,node86:2181,node87:2181/kafka \--replication-factor 3 \--partitions 3 \--topic test

高并发写/读 :

bin/kafka-topics.sh --list \--zookeeper node85:2181,node86:2181,node87:2181/kafka

生产者:

bin/kafka-console-producer.sh \--broker-list node85:9092,node86:9092,node87:9092 \--topic test

消费者

bin/kafka-console-consumer.sh \--zookeeper node85:2181,node86:2181,node87:2181/kafka \--topic test \--from-beginning

查看topic描述信息:

bin/kafka-topics.sh \--describe \--zookeeper node85:2181,node86:2181,node87:2181/kafka \--topic test

修改topic 分区:

bin/kafka-topics.sh \--alter \--zookeeper node85:2181,node86:2181,node87:2181/kafka \--topic test \--partitions 4 

彻底删除topic的步骤:

bin/kafka-topics.sh --delete \--zookeeper node85:2181,node86:2181,node87:2181/kafka \--topic test 

rmr /kafka/admin/delete_topics/test 

rmr /kafka/config/topics/test 

rmr /kafka/brokers/topics/test 

rm -rf logs/test-*

概念:topic:主题

partitions:分区
partitions 3 3个分区 下标从0开始
replication-factor 3 一个分区3个副本 单个分区:有序

Note:

全局分区: 无序如何保证生产上 全局有序?
    理解:生产上并不是所有的数据都要求有序消费,只是具体的某个业务线要求消息必须严格有序。
例如下面的案例:

通过canal或者maxwell 实时收集MySQL的binlog,因为数据存在更新操作,所以必须严格有序。
 解决方法:  目前kafka支持一个分区的全局有序。
    所以就需要通过消息的key,将这一类的消息hash到一个分区内,实现有序的处理。

具体步骤如下:

MySQL BINLOG 日志文件 按顺序—-有序。—–》

Kafka test 3个分区

siphondata.typeid
包含: name age两列。

原始数据:

insert into stu values(1,'bool',18);
insert into stu values(2,'siphon',28);
update stu set age=26 where id=1;
delete from stu where id=1;

生产时:

test-0:
insert into stu values(1,'bool',18);  

test-1:
insert into stu values(2,'siphon',28);
delete from stu where id=1;    

test-2:
update stu set age=26 where id=1;

消费时

insert into stu values(2,'siphon',28);
delete from stu where id=1;
insert into stu values(1,'bool',18);
update stu set age=26 where id=1;

核心点:

 共性数据发送到同一个topic的1个分区拼装的Key:例如, siphondata_stu_id=1  

代码 hash(siphondata_stu_id=1 ) 取模 0,1,2
value: sql

test-0:
insert into stu values(1,’bool’,18);
update stu set age=26 where id=1;
delete from stu where id=1;

test-1:
insert into stu values(2,’siphon’,28);test-2:
[root@node86 kafka]# bin/kafka-topics.sh –describe –zookeeper node85:2181,node86:2181,node87:2181/kafka –topic test

Topic:test PartitionCount:3 ReplicationFactor:3 Configs:
Topic: test Partition: 0 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3
Topic: test Partition: 1 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1
Topic: test Partition: 2 Leader: 3 Replicas: 3,1,2 Isr: 3,1,2

[root@node86 kafka]#
第一行: 哪个topic 多少个分区 每个分区多少个副本数
Topic: test Partition: 0 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3

分区-0
Replicas: 1,2,3 三个副本位于Leader: 1 读写 Isr: 1,2,3

[root@node86 kafka]# bin/kafka-topics.sh –describe –zookeeper node85:2181,node86:2181,node87:2181/kafka –topic testTopic:test
PartitionCount:3 ReplicationFactor:3 Configs:Topic: test Partition: 0 Leader: 2 Replicas: 1,2,3 Isr: 2,3Topic: test Partition: 1 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1Topic: test Partition: 2 Leader: 3 Replicas: 3,1,2 Isr: 3,1,2

[root@node86 kafka]# bin/kafka-topics.sh --describe --zookeeper node85:2181,node86:2181,node87:2181/kafka --topic testTopic:test      PartitionCount:4        ReplicationFactor:3     Configs:Topic: test     Partition: 0    Leader: 2       Replicas: 1,2,3 Isr: 2,3,1Topic: test     Partition: 1    Leader: 2       Replicas: 2,3,1 Isr: 2,3,1Topic: test     Partition: 2    Leader: 3       Replicas: 3,1,2 Isr: 3,2,1Topic: test     Partition: 3    Leader: 1       Replicas: 1,3,2 Isr: 1,3,2

如果整个流程串起来,
就是 MySQL –>maxwell(producer) —> Kafka(hash ) –>Spark streaming(按顺序消费)—> (exactly-once)(mysql)

    通过对偏移量的管理可以实现数据的零丢失。
    通过对消息的合理分区可以实现有序的消费。
    通过对数据源的replay 和 数据存储的幂等,可以实现exactly -once。

流处理:offset + skew

offset管理可以选择:

    checkpoint(FS)
    zk、nosql、rdbms,
    kafka

偏移量存储MySQL时:
Note:

   如果建表时没有添加主键,就需要添加主键:
   ALTER TABLE `test` DROP PRIMARY KEY ,ADD PRIMARY KEY ( `id` )



create table ssc_offsets_storage(
topic varchar(32),
groupid varchar(50),
partitions int,
offset bigint,
primary key(topic,groupid,partitions)
);

要求exactly-once 输出幂等时候,这里也可以使用replace into 语法:

insert into traffic_m5(m5,domain,traffic) values("201809122145","www.bilibili.com",1772342) on duplicate key update traffic=1772342;
insert into traffic_m5(m5,domain,traffic) values("201809152345","www.dou.live.com",6008023) on duplicate key update traffic=6008023;

具体replace into 语法和 insert into on duplicate key的主要区别在于,replace into 更新时如果字段不全,则未更新的字段会自动填充为该字段类型的默认值。
参考:https://blog.csdn.net/xlxxcc/article/details/52439734

你可能感兴趣的:(流全栈处理)