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) 流处理要替代批处理需要具备两个核心优势 实现正确性(正确性是流处理能够匹敌批处理的基石) 提供能够推导时间的工具 正确性一直都是批处理的强项,而实现正确性的基石是要求...
Java性能 -- 正则表达式
元字符 正则表达式使用一些特定的元字符来检索、匹配和替换符合规则的字符串 元字符:普通字符、标准字符、限定字符(量词)、定位字符(边界字符) 正则表达式引擎 正则表达式是一个用正则符号写出来的公式 程序对正则表达式进行语法分析,建立语法分析树 再根据语法分析树结合正则表达式引擎生成执行程序(状态机),用于字符匹配 正则表达式引擎是一套核心算法,用于建立状态机 小结 正则表达式 => 语法分析树 语法分析树 + 正则表达引擎 => 状态机 => 用于字符匹配 目前实现正则表达式引擎的方式有两种 DFA自动机(Deterministic Finite Automaton,确定有限状态自动机) NFA自动机(Nondeterministic Finite Automaton,非确定有限状态自动机) DFA自动机的构造代价远大于NFA自动机,但DFA自动机的执行效率高于NFA自动机 假设一个字符串的长度为n,如果采用DFA自动机作为正则表达式引擎,则匹配的时间复杂度为O(n) 如果采用NFA自动机作为正则表达式引擎,NFA自动机在匹配过程...
Kafka -- 术语
主题 + 客户端 发布订阅的对象是主题(Topic) 向主题发布消息的客户端应用程序称为生产者(Producer),生产者可以持续不断地向多个主题发送消息 订阅这些主题消息的客户端应用程序称为消费者(Consumer),消费者能够同时订阅多个主题的消息 生产者和消费者统称为客户端 服务端 Kafka的服务端由被称为Broker的服务进程构成,一个Kafka集群由多个Broker组成 Broker负责接收和处理客户端发送过来的请求,以及对消息进行持久化 多个Broker进程能够运行在同一台机器上,但更常见的做法是将不同的Broker分散运行在不同的机器上 这样如果集群中某一台机器宕机了,即使在它上面运行的所有Broker进程都挂掉了 其他机器上的Broker也依然能够对外提供服务,这是Kafka提供高可用的手段之一 备份 实现高可用的另一个手段是备份机制(Replication) 备份:把相同的数据拷贝到多台机器上,这些相同的数据拷贝在Kafka中被称为副本(Replica) 副本的数量是可以配置的,Kafka定义了两类副本:领导者副本(Leader Replica)和追随者副本(Follow...
Kafka -- 消息引擎系统
术语 Apache Kafka是一款开源的消息引擎系统 消息队列:给人某种暗示,仿佛Kafka是利用队列实现的 消息中间件:过度强调中间件,而不能清晰地表达实际解决的问题 解决的问题 系统A发送消息给消息引擎系统,系统B从消息引擎系统中读取A发送的消息 消息引擎传输的对象是消息 如何传输消息属于消息引擎设计机制的一部分 消息格式 成熟解决方案:CSV、XML、JSON 序列化框架:Google Protocol Buffer、Facebook Thrift Kafka:纯二进制的字节序列 消息引擎模型 点对点模型 即消息队列模型,系统A发送的消息只能被系统B接收,其他任何系统不能读取A发送的消息 发布订阅模型 主题(Topic)、发布者(Publisher)、订阅者(Subscriber) 多个发布者可以向相同的主题发送消息,多个订阅者可以接收相同主题的消息 Kafka同时支持上面两种消息引擎模型 JMS JMS:Java Message Service JMS也支持上面的两种消息引擎模型 JMS并非传输协议,而是一组API JMS非常出名,很多主流的消息引擎系统都支持JMS规范 A...
Java并发 -- CSP模型
Go Go是一门号称从语言层面支持并发的编程语言,支持并发也是Go非常重要的特性之一 Go支持协程,协程可以类比Java中的线程,解决并发问题的难点在于线程(协程)之间的协作 Go提供了两种方案 支持协程之间以共享内存的方式通信,Go提供了管程和原子类来对协程进行同步控制,该方案与Java类似 支持协程之间以消息传递的方式通信,本质上是要避免共享,该方案是基于CSP模型实现的,Go推荐该方案 CSP模型 CSP:Communicating Sequential Processes Do not communicate by sharing memory; instead, share memory by communicating. 累加器12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455package mainimport ( "fmt" "time")func main() {...
Java性能 -- 字符串
实现 在Java 6以及之前的版本中,String对象是对char数组进行了封装实现的对象 主要四个成员变量:char数组、偏移量offset、字符数量count、哈希值hash String对象通过offset和count两个属性来定位char数组,获取字符串 这样可以高效快速地共享数组对象,同时节省内存空间,但也有可能会导致内存泄露 Java 7/8,String类中不再有offset和count两个变量 这样String对象占用的内存稍微少了一点 另外,String.substring不再共享char[],从而解决了使用该方法可能导致的内存泄露问题 从Java 9开始,将char[]修改为byte[],同时维护了一个新的属性coder,它是一个编码格式的标识 一个char字符占用16位,2个字节,用一个char去存储单字节编码的字符会非常浪费 Java 9的String类为了节约内存空间,使用了占用8位,1个字节的byte数组来存放字符串 coder的作用:使用length()或者indexOf() coder有两个默认值:0代表LATIN1,1代表UTF16 ...
Java并发 -- 协程
协程 协程可以理解为一种轻量级的线程 从操作系统的角度来看,线程是在内核态中调度的,而协程是在用户态调度的,协程的切换成本更低 协程栈比线程栈要小得多,典型的线程栈在1M左右,而协程栈一般在几K或者几十K左右 因此无论在时间维度还是在空间维度,协程都比线程轻量很多 支持协程的语言:Go、Python、Lua、Kotlin Java OpenSDK的Loom项目的目标是为了支持协程 Go中的协程12345678910func hello(msg string) { fmt.Println("Hello " + msg)}func TestCoroutine(t *testing.T) { // 在新的协程中执行hello方法 go hello("Go") // 等待100毫秒让协程执行结束 time.Sleep(100 * time.Millisecond)} Java中的线程是一个重量级对象,因此无法很好地实现Thread-Per-Message模式,而协程可以 Thread-Per...
Java并发 -- 软件事务内存
STM STM:Software Transactional Memory,软件事务内存,借鉴于数据库的事务管理 传统的数据库事务支持ACID,即原子性(A)、一致性(C)、隔离性(I)和持久性(D) STM不支持持久化,即只支持ACI 数据库事务数据库保证在并发情况下不会发生死锁,而且还能保证ACID 1234567891011121314Connection conn = null;try{ // 获取数据库连接 conn = DriverManager.getConnection(); // 设置手动提交事务 conn.setAutoCommit(false); // 执行转账SQL ... // 提交事务 conn.commit();} catch (Exception e) { // 出现异常回滚事务 conn.rollback();} synchronized转账12345678910111213141516@AllArgsConstructorpublic class UnsafeA...
Java性能 -- 性能调优策略
性能测试测试方法 微基准性能测试 可以精准定位到某个模块或者某个方法的性能问题,例如对比一个方法使用同步实现和非同步实现的性能差异 宏基准性能测试 宏基准性能测试是一个综合测试,需要考虑到测试环境、测试场景和测试目标 测试环境:模拟线上的真实环境 测试场景:在测试某个接口时,是否有其他业务的接口也在平行运行,进而造成干扰 测试目标 可以通过吞吐量和响应时间来衡量系统是否达标,如果不达标,就需要进行优化 如果达标,就继续加大测试的并发数,探底接口的TPS 除了关注接口的吞吐量和响应时间外,还需要关注CPU、内存和IO的使用率情况 干扰因素热身问题 在Java编程语言和环境中,.java文件编译成.class文件后,需要通过解析器将字节码转换成本地机器码才能运行 为了节约内存和执行效率,代码在最初被执行时,解析器会率先解析执行这段代码 随着代码被执行的次数增加,当JVM发现某个方法或代码块运行得很频繁时,就会把这些代码认定为热点代码 为了提高热点代码的执行效率,在运行时,JVM将通过即时编译器(JIT)把这些代码编译成与本地平台相关的机器码 并进行各层次的优化,然后存储在内存中,之后每次运...
Java并发 -- Actor模型
Actor模型 Actor模型在本质上是一种计算模型,基本的计算单元称为Actor,在Actor模型中,所有的计算都在Actor中执行 在面向对象编程里,一切都是对象,在Actor模型里,一切都是Actor,并且Actor之间是完全隔离的,不会共享任何变量 Java本身并不支持Actor模型,如果需要在Java里使用Actor模型,需要借助第三方类库,比较完备的是Akka Hello Actor12345678910111213141516public class HelloActor extends UntypedAbstractActor { // 该Actor在收到消息message后,会打印Hello message @Override public void onReceive(Object message) throws Throwable { System.out.printf("Hello %s%n", message); } public static void main(String[...













