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 ...
Kafka -- 分布式流处理平台
历史消息引擎系统
Kafka在刚诞生时是以消息引擎系统的面目出现在大众视野中
Kafka在0.10.0.0之前的定位:分布式、分区化且带备份功能的提交日志(Commit Log)服务
Kafka在设计之初的功能特性
提供一套API实现生产者和消费者
降低网络传输和磁盘存储开销
实现高伸缩架构
分布式流处理平台
Kafka于2011年正式进入Apache基金会孵化并于次年10月成为Apache顶级项目
Kafka社区于0.10.0.0版本正式推出流处理组件Kafka Streams,定位变成了分布式流处理平台
同等级的实时流处理平台:Apache Kafka、Apache Storm、Apache Spark、Apache Flink
目前国内对Kafka是流处理平台的认知还不普及,其核心的流处理组件Kafka Streams更是少有大厂在使用
优势端到端的正确性
Kafka更容易实现端到端的正确性(Correctness)
流处理要替代批处理需要具备两个核心优势
实现正确性(正确性是流处理能够匹敌批处理的基石)
提供能够推导时间的工具
正确性一直都是批处理的强项,而实现正确性的基石是要求框架能 ...