Skip to content

BIP 3: Optimize Byzer lang script

PENG Zhengshuai edited this page Apr 25, 2022 · 10 revisions

Status: MERGED

Author: @AdmondGuo

Contributor: @AdmondGuo @ZhengshuaiPENG

Date: 2022.04.13

Issue: #1726

Pull Requests: #1745 #1761 #1762

背景

目前 Byzer-lang 脚本不够完善,用户在使用时存在以下问题:

  • 没有进行环境检查,例如 jvm 和 port
  • 启动参数冗长,可读性比较差,更新启动参数必须更改脚本
  • 不同环境启动应用的脚本不同(start-local.sh/java -cp)
  • 日志信息不够清晰

预期收益

优化 Byzer-lang 脚本,达成如下效果:

  • 启动时进行环境检查(本期暂时只检测 JVM & port)
  • 根据配置文件选项(yarn/local/k8s),读取不同的默认配置,组成启动参数
  • 不同环境启动应用的脚本相同
  • 输出更多日志,方便排查问题

变更点

Byzer-lang 可能涉及到的涉及到的启动参数有这样几种:

  • JVM 参数
  • Spark 启动参数
  • Byzer 的可变参数
  • Byzer 的不可变参数 应当为它们做出标识或区分,以便用户进行分别使用。 因此做出如下更改
  • 更改原 ./dev 下的相关脚本
    • 增加环境检查
    • 增加日志归档
    • 增加 byzer.sh 封装 start stop
  • 增加 ./conf 目录,用于存放配置文件
    • Byzer 不可变配置
    • Byzer 可变配置
    • Byzer 不同环境下配置
    • JVM 配置
    • 日志配置
  • 代码中增加 getProperties() 方法,用于获取配置文件中的参数(详情请看【获取配置方式】章节) 使用介绍

目录结构

// 以下都是 byzer-lang 下的二级目录

conf
├── byzer.properties.override
├── byzer.properties
├── byzer-yarn.properties.example
├── byzer-local.properties.example
├── byzer-k8s.properties.example
└── log4j.properties

logs
├── byzer.log
├── byzer_access.2022-04-06.log
├── check-env.error
├── check-env.out
├── shell.stderr
└── shell.stdout

dev
├── bootstrap.sh        //new
├── byzer.sh            //new
├── change-scala-version.sh
├── change-version-to-2.11.sh
├── change-version-to-2.12.sh
├── check-1000-os.sh  //new
├── check-1100-java.sh  //new
├── check-1200-port.sh  //new
├── check-env.sh.       //new
├── empty.json
├── fetchPR.sh
├── get-properties.sh   //new
├── header.sh           //new
├── kill-process-tree.sh //new
├── make-distribution.sh
├── package.cmd
├── package.sh
├── python
│   └── convert_pom.py
├── releaseDoc.sh
├── run-test.sh
└── switch.sh

脚本介绍

byzer.sh

命令入口,在这里产生 err 和 out 日志。 byzer.sh 调用 bootstrap.sh 实现具体的启动逻辑。 可以如下使用它:

  • 启动:byzer.sh start
  • 停止:byzer.sh stop

bootstrap.sh

实现 stop / start 逻辑 get-properties.sh 通过 java -cp 获取配置文件中的参数

header.sh

包装通用方法,设置变量

check-env.sh

启动前进行环境检查,目前检查

  • jvm 环境
  • 端口占用情况 环境检查失败将不会启动应用

配置文件介绍

byzer.properties

  • 保存打包选项(yarn/local/k8s),get-properties.sh 将根据打包选项选择读取不同配置
  • 保存不建议被更改的配置

下面是一个例子:

streaming.rest=true
streaming.platform=spark
streaming.spark.service=true
...

新增配置 byzer.server.mode=all-in-one | server, 由于 Byzer 引擎的包的产出会分两个版本,all in one 以及 二进制的 server 版本,其中 all-in-one 的启动是通过 java -cp 的命令进行启动的,server 版本则是通过spark submit 命令来启动的,二者的启动方式都有些差别,以及一些依赖也会有区别,主要是 java 以及 spark 的依赖,所以通过该配置项进行分支控制。

byzer.properties.override

  • 具有最高优先级的配置文件,写在 override 中的配置会覆盖掉 byzer.properties 中相同参数 key 的值

byzer.properties.all-in-one.example

  • 默认 all-in-one 产品包的 example config,打包时将其覆盖为 byzer.properties.override

byzer-local.properties

  • 默认 server 产品包的 example config,打包时将其覆盖为 byzer.properties.override
spark.sql.hive.thriftServer.singleSession=true
spark.kryoserializer.buffer=256k
spark.kryoserializer.buffer.max=1024m
spark.serializer=org.apache.spark.serializer.KryoSerializer
spark.scheduler.mode=FAIR
...

log4j.properties

  • log4j 配置

配置获取方式

Shell 脚本调用 Java 工具类读取配置,并返回拼接好的启动参数。 Java 工具类的路径 streamingpro-spark-3.0.0-adaptor/src/main/java/org/apache/spark/util/ByzerConfigCLI.java streamingpro-spark-2.4.0-adaptor/src/main/java/org/apache/spark/util/ByzerConfigCLI.java 工具类伪代码

public class ByzerConfigCLI {
    public static void main(String[] args) {
        execute(args);
        Unsafe.systemExit(0);
    }

    public static void execute(String[] args) {
        // check args length
        // get byzer.mode from byzer.properties
        // if local: load byzer-local.properties
        // if yarn: load byzer-yarn.properties
        // if k8s: load byzer-k8s.properties
        // concat properties
        system.out.println(properties);
    }   
}

Shell 代码

result=`java -cp org/apache/spark/util/ByzerConfigCLI $@ 2>>${BYZER_HOME}/logs/shell.stderr`

echo "$result"

技术要点

参考 Apache Kylin 的启动脚本设计,通过 shell 脚本和 java 代码实现。 将启动命令脚本规范化,脚本和配置文件分离,用户需要交互的只有配置文件和 byzer.sh 脚本里包装好的命令,这样的设计用户无需关心脚本的实现,并且 KV 的配置文件可读性很高。

测试要点

  • 测试是否能检测出环境问题
  • 测试是否能正确 启动/停止 应用
  • 测试是否能正确运行插件
  • 测试是否可以根据不同打包参数,读取相应的配置
  • 测试是否能生成多份不同级别日志,并进行日志轮转