经常有人问的一个问题就是:Kafka broker到底是不是无状态的?网上有这样的说法:

正常情况下consumer会在消费完一条消息后线性增加这个offset。当然,consumer也可将offset设成一个较小的值,重新消费一些消息。因为offet由consumer控制,所以Kafka broker是无状态的。。。。。。

  我猜想作者的意思应该是说:broker不保存消费者的状态。如果从这个角度来说,broker无状态的说法倒也没有什么问题。不过实际上,broker是有状态的服务:每台broker在内存中都维护了集群上所有节点和topic分区的状态信息——Kafka称这部分状态信息为元数据缓存(metadata cache)。本文就将讨论一下这个metadata cache的设计与实现。

1. cache里面存了什么?

  首先,我们来看下cache里面都存了什么,我们以Kafka 1.0.0版本作为分析对象。Metadata cache中保存的信息十分丰富,几乎囊括了Kafka集群的各个方面,它包含了:

  • controller所在的broker ID,即保存了当前集群中controller是哪台broker
  • 集群中所有broker的信息:比如每台broker的ID、机架信息以及配置的若干组连接信息(比如配置了PLAINTEXT和SASL监听器就有两套连接信息,分别使用不同的安全协议和端口,甚至主机名都可能不同)
  • 集群中所有节点的信息:严格来说,它和上一个有些重复,不过此项是按照broker ID和监听器类型进行分组的。对于超大集群来说,使用这一项缓存可以快速地定位和查找给定节点信息,而无需遍历上一项中的内容,算是一个优化吧
  • 集群中所有分区的信息:所谓分区信息指的是分区的leader、ISR和AR信息以及当前处于offline状态的副本集合。这部分数据按照topic和分区ID进行分组,可以快速地查找到每个分区的当前状态。(注:AR表示assigned replicas,即创建topic时为该分区分配的副本集合)

2. 每台broker都保存相同的cache吗?

  是的,至少Kafka在设计时的确是这样的愿景:每台Kafka broker都要维护相同的缓存,这样客户端程序(clients)随意地给任何一个broker发送请求都能够获取相同的数据,这也是为什么任何一个broker都能处理clients发来的Metadata请求的原因:因为每个broker上都有这些数据!要知道目前Kafka共有38种请求类型,能做到这一点的可谓少之又少。每个broker都能处理的能力可以缩短请求被处理的延时从而提高整体clients端的吞吐,因此用空间去换一些时间的做法是值得的。

3. cache是怎么更新的?

  如前所述,用空间去换时间,好处是降低了延时,提升了吞吐,但劣势就在于你需要处理cache的更新并且维护一致性。目前Kafka是怎么更新cache的?简单来说,就是通过发送异步更新请求(UpdateMetadata request)来维护一致性的。既然是异步的,那么在某一个时间点集群上所有broker的cache信息就未必是严格相同的。只不过在实际使用场景中,这种弱一致性似乎并没有太大的问题。原因如下:1. clients并不是时刻都需要去请求元数据的,且会缓存到本地;2. 即使获取的元数据无效或者过期了,clients通常都有重试机制,可以去其他broker上再次获取元数据; 3. cache更新是很轻量级的,仅仅是更新一些内存中的数据结构,不会有太大的成本。因此我们还是可以安全地认为每台broker上都有相同的cache信息。

  具体的更新操作实际上是由controller来完成的。controller会在一定场景下向特定broker发送UpdateMetadata请求令这些broker去更新它们各自的cache,这些broker一旦接收到请求便开始全量更新——即清空当前所有cache信息,使用UpdateMetadata请求中的数据来重新填充cache。

4. cache什么时候更新?

  实际上这个问题等同于:controller何时向特定broker发送UpdateMetadata请求? 如果从源码开始分析,那么涉及到的场景太多了,比如controller启动时、新broker启动时、更新broker时、副本重分配时等等。我们只需要记住:只要集群中有broker或分区数据发生了变更就需要更新这些cache。

  举个经常有人问的例子:集群中新增加的broker是如何获取这些cache,并且其他broker是如何知晓它的?当有新broker启动时,它会在Zookeeper中进行注册,此时监听Zookeeper的controller就会立即感知这台新broker的加入,此时controller会更新它自己的缓存(注意:这是controller自己的缓存,不是本文讨论的metadata cache)把这台broker加入到当前broker列表中,之后它会发送UpdateMetadata请求给集群中所有的broker(也包括那台新加入的broker)让它们去更新metadata cache。一旦这些broker更新cache完成,它们就知道了这台新broker的存在,同时由于新broker也更新了cache,故现在它也有了集群所有的状态信息。

5. 目前的问题?

  前面说过了,现在更新cache完全由controller来驱动,故controller所在broker的负载会极大地影响这部分操作(实际上,它会影响所有的controller操作)。根据目前的设计,controller所在broker依然作为一个普通broker执行其他的clients请求处理逻辑,所以如果controller broker一旦忙于各种clients请求(比如生产消息或消费消息),那么这种更新操作的请求就会积压起来(backlog),造成了更新操作的延缓甚至是被取消。究其根本原因在于当前controller对待数据类请求和控制类请求并无任何优先级化处理——controller一视同仁地对待这些请求,而实际上我们更希望controller能否赋予控制类请求更高的优先级。社区目前已经开始着手改造当前的设计,相信在未来的版本中此问题可以得到解决。

  本文探讨了一些关于metadata cache方面的内容,因为时间有限,并没有涵盖方方面面。不过对于我们了解cache的工作原理应该可以还是有帮助的~~

Kafka元数据缓存(metadata cache)的更多相关文章

  1. [Java 缓存] Java Cache之 DCache的简单应用.

    前言 上次总结了下本地缓存Guava Cache的简单应用, 这次来继续说下项目中使用的DCache的简单使用. 这里分为几部分进行总结, 1)DCache介绍; 2)DCache配置及使用; 3)使 ...

  2. 缓存篇(Cache)~大话开篇

    回到占占推荐博客索引 闲话杂淡 想写这篇文章很久了,但总是感觉内功还不太够,总觉得,要写这种编程领域里的心法(内功)的文章,需要有足够的实践,需要对具体领域非常了解,才能写出来.如今,感觉自己有写这种 ...

  3. HTML5学习总结-08 应用缓存(Application Cache)

    一 应用缓存(Application Cache) 1 应用缓存 HTML5 引入了应用程序缓存,这意味着 web 应用可进行缓存,并可在没有因特网连接时进行访问. 应用程序缓存为应用带来三个优势: ...

  4. 如何在 Linux 中清除缓存(Cache)

              如何在 Linux 中清除缓存(Cache)            方法一: http://mp.weixin.qq.com/s?__biz=MjM5ODAzODgyMQ==&am ...

  5. 从Java视角理解CPU缓存(CPU Cache)

    从Java视角理解系统结构连载, 关注我的微博(链接)了解最新动态众所周知, CPU是计算机的大脑, 它负责执行程序的指令; 内存负责存数据, 包括程序自身数据. 同样大家都知道, 内存比CPU慢很多 ...

  6. 关于Linux的缓存内存 Cache Memory详解<转>

    转自 http://www.ha97.com/4337.html PS:前天有童鞋问我,为啥我的Linux系统没运行多少程序,显示的可用内存这么少?其实Linux与Win的内存管理不同,会尽量缓存内存 ...

  7. ASP.NET缓存中Cache过期的三种策略

    原文:ASP.NET缓存中Cache过期的三种策略 我们在页面上添加三个按钮并双击按钮创建事件处理方法,三个按钮使用不同的过期策略添加ASP.NET缓存. <asp:Button ID=&quo ...

  8. WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[元数据描述篇]

    原文:WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[元数据描述篇] 在[WS标准篇]中我花了很大的篇幅介绍了WS-MEX以及与它相关的WS规范:WS-Policy.WS-Tra ...

  9. yii中缓存(cache)详解

    缓存是用于提升网站性能的一种即简单又有效的途径.通过存储相对静态的数据至缓存以备所需,我们可以省去生成这些数据的时间.在 Yii 中使用缓存主要包括配置和访问缓存组件 . 内部方法 一.缓存配置: 1 ...

随机推荐

  1. Oracle 内连接和外连接

    内连接用于返回满足连接条件的记录:而外连接则是内连接的扩展,它不仅会返回满足连接条件的所有记录,而且还会返回满足不满足连接条件的记录!从Oracle9i开始,可以在From 子句中指定连接语法.语法如 ...

  2. 一个CSS背景颜色问题

    div{ background: rgba(0,0,0,.1);     background-color: #19FFFFFF; } 安卓下会显示上面的透明颜色,而在iOS上则显示下面的颜色,并且其 ...

  3. Redis的集群配置

    如果我们redis的压力很大,如果我们的并发高到我们读数据和写数据都有了很大压力. 那么我们可能就需要把redis分开部署,并且配置为一个『主从』的状态. 在服务器上构筑Redis的集群配置: 1.切 ...

  4. azkaban的安装部署

    一.所需环境 1,JDK 2,HADOOP 4,mysql 3,HIVE 二.安装azkaban 1,安装git命令: yum install git 2,下载azkaban源码:git clone ...

  5. 数据库面试题目- ORACLE

    Posted on 2009-06-08 17:38 漠北的天空 阅读(110) 评论(0)  编辑 收藏 1.       列举几种表连接方式 Answer:等连接(内连接).非等连接.自连接.外连 ...

  6. UML2.0

    一.系统过滤器使用说明 1.OutputCache过滤器 OutputCache过滤器用于缓存你查询结果,这样可以提高用户体验,也可以减少查询次数.它有以下属性: Duration:缓存的时间,以秒为 ...

  7. Python用pip安装IPython/Jupyter最佳交互环境

    一.Python模块及安装包简介 如果说编程语言是武器,那么Python就是一把双管枪(Python2/Python3),而各种为Python编写的模块和包就是子弹.使用pip来填满我们的武器吧! I ...

  8. TabBarController和其他view无法建立Relationship segue的原因

    拖拽怎么也没有那个出现,最后看sourcecode发现是那个那个viewcrontroler的XML 元素不是TabBarController.在Sourcecode里面改了一下,解决了这个问题. 总 ...

  9. 通知:QQ互联网回调地址校验加强

    今天公司网站第三方qq快捷登录突然登录不了了,之前明明是ok的. 可以看到有一个错误信息提示 在qq互联的官网看到了这个通知 然后解决办法是: 1.打开http://open.qq.com/tools ...

  10. ThinkPHP5从零基础搭建CMS系统(二)

    接上节,开启wamp集成环境,在浏览器地址栏输入http://localhost/cms/public,即可运行项目,但是这边域名太长,做一下处理. 注:需要查看tp5全部教程,请点击右侧thinkp ...