一直在使用kafka,遇到过很多问题,总结一下

很多人对比kafka和AMQP的时候,都会强调kafka会丢数据,感觉好像只要用kafka就会丢数据一样,从而排斥使用kafka,亦或者在使用的过程中,发现数据丢失就认定罪魁祸首是kafka,好像丢数据就是使用kafka的代价。悄悄的鄙视一下这些伪程序猿。

kafka是一个强调高性能、高吞吐量的分布式消息中间件,在CAP中强调CP,当失去Broker Controller,选举新的Controller前服务处于不可用的状态,毕竟作为消息中间件对数据一致性还是有很高的要求。

大致解释一下kafka集群,kafka server一般叫broker,在集群里,各个broker通过zookeeper抢占broker controller,Controller的职责是管理所有的Partition和Replica的分布以及ISR列表并通知其他broker,如果controller宕机,其他broker又通过zk抢占Controller,在Controller选举的过程中,服务处于不可用的状态。

partition leader和partition replica:新建过topic的同学肯定知道,在新建topic的时候,我们一般会指定两个变量partition和replica,其实每个topic都是由多个partition组成的,一般情况下,partition的数量等于broker的数量,生产端产生数据存储在这些partition中。如果每个partition都没有备份,一旦服务器宕机,其中的数据都无法消费了,所以需要若干partition replica去备份这些partition, 而这些被备份的partition就称之为partition leader。这里再解释一下leader和replica切换的问题,leader与replica的数据copy肯定会有延迟的问题,不可能保证每时每刻replica的数据都与leader一致,所以就引入了一个ISR列表去维护哪些replica的数据是完整的,是值得信赖的,当replica中的数据与leader中的数据的延迟量超过一定的数值(可以自己设定的)或者卡住多少时间不返回的时候,这个replica就会被移除ISR列表,意味着此时如果leader宕机,当前这个replica是没有机会成为leader的,除非ISR列表里没有可用的replica。当这个replica的延迟或者返回时间恢复正常后,又会动态的把这个replica加入到ISR列表,总之ISR列表是动态的。

消息写入kafka的过程:producer会通过所连接的broker获取到当前kafka集群的状态例如broker地址、partition的分配等,producer通过消息中的key或者round robin选择要写入的partition, producer只会将消息写入partition leader, 再由leader分发给所有的replica。在这个过程中,producer可以指定消息写入的ack模型,acks= 大专栏  kafka相关问题总结0时,意味着不在乎消息是否已经写入partition leader,只要发送了就好;acks=1,消息写入leader需要返回ack才算成功;acks=-1或者all,消息写入leader后且所有replica也都写入并返回leader ack后才算成功。producer发送消息的确认模式选择就可能导致数据丢失,例如:当acks=1时,数据成功写入partition leader,producer会认为消息投递成功啦,突然partition leader在通知replica备份之前挂了,这条数据就沉入大海了,即使这个leader在一段时间后恢复,其他的replica可能早就已经取代它,成为新的leader了。

消息持久化broker时也可能发生丢失,在未写入硬盘前,机器挂掉也可能丢失数据,这种情况就认命吧,或者让acks更严格,消息未确认写入成功时能够继续重试。

最后就是消费的时候也可能发生丢失,kafka的消费模式和传统的AMQP是完全不同的,传统AMQP通过broker推送从而由broker控制消息的消费,消费端处理消息后需要通知broker消费状态(例如rabbitmq的ack,nack)如果失败broker会重新将消息推给其他消费端;kafka则是通过pull的方式,由消费端从broker上拉取消息,而拉取哪些消息由消费端自己控制(存在zk也是自己控制),这就导致如果消费失败,且消费端没有做好相应处理,offset+1后,这条消息也就丢失了,所以对不允许数据丢失的业务,可以通过代码管理offset。

消费消息没有顺序???

kafka的消费端有两个概念consumer group和consumer, consumer group由多个consumer组成,partition只能被在同一个consumer group中的一个consumer消费,但是可以被多个不同consumer group的consumer同时消费,如果consumer group中只有一个consumer,那么这个consumer可以消费所有的partition,所以一般来说有多少partition就初始化多少consumer,这样消费效率最高。

既然kafka允许多个consumer对多个partition同时消费且producer投递的消息也落于不同的partition中,那么在这种情况下,消费这些消息的顺序肯定是不可控的。但是要知道kafka的partition是只能被一个consumer(同一group下)消费的,那么只要让消息全部都落入同一个partition不就好了,我们投递消息的过程中通过设定消息的key就能让kafka producer根据key进行hash选择要写入的partition,就能保证消息写入的顺序以及消费的顺序。

kafka相关问题总结的更多相关文章

  1. 简单封装kafka相关的api

    一.针对于kafka版本 <dependency> <groupId>org.apache.kafka</groupId> <artifactId>ka ...

  2. kafka相关文章引用

    kafka相关内容说明: Kafka压缩 Kafka端到端审计 kafka数据可靠性深度解读 Kafka发送超过broker限定大小的消息时Client和Broker端各自会有什么异常? Kafka之 ...

  3. kafka相关应用

    一.kafka官网地址 http://kafka.apache.org 下载地址: http://kafka.apache.org/downloads.html 二.版本 0.9.0.1 is the ...

  4. Kafka相关内容总结(存储和性能)

    Kafka消息的存储 Kafka的设计基于一种非常简单的指导思想:不是要在内存中保存尽可能多的数据,在需要时将这些数据刷新(flush)到文件系统,而是要做完全相反的事情.所有数据都要立即写入文件系统 ...

  5. Kafka相关内容总结(概念和原理)

    说明 主要内容是在网上的一些文章中整理出来: 加粗的字体是比较重要的内容,部分是自己的经验和理解: 整理的目的主要是为了方便查阅: 为什么需要消息系统 解耦: 在项目启动之初来预测将来项目会碰到什么需 ...

  6. kafka相关资料

    先来说一下Kafka与RabbitMQ的对比: RabbitMQ,遵循AMQP协议,由内在高并发的erlanng语言开发,用在实时的对可靠性要求比较高的消息传递上. kafka是Linkedin于20 ...

  7. kafka相关业务必会操作命令整理

    参考:https://kafka.apache.org 服务相关命令 1.启动/停止zk > bin/zookeeper-server-start.sh config/zookeeper.pro ...

  8. kafka 相关命令 偏移重置

    kafka官方文档 https://kafka.apache.org/documentation.html#quickstart kafka 安装文档 https://www.jianshu.com/ ...

  9. 日志收集ELK+kafka相关博客

    SpringBoot+kafka+ELK分布式日志收集 使用 logstash + kafka + elasticsearch 实现日志监控 Kibana 安装 与 汉化 windows系统安装运行f ...

随机推荐

  1. 微信小程序裁剪图片后上传

    上传图片的时候调起裁剪页面,裁剪后再回调完成上传; 图片裁剪直接用we-cropper   https://github.com/we-plugin/we-cropper we-cropper使用详细 ...

  2. 11)PHP,单选框和复选框的post提交方式处理

    就是一个表单中会有input的checkbox形式,那么怎么处理,就有了问题,一般采用二维数组来处理 代码展示: <!DOCTYPE html PUBLIC "-//W3C//DTD ...

  3. WebServerFactoryCustomizer set the port, address, error pages etc.

    package com.ioc; import org.springframework.boot.SpringApplication; import org.springframework.boot. ...

  4. 分辨率单位及换算,LW / PH、LP / mm、L / mm、Cycles / mm、Cycles / pixel、LP / PH

    对于测试数字成像设备非常重要的参数是分辨率.但有不同的方式来表达数码相机的分辨率,有时令人困惑.下面介绍的是是最常见的单位. 百万像素 “这台相机有1000万像素的分辨率”是我们经常在广告上看到的数据 ...

  5. 图遍历算法的应用(包括输出长度为l的路径最短最长路径)

    判断从顶点u到v是否有路径 void ExistPath(AdjGraph* G, int u, int v, bool& has) { int w; ArcNode* p; visit[u] ...

  6. kotlin 单例模式

    class Single{ companion object { val instance:Single by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZE ...

  7. i2c驱动dht12的原理和步骤

    一.步骤 1.首先匹配i2c的控制器设备和控制器驱动,会生成一个struct i2c_adapter对象, 2.根据i2c_board_info   ,在  arch/arm/mach-sunxi/s ...

  8. Linux_列出文件和文件属性

    ls +文件名:列出该文件 ls +目录名:列出该目录下的文件 ls 什么也不加:列出当前工作目录下的文件 ls -a  列出包括隐藏文件,即所有文件名 ls -l 列出文件名+详细信息 ls -al ...

  9. 23)PHP,数组操作函数

    汇总:

  10. Spring的分模块开发的配置

    参考:Spring学习笔记-Spring的分模块开发的配置 在加载配置文件的时候,加载多个 例如把applicationContext.xml配置文件中的关于集合配置的部分剪切到application ...