Kafka -- 压缩
压缩的目的时间换空间,用CPU时间去换磁盘空间或网络IO传输量
消息层次
消息集合(Message Set)和消息
一个消息集合中包含若干条日志项(Record Item),而日志项用于封装消息
Kafka底层的消息日志由一系列消息集合日志项组成
Kafka不会直接操作具体的消息,而是在消息集合这个层面上进行写入操作
消息格式
目前Kafka共有两大类消息格式,社区分别称之为V1版本和V2版本(在0.11.0.0引入)
V2版本主要针对V1版本的一些弊端进行了优化
优化1:把消息的公共部分抽取到外层消息集合里面
在V1版本中,每条消息都需要执行CRC校验,但在某些情况下,消息的CRC值会发生变化
Broker端可能对消息的时间戳字段进行更新,重新计算后的CRC值也会相应更新
Broker端在执行消息格式转换时(兼容老版本客户端),也会带来CRC值的变化
因此没必要对每条消息都执行CRC校验,浪费空间和时间
在V2版本中,消息的CRC校验被移到了消息集合这一层
优化2:对整个消息集合进行压缩
在V1版本中,对多条消息进行压缩,然后保存到外层消息的消息体字段中
压缩的时机在Kafka中,压 ...
Java性能 -- 序列化
序列化方案
Java RMI采用的是Java序列化
Spring Cloud采用的是_JSON序列化_
Dubbo虽然兼容Java序列化,但默认使用的是_Hessian序列化_
Java序列化原理
Serializable
JDK提供了输入流对象ObjectInputStream和输出流对象ObjectOutputStream
它们只能对实现了Serializable接口的类的对象进行序列化和反序列化
12345// 只能对实现了Serializable接口的类的对象进行序列化// java.io.NotSerializableException: java.lang.ObjectObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_PATH));oos.writeObject(new Object());oos.close();
transient
ObjectOutputStream的默认序列化方式,仅对对象的非transient的实例变量进行序列化
不会序列化对象的transient的实例变量,也不 ...
Kafka -- 生产者消息分区机制
分区概念
主题是承载真实数据的逻辑容器,主题之下分为若干个分区,Kafka的消息组织方式为三级结构:主题、分区、消息
主题下的每条消息只会保存在某个分区中,而不会在多个分区中被保存多份
分区的作用是提供负载均衡的能力,实现系统的高伸缩性
不同的分区能够被放置在不同的机器节点上,而数据读写操作的粒度也是分区
每个机器节点都能独立地执行各自分区的读写请求处理,还可以通过添加新的机器节点来增加整体系统的吞吐量
分区在不同的分布式系统有不同的叫法,但分区的思想都是类似的
Kafka – Partition
MongoDB、Elasticsearch – Shard
HBase – Region
分区策略
分区策略:决定生产者将消息发送到哪个分区的算法,Kafka提供了默认的分区策略,也支持自定义的分区策略
自定义的分区策略,需要显式地配置生产者端的参数partitioner.class
实现接口:org.apache.kafka.clients.producer.Partitioner
消息数据:topic、key、keyBytes、value、valueBytes
集群数据:cluster
...
Java性能 -- IO模型
什么是IO
IO是机器获取和交换信息的主要渠道,而流是完成IO操作的主要方式
在计算机中,流是一种信息的转换
流是有序的
把机器或者应用程序接收外界的信息称为输入流(InputStream)
从机器或者应用程序向外输出的信息称为输出流(OutputStream)
流可以被看作一种数据的载体,通过它可以实现数据的交换和传输
Java IO
Java IO主要在java.io下,有四个基本类:InputStream、OutputStream、Reader、Writer,分别用于处理字节流和字符流
字符到字节必须经过转码,该过程非常耗时,如果不知道编码类型就很容易出现乱码问题
因此IO流提供了直接操作字符的接口,方便对字符进行流操作
字节流
字节流的抽象类:InputStream/OutputStream
文件的读写操作:FileInputStream/FileOutputStream
数组的读写操作:ByteArrayInputStream/ByteArrayOutputStream
普通字符串的读写操作:BufferedInputStream/Buff ...
Kafka -- 集群参数
Broker参数存储
log.dir:表示单个路径
log.dirs:表示多个路径,推荐使用
/home/kafka1,/home/kafka2,/home/kafka3
线上生产环境中一定要为log.dirs配置多个路径,格式为CSV,逗号分隔
建议把不同的路径挂载到不同的物理磁盘上
提升读写性能,比起单块硬盘,多块物理磁盘同时读写数据有更高的吞吐量
能够实现故障转移(Failover),从Kafka 1.1引入,坏掉的磁盘上的数据会自动地转移到其他正常的磁盘上
Zookeeper
Zookeeper是一个分布式协调框架,负责协调管理并保存Kafka集群的所有元数据信息
集群有哪些Broker在运行,创建了哪些Topic,每个Topic有多少分区、分区的Leader副本在哪些机器上
zookeeper.connect,CSV格式,zk1:2181,zk2:2181,zk3:2181
Zookeeper地chroot,只需写一次,zk1:2181,zk2:2181,zk3:2181/kafka1和zk1:2181,zk2:2181,zk3:2181/kafka2
连接
listeners
...
Java性能 -- HashMap
实现结构
HashMap是基于哈希表实现的,继承了AbstractMap并且实现了Map接口
HashMap根据键的Hash值来决定对应值的存储位置,通过这种索引方式,HashMap获取数据的速度会非常快
当发生哈希冲突时,有3种常用的解决方法:开放定址法、再哈希函数法、链地址法
开放定址法
当发生哈希冲突时,如果哈希表未被填满,说明在哈希表中必然还有空位置
可以把Key存放到冲突位置后面的空位置上
该方法存在很多问题,例如查找、扩容等,不推荐
再哈希函数法
在同义词产生地址冲突时再计算另一个哈希函数地址,直到不再冲突
这种方法不容易产生聚集,但却增加了计算时间
链地址法
HashMap综合考虑了所有因素,采用了链地址法来解决哈希冲突问题
该方法采用了数组(哈希表)+链表的数据结构,当发生哈希冲突时,就用一个链表结构存储相同Hash值的数据
重要属性NodeHashMap是由一个Node数组构成的,每个Node包含一个Key-Value键值对
1transient Node<K,V>[] table;
Node类是HashMap的一个内部类,定义了一个next指针,指向具有 ...
Kafka -- 线上部署
操作系统Linux的表现更胜一筹:IO模型的使用、网络传输效率、社区支持度
IO模型
主流的IO模型:阻塞式IO、非阻塞式IO、IO多路复用、信号驱动IO、异步IO,后一种模型比前一种高级
Java中的Socket对象的阻塞模式和非阻塞模式,对应阻塞式IO和非阻塞式IO
Linux中的系统调用select函数属于IO多路复用模型
大名鼎鼎的epoll系统调用则介于第三种模型和第四种模型之间
很少有Linux系统支持异步IO,Windows系统提供的IOCP线程模型属于异步IO
Kafka客户端底层使用了Java的selector,selector在Linux上的实现机制是epoll,在Windows上是select
Kafka部署在Linux上,能够获得更高效的IO性能
网络传输效率
Kafka生产和消费的消息都是通过网络传输的,而消息是保存在磁盘上的
因此Kafka需要在磁盘和网络间进行大量的数据传输
Linux支持零拷贝技术
当数据在磁盘和网络进行传输时,避免昂贵的内核态数据拷贝,从而实现快速的数据传输
在Windows平台必须等待Java 8 Update 60才能享受到类似Linux ...
Java性能 -- Stream
Stream API
Java 8集合中的Stream相当于高级版的Iterator
Stream API通过Lambda表达式对集合进行各种非常便利高效的聚合操作,或者大批量数据操作
Stream的聚合操作与数据库SQL的聚合操作sorted、filter、map等非常类似
在数据操作方面,Stream不仅可以通过串行的方式实现数据操作,还可以通过并行的方式处理大批量数据,提高处理效率
12345678// java.util.Collectiondefault Stream<E> stream() { return StreamSupport.stream(spliterator(), false);}default Stream<E> parallelStream() { return StreamSupport.stream(spliterator(), true);}
123456789101112131415161718192021222324@Dataclass Student { privat ...
Kafka -- “发行版”
Kafka Connect
Kafka Connect, an open source component of Kafka, is a framework for connecting Kafka with external systems such as databases, key-value stores, search indexes, and file systems.
Using Kafka Connect you can use existing connector implementations for common data sources and sinks to move data into and out of Kafka.
Apache Kafka
Apache Kafka是最正宗的Kafka,被称为社区版Kafka,是其他发行版的基础
优点:开发人数最多,版本迭代速度最快,社区响应度高
缺点:仅仅提供最基础的组件,没有提供任何监控框架或工具,缺失高级功能
应用场景:仅仅需要一个消息引擎系统或者简单的流处理应用场景,同时需要对系统有较大的把控度
Confluent ...
Java性能 -- ArrayList + LinkedList
List接口
ArrayList、Vector、LinkedList继承了AbstractList,AbstractList实现了List,同时继承了AbstractCollection
ArrayList和Vector使用了数组实现,LinkedList使用了双向链表实现
ArrayList常见问题
ArrayList的对象数组elementData使用了transient(表示不会被序列化)修饰,为什么?
ArrayList在大量新增元素的场景下,效率一定会变慢?
如果要循环遍历ArrayList,采用for循环还是迭代循环?
类签名123public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}
ArrayList实现了List接口,继承了AbstractList抽象类,底层是数组实现,并且实现了自增扩容
ArrayList实现了Cloneabl ...