0%

Kafka的背景

kafka是一个分布式高性能高可用可水平拓展发布-订阅式消息队列,更是一个流式处理系统。
对于消息,提供了O(1)时间复杂度的持久化能力,具备高吞吐率,同时支持实时、离线数据处理。

Kafka的架构

KafkaKafka包含了:

  • Broker: Kafka运行所在的服务器。
  • Topic: Kafka生产、消费数据都是需要指定一个Topic的,相当于一个队列。
  • Partition: 一个Topic可划分多个Partition,多机部署,可定义partition路由算法。
  • Segment: 一个Partition被切分为多个Segment,每个Segment包含索引文件和数据文件。
  • Producer: 生产者只需要指定Topic,往里头写数据即可。
  • Consumer: 一个Consumer Group包含多个Consumer,一条消息只被同组中的一个消费。
  • Zookeeper: Zookeeper用来管理Kafka集群。

对于服务器来说,Broker只是一个进程。

Topic则是服务器上的目录,存放在log.dirs指定的路径下,默认是/tmp/kafka-logs,支持路径,逗号分隔,可将数据分散到多个磁盘中,使Kafka吞吐率线性提高。通过指定--partitions数值,可创建多个Partition,命名为TopicName-K,从0开始。

通过指定--replication-factor副本因子数值,可将这些Partition分散、备份在一个或多个可用的Broker中,前提是可用的Broker数要大于等于replication-factor的值,既可数据备份、又可实现高可用、分散负载,提高吞吐量。

每个Partiton目录下存储的是一段段的Segment,包含了索引文件和数据文件,以offset命名。

Kafka采用推拉结合模型

生产消息方面,采用主动推送消息模式,在客户端会累积、压缩、批量发送到Broker。

消费消息方面,采用主动拉取消息模式,由客户端轮询拉取消息,并按照策略提交offset

另外,通过消费者拉消息的方式,可以由消费者自行控制消费的频率。

kafka-ps

此种方式,有利于减轻Broker压力,不需要维护太多状态,可由客户端自定义从哪个offset开始拉取消息。

kafka-offset

内存是操作系统的核心,程序指令只有被加载到内存中才可以被CPU调度执行。

内存,是由字节队列组成,每个字或字节队列都有它自己的地址
CPU,根据程序计数器的值从内存中取指令,可能是从指定内存地址读数据或将数据存入指定内存地址。

系统总线

CPU与内存之间的数据交互通过系统总线来传输。
通常来说,程序是以二进制的形式存储在硬盘上。只有将程序加载到内存中,并构造成进程的形式,才可以被真正的使用。在进程的运行过程中,CPU从内存中获取指令和数据,并服务于进程,而在进程使用完毕,终止之后,将会释放所占用的内存资源。

CPU产生的地址称为:逻辑地址,内存单元的地址称为:物理地址。

逻辑地址,又称为:虚拟地址,程序所产生的所有逻辑地址形成了逻辑地址空间
逻辑地址空间所对应物理地址形成了物理地址空间
有一种物理硬件设备负责将逻辑地址物理地址进行映射,这种设备称为:内存管理单元MMU。
MMU内存管理的核心:将逻辑地址空间绑定到物理地址空间。

内存分配分为:连续内存分配、非连续内存分配。

连续内存分配,包含有:多分区分配方法固定分区机制

  • 多分区分配方法
    当一个区被释放时,就从输入队列中取出一个进程,将其载入空闲区中,当该进程结束运行时,该区又可以被其它进程使用。不过这种方法早年前已经被弃用了。

  • 固定分区机制
    在操作系统内部保留一个用来标识哪块内存可用,哪块内存被占用,当一个进程到达时,就在表中根据首先适应最佳适应最差适应等策略为其分配一个合适的分区。如果分区过大,那么将可以被多个进程使用,如果无法使用就浪费了。当进程终止,就释放内存分区交还给系统,继续为其它进程服务。如果分区过小,可以合并使用。

以上2种方式,都存在着碎片问题,另外,维护内存分区及移动分区的代价过高

非连续内存分配,包含有:分页机制分段机制

  • 分页机制
    分页机制是一种非连续的内存管理策略,相比连续的内存管理策略来说,不需要再为找不到一块完整的、连续的内存而苦恼。在分页机制中,不会产生外部碎片,因为允许不连续,每一块内存都会被利用,但会产生内部碎片。
    物理内存分成固定大小的块,称为:,将逻辑内存也分成固定大小的块,称为:。程序执行的时候,页就从后备存储器装入到有效物理帧中。
    CPU执行的时候,产生的地址包含:页号页偏移
    逻辑内存是连续的,根据页号页偏移计算得到物理内存具体位置。
    memmem在程序的内存视觉中,内存都是单调递增的。
    通过页号可以索引到页表页表包含了物理内存每个页基地址,也就是帧号
    基地址乘以页面大小,再加上页偏移,就得到物理内存的具体地址。
    每个物理帧都在帧表中存储着,包含:分配了哪些帧、哪些帧空闲、共有多少帧。
    如果被分配了,那么会记录分配给了哪些进程
    由于通过页表这种方式计算出物理内存地址的方式需要访问2次内存,效率较,也就产生了TLB,这是一种较小的快速查找硬件高速缓冲,只通过页号就可以迅速查找到帧号。如果没有查找到,那就通过页表去查找。
    TLB由于现在的计算机支持的逻辑空间较大,在2^32 ~ 2^64之间,基于页表这种机制,这样会导致每一个进程需要创建至少4MB物理空间给页表使用。
    通过两级分页算法页表再次分页,分为:页号页表页号偏移量
    page利用这种方式,可以有效减少物理内存的使用量,甚至还可以使用三级分页再次减少内存使用量。

  • 分段机制
    分页机制不同,分段机制采用一段一段划分的,每一段的大小可以不一样,并且可以动态伸缩。在段表中记录的是二维地址,包含:< 段号 - 偏移量 >
    通过二维地址段表中查找计算出具体的物理地址segment虽然,分段机制不是连续的,但是每一段大小不一致,可能有些段过大,暂时难以找到合适的位置,需要等待且外部碎片会比较多。另外,通过分段,可以针对某些段设置为只读、共享,可以有效的保护内存段不被修改且节约内存。

CPU,中央处理器,是计算机系统的运算和控制中心,是信息处理、程序运行的最终执行单元。

CPU

程序,最终都会变成计算机指令,然后被CPU调度执行

CPU分为:运算器、控制器、高速缓冲存储器。

运算器,包含:算术运算器逻辑运算器,是用来实现加减乘除、与或非、移位、异或等的运算器。

控制器,包含:指令寄存器程序计数器操作控制器,是用来指挥各个部件,按照计算机指令的要求协调工作的部件,是计算机的神经中枢指挥中心
指令寄存器:用来保存当前执行或者即将要执行的指令的寄存器。
程序计数器:用来指明程序下一次要执行的指令的地址。
操作控制器:根据指令操作码和时序信号,产生各自操作信号,以便正确地创建数据链路,从而完成取指令和执行指令的控制。

高速缓冲存储器,位于主存和CPU之间的一级缓存,容量小,但是速度比主存快。

有了CPU之后,那么就需要利用调度算法去让CPU调度程序了。

CPU调度是多道程序操作系统的基础,通过在进程间转换CPU,操作系统可以提高计算机的生产力。

为了极尽CPU所能,操作系统不会让CPU闲着,一旦就绪队列中有新的进程,将被CPU调度,然后移交CPU使用权执行,而CPU如何从就绪队列中获取要执行的进程任务,就依赖于调度算法

CPU也不是随便就能调度的,需要等待时机

  • 当进程从运行状态转换为等待状态。
  • 当进程从运行状态转换为就绪状态。
  • 当进程从等待状态转换为就绪状态。
  • 当进程终止的时候。

衡量CPU调度算法也是有指标的。

  • CPU利用率
  • 吞吐量
  • 周转时间
  • 等待时间
  • 响应时间

理想的情况是,CPU利用率、吞吐量最大化,周转时间、等待时间、响应时间最小化

cpu-mark

围绕以上指标,产生了一些CPU调度算法

CPU调度,决定了哪个进程会被从就绪队列中拿出来,并被分配CPU资源。

CPU就绪队列作为一个队列,可以通过FIFO优先级无序来实现。

调度算法分为:

  • 先来先服务算法
    按照进入队列的顺序,一个一个调度。
  • 短作业优先算法
    本质上也是优先调度算法,根据CPU Burst排序。
  • 优先调度算法
    为每一进程配置优先级,根据优先级排序。
  • 轮转调度算法
    分配时间片,循环调度队列中的进程。
  • 多级队列调度算法
    将反馈队列分为多个队列,采用不同调度算法。
  • 多级队列反馈调度算法
    根据CPU Burst调整进程应该所处带有不同优先级的队列。