1、首先请介绍一下您在kafka和相关项目主要负责哪些工作?
秦江杰:kafka是一个open source的项目,这个社区并没有某一个人单独负责哪一块东西,如果谁提出来一个想法,一般会由这个人实施,但没有规定一定是这个人实施或者怎样,所以是比较宽泛松散的环境,没有固定的负责人。当然一般来讲如果在某一方面做的工作多一些,那可能相对看这方面code也会多一些。从LinkedIn内部来讲也是类似,以team为单位做一些项目,这些项目会有具体的相关的实施人员,但是从整个设计之初,整个team都会参与进去帮助一起看到底有没有一些东西需要改进,我个人最近做的比较多的是两个项目,一个是LinkedIn的kafka clients,主要的原因是因为我们在LinkedIn对于kafka的应用越来越多,以前我们把它作为一个传统的消息队列,现在我们的change capture system也开始使用kafka,分布式数据库内部的数据备份也开始使用kafka,kafka的应用现在越来越广泛越来越多,这就使得我们需要对kafka整个消息的完整性包括性能和一些超大信息传送这些问题进行一个比较统一的解决方案,这个我们是放在了kafka clients library里面开源出来,这是其中一个项目。另外一个项目是关于怎样在大规模的kafka的部署的情况下非常有效的operate kafka,现在LinkedIn已经超过1800台kafka服务器,80、90个cluster,每天超过有1.3万亿个消息经kafka流出流入,基本上每一天SRE都需要做很多administrative相关的东西,比如会宕掉、新的topic创造出来、集群的workload不均衡,这种事情每天要做就会导致跑kafka的overhead比较大,这是我们想要解决的另外一个问题,也是我正在做的项目叫kafka Cruise Control。
2、您认为kafka适合做什么?相对传统队列解决方案它有什么优势?
秦江杰:我觉得kafka从最大的广义来讲其实就是帮助你把消息从一个地方挪到另外一个地方,这是最基本的功能,也是所有其他消息队列最基本的功能,大家的区别更多的是在于各个消息系统不同的特性,有的消息系统可能延迟非常非常低,不会把消息persist到系统里,消息发出去就发出去了,如果要重新consume是做不到的,这种情况下吞吐量很高,但是就放弃了persistence这一块,kafka我觉得从这个角度来讲是做了一个平衡,有很多方面能够做到更广泛的适用于不同的应用场景,特别是persistency在很多应用场景下非常有用,比方说我们很多时候需要重新计算一个模型,需要re-process之前的data,通常来讲你不太可能要求producer重新把消息produce一遍,最好的办法就是kafka帮你persist之前的数据,你可以非常方便的回到某一个过去的时间点。我觉得kafka之所以成功有一个很大的原因是因为他把数据模型定义的非常好,从他的topic、 partition、offset这些最基本的概念上来讲,把消息的模型定义的非常好,所以能够比较广泛的适用于很多不同的应用场所。
3、刚才您提到LinkedIn越来越广泛的使用kafka,除了您刚才提的,还有哪些地方用到?
秦江杰:现在LinkedIn内部有这样一个趋势或者想法,因为现在kafka越来越稳定,它的应用场景也越来越多,所以我们现在想做的事情就是想去看,在每一个product内部是不是有可能去用kafka,我们会有一个unified messaging layer,所有的消息传输层的应用都会由kafka来做,包括我刚才提到数据库内部的备份,是消息传输的一个例子,再比方说stream processing也是一个消息传输的例子,内部还在做一些multiple version的key-value store也是涉及消息传输的问题,简单来说我们希望尽量的把kafka这个产品做到非常稳定、非常好,尽量拓宽它的使用场景使用面,整个系统会变的简单,你只需要维护这一个产品,同时也会变的更稳定,因为产品维护越来越成熟。
4、他会成为你们的基础组件?
秦江杰:kafka已经是LinkedIn的基础组件,对很多LinkedIn infrastructure的产品来讲,我们会有availability的要求,对于kafka的availability现在要求是非常高的,至少要有四个九,正在向五个九努力。
5、最近看有一篇文章介绍了kafka的生态,LinkedIn围绕kafka打造了一些相关的项目,能不能介绍一下包括哪些关键系统?
秦江杰:这个生态是花了很长时间建立的,开始建立的时间可能比我进LinkedIn的时间还要早,后面也有很多的发展。具体来讲LinkedIn的kafka生态,最主要有这么几个部分,第一个部分是kafka自己本身的server端,另外一个就是kafka 的client端,在LinkedIn我们有一个数据标准化的工作,目的是在整个LinkedIn里面,每一个人对于消息格式都有一个非常固定的标准,而不是每一个组自己定自己的消息格式,发出去之后可能很多其他人没有办法用,我们要求所有经过kafka的消息都必须用固定的format,我们有一个集中式的schema管理的部件,每次发送消息的时候,他做的过程是把我们的消息通过schema序列化成var bytes,我们不会把schema随着消息一起发出去,他做的事情是把schema注册到schema registry拿到一个schema id,把这个id随着消息一起发送出到kafka,当consumer拿到这个消息的时候会先去看schema id,然后到schema registry把schema拿回来,就可以把这个消息反序列化出来,在整个过程当中,最主要的好处是消息的overhead比较小,这是一个最基本的数据的收发过程和数据的格式标准。
围绕这个基础之上,还有一些其他的component,比方说为了查看消息到底是不是被完整传送,我们外部会有一个auditing system,之前也有很多的人讲,现在有很多公司已经根据我们这个做法去做了他们自己的auditing system,基本的想法就是一个计数的想法,也就是说我去看在比如说每10分钟时间段里面,producer往broker发送了多少消息,多少消息发送成功了,producer只是告诉你一个数量,这段时间内发了10条消息,consumer端也是一样,它consume完了一个topic以后也会汇报在这10分钟之内看到了多少条消息,producer产生了10条,consumer也消费了10条,说明消息没丢,否则消息可能就丢掉了,这是一个最基本的auditing,其实就是看消息有没有丢。在这个基础之上,我们今年还试图去看每一个application用了kafka cluster多少资源,我们也把这个信息放在了auditing system里面,也就是说producer也会汇报在这一段时间里面它发送了多少消息,总共是这么多bytes,在broker端我们会有一个单独的consumer去consume这些消息,他也会说在broker端有这么多消息,这些消息在磁盘上面存放了多久,你的成本跟存放时间也会有函数关系,最后的目标就是我们能够非常清楚的看到在1800多台broker上面,application到底是怎么用的,每一个application用了多少,什么时候用了什么东西,希望能够看到这样一个图,可以非常清晰的看到成本的分布到底是怎样,了解成本分布之后进一步就有可能会去做一些cost reduction的工作。
6、您本次在QCon的演讲是关于LinkedIn的Espresso数据库冗余数据备份的项目,请谈一谈这个项目的背景,之前是怎么做的,为什么要用kafka重做?
秦江杰:这次是基于数据库备份的场景来提供的用kafka进行关键业务的消息传输这么一个主题,Espresso是LinkedIn一个最主要的数据库,里面存放了非常多关键的用户数据,比方所有LinkedIn用户的profile,所以它部署的server非常多,在此之前我们用的是MySQL instance level的replication,他有两个问题,第一个问题是他的颗粒度非常大,只能做到MySQL instance level,意味着说如果一个storage node是master的话,那它所含有的所有的partition都是master,如果一个storage node是slave的话,它上面所有的partition都是slave。对于这么关键的应用来讲,一般都会有至少三份拷贝,所以就会有两个slave,但这两个slave不会serve任何data,我们只能做到整个storage node是master或者slave,颗粒度非常大,用kafka做数据备份之后,我们可以做到把master/slave的颗粒度从storage node放到partition,换句话讲可以让一个storage node只是他含有的其中某一些partition的leader,而不是所以partition的leader,剩下的storage node就可以均摊一些workload,这样可以使得我们的workload分布更均匀,某种情况下我们可以减少一些replica的数量。
7、能谈一下在这个项目里面踩过哪些坑吗,有哪些经验可以和大家分享?
秦江杰:这个项目里面遇到的坑不少,最主要的一个原因是因为在此之前就我们了解还没有一个利用kafka来进行数据库备份的应用的实例,当然因为kafka本身是一个high throughput low latency的系统,所以理论上来讲是完全可以support这种应用场景的。但是我们在实际操作过程当中的确碰到不少的问题,一个非常明显的问题就是在数据库里面我们对每一行的大小没有限定,比方说可以把一个user的profile做的非常大,数据库里面就是一行,但是消息系统对于大消息一般都不太喜欢,因为会导致broker上有很多压力,这就是我们为什么在client端去实现超大消息的支持,这是一个比较重要的困难。
另外一个困难,我们发现因为Espresso是一个online的系统,所以对延迟性要求非常高,它的throughput也非常高,虽然kafka支持high throughput low latency ,但是对于不同的应用的要求我们需要对它进行特殊的performance tuning,这个过程当中我们也发现了很多值得跟大家分享的方面,之前湾区的一些tech talk里我们也提到过这些内容,这次由于时间关系就没有详细讲,但是会有link给到大家,大家可以下去看。
另外在安全性方面,我们也碰到了一些需要解决的问题,刚才提到Espresso里面存放了一些用户的敏感数据,所以对于安全性的要求非常高,我们会要求一个socket compliant,在这个过程当中需要把我们的authorization逻辑加到broker上面,但是这个逻辑是在broker上的critical path上,如果authorization做的慢了,整个broker的性能就会掉的非常多,为了解决这个问题,我们也进行了一些特殊的设计,包括做一些local的cache,包括在一些特殊情况下我们会返回特殊错误让client重试,这个也是很多对安全有要求的系统里面可能要注意的一点。我们在这个过程当中还修掉了kafka本身的很多Bug,之前会有一些out of order delivery的问题,即使用了正确的setting,可能发送的顺序也会产生错误,我们在这个过程当中也修了很多诸如此类的bug。
8、刚才提到因为要解决数据库备份问题,所以给kafka的client加了很多feature对吧?您认为这是kafka的正统优化吗?因为大家对它的是印象是消息队列或消息中间件。
秦江杰:时代在发展,事情都在变化,kafka一开始确实是消息队列,但现在kafka的应用越来越广泛,在LinkedIn我们有利用LinkedIn做传统消息队列的做法,也有用他做数据库的备份,也有用他做数据库的change capture,也有用他来做multiple version的key-value store的临时存储,所以他的应用非常多,不仅仅是消息队列,就像我刚才说的,你可以认为他是一个消息队列,消息队列的本质无非就是把消息从一个地方传到另外一个地方,如果你把他从这个本质上抽象,在所有的运用场景里面只要你有需要把消息从一个地方传到另外一个地方,你都可以用kafka,具体的应用场景说到底是要把消息从一个地方传到另外一个地方。
kafka还有一个另外的特点,是可以作为一个临时storage使用,这也是我们在 stream processing里经常用到的feature,可以作为键值库的备份,stream processing我会重点提一下,open source kafka的component越来越丰富,从之前只有server和client现在又加进去了一些新的component,比如kafka connect和kafka streams,这是两个在最近一两年加进去大的组件,kafka connect帮助你做的事情是从不同的系统把数据导入导出到kafka,一头必须是kafka,另外一头可以是其他的地方,比方说hdfs,比方说MySQL数据库。kafka streams是基于kafka做的stream processing的engine,它跟samza非常像,samza是LinkedIn自己的stream processing engine,它跟现在比较流行的spark streaming、storm,包括今年很流行的flink都是stream processing engine,但samza有自己独到的优势,他有local state,所以single db的throughput可以做到非常高,一百万个事件每秒钟。应该说open source kafka现在已经不仅仅是消息队列了,实际上在它的apache主页上面,最近刚刚把他从一个消息队列的定义改成了stream processing platform,已经变成流处理的平台。
9、能介绍一下kafka未来的演进有哪些目标吗?
秦江杰:从大的方向来看, kafka在近几年的发展应该会越来越多的偏向于stream processing。至于应用场景来看,我觉得就像刚才提的,更多的是看你怎么样抽象这个问题,它可以作为一个非常好的临时存储,同时可以帮助你把数据从一端搬到另一端。