大数据中最厉害的消息系统
1、什么是kafka??
Kafka是一个高吞吐量、低延迟、分布式的消息队列系统,每秒可以处理几十万条消息,它的延迟最低只有几毫秒;
Kafka提供了一个生产者、缓冲区、消费者的模型;kafka是由多个broker服务器组成,用于存储数据;不同的数据被分为不同的topic;producer往topic里生产数据,consumer从topic中获取数据;一个个消息组成partition,多个partition组成topic;每一个消息被标识了一个递增序列号代表其进来的先后顺序,将进来的消息追加到该partition的后面;每次消费之后会产生偏移量offset,它是唯一的标识该分区中的每个记录;kafka对消息默认保存7天,当然这个数据时可以调整的;每一个消费者唯一保存的元数据信息就是消费者当前消费日志的偏移量;该偏移量是由消费者控制,也就说消费者可以通过修改该偏移量来读取任何位置的数据;每个consumer都保留自己的offset,互相不干扰,不存在线程安全问题;partition均匀分配到集群server中。生产、消费消息时,会被路由到指定的partition,减少单台服务器的压力,增加了程序的并行能力;消息消费完成之后不会删除,可以通过重置offset重新消费;
应用场景:日志收集开放给各种consumer,比如hadoop、hbase、solr等;用户活动跟踪等等,可以装载到hadoop、数仓做离线分析和挖掘等等;
2、了解kafka的数据一致性是怎样做到的吗??
Producer往某个partition中写入数据时,只会往leader中写入数据,然后数据才会被复制进其他的replica中;kafka是由follower到leader上拉取数据的方式进行同步的;简单的说就是写都往leader上写,读也只在leader上读,flower只是数据的一个备份,只是为了防止leader挂掉,并不往外提供服务。
说到同步,在分布式架构中分为两种:第一种同步复制,即所有的follower把数据拿过去之后才commit,这样一致性好,但是性能不高;另一种是异步复制,只要leader拿到数据就立即commit,等follower慢慢复制,性能高,立即返回,但是一致性差;
我们kafka并不是同步也不是异步的,是一种独特的ISR机制;leader会维护一个与其基本保持同步的replica列表,被称之为ISR,每一个partition都会有一个ISR,由leader动态维护,如果一个follower比一个leader落后太多,或者超过一定时间没有发起数据复制请求,则leader将其ISR中移除;涉及到两个相关参数:replica.lag.time.max.ms和replica.lag.max.messages;当ISR中所有Replica都向Leader发送ACK时,leader才commit,当follower同时满足这两个条件时,leader又会将它加入ISR机制中,故ISR是一个处于动态调整的情况;
replica的作用:当partition的leader挂掉后,则会优先从ISR列表里挑选一个follower选举成新的leader,同时将旧的leader移除出ISR列表;
消费者API分为两种:highlevel consumer API偏移量由zookeeper来保存,使用简单,但是不灵活;simplelevelconsumerAPI 不依赖于zookeeper,无论从自由度和性能上都有更好的表现,但是开发很复杂。
1、kafka数据丢失和重复消费是怎样产生的,怎样解决???
先说数据丢失问题,有两种地方会数据丢失:第一种,producer端:有两种原因:第一,producer发数据给kafka时,它才开始将数据存储在服务器的pagecache中的,定期flush到磁盘上的,如果数据刚进来,这个时候断电的话,数据就会丢失;第二,是在使用kafka的备份机制时,producer的ack设置为0或1,最多只能保证leader有数据,假如producer发送的数据leader刚接收完毕,leader就挂掉了,那么partition的replica副本还未来得及同步,就会造成数据丢失;
这个问题怎么解决呢,我们可以提高flush的频率来减少数据丢失量,但这只是治标不治本,官方建议通过备份机制来解决数据丢失问题;
对于备份机制而导致的数据丢失问题,我们可以将ack设置为all,也就是所有的备份分区都同步到这条数据,再发第二条数据,但是这样就降低了性能,所以我们往往得结合业务来平衡数据的一致性和系统的性能;
第二种:consumer端导致数据丢失:在使用kafka高级API时,消费者会每个一段时间将offset自动保存到zookeeper上,假如刚提交完offset,数据还没消费,此时机器宕机,那么数据就丢失了;解决方案:关闭偏移量自动提交,改成手动提交,待数据每次处理完后再提交;
关于数据重复消费产生:消费者自动提交offset到zookeeper后,程序又消费了几条数据,但是还没到下次offset提交的时候。这个时候机器宕机。重启后,消费者会去zookeeper上读offset进行消费,这就会导致数据重复消费;解决方法就是关闭自动提交,改成手动提交。
4、kafka高吞吐的本质了解吗??讲讲
这个是kafka的一个最大的特点:为了保证数据写入性能,kafka是基于操作系统的页缓存来实现文件写入,即就是在数据写入文件时,先将数据写入OS cache中也就是仅仅写入内存中,接下来由操作系统自己决定什么时候把OS cache中的数据写刷入磁盘中;最重要的一点是:以磁盘顺序写的方式来写入文件的,也就是将数据追加到文件的末尾,不是在文件的随机位置来修改数据;磁盘顺序写的性能会比随机写快上几百倍;正因为这两点造就了kafka的超高性能;
另外一个原因就是零拷贝技术:正常的读取数据的顺序是:操作系统从磁盘将数据读取内核区的pagecache中;用户进程把数据从内核区copy到用户区的内存里;用户进程再把数据写入到socket,数据流入内核区socket buffer上;OS再把数据从socket buffer中copy到网卡上,最后发送给客户端消费者;
零拷贝技术就是直接让操作系统的cache中的数据发送到网卡后传输下游的消费者,中间跳过了两次拷贝数据的步骤;socket缓存中仅仅会拷贝一个描述符过去,不会拷贝数据到socket缓存。
这么说吧!!通过零拷贝技术,就不需要把OS cache里的数据拷贝到应用缓存,再从应用缓存拷贝到socket缓存了,两次拷贝都省略了,故叫零拷贝;对socket缓存仅仅就是拷贝数据的描述符过去,然后数据就直接从OS cache中发送到网卡上去了,这个过程大大的提升了数据消费时读取文件数据的性能;这样做之后相当于完全基于内存提供数据的读和写了,所以性能会极其的高。
5.kafka是怎样进行数据持久化的???
Kafka topic的数据存储在磁盘时会默认存储在/tmp/kafka-logs目录下,当然也可以自己设置,在该目录下会按topic的每个partition分区来存储,一个分区一个目录,一个partition目录下会有多个segment文件,分为.index和.log文件:其中.index文件为索引文件,命名从0开始,后续由上一个文件的最大的offset偏移量来开头;.log文件为数据文件,存放具体消息数据;kafka从磁盘上查找数据时,会先根据offset偏移量,对index文件名字进行扫描,通过用二分法的查找方式,可以快速定位到此offset所在的索引文件,然后通过索引文件里的索引,去对应的log文件种查找数据。
具体的相关参数:message.max.bytes (默认:1000000) – broker能接收消息的最大字节数;log.segment.bytes (默认: 1GB) – segment数据文件的大小;log.roll.hours (默认:7天) - 当segment文件7天时间里都没达到log.segment.bytes 大小,也会产生一个新文件;replica.fetch.max.bytes (默认: 1MB) – broker可复制的消息的最大字节数;fetch.message.max.bytes (默认 1MB) – 消费者能读取的最大消息;