Kafka -- 无消息丢失
持久化保证 Kafka只对已提交的消息做有限度的持久化保证 已提交的消息 当Kafka的若干个Broker成功地接收到一条消息并写入到日志文件后,会告诉生产者这条消息已经成功提交 有限度的持久化保证 Kafka不保证在任何情况下都能做到不丢失消息,例如机房着火等极端情况 消息丢失生产者丢失 目前Kafka Producer是异步发送消息的,Producer.send(record)立即返回,但不能认为消息已经发送成功 丢失场景:网络抖动,导致消息没有到达Broker;消息太大,超过Broker的承受能力,Broker拒收 解决方案:Producer永远要使用带有回调通知的发送API,即**Producer.send(record, callback)** callback能够准确地告知Producer消息是不是真的提交成功,一旦出现消息提交失败,可以进行针对性的处理 消费者丢失 Consumer端丢失数据主要体现在Consumer端要消费的消息不见了 Consumer程序有位移的概念,表示该Consumer当前消费到Topic分区的位置 丢失原因:Consumer接收一批消息后,在未...
Java性能 -- 优化RPC网络通信
服务框架的核心 大型服务框架的核心:RPC通信 微服务的核心是远程通信和服务治理 远程通信提供了服务之间通信的桥梁,服务治理提供了服务的后勤保障 服务的拆分增加了通信的成本,因此远程通信很容易成为系统瓶颈 在满足一定的服务治理需求的前提下,对远程通信的性能需求是技术选型的主要影响因素 很多微服务框架中的服务通信是基于RPC通信实现的 在没有进行组件扩展的前提下,Spring Cloud是基于Feign组件实现RPC通信(基于HTTP+JSON序列化) Dubbo是基于SPI扩展了很多RPC通信框架,包括RMI、Dubbo、Hessian等(默认为Dubbo+Hessian序列化) 性能测试基于Dubbo:2.6.4,单一TCP长连接+Protobuf(响应时间和吞吐量更优),短连接的HTTP+JSON序列化 RPC通信架构演化无论是微服务、SOA、还是RPC架构,都是分布式服务架构,都需要实现服务之间的互相通信,通常把这种通信统称为RPC通信 概念 RPC:Remote Process Call,远程服务调用,通过网络请求远程计算机程序服务的通信技术 RPC框架封装了底层网络通信和序列...
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/B...
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 连接 listene...
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才能享受到类似Li...
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 { pri...













