从实际案例聊聊Java应用的GC优化

当Java程序性能达不到既定目标,且其他优化手段都已经穷尽时,通常需要调整垃圾回收器来进一步提高性能,称为GC优化。但GC算法复杂,影响GC性能的参数众多,且参数调整又依赖于应用各自的特点,这些因素很大程度上增加了GC优化的难度。即便如此,GC调优也不是无章可循,仍然有一些通用的思考方法。本篇会介绍这些通用的GC优化策略和相关实践案例,主要包括如下内容:

优化前准备: 简单回顾JVM相关知识、介绍GC优化的一些通用策略。
优化方法: 介绍调优的一般流程:明确优化目标→优化→跟踪优化结果。
优化案例: 简述笔者所在团队遇到的GC问题以及优化方案。

深入分析CAS

CAS,Compare And Swap,即比较并交换。Doug lea大神在同步组件中大量使用CAS技术鬼斧神工地实现了Java多线程的并发操作。整个AQS同步组件、Atomic原子类操作等等都是以CAS实现的,甚至ConcurrentHashMap在1.8的版本中也调整为了CAS+Synchronized。可以说CAS是整个JUC的基石。

深入分析volatile

volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在Java 5之后,volatile关键字才得以重获生机。
volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情。由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatile关键字的实现原理,最后给出了几个使用volatile关键字的场景。

深入分析synchronized

记得刚刚开始学习Java的时候,一遇到多线程情况就是synchronized,相对于当时的我们来说synchronized是这么的神奇而又强大,那个时候我们赋予它一个名字“同步”,也成为了我们解决多线程情况的百试不爽的良药。但是,随着我们学习的进行我们知道synchronized是一个重量级锁,相对于Lock,它会显得那么笨重,以至于我们认为它不是那么的高效而慢慢摒弃它。
诚然,随着Javs SE 1.6对synchronized进行的各种优化后,synchronized并不会显得那么重了。下面跟随LZ一起来探索synchronized的实现机制、Java是如何对它进行了优化、锁优化机制、锁的存储结构和升级过程;

Kafka设计解析(八)- Kafka Exactly Once语义与事务机制原理

本文介绍了Kafka实现事务性的几个阶段——正好一次语义与原子操作。之后详细分析了Kafka事务机制的实现原理,并介绍了Kafka如何处理事务相关的异常情况,如Transaction Coordinator宕机。最后介绍了Kafka的事务机制与PostgreSQL的MVCC以及Zookeeper的原子广播实现事务的异同

Kafka消费者重新实现的细节

上一章分析的消费者高级API使用ConsumerGroup的语义管理多个消费者,但是在消费者或者Partition发生变化时都需要rebalance,它的实现对ZooKeeper依赖比较严重,
由Kafka内置实现了失败检测和Rebalance(ZKRebalancerListener),但是它存在羊群效应和脑裂的问题,客户端代码实现低级API也不能解决这个问题。如果将失败探测和Rebalance的逻辑放到一个高可用的中心Coordinator,这两个问题即可解决。同时还可大大减少Zookeeper的负载,有利于Kafka Broker的扩展(Broker也会作为协调节点的角色存在)。

Kafka controller架构分析

kafka在0.8版本前没有提供Partition的Replication机制,一旦Broker宕机,其上的所有Partition就都无法提供服务,而Partition又没有备份数据,数据的可用性就大大降低了。所以0.8后提供了Replication机制来保证Broker的failover。由于Partition有多个副本,为了保证多个副本之间的数据同步,有多种方案:

  • 1.所有副本之间是无中心结构的,可同时读写数据,需要保证多个副本之间数据的同步
  • 2.在所有副本中选择一个Leader,生产者和消费者只和Leader副本交互,其他follower副本从Leader同步数据

Kafka controller 设计分析

本文主要参考社区0.11版本Controller的重设计方案,试图给大家梳理一下Kafka controller这个组件在设计上的一些重要思考。众所周知,Kafka中有个关键组件叫controller,负责管理和协调Kafka集群。网上关于controller的源码分析也有很多,本文就不再大段地列出代码重复做这件事情了。实际上,对于controller的代码我一直觉得写的非常混乱,各种调用关系十分复杂,想要完整地理解它的工作原理确实不易。好在我们就是普通的使用者,大致了解controller的工作原理即可。下面我就带各位简要了解一下当前Kafka controller的原理架构以及社区为什么要在大改controller的设计。

Spark 内存管理之UnifiedMemoryManager

Spark的内存使用,大体上可以分为两类:Execution内存和Storage内存。在Spark 1.5版本之前,内存管理使用的是StaticMemoryManager,该内存管理模型最大的特点就是,可以为Execution内存区与Storage内存区配置一个静态的boundary,这种方式实现起来比较简单,但是存在一些问题:

  1. 没有一个合理的默认值能够适应不同计算场景下的Workload
  2. 内存调优困难,需要对Spark内部原理非常熟悉才能做好
  3. 对不需要Cache的Application的计算场景,只能使用很少一部分内存
,