Apache Wayang 配置参数详解
解析 Apache Wayang 1.1.1 配置体系:Configuration 加载优先级与代码注入、wayang.properties 用法与加载坑规避、默认键位全表、spark.master 注入、日志与 JVM 堆验证。
Apache Wayang 配置参数详解
一、配置体系总览
Apache Wayang 1.1.1 的运行期配置由内核类 org.apache.wayang.core.api.Configuration 承载,本质是一组带层级的键值对(Key-Value),外加若干按平台/算子维度的 Provider(如基数估计器、代价估算器的注册表)。本文全部结论基于 1.1.1 真实运行验证。
配置生效优先级(实测确认):
- 代码注入:
configuration.setProperty(key, value)—— 最高优先级; - 外部属性文件:
new Configuration("file:///path/wayang.properties")显式加载; - classpath 根目录
wayang.properties(默认自动探测); - 内置默认值:wayang-core-1.1.1.jar 内
wayang-core-defaults.properties—— 最低优先级。
常用入口方法(javap org.apache.wayang.core.api.Configuration 实测签名):
public Configuration(); // 默认构造,自动加载 classpath 的 wayang.properties
public Configuration(String propertiesFileUrl); // 显式指定文件 URL
public void load(String location); // 追加加载 properties 文件
public void load(java.io.InputStream stream); // 从输入流加载
public void setProperty(String key, String value); // 写入配置
public String getStringProperty(String key); // 读取字符串配置
public Optional<String> getOptionalStringProperty(String key);
public String getStringProperty(String key, String fallback); // 带默认值读取
public static Configuration getDefaultConfiguration(); // 全局默认配置单例
public Configuration fork(); // 派生副本,作业级覆盖不影响全局
注意:1.1.1 中读取值的 API 是 getStringProperty(...),旧文档里出现的 getPropertyValue 在该版本不存在(实测编译报 cannot find symbol)。
二、内置默认配置参数
以下内容从 wayang-core-1.1.1.jar 内提取的 wayang-core-defaults.properties 原文整理(未注释行为 1.1.1 实际默认值):
2.1 优化器与计划枚举
| 键 | 默认值 | 说明 |
|---|---|---|
| wayang.core.optimizer.pruning.strategies | org.apache.wayang.core.optimizer.enumeration.LatentOperatorPruningStrategy | 计划枚举剪枝策略类,可替换为 TopKPruningStrategy |
| wayang.core.optimizer.pruning.topk | 5(注释示例) | TopK 剪枝保留的候选计划数 |
| wayang.core.optimizer.channels.selection | CostbasedTreeSelectionStrategy(注释示例) | 通道转换选择策略 |
| wayang.core.optimizer.enumeration.concatenationprio | plans2 | 枚举串联优先级 |
| wayang.core.optimizer.enumeration.invertconcatenations | false | 是否反转串联 |
| wayang.core.optimizer.enumeration.branchesfirst | false | 是否优先展开分支 |
| wayang.core.optimizer.enumeration.parallel-tasks | false | 枚举阶段是否并行 |
2.2 统计与再优化
| 键 | 默认值 | 说明 |
|---|---|---|
| wayang.core.log.enabled | true | 是否记录执行统计(写入 ~/.wayang/) |
| wayang.core.log.cardinalities | ~/.wayang/cardinalities.json(注释示例) | 基数统计文件位置 |
| wayang.core.log.executions | ~/.wayang/executions.json(注释示例) | 执行统计文件位置 |
| wayang.core.explain.enabled | false | 是否输出执行计划解释 |
| wayang.core.explain.directrory | ~/.wayang/ | 解释文件目录(官方默认文件中键名即为 directrory) |
| wayang.core.optimizer.reoptimize | false | 运行中是否再优化 |
| wayang.core.optimizer.reoptimize.proactive | false | 是否主动触发再优化 |
| wayang.core.optimizer.cardinality.maxspread | 10 | 基数散布上限 |
| wayang.core.optimizer.cardinality.spreadsmoothing | 10000 | 基数散布平滑系数 |
| wayang.core.optimizer.cardinality.minconfidence | 0.5 | 估计器最低置信度 |
2.3 UDF 与算子的代价兜底估计
| 键 | 默认值 | 说明 |
|---|---|---|
| wayang.core.fallback.udf.cpu.lower / upper | 100 / 1000 | UDF CPU 开销兜底区间(纳秒级量化) |
| wayang.core.fallback.udf.cpu.confidence | 0.2 | 对应置信度 |
| wayang.core.fallback.udf.ram.lower / upper | 100 / 1000 | UDF 内存开销兜底区间 |
| wayang.core.fallback.udf.ram.confidence | 0.2 | 对应置信度 |
| wayang.core.fallback.operator.cpu.lower / upper | 100 / 1000 | 算子 CPU 兜底区间 |
| wayang.core.fallback.operator.cpu.confidence | 0.2 | 对应置信度 |
| wayang.core.fallback.operator.ram.lower / upper | 100 / 1000 | 算子内存兜底区间 |
| wayang.core.fallback.operator.ram.confidence | 0.2 | 对应置信度 |
2.4 其他
| 键 | 默认值 | 说明 |
|---|---|---|
| wayang.core.monitor.enabled | false | 是否启用 Monitor |
| wayang.core.optimizer.instrumentation | (默认注释) | 可设为 OutboundInstrumentationStrategy 或 FullInstrumentationStrategy,配合激进再优化 |
三、配置加载方式与实测
3.1 方式一:classpath 下的 wayang.properties
把 wayang.properties 放在 src/main/resources/,内容示例:
wayang.core.log.enabled = false
wayang.core.explain.enabled = false
用探针程序验证(实测代码):
Configuration configuration = new Configuration();
System.out.println(configuration.getStringProperty("wayang.core.log.enabled"));
- 文件在 classpath 时实测输出:
false(文件生效); - 移除文件后实测输出:
true(回落到内置默认)。
重要坑点(实测复现):该文件被打进 jar 包后,new Configuration() 默认按 jar:file:...!/wayang.properties 路径访问会抛出:
Exception in thread "main" org.apache.wayang.core.api.exception.WayangException: Could not access jar:file:/root/wayang-demo/target/wayang-demo-1.0.0.jar!/wayang.properties.
at org.apache.wayang.core.api.Configuration.load(Configuration.java:241)
规避方式二选一:文件留在 jar 外;或按 3.2 节显式以 file:// URL 加载。
3.2 方式二:显式文件 URL 加载(推荐用于生产)
cp wayang.properties /root/wayang.properties
Configuration configuration = new Configuration("file:///root/wayang.properties");
实测:以 jar 方式运行时正常读取,wayang.core.log.enabled 返回 false,加载成功。
3.3 方式三:代码注入(优先级最高)
Configuration configuration = new Configuration("file:///root/wayang.properties");
configuration.setProperty("wayang.core.fallback.udf.cpu.lower", "777");
System.out.println(configuration.getStringProperty("wayang.core.fallback.udf.cpu.lower"));
实测输出:
wayang.core.fallback.udf.cpu.lower = 777
四、平台选择与执行参数
4.1 平台注册
Wayang 不用配置文件声明后端,而是在代码中注册插件(Plugin),注册哪些引擎决定了优化器的选择空间:
WayangContext wayang = new WayangContext(new Configuration())
.withPlugin(Java.basicPlugin()); // Java Stream 后端
// .withPlugin(Spark.basicPlugin()); // Spark 后端(需 wayang-spark 依赖)
只注册一个平台时任务必然路由到它;注册多个平台时由代价优化器按估算成本逐算子选择(小数据量几乎总选本地 Java 引擎,属正常行为)。
4.2 Spark 相关键值
Spark 后端复用 Spark 自身的配置键,直接写入 Configuration 即可传递给 SparkConf,实测注入 spark.master 后 local 模式运行成功:
Configuration configuration = new Configuration();
configuration.setProperty("spark.master", "local[2]");
WayangContext wayang = new WayangContext(configuration).withPlugin(Spark.basicPlugin());
常用键:spark.master(如 local[2]、local[*])、spark.driver.memory、spark.app.name。
4.3 Java 后端执行参数
wayang-java 后端无独立服务进程,执行参数主要是 JVM 参数本身(堆、并行度由 JVM/Stream 框架决定),配合 2.2/2.3 节的优化器键控制行为。
五、日志配置
5.1 绑定现状(实测)
对 wayang-java 工程执行 mvn dependency:copy-dependencies 后,target/lib 中日志相关 jar 如下(实测清单):
jcl-over-slf4j-2.0.6.jar
jul-to-slf4j-2.0.6.jar
log4j-1.2-api-2.19.0.jar
log4j-api-2.20.0.jar
log4j-core-2.20.0.jar
log4j-slf4j-impl-2.20.0.jar
log4j-slf4j2-impl-2.19.0.jar
slf4j-api-2.0.6.jar
slf4j-reload4j-1.7.36.jar
即:API 层为 slf4j 2.0.6,后端绑定 log4j2 2.20(log4j-core + log4j-slf4j2-impl),同时存在兼容桥(log4j-1.2-api、jcl-over-slf4j 等)。Wayang 自身日志直接走 log4j2 输出。
5.2 调整日志级别
在工程 src/main/resources/ 放置 log4j2.xml 即可生效,示例:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout pattern="%d{HH:mm:ss} %-5level %logger{1} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.apache.wayang" level="DEBUG"/>
<Root level="INFO">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
5.3 统计类开关
wayang.core.log.enabled=false:关闭执行统计落盘(~/.wayang/ 目录),实测设为 false 后 Configuration 读值为 false;wayang.core.monitor.enabled:Monitor 开关,默认 false;wayang.core.explain.enabled:开启后输出计划解释到wayang.core.explain.directrory指定目录。
六、JVM 参数与实测验证
6.1 堆参数设置位置
| 场景 | 参数位置 | 推荐值 |
|---|---|---|
| Maven 构建(mvn package 等) | MAVEN_OPTS,写入 /etc/profile.d/wayang-maven.sh 或登录 shell 的 ~/.bashrc | -Xms256m -Xmx512m |
| java 直跑任务 | 命令行 java -Xms256m -Xmx512m ...,或启动脚本中的 JAVA_OPTS | -Xms256m -Xmx512m |
/etc/profile.d/wayang-maven.sh 内容:
export MAVEN_OPTS="-Xms256m -Xmx512m"
6.2 运行验证
启动任务(后台运行以便另开会话观测):
java -Xms256m -Xmx512m -cp "target/wayang-demo-1.0.0.jar:target/lib/*" com.example.WordCount
任务运行期间执行 ps -ef | grep "[j]ava -Xms",实测回显:
root 5820 5818 99 14:48 ? 00:00:02 java -Xms256m -Xmx512m -cp target/wayang-demo-1.0.0.jar:target/lib/* com.example.WordCount
执行 jps -v,实测回显:
5820 WordCount -Xms256m -Xmx512m
两种方式均确认堆下限 256 MB、上限 512 MB 已生效。小数据量任务在 512 MB 上限内稳定运行;数据规模增大时再按需上调,但应结合机器物理内存评估。
七、常见问题
Q1:configuration.getPropertyValue(...) 编译不过怎么办?
1.1.1 的 Configuration 读取方法是 getStringProperty(String)、getStringProperty(String, String) 与 getOptionalStringProperty(String),改用其一即可(实测编译通过)。
**Q2:**把 wayang.properties 打进 jar 后启动报 Could not access jar:...!/wayang.properties 怎么办?
这是 Configuration 默认加载路径对 jar 内资源访问失败所致(实测复现,异常栈指向 Configuration.load)。解决:属性文件放 jar 外部,并用 new Configuration("file:///root/wayang.properties") 显式加载,实测正常读取。
**Q3:**代码里 setProperty 不生效怎么办?
确认三点:一是 setProperty 发生在构建 WayangContext 之前;二是键名拼写与内置键一致;三是读取时使用同一个 Configuration 实例(或其 fork)。实测在 WayangContext 构造前注入 wayang.core.fallback.udf.cpu.lower=777 后读值即为 777。
**Q4:**spark.master 在哪里设置?
Wayang 没有独立的 spark 配置文件,直接写进 Configuration:configuration.setProperty("spark.master", "local[2]"),Spark 后端初始化时读取(实测 local 模式任务成功执行)。
Q5:~/.wayang 目录不断增长怎么办?
这是 wayang.core.log.enabled=true 产生的统计文件(cardinalities.json、executions.json)。不需要统计分析时设为 false,或定期清理该目录。
八、参考链接
- Apache Wayang 官网:https://wayang.apache.org/
- 快速上手指南:https://wayang.apache.org/docs/guide/getting-started
- GitHub 仓库(apache/wayang,Configuration 源码):https://github.com/apache/wayang
- Maven Central 上 wayang-core 构件(内含 wayang-core-defaults.properties):https://repo1.maven.org/maven2/org/apache/wayang/wayang-core/
- Sonatype Central(版本检索):https://central.sonatype.com/artifact/org.apache.wayang/wayang-core
- Log4j2 官方文档(log4j2.xml 配置参考):https://logging.apache.org/log4j/2.x/manual/configuration.html