Kafka 事务性之幂等性实现

Apache Kafka 从 0.11.0 开始,支持了一个非常大的 feature,就是对事务性的支持,在 Kafka 中关于事务性,是有三种层面上的含义:一是幂等性的支持;二是事务性的支持;三是 Kafka Streams 的 exactly once 的实现,关于 Kafka 事务性系列的文章我们只重点关注前两种层面上的事务性,与 Kafka Streams 相关的内容暂时不做讨论。社区从开始讨论事务性,前后持续近半年时间,相关的设计文档有六十几页(参考 Exactly Once Delivery and Transactional Messaging in Kafka)。事务性这部分的实现也是非常复杂的,之前 Producer 端的代码实现其实是非常简单的,增加事务性的逻辑之后,这部分代码复杂度提高了很多,本篇及后面几篇关于事务性的文章会以 2.0.0 版的代码实现为例,对这部分做了一下分析,计划分为五篇文章:

阅读更多

BookKeeper 集群搭建及使用

随着 Apache Pulsar 成为 Apache 的顶级开源项目,其存储层的解决方案 Apache BookKeeper 再次受到业界广泛关注。BookKeeper 在 Pulsar 之前也有很多成功的应用,比如使用 BookKeeper 实现了 HDFS NameNode 的 HA 机制(可能大部分公司使用的还是 Quorum Journal Manage 方案)、Twitter 开源的 DistributedLog 系统(可参考Twitter开源分布式高性能日志复制服务),BookKeeper 作为一个高扩展、强容错、低延迟的存储服务(A scalable, fault-tolerant, and low-latency storage service optimized for real-time workloads),它相当于把底层的存储层系统服务化(BookKeeper 是更底层的存储服务,类似于 Kafka 的存储层)。这样可以使得依赖于 BookKeeper 实现的分布式存储系统(包括分布式消息队列)在设计时可以只关注其应用层和功能层的内容,存储层比较难解决的问题像一致性、容错等,BookKeeper 已经实现了,从这个层面看,BookKeeper 确实解决业内的一些问题,而且 BookKeeper (Ledger 化,Ledger 相当于 Kafka segment)天生适合云上部署,未来还是有很大潜力的。近段对 BookKeeper 做了一些相应的调研,做了一些总结,本文将会主要从集群部署和使用角度来介绍一下 Apache BookKeeper,后面准备再写一篇文章来深入讲述其架构设计及实现原理。

阅读更多

YARN 架构学习总结

关于 Hadoop 的介绍,这里就不再多说,可以简答来说 Hadoop 的出现真正让更多的互联网公司开始有能力解决大数据场景下的问题,其中的 HDFS 和 YARN 已经成为大数据场景下存储和资源调度的统一解决方案(MR 现在正在被 Spark 所取代,Spark 在计算这块的地位也开始受到其他框架的冲击,流计算上有 Flink,AI 上有 Tensorflow,两面夹击,但是 Spark 的生态建设得很好,其他框架想要在生产环境立马取代还有很长的路要走)。本篇文章就是关于 YARN 框架学习的简单总结,目的是希望自己能对分布式调度这块有更深入的了解,当然也希望也这篇文章能够对初学者有所帮助,文章的主要内容来自 《Hadoop 技术内幕:深入解析 YARN 架构设计与实现原理》《大数据日知录:架构与算法》

阅读更多

如何学习开源项目

本篇文章的方法论内容基本来自订阅的极客时间-李运华老师的《从0开始学架构》中的一篇文章,会结合自己的学习经验、加上以 Flink 为例来做一个总结,也为了让自己再学习其他开源项目时能够按照这样的一个方法论高效的深入学习。先简单说一下开源项目,开源项目最早从上个世纪开始,我知道最早的是 linux 项目(其他的不是很了解),再到近几年大数据领域,发展非常迅速,开源给本公司带来的好处,首先是提高这家在技术界的影响力,然后如果这个项目比较受大家认可,那么这家公司的这个技术可能会成为业界的统一解决方案,就像 Hadoop、Kafka 等。对其他公司的好处是,节省成本、可以快速应用来解决业务中的问题。

阅读更多

JVM 之 ParNew 和 CMS 日志分析

在两年前的文章 JVM 学习——垃圾收集器与内存分配策略 中,已经对 GC 算法的原理以及常用的垃圾收集器做了相应的总结。今天这篇文章主要是对生产环境中(Java7)常用的两种垃圾收集器(ParNew:年轻代,CMS:老年代)从日志信息上进行分析,做一下总结,这样当我们在排查相应的问题时,看到 GC 的日志信息,不会再那么陌生,能清楚地知道这些日志是什么意思,GC 线程当前处在哪个阶段,正在做什么事情等。

阅读更多

HDFS 架构学习总结

HDFS(Hadoop Distributed File System)是一个分布式文件存储系统,几乎是离线存储领域的标准解决方案(有能力自研的大厂列外),业内应用非常广泛。近段抽时间,看一下 HDFS 的架构设计,虽然研究生也学习过相关内容,但是现在基本忘得差不多了,今天抽空对这块做了一个简单的总结,也算是再温习了一下这块的内容,这样后续再看 HDFS 方面的文章时,不至于处于懵逼状态。

阅读更多

Kafka Controller Redesign 方案

Kafka Controller 是 Kafka 的核心组件,在前面的文章中,已经详细讲述过 Controller 部分的内容。在过去的几年根据大家在生产环境中应用的反馈,Controller 也积累了一些比较大的问题,而针对这些问题的修复,代码的改动量都是非常大的,无疑是一次重构,因此,社区准备在新版的系统里对 Controller 做一些相应的优化(0.11.0及以后的版本),相应的设计方案见:Kafka Controller Redesign,本文的内容就是结合这篇文章做一个简单的总结。

阅读更多

分布式系统的一致性协议之 2PC 和 3PC

在分布式系统领域,有一个理论,对于分布式系统的设计影响非常大,那就是 CAP 理论,即对于一个分布式系统而言,它是无法同时满足 Consistency(强一致性)、Availability(可用性) 和 Partition tolerance(分区容忍性) 这三个条件的,最多只能满足其中两个。但在实际中,由于网络环境是不可信的,所以分区容忍性几乎是必不可选的,设计者基本就是在一致性和可用性之间做选择,当然大部分情况下,大家都会选择牺牲一部分的一致性来保证可用性(可用性较差的系统非常影响用户体验的,但是对另一些场景,比如支付场景,强一致性是必须要满足)。但是分布式系统又无法彻底放弃一致性(Consistency),如果真的放弃一致性,那么就说明这个系统中的数据根本不可信,数据也就没有意义,那么这个系统也就没有任何价值可言。

阅读更多

Java 守护线程

在 Java 并发编程实践或看涉及到 Java 并发相关的代码时,经常会遇到一些线程(比如做 metrics 统计的线程等)会通过 setDaemon() 方法设置将该线程的 daemon 变量设置为 True,也就是将这个线程设置为了守护线程(daemon thread),那么什么是守护线程呢?或者说守护线程与非守护线程(普通线程)的区别在什么地方呢?这个就是本文主要讲述的内容。

阅读更多

Kafka 源码解析之 Server 1+N+M 网络处理模型(二十三)

前面7篇对 Kafka Controller 的内容做了相应的总结,Controller 这部分的总结算是暂时告一段落,本节会讲述 Kafka 源码分析系列中最后一节的内容,是关于 Server 端对不同类型请求处理的网络模型。在前面的文章中也讲述过几种不同类型的请求处理实现,如果还有印象,就会知道它们都是通过 KafkaApis 对象处理的,但是前面并没有详细讲述 Server 端是如何监听到相应的请求、请求是如何交给 KafkaApis 对象进行处理,以及处理后是如何返回给请求者(请求者可以是 client 也可以是 server),这些都属于 Server 的网络处理模型,也是本文讲述的主要内容。

阅读更多

Kafka 源码解析之 LeaderAndIsr 请求的处理(二十二)

本篇算是 Controller 部分的最后一篇,在前面讲述 ReplicaManager 时,留一个地方没有讲解,是关于 Broker 对 Controller 发送的 LeaderAndIsr 请求的处理,这个请求的处理实现会稍微复杂一些,本篇文章主要就是讲述 Kafka Server 是如何处理 LeaderAndIsr 请求的。

阅读更多

Kafka 源码解析之 Controller 发送模型(二十一)

本篇主要讲述 Controller 向各个 Broker 发送请求的模型,算是对 Controller Channel Manager 部分的一个补充,在这篇文章中,将会看到 Controller 在处理 leader 切换、ShutDown 请求时如何向 Broker 发送相应的请求。

阅读更多

Kafka 源码解析之 Topic 的新建/扩容/删除(二十)

本篇接着讲述 Controller 的功能方面的内容,在 Kafka 中,一个 Topic 的新建、扩容或者删除都是由 Controller 来操作的,本篇文章也是主要聚焦在 Topic 的操作处理上(新建、扩容、删除),实际上 Topic 的创建在 Kafka 源码解析之 topic 创建过程(三) 中已经讲述过了,本篇与前面不同的是,本篇主要是从 Controller 角度来讲述,而且是把新建、扩容、删除这三个 Topic 级别的操作放在一起做一个总结。

阅读更多

Kafka 源码解析之 Broker 上线下线(十九)

本篇接着讲述 Controller 对于监听器的处理内容 —— Broker 节点上下线的处理流程。每台 Broker 在上线时,都会与 ZK 建立一个建立一个 session,并在 /brokers/ids 下注册一个节点,节点名字就是 broker id,这个节点是临时节点,该节点内部会有这个 Broker 的详细节点信息。Controller 会监听 /brokers/ids 这个路径下的所有子节点,如果有新的节点出现,那么就代表有新的 Broker 上线,如果有节点消失,就代表有 broker 下线,Controller 会进行相应的处理,Kafka 就是利用 ZK 的这种 watch 机制及临时节点的特性来完成集群 Broker 的上下线,本文将会深入讲解这一过程。

阅读更多

Kafka 源码解析之 Partition 副本迁移实现(十八)

前面两篇关于 Controller 的内容分别讲述了 Controller 选举和启动,以及副本状态机和分区状态机的内容,从本文开始会详细讲述 Controller 的一些其他功能,主要是 Controller 的对不同类型监听器的处理,这部分预计分三篇左右的文章讲述。Controller 在初始化时,会利用 ZK 的 watch 机制注册很多不同类型的监听器,当监听的事件被触发时,Controller 就会触发相应的操作。

阅读更多

Kafka 源码解析之副本状态机与分区状态机(十七)

上篇讲述了 KafkaController 的启动流程,但是关于分区状态机和副本状态机的初始化并没有触及,分区状态机和副本状态机的内容将在本篇文章深入讲述。分区状态机记录着当前集群所有 Partition 的状态信息以及如何对 Partition 状态转移进行相应的处理;副本状态机则是记录着当前集群所有 Replica 的状态信息以及如何对 Replica 状态转变进行相应的处理。

阅读更多

Kafka 源码解析之 Controller 选举及服务启动流程(十六)

从本篇文章开始,Kafka 源码解析就正式进入了 Controller 部分,Controller 作为 Kafka Server 端一个重要的组件,它的角色类似于其他分布式系统 Master 的角色,跟其他系统不一样的是,Kafka 集群的任何一台 Broker 都可以作为 Controller,但是在一个集群中同时只会有一个 Controller 是 alive 状态。Controller 在集群中负责的事务很多,比如:集群 meta 信息的一致性保证、Partition leader 的选举、broker 上下线等都是由 Controller 来具体负责。Controller 部分的内容还是比较多的,计划分5篇左右的文章讲述,本文先来看下 Controller 的简介、Controller 的选举、Controller 选举后服务的启动流程以及 Controller 的四种不同 leader 选举机制。分区状态机、副本副本状态机以及对各种 listener 的处理将在后续的文章中展开。

阅读更多

Kafka 源码解析之 ReplicaManager 详解(十五)

前面几篇文章讲述了 LogManager 的实现、Produce 请求、Fetch 请求的处理以及副本同步机制的实现,Kafka 存储层的主要内容基本上算是讲完了(还有几个小块的内容后面会结合 Controller 再详细介绍)。本篇文章以 ReplicaManager 类为入口,通过对 ReplicaManager 的详解,顺便再把 Kafka 存储层的内容做一个简单的总结。

阅读更多

Kafka 源码解析之副本同步机制实现(十四)

在上篇文章中讲述了 Fetch 请求是如何处理的,其中包括来自副本同步的 Fetch 请求和 Consumer 的 Fetch 请求,副本同步是 Kafka 多副本机制(可靠性)实现的基础,它也是通过向 leader replica 发送 Fetch 请求来实现数据同步的。本篇文章我们就来看一下 Kafka 副本同步这块的内容,对于每个 broker 来说,它上面的 replica 对象,除了 leader 就是 follower,只要这台 broker 有 follower replica,broker 就会启动副本同步流程从 leader 同步数据,副本同步机制的实现是 Kafka Server 端非常重要的内容,在这篇文章中,主要会从以下几块来讲解:

阅读更多

Kafka 源码解析之 Server 端如何处理 Fetch 请求(十三)

上一篇讲述完 Kafka 如何处理 Produce 请求以及日志写操作之后,这篇文章开始讲述 Kafka 如何处理 Fetch 请求以及日志读操作。日志的读写操作是 Kafka 存储层最重要的内容,本文会以 Server 端处理 Fetch 请求的过程为入口,一步步深入到底层的 Log 实例部分。与 Produce 请求不一样的地方是,对于 Fetch 请求,是有两种不同的来源:consumer 和 follower,consumer 读取数据与副本同步数据都是通过向 leader 发送 Fetch 请求来实现的,在对这两种不同情况处理过程中,其底层的实现是统一的,只是实现方法的参数不同而已,在本文中会详细讲述对这两种不同情况的处理。

阅读更多