ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## kafka的重要组件 ![](file:///C:/Users/fzuxi/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg) ## Producer: 生产者负责将数据传入Kafka,比如flume、java后台服务、logstash 生产者可以有多个,并且可以同时往一个topic中写数据,也可以同时往一个partition中传入数据。 每个生产者都是一个独立的进程,而且单个生产者就具有分发数据的能力。 一个生产者可以同时往多个topic中分发数据。(一般不会这么操作) ## Kafka cluster: Kafka由多个broker组成,一个broker作为一个实例(节点) Kafka集群可以保存多种类型的数据,是由多个topic进行分类的 一个topic其实就是一个队列 每个topic可以创建一个或多个partition,partition的数量是可以更改的 每个partition是由多个segment组成的,segment的大小是相同的,默认的是1G topic中的数据是有多副本机制的,原始数据和副本数据不会在同一个节点上(所以若只有一个节点,副本数为3,也并不会在同一个节点上存3份) ## Consumer group: 消费者负责拉取数据,比如:streaming、storm、java服务 消费者组中可以存在多个consumer,在stream中,一个consumer作为一个线程 新增或减少consumer数量会触发负载均衡,目的是减少部分broker压力,提高Kafka的吞吐量 一个consumer group可以消费多个分区的数据 一个分区的数据最多在同一个时刻被一个consumer消费 在同一个consumer group中,数据是不可以重复消费(若想要重复消费,可以修改group名,或者设置Kafka集群映射,或者手动调整已经变化了的偏移量) ## Kafka数据的存储机制(Kafka是怎么存储数据的)? 1、broker先接受到producer传过来的数据,将数据写入到操作系统(Linux)的缓存(pagecache)里,pagecache会尽可能的使用空闲内存来存储数据 2、使用sendfile技术尽可能多的减少操作系统和应用程序之间的重复缓存,写数据时是顺序写入(顺序写入的速度可达到600m/s) - consumer是怎么解决负载均衡的? 1、获取consumer消费的起始分区号;2、计算出consumer消费的分区数量;3、用分区号的hash值%分区数 - segment是什么? 1、一个分区被分为多个相同大小的segment,默认是1G, 2、每个segment是由多个index和log文件组成的,index存储数据对应的索引,实际的数据是存储在log文件中。 3、segment是有生命周期的,默认是168小时(七天) ## 数据是怎么分发的(数据的分发策略)? 1、Kafka接收到数据后会根据创建的topic指定的副本来存储,多副本之间会有选举的过程,即有leader和follower,数据会首先写到leader,然后再同步到follower 2、Kafka会调用分区器来进行分发数据,默认分区器是DefaultPartitioner(分区的逻辑是key的hash值%分区数),也可以自定义分区器,需要实现Partitioner特质,实现partition方法 - Kafka存储数据能做到全局有序吗? 不能。只能做到分区内有序。 如果就想做到topic的全局有序,只声明一个分区,但会影响吞吐量。(1秒20MB数据,一天也是1.7T的数据) ## Kafka的消息传递语义,Kafka怎么保持数据的一致性(怎么保证数据0丢失)? 1\. 幂等写入( idempotent writes) 设置好唯一主键等,比如用redis、mysql。再比如每次往一个目录覆盖写数据,这样主键不容易获取。 一次语义:幂等写入 当获取到数据后,先写到mysql,再保存offset,如果在写到mysql数据后,在保存offset之前宕机,重启作业后也不会影响一次语义,因为会在mysql重复更新。 注:在软件开发领域,幂等写入即为同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的,实际上就是接口的可重复调用(包括时间和空间上两个维度)。 2.事务控制 保证数据和offset在同一个事务里面,比如用mysql,这样需要事务存储的支持。 3.自己实现Exactly-once,offset和数据绑定保存等。