Java Feature - Text Blocks
概述
Text Blocks 在 JDK 15 正式发布
Text Blocks 是一个由多行文字构成的字符串
丑陋
所见即所得
Text Blocks 是一个由多行文本构成的字符串
Text Blocks 使用新的形式来表达字符串
Text Blocks 尝试消除换行符、连接符、转义字符的影响
使文字对齐和必要的占位符更加清晰,简化多行字符串的表达
消失的特殊字符 - 换行符(\n)、连接字符(**+**)、双引号没有使用转义字符(\)
Text Blocks 由零个或多个内容字符组成,从开始分隔符开始,到结束分隔符结束
开始分隔符 - """,后跟零个或者多个空格,以及行结束符组成的序列 - 必须单独成行
结束分隔符 - 只有 """ - 之前的字符,包括换行符,都属于 Text Blocks 的有效内容
Text Blocks 至少两行代码,即便只是一个空字符串,结束分隔符也不能和开始分隔符在同一行
Text Blocks 不再需要特殊字符 - 所见即所得
12345678910$ jshell> Strin ...
Java Feature - JShell
概述
JShell 在 JDK 9 中正式发布
JShell API 和工具提供了一种在 JShell 状态下交互式评估 Java 编程语言的声明、语句和表达式的方法
JShell 的状态包括不断发展的代码和执行状态
为了快速调查和编码,语句和表达式不需要出现在方法中,变量和方法也不需要出现在类中
JShell 在验证简单问题时,比 IDE 更高效
启动 JShell
12345$ jshell| Welcome to JShell -- Version 17.0.9| For an introduction type: /help introjshell>
详细模式 - 提供更多的反馈结果,观察更多细节
12345$ jshell -v| Welcome to JShell -- Version 17.0.9| For an introduction type: /help introjshell>
退出 JShell
123456$ jshell -v| Welcome to JShell -- Version 17.0.9| For an introduct ...
MQ - Concept
消息管道
在系统架构中,MQ 的定位是消息和管道,主要起到解耦上下游系统,数据缓存的作用,主要操作为生产和消息
架构
Broker
Broker 本质上是一个进程
在实际部署过程中,通常一个物理节点只会起一个进程,在大部分情况下,Broker 表示一个节点
Topic
在大部分 MQ 中,Topic 都是用来组织分区关系的一个逻辑概念
通常情况下,一个 Topic 会包含多个分区
在 RabbitMQ 中,Topic 是指具体的一种主题模式
Partition
Queue / MessageQueue
在 MQ 中,分区、分片、Partition、Queue、MessageQueue 是一个概念,用来表示数据存储的最小单位
可以将消息写入到一个分区中,也可以将消息写入到 Topic 中,再分发到具体的某个分区
一个 Topic 通常会包含一个或多个分区
Producer
消息的发送方,即发送消息的客户端
Consumer
消息的接收方,即接收消息的客户端
ConsumerGroup
Subscription
一般情况下,MQ 中的 ConsumerGroup 和 Sub ...
MQ - Context
MQ
消息队列 - 具有缓冲作用、具备发布和订阅能力的存储引擎
消息队列的最基本功能 - 生产 + 消费
标准消息队列 - 功能齐全
在发布订阅的基础上,高阶能力 - 死信队列、顺序消息、延时消息等
实现高吞吐、低延时、高可靠的特征
社区
Year
MQ
< 2000
史前消息队列
2001
JMS - ActiveMQ
2006
AMQP
2007
RabbitMQ
2011
Kafka
2013
RocketMQ
2017
Pulsar
TimelineKafka
Kafka 于 2011 年贡献给 ASF,主要满足大数据领域中的高吞吐量、低延迟的场景
核心功能简单,只提供生产和消费,后来加入了幂等和事务
RabbitMQ
RabbitMQ 于 2007 年开源,使用 Erlang,主要满足业务中消息总线的场景
特点为功能丰富(支持延时消息、死信队列、优先级队列、事务消息等),在低流量下稳定性较高
缺点 - 在大流量的情况下,会有明显的性能瓶颈和稳定性分险
ActiveMQ 基于 JMS 协议(国内较少使用),而 RabbitMQ 基于 AMQP 协 ...
Beam - Future
技术迭代
2006,Apache Hadoop 发布,基于 MapReduce 计算模型
2009,Spark 计算框架在 加州伯克利大学诞生,于 2010 年开源,于 2014 年成为 Apache 的顶级项目
Spark 的数据处理效率远在 Hadoop 之上
2014,Flink 面世,流批一体,于 2018 年被阿里收购
Apache Beam
Apache Beam 根据 Dataflow Model API 实现的,能完全胜任批流一体的任务
Apache Beam 有中间的抽象转换层,工程师无需学习新 Runner 的 API 的语法,减少学习新技术的时间成本
Runner 可以专心优化效率和迭代功能,而不必担心迁移
Beam Runner
迭代非常快 - 如 Flink
Beam - Streaming
有界数据 vs 无界数据
在 Beam 中,可以用同一个 Pipeline 处理有界数据和无界数据
无论是有界数据还是无界数据,在 Beam 中,都可以用窗口把数据按时间分割成一些有限大小的集合
对于无界数据,必须使用窗口对数据进行分割,然后对每个窗口内的数据集进行处理
读取无界数据
withLogAppendTime - 使用 Kafka 的 log append time 作为 PCollection 的时间戳
12345678Pipeline pipeline = Pipeline.create();pipeline.apply( KafkaIO.<String, String>read() .withBootstrapServers("broker_1:9092,broker_2:9092") .withTopic("shakespeare") // use withTopics(List<String>) to read from multiple topics. .withK ...
Beam - Window
Window
在 Beam 中,Window 将 PCollection 里的每个元素根据时间戳划分成不同的有限数据集合
要将一些聚合操作应用在 PCollection 上时,或者对不同的 PCollection 进行 Join 操作
Beam 将这些操作应用在这些被 Window 划分好的不同的数据集上
无论是有界数据还是无界数据,Beam 都会按同样的规则进行处理
在用 IO Connector 读取有界数据集的过程中,Read Transform 会默认为每个元素分配一个相同的时间戳
一般情况下,该时间戳为运行 Pipeline 的时间,即处理时间 - Processing Time
Beam 会为该 Pipeline 默认分配一个全局窗口 - Global Window - 从无限小到无限大的时间窗口
Global Window
可以显式将一个全局窗口赋予一个有界数据集
12PCollection<String> input = p.apply(TextIO.read().from(filepath));PCollection<String> batchInpu ...
Beam - WordCount
步骤
用 Pipeline IO 读取文本
用 Transform 对文本进行分词和词频统计
用 Pipeline IO 输出结果
将所有步骤打包成一个 Pipeline
创建 Pipeline
默认情况下,将采用 DirectRunner 在本地运行
1PipelineOptions options = PipelineOptionsFactory.create();
一个 Pipeline 实例会构建数据处理的 DAG,以及这个 DAG 所需要的 Transform
1Pipeline p = Pipeline.create(options);
应用 Transform
TextIO.Read - 读取外部文件,生成一个 PCollection,包含所有文本行,每个元素都是文本中的一行
123String filepattern = "file:///Users/zhongmingmao/workspace/java/hello-beam/corpus/shakespeare.txt";PCollection<String> lines = p.a ...
Beam - Execution Engine
Pipeline
读取输入数据到 PCollection
对读进来的 PCollection 进行 Transform,得到另一个 PCollection
输出结果 PCollection
1234567891011121314// Start by defining the options for the pipeline.PipelineOptions options = PipelineOptionsFactory.create();// Then create the pipeline.Pipeline pipeline = Pipeline.create(options);PCollection<String> lines = pipeline.apply( "ReadLines", TextIO.read().from("gs://some/inputData.txt"));PCollection<String> filteredLines = lines.apply(new FilterLines());filteredLi ...
Beam - Pipeline Test
Context
设计好的 Pipeline 通常需要放在分布式环境下执行,具体每一步的 Transform 都会被分配到任意机器上执行
如果 Pipeline 运行出错,则需要定位到具体机器,再到上面去做调试是不现实的
另一种办法,读取一些样本数据集,再运行整个 Pipeline 去验证哪一步逻辑出错 - 费时费力
正式将 Pipeline 放在分布式环境上运行之前,需要先完整地测试整个 Pipeline 逻辑
Solution
Beam 提供了一套完整的测试 SDK
可以在开发 Pipeline 的同时,能够实现对一个 Transform 逻辑的单元测试
也可以对整个 Pipeline 的 End-to-End 测试
在 Beam 所支持的各种 Runners 中,有一个 DirectRunner
DirectRunner 即本地机器,整个 Pipeline 会放在本地机器上运行
DoFnTester - 让用户传入一个自定义函数来进行测试 - UDF - User Defined Function
DoFnTester 接收的对象是用户继承实现的 DoFn
不应该将 DoFn 当成一个单 ...