走进Kafka系列3 创建topic流程
走进Kafka系列3 创建topic流程
上篇文章描述了集群选举的一些概念,本章开始已创建topic为例,讲述一下元数据变更在不同集群间的同步过程。
1 前言是真的没有想到创建一个topic流程居然如此复杂,涉及到了Kafka的很多核心概念,所以理解起来会比较吃力一点。
2 创建topic流程在Kafka中,创建topic总体过程如下(一如既往一图流)
当client端执行创建命令后
./bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic kraft1 --partitions 2 -replication-factor 2
集群leader会根据创建命令,预生成对应的topic和partition的records,随后对records生成event事件投递到队列中开始等待执行。
当event开始执行时,首先会写入到本地的元数据中(也就是之前提到的__cluster_metadata队列),从这里开始就可以分成两部分讲解了。
leader写入元数据后,随后会将topic和pa ...
走进Kafka系列2 集群选举
走进Kafka系列2 集群选举
上一篇讲的是consumer group的共识,其实顺序有点颠倒了,应该先讲集群共识的。但是因为时间关系,个人对于consumer group更熟悉一点,所以集群的选举就放到第二篇了。对于共识选举的学习建议大家从切面的角度看待,其实像ZK、Kafka、ES的选举都是有共通之处的。
1 Kraft选举实现在Kafka3.0中的新特性就是有了Kraft模式来替代之前Zookeeper的依赖(其实从2.8开始就已经支持了)。
Zookeeper可以理解为一个分布式的KV系统,具有很高的一致性,所以普遍被用来储存元数据使用。
但因ZK自身缺陷,所以Kafka选择使用了自己内部的topic来储存元数据,在这基础上就是Kraft模式(使用了raft协议的思想)
1.1 Kraft相关基础概念一般来说,中心化的分布式系统都需要进行集群选举来产生Leader,Leader主要作用是为了更容易控制整个集群状态的一致性。在Kraft中,把集群的元数据信息都储存到了Kafka自身的topic (__cluster_metadata) 中来摆脱对ZK的依赖 ...
走进Kafka系列1 consumer group
走进Kafka系列1 consumer group
本篇文章基于Kafka3.0,为Kafka系列的开篇之作,接下来的一段时间内,会着重投入研究Kafka。本期讲解的是consumer group概念,可以算是Kafka中比较重要的一个部分。
1 Kafka基础概念最基础的概念,因为本篇重点是consumer group,至于其他内容的详尽介绍在之后的文章中会提及。
一个Kafka集群中有若干的broker(基础组成单位),而producer和consumer则是使用了Kafka协议的外部调用者。
Kafka为了维护consumer 与 集群之间的关系,抽象出了一个consumer group的概念(这在MQ中是个非常非常棒的概念,他可以使得开发者可以自由控制广播还是单播) 因为consumer group是个组的概念,所以在其内部也有选举、同步、故障恢复等一系列的措施存在,这也同样提供给了消费者开箱即用的高可用能力。所以下面来具体看下consumer group的实现原理
2 consumer加入group流程当一个新的consumer要连接集群时,首先会向集群 ...
实时数据报表需求技术设计
实时数据报表需求技术设计
目前普通的T + 1报表已经无法满足很多商家和用户的实际需求了,如果自身的产品上能实现实时数据报表将会是自身产品的一大优势,本文注重讲解实时数据报表的技术实现。
1 背景随着技术的不断发展,用户或者商家对于实时数据报表的需求日益提升,但是对于绝大多数的实现方案来讲,依然是传统的离线报表方案,如何高效、低成本的实现实时数据报表无疑是一次强有力的个人能力展示。
要达到的目标:三年累积1E数据,平均日增十万(写QPS峰值满足1000)情况下,实时聚合查询QPS至少达到200
2 简单实时数据报表什么是简单的实时报表,以下举个例子
可以简单认为就是没有搜索条件的报表,没有搜索条件意味着用户永远只能看到全部的汇总数据。
这种需求就算要求实时,做起来也是很简单的,可以参考以下标准流程
总体思路就是冷热分离思想,通过离线任务将99%的数据聚合,来减少数据的储存量。
而实时且变动快的数据(一般来讲为当天数据),通过 Kafka -> Flink 处理后输出到Redis中给业务应用进行读取(因为Redis本身的读写能力足以满足我们的目标)。当然 ...
zookeeper如何保证数据一致性
zookeeper如何保证数据一致性
虽说zk是比较老的框架了,但是其一致性的保证放在今天的中间件中依然是很强力的存在。其数据持久化的流程也是非常标准的流程,兼具了性能和一致性的取舍,非常值得我们学习。
1 zk数据同步简述重要知识点:首先ZK的数据分为两部分,磁盘数据和内存数据
磁盘数据:存储在物理介质上的数据(持久化数据),可能与内存数据不一致。
内存数据:zk在启动时,会从磁盘上加载数据到内存中,加载数据完成、选举完成、数据同步完成才能对外提供服务,运行期间内,客户端访问的数据都是内存中数据,不会访问磁盘数据。
ZK总体上来说,使用事务日志持久化的方式来保障被提交的数据不会丢失(也是很多数据库常用的操作),再通过内存数据与磁盘数据隔离的形式,来避免分布式环境下各种数据丢失、错乱的问题产生。
zk数据写入简要流程
结合zk的数据存储以及上述数据写入流程可知,只有当数据被半数以上的zk节点持久化后,ZK的Leader节点才会把该次事务在内存中生效(内存生效才能被客户端访问)。
因为过半数的节点ACK数据就会写到内存中,所以会存在提交过程中,节点1能读到最新 ...
会员体系设计
会员体系设计
又到了年终回顾总结的时候,突然发现自己个人博客上没有关于业务知识的分享,全是技术篇。这给了我很大的启示,因为我自己长期都在做业务,大大小小、不同领域的业务做过很多了,感觉可以把自己对业务设计上的感悟分享一下(又有了灌水的好方法)。
1 应用架构对于我们做业务的后端同学来讲,虽然一些领域设计、架构设计很高大上,但是在实际的业务开发中所应用到的非常小,所带来的作用也是一个长期作用,在互联网行业的快速发展下优势不明显。而最重要的其实就是一个应用的结构划分还比较实在一点,更具体的说应用划分其实也是为了减轻一部分的管理成本。
在整个会员业务的迭代中,踩了很多很多的坑,最终慢慢形成了以下的用户会员域-应用划分结构,希望可以给大家带来一点帮助。
我个人认为,应用划分应该追求的是业务单向流转,所以我的基本设计理念就是DAG(有向无环图)。
同时为了能够使应用的划分更为清晰,职责更为明确,将所有的业务应用抽象为了三类应用,
业务应用
业务应用位于各个业务线的最上层应用,可以理解为整个业务的对外入口。
能力应用
部分参考了中台的设计理念,将部分复杂、难度高、聚合度高的业务 ...
缓存进阶使用指南
缓存进阶使用指南
在目前大多数系统中,数据库还无法很好的支持横向扩展,所以在高流量下,都要依靠缓存来抗住高并发的访问请求,因此缓存就成为了一个至关重要的组件,对于开发人员来讲,如何正确使用缓存也变得至关重要。
1 缓存的选型目前在我们项目开发过程中,缓存(这里特指redis)的使用场景主要有以下三种
单纯做缓存
处理业务逻辑,例如利用其高性能读写,实时累加用户停留时长、保存用户最近浏览数据
分布式锁
以上三种场景所要求的中间件能力其实是有很大不同的。
纯缓存场景:需要具有超高可用(4个9)、超高性能,并不需要具有数据持久化能力。
业务处理场景:需要具有高可用、可靠存储(数据不丢失)、高性能。
分布式锁:需要具有高可用、可靠存储(数据不丢失)。
而目前不管是哪一种redis集群模式,都是明显无法同时具备以上三种场景的要求的。所以当业务发展到一定程度,有了更多的系统性能要求,往往会将缓存拆成三个组件分别用于以上三种场景。
纯缓存:可以直接使用redis-cluster,这时候也可以把redis的持久化日志功能给关闭,进一步的提升性能
业务处理场景:可靠存储的缓 ...
借助Tomcat聊一下高性能IO模型-Reactor
借助Tomcat聊一下高性能IO模型-Reactor
目前在硬件资源上,比如CPU和内存都有了很高的一个扩展,所以网络带宽以及IO成为了制约性能最重要的一个因素,了解高性能的IO模型对于开发人员来说是不可缺少的。
1 传统IO流程
可以看出在传统的IO处理过程中,首先服务端要等待客户端建立连接(一次阻塞),建立好连接后,要等待客户端的数据发送(一次阻塞),最终才能执行自身的业务处理(一次阻塞)并且向客户端返回数据。
整个过程下来一共发生了三次阻塞过程,这使得程序无法充分利用硬件资源,并且在阻塞时还会发生系统调用带来上下文的切换过程,最终导致服务端能够同时处理的Socket是有限制的。
而现在的技术演进,不管是操作系统级别的多路复用,还是程序设计上的Reactor模型,其实归根结底就是为了减少这些阻塞过程的。
2 Reactor模型如果清楚了上图中的三个阻塞过程,那么你将会对Reactor中的三个组件感到无比的清晰易懂。
Reactor:Reactor负责监听并分发来自Socket的事件(包括建立连接、可读、可 ...
G1回收器全面解析
G1回收器全面解析
最近在整理复习知识点的时候,发现对G1已经了解这么多了,趁此机会,把G1的相关设计理念给串一下
1.从阅读论文开始如果想对G1有非常深入的一个了解的话,阅读G1的论文是必不可少的,页数也只有十几页(有用的也就七八页),而且都是概念上的知识,阅读完以后再去学习细节部分,会事半功倍。
G1论文传送门
还有一本书是源码级别讲解G1的,细节非常全,但是是日本人写的。。。我也是靠翻译器看的(不过好像日语翻译支持的不是很好)
G1彻底剖析
以上两本书一本论文讲概念,一本讲G1实际的实现,如果都能研究透彻,那么你就是G1的大神人物了。
在追加一篇文章G1重要参数,里面有G1的相关参数设置,作者是oracle的垃圾回收开发者,可信度有保障(网上一些文章讲解的这些参数真的有很多误区,建议各位学习的话还是去官方途径比较好)
本篇文章需要阅读人员具备以下基础知识:
GC roots包括哪些
堆空间分代模型及分代GC(年轻代、老年代)
GC安全点和安全区域
三色标记(并发标记基础)
Card Table 和 Remembered Set
G1中的Collection Set
2.G ...
Mysql跨库数据迁移方案
Mysql跨库数据迁移方案
随着微服务的持续落地和业务量的快速发展,原先单实例单数据库的Mysql势必要进行多实例、分库分表的方向进行发展,来增加系统性能和减少彼此影响的概率。所以如何追求低停顿的数据迁移方案也成了摆在桌面上的问题。
1 停机维护不是办法的办法,但是风险基本上是最小的,并且实现起来也很容易。
对于某些使用程度不高的业务来讲,在访问低谷期进行停机数据迁移是综合成本最小的方案。
2 基于强可靠的Kafka实现跨库迁移惯用流程,上来一张图
整体方案分为以下六个阶段
标记数据迁移开始
然后将该段时间内的binlog都同步到消息队列中(我用的是Kafka)用于数据回放。
开启表数据的全量同步
全量的方案有很多,比如可以使用mysql自带的mysqldump来迁移,也可以写程序连JDBC进行查询迁移。
但是这时候,迁移的是当前数据库的快照数据,新修改的数据不用理会。
增量数据回放
由于上一步迁移的是快照数据,所以要把这一段时间内的增量数据给补齐。
补齐的方式很简单,之前的增量binlog已经都记录到Kafka中了,所以只需要放开消费者的限制,开始消费K ...