精华内容
下载资源
问答
  • Apache-Kafka简介Apache Kafka安装和使用Apache-Kafka核心概念Apache-Kafka核心组件和流程-协调器Apache-Kafka核心组件和流程(副本管理器)Apache-Kafka 核心组件和流程-控制器Apache-Kafka核心组件和流程-日志管理器...

    890fd4255430dad41a82a920df873a3a.png

    Apache Kafka 编程实战您可能感性的文章:

    Apache-Kafka简介

    Apache Kafka安装和使用

    Apache-Kafka核心概念

    Apache-Kafka核心组件和流程-协调器

    Apache-Kafka核心组件和流程(副本管理器)

    Apache-Kafka 核心组件和流程-控制器

    Apache-Kafka核心组件和流程-日志管理器

    ....

    通过前几章的学习,我们已经从宏观层面了解了kafka的设计理念。包括kafka集群的组成、消息的主题、主题的分区、分区的副本等内容。接下来我们会继续深入,了解kafka的主要组件以及核心的流程,最后还会介绍kafka的消息是如何存储的。此章非常重要,通过本章和上一章的学习,你已经能够掌握kafka 80%的核心内容。当然随着学习的深入,难度也会越来越大,有任何问题欢迎留言或者私信。

    Kafka主要的组件如下

    • 控制器
    • 协调器
    • 日志管理器
    • 副本管理器

    我们将会逐个进行讲解,讲解过长还将保持前面章节的特点,多用有形的图表帮助读者理解。本篇博客先讲解控制器部分。

    1、控制器

    在前一章的学习中,我们已经知道Kafka的集群由n个的broker所组成,每个broker就是一个kafka的实例或者称之为kafka的服务。其实控制器也是一个broker,控制器也叫leader broker。他除了具有一般broker的功能外,还负责分区leader的选取,也就是负责选举partition的leader replica。控制器是kafka核心中的核心,需要重点学习和理解。

    控制器选举

    kafka每个broker启动的时候,都会实例化一个KafkaController,并将broker的id注册到zookeeper,这在第二章中已经通过例子做过讲解。集群在启动过程中,通过选举机制选举出其中一个broker作为leader,也就是前面所说的控制器。

    包括集群启动在内,有三种情况触发控制器选举:

    1、集群启动

    2、控制器所在代理发生故障

    3、zookeeper心跳感知,控制器与自己的session过期

    按照惯例,先看图。我们根据下图来讲解集群启动时,控制器选举过程。

    9012da9240348ede1ff1fd8b6bf0f08d.png

    假设此集群有三个broker,同时启动。

    (一)3个broker从zookeeper获取/controller临时节点信息。/controller存储的是选举出来的leader信息。此举是为了确认是否已经存在leader。

    (二)如果还没有选举出leader,那么此节点是不存在的,返回-1。如果返回的不是-1,而是leader的json数据,那么说明已经有leader存在,选举结束。

    (三)三个broker发现返回-1,了解到目前没有leader,于是均会触发向临时节点/controller写入自己的信息。最先写入的就会成为leader。

    (四)假设broker 0的速度最快,他先写入了/controller节点,那么他就成为了leader。而broker1、broker2很不幸,因为晚了一步,他们在写/controller的过程中会抛出ZkNodeExistsException,也就是zk告诉他们,此节点已经存在了。

    经过以上四步,broker 0成功写入/controller节点,其它broker写入失败了,所以broker 0成功当选leader。

    此外zk中还有controller_epoch节点,存储了leader的变更次数,初始值为0,以后leader每变一次,该值+1。所有向控制器发起的请求,都会携带此值。如果控制器和自己内存中比较,请求值小,说明kafka集群已经发生了新的选举,此请求过期,此请求无效。如果请求值大于控制器内存的值,说明已经有新的控制器当选了,自己已经退位,请求无效。kafka通过controller_epoch保证集群控制器的唯一性及操作的一致性。

    由此可见,Kafka控制器选举就是看谁先争抢到/controller节点写入自身信息。

    控制器初始化

    控制器的初始化,其实是初始化控制器所用到的组件及监听器,准备元数据。

    前面提到过每个broker都会实例化并启动一个KafkaController。KafkaController和他的组件关系,以及各个组件的介绍如下图:

    573c891d1cc56fdd8712c8d609e5fdca.png

    图中箭头为组件层级关系,组件下面还会再初始化其他组件。可见控制器内部还是有些复杂的,主要有以下组件:

    1、ControllerContext,此对象存储了控制器工作需要的所有上下文信息,包括存活的代理、所有主题及分区分配方案、每个分区的AR、leader、ISR等信息。

    2、一系列的listener,通过对zookeeper的监听,触发相应的操作,黄色的框的均为listener

    3、分区和副本状态机,管理分区和副本。

    4、当前代理选举器ZookeeperLeaderElector,此选举器有上位和退位的相关回调方法。

    5、分区leader选举器,PartitionLeaderSelector

    6、主题删除管理器,TopicDeletetionManager

    7、leader向broker批量通信的ControllerBrokerRequestBatch。缓存状态机处理后产生的request,然后统一发送出去。

    8、控制器平衡操作的KafkaScheduler,仅在broker作为leader时有效。

    图片是我根据资料所总结,个人认为对于理解kafkaController的全貌很有帮助。本章节后面讲到相应组件和流程时,还需要反复回来理解此图,思考组件所处的位置,对整体的作用。

    故障转移

    故障转移其实就是leader所在broker发生故障,leader转移为其他的broker。转移的过程就是重新选举leader的过程。

    重新选举leader后,需要为该broker注册相应权限,调用的是ZookeeperLeaderElector的onControllerFailover()方法。在这个方法中初始化和启动了一系列的组件来完成leader的各种操作。具体如下,其实和控制器初始化有很大的相似度。

    1、注册分区管理的相关监听器

    监听名称监听zookeeper节点作用PartitionsReassignedListener/admin/reassign_partitions节点变化将会引发分区重分配IsrChangeNotificationListener/isr_change_notification处理分区的ISR发生变化引发的操作PreferredReplicaElectionListener/admin/preferred_replica_election将优先副本选举为leader副本

    2、注册主题管理的相关监听

    监听名称监听zookeeper节点作用TopicChangeListener/brokers/topics监听主题发生变化时进行相应操作DeleteTopicsListener/admin/delete_topics完成服务器端删除主题的相应操作。否则客户端删除主题仅仅是表示删除

    3、注册代理变化监听器

    监听名称监听zookeeper节点作用BrokerChangeListener/brokers/ids代理发生增减的时候进行相应的处理

    4、重新初始化ControllerContext,

    5、启动控制器和其他代理之间通信的ControllerChannelManager

    6、创建用于删除主题的TopicDeletionManager对象,并启动。

    7、启动分区状态机和副本状态机

    8、轮询每个主题,添加监听分区变化的PartitionModificationsListener

    9、如果设置了分区平衡定时操作,那么创建分区平衡的定时任务,默认300秒检查并执行。

    除了这些组件的启动外,onControllerFailover方法中还做了如下操作:

    1、/controller_epoch值+1,并且更新到ControllerContext

    2、检查是否出发分区重分配,并做相关操作

    3、检查需要将优先副本选为leader,并做相关操作

    4、向kafka集群所有代理发送更新元数据的请求。

    下面来看代理下线的方法onControllerResignation

    1、该方法中注销了控制器的权限。取消在zookeeper中对于分区、副本感知的相应监听器的监听。

    2、关闭启动的各个组件

    3、最后把ControllerContext中记录控制器版本的数值清零,并设置当前broker为RunnignAsBroker,变为普通的broker。

    通过对控制器启动过程的学习,我们应该已经对kafka工作的原理有了了解,核心是监听zookeeper的相关节点,节点变化时触发相应的操作。其它的处理流程都是相类似的。本篇教程接下来做简要介绍,想要了解详情的,可以先找其它资料。我后续也会再补充更为详细的教程。

    代理上下线

    有新的broker加入集群时,称为代理上线。反之,当broker关闭,推出集群时,称为代理下线。

    代理上线:

    1、新代理启动时向/brokers/ids写数据

    2、BrokerChangeListener监听到变化。对新上线节点调用controllerChannelManager.addBroker(),完成新上线代理网络层初始化

    3、调用KafkaController.onBrokerStartup()处理

    3.1通过向所有代理发送UpdateMetadataRequest,告诉所有代理有新代理加入

    3.2根据分配给新上线节点的副本集合,对副本状态做变迁。对分区也进行处理。

    3.3触发一次leader选举,确认新加入的是否为分区leader

    3.4轮询分配给新broker的副本,调用KafkaController.onPartitionReassignment(),执行分区副本分配

    3.5恢复因新代理上线暂停的删除主题操作线程

    代理下线:

    1、查找下线节点集合

    2、轮询下线节点,调用controllerChannelManager.removeBroker(),关闭每个下线节点网络连接。清空下线节点消息队列,关闭下线节点request请求

    3、轮询下线节点,调用KafkaController.onBrokerFailure处理

    3.1处理leader副本在下线节点上上的分区,重新选出leader副本,发送updateMetadataRequest请求。

    3.2处理下线节点上的副本集合,做下线处理,从ISR集合中删除,不再同步,发送updateMetadataRequest请求。

    4、向集群全部存活代理发送updateMetadataRequest请求

    主题管理

    通过分区状态机及副本状态机来进行主题管理

    1、创建主题

    /brokers/topics下创建主题对应子节点

    TopicChangeListener监听此节点

    变化时获取重入锁ReentrantLock,调用handleChildChange方法进行处理。

    通过对比zookeeper中/brokers/topics存储的主题集合及控制器的ControllerContext中缓存的主题集合的差集,得到新增的主题。反过来求差集,得到删除的主题。

    接下来遍历新增的主题集合,进行主题操作的实质性操作。之前仅仅是在zookeeper中添加了主题。新增主题涉及的操作有分区、副本状态的转化、分区leader的分配、分区存储日志的创建等。

    2、删除主题

    /admin/delete_topics创建删除主题的子节点

    DeleteTopicsListener监听此节点,

    变化时获取重入锁ReentrantLock,进行处理

    具体的删除逻辑再次就不再详述。

    分区管理

    1、分区自动平衡

    onControllerFailover方法中启动分区自动平衡任务。定时检查是否失去平衡。

    自动平衡的操作就是把优先副本选为分区leader,AR中第一个副本为优先副本。

    先查出所有可用副本,以分区AR头节点分组。

    轮询代理节点,判断分区不平衡率是否超过10%(leader为非优先副本的分区/该代理分区总数),则调用onPreferredReplicaElection(),让优先副本成为leader。达到自动平衡。

    分区平衡操作的流程已经在第三章做了很详细的讲解,此处不再重复,可以参考kafka核心概念。

    2、分区重分配

    当zk节点/admin/reassign_partitions变化时,触发分区重分配操作。该节点存储分区重分配的方案。

    通过计算主题分区原AR(OAR)和重新分配后的AR(RAR),分别做相应处理:

    1、OAR+RAR:更新到该主题分区AR,并通知副本节点同步。leader_epoch+1

    2、RAR-OAR:副本设为NewReplica。

    3、(OAR+RAR)- RAR:需要下线的副本,做下线操作

    具体流程不再详述

    小结:关于控制器的相关知识点就先讲到这里,控制器初始化中的那张图需要充分去理解,理解了此图,对控制器内部的构造,以及控制器要做什么事情、如何做的,就已经掌握了。

    你真的不关注一下嘛~

    ed9e93ad47dbc7c13251b788ea356ce4.png
    展开全文
  • 权限控制说到权限控制,有人不明白为什么要单独设计权限模块,难道不能直接在代码里面直接写死一些权限的控制吗?是的,确实可以,但是如果你需要更换权限的时候不改动代码的话,那你就需要好好设计一下权限这模块...

    权限控制

    说到权限控制,有人不明白为什么要单独设计权限模块,难道不能直接在代码里面直接写死一些权限的控制吗?

    是的,确实可以,但是如果你需要更换权限的时候不改动代码的话,那你就需要好好设计一下权限这个模块。

    权限控制的三要素:用户-用户组-节点,正是这3者之间扯不清的关系,形成了权限控制的复杂性。(注:节点:用户的任何的一个操作都被称为节点)

    RBAC权限控制

    很多人在做权限控制的时候习惯性的去使用RBAC这种方式:用户对应用户组,用户组对应节点,用户组拥有的权限即这个用户所有的权限。

    这种方式有个比较明显的缺点:

    颗粒太粗:权限控制只能到分组,当管理员组下面有100个用户,这100个用户需要根据每个用户的积分值情况再分配不同的权限,那这个就很难实现。

    RBAC的这种缺陷,我们的auth权限控制可以弥补!

    AUTH权限控制的优势

    粒度很细:能在分组下再根据用户的一些属性进行权限的分配。

    先来看看RBAC的表设计

    用户表:

    用户名称 积分

    小明 188

    小红 233

    小花 92

    用户组表:

    用户组名称

    一级管理员组

    二级管理员组

    三级管理员组

    超级管理员组

    节点表:

    节点说明 节点名称

    抽奖 activity/chou

    抢红包 activity/qiang

    砸金蛋 activity/za

    用户组与节点关系表:

    用户组 权限

    管理员组 抽奖,抢红包,砸金蛋

    用户与用户组关系表:

    用户 用户组

    小明 管理员组

    RBAC的权限判断也很简单:

    (1)根据用户得到用户组

    (2)根据用户组得到节点

    (3)判断需要验证的节点是否在用户所拥有的节点列表中,在就有权限,不在就没有权限

    再来看看AUTH的表设计

    用户表:

    用户名称 积分

    小明 188

    小红 233

    小花 92

    用户组表:

    用户组名称

    一级管理员组

    二级管理员组

    三级管理员组

    超级管理员组

    节点表:

    节点说明 节点名称 附加规则

    抽奖 activity/chou {score}>1 &&{score}<100

    抢红包 activity/qiang {score}>100 &&{score}<200

    砸金蛋 activity/za {score}>200 &&{score}<300

    用户组与节点关系表:

    用户组 权限

    管理员组 抽奖,抢红包,砸金蛋

    用户与用户组关系表:

    用户 用户组

    小明 管理员组

    光看上面的表设计,其实我们可出看出两者的区别:

    在节点表的设计中,auth比rbac多了一个附加规则的字段。

    多了一个字段也就多了一个判断,AUTH权限判断步骤如下:

    (1)根据用户得到用户组

    (2)根据用户组得到节点

    (3)判断需要验证的节点是否在用户所拥有的节点列表中,在的话进行步骤4的判断,不在的话直接提示没有权限

    (4)如果有附件条件,再判断下用户的属性是否符合附加条件,符合才返回符合权限,否则返回没有权限。

    关于condition条件的判断代码实现的逻辑

    前面我们看到节点表里面,多加了一个condition字段,这个字段的写法是{score}>100 &&{score}<200,我们在权限判断的时候,先用正则替换的方式将这句话变成$user['score']>100&&$user['score']<200,然后用eval函数执行这段话,然后记录这个语句的返回值true/false来作为判断是否有权限的依据。

    AUTH权限控制存在的不足

    由于AUTH权限的节点表设计的时候多加了一个condition字段,对节点进行验证的时候,比如有一个节点是审核操作,condition是score>100,如果需求是用户是初级管理员组必须score>100才能进行审核操作,而高级管理员组却可以直接进行审核操作,那么对于这种权限控制,auth也无法控制,因为多个组共享了一个节点的condition。

    关于权限控制,如果大家有好的操作方式,一起探讨。

    展开全文
  • 为什么控制前台的标签按钮. 我们知道按钮的标签文字都是一个名字,但是这个名字不一定适合用户的要求。 比如在请假流程有三个点,发起流程,部门经理审批,人事备案。 1, 在开始节点的 [发送] 按钮名词就比较...

    为什么要控制前台的标签按钮.

    我们知道按钮的标签文字都是一个名字,但是这个名字不一定适合用户的要求。

    比如在请假流程有三个点,发起流程,部门经理审批,人事备案。

    1, 在开始节点的 [发送] 按钮名词就比较专业化,如果修改成[发起请假流程]就比较贴切。
    2, 在第二个节点 [退回] 如果修改成[退回给发起人] 就比较让人容易看懂。
    3, 在人事备案节点上,如果不需要[退回]按钮,可以禁用它。


    设置方法: 打开流程设计器 -> 打开流程 -> 节点属性 中设置.

     

    展开全文
  • 一、为什么需要 k8s? 应用部署模式的演进 虚拟化模式 容器化模式 相比虚拟机和容器 容器更加轻量级,启动更快(秒级) 容器可移植性更好 2. 管理大量的容器带来了新的挑战 容器编排调度引擎 —— k8s 的好处 简化...

    一、为什么需要 k8s?

    1. 应用部署模式的演进
      虚拟化模式

    容器化模式

    相比虚拟机和容器

    容器更加轻量级,启动更快(秒级)
    容器可移植性更好
    2. 管理大量的容器带来了新的挑战
    容器编排调度引擎 —— k8s 的好处

    简化应用部署
    提高硬件资源利用率
    健康检查和自修复
    自动扩容缩容
    服务发现和负载均衡
    二、k8s 的集群架构
    主节点,承载 k8s 的控制和管理整个集群系统的控制面板
    工作节点,运行用户实际的应用

    k8s 集群组件
    三、pod —— k8s 调度的最小单元

    1. 一个 pod 包含一组容器,一个 pod 不会跨越多个工作节点
      pod 不会跨越工作节点
    2. 了解 pod
      pod 相当与逻辑主机,每个 pod 都有自己的 IP 地址
      pod 内的容器共享相同的 IP 和端口空间
      默认情况下,每个容器的文件系统与其他容器完全隔离
    展开全文
  • 什么是VLAN

    2013-10-23 09:59:12
     VLAN除了能将网络划分广播域,从而有效地控制广播风暴的发生,以及使网络的拓扑结构变得非常灵活的优点外,还可以用于控制网络中不同部门、不同站点之间的互相访问。  VLAN是解决以太网的广播问题和安全...
  • 需求应该已经满足了啊,但是量变引起质变,当服务数量增加后,我们就需要对服务进行管理,我们需要知道服务现在的情况和一些信息,以及流量控制。 这时候我们就需要中服务之前加一类似于前台一样的注册中心。 ...
  • 你必须知道的495C语言问题

    千次下载 热门讨论 2015-05-08 11:09:25
    1.24 我在一文件中定义了一extern数组,然后在另一文件中使用,为什么sizeof取不到数组的大小? 声明问题 1.25 函数只定义了一次,调用了一次,但编译器提示非法重声明了。 *1.26 main的正确定义是什么...
  • 我们可以给每文本节点外加上一 class <code>highlight</code> 的 <code><span></code> 元素;而背景样式则通过 CSS <code>.highlight</code> 选择器设置。 <pre><code>JavaScript // 使用上一步...
  • 《你必须知道的495C语言问题》

    热门讨论 2010-03-20 16:41:18
    1.24 我在一文件中定义了一extern数组,然后在另一文件中使用,为什么sizeof取不到数组的大小? 13 声明问题 14 1.25 函数只定义了一次,调用了一次,但编译器提示非法重声明了。 14 *1.26 main的正确...
  • 1.24 我在一文件中定义了一extern数组,然后在另一文件中使用,为什么sizeof取不到数组的大小? 13 声明问题 14 1.25 函数只定义了一次,调用了一次,但编译器提示非法重声明了。 14 *1.26 main的正确...
  • 1.24 我在一文件中定义了一extern数组,然后在另一文件中使用,为什么sizeof取不到数组的大小? 42 声明问题 43 1.25 函数只定义了一次,调用了一次,但编译器提示非法重声明了。 43 *1.26 main的正确定义...
  • 1.24 我在一文件中定义了一extern数组,然后在另一文件中使用,为什么sizeof取不到数组的大小? 42 声明问题 43 1.25 函数只定义了一次,调用了一次,但编译器提示非法重声明了。 43 *1.26 main的正确定义...
  • 1.24 我在一文件中定义了一extern数组,然后在另一文件中使用,为什么sizeof取不到数组的大小?  声明问题  1.25 函数只定义了一次,调用了一次,但编译器提示非法重声明了。  *1.26 main的正确定义是...
  •  1.24 我在一文件中定义了一extern数组,然后在另一文件中使用,为什么sizeof取不到数组的大小? 声明问题 1.25 函数只定义了一次,调用了一次,但编译器提示非法重声明了。 *1.26 main的正确定义是...
  • 为什么要集群文件系统,在什么场景中适用我就用一句话来概括,当多个节点需要读写同一文件系统时,需要使用集群文件系统,它可以将文件系统持有的锁信息传递到各个节点。实验一、将iSCSI共享出来的磁盘,做成gfs2...
  • 入门学习Linux常用必会60命令实例详解doc/txt

    千次下载 热门讨论 2011-06-09 00:08:45
    -F:这命令通常和-a一起使用,它会每一mount的动作产生一行程负责执行。在系统需要挂上大量NFS文件系统时可以加快加载的速度。 -f:通常用于除错。它会使mount不执行实际挂上的动作,而是模拟整个挂上的...
  • // 设置一div 宽度 两点之间的距离,并且以 transform-origin: 0 50% 圆心旋转,角度已经算出来 let lineHtmlStr = `;border-top:1px solid red;width:${lineLength}px;top:${firstPoint.yPoint}px;left:${...
  • 文章目录1 Cluster 模式与主从模式的区别2 Cluster 模式下节点数据的划分3 Cluster 模式至少需要三个节点4 Cluster 模式集群高可用5 Cluster 模式下单 key 的操作5.1 简单客户端 redis-cli 下操作5.1.1 为什么是 ...
  • 为什么还要使用第方的工作流框架? 我们自己来编写,通过代码来实现业务流程的跳转, 一旦业务流程发生变化,我们将需要通过修改代码来实现 那么工作流框架可以达到什么效果? 1,画好流程图 2,让工作流引擎...
  • 在css中,每元素节点都可以看作是一盒子,或者一张卡片。在css中,元素并非本身就是层叠元素,如果需要元素层叠,需要用特定的属性来告诉浏览器,把该元素渲染成层叠样式。 创建层叠样式 position值absolute...

空空如也

空空如也

1 2 3 4 5 ... 12
收藏数 228
精华内容 91
关键字:

为什么控制节点需要三个