dremio SetOptionHandler 简单说明
SetOptionHandler 可以进行基于sql 的配置处理,以下是一个简单说明
SetOptionHandler 的创建
是在CommandCreator中
- 参考代码
case SET_OPTION:
if (sqlNode instanceof SqlAlterTableSetOption) {
return direct.create(new AlterTableSetOptionHandler(catalog, context.getSession()));
} else if (sqlNode instanceof SqlAlterTableChangeColumnSetOption) {
return direct.create(new AlterTableChangeColumnSetOptionHandler(catalog));
} else if (sqlNode instanceof SqlSetOption) {
checkIfAllowedToSetOption(sqlNode);
// 创建sql 处理,注意此sql 是在协调节点执行的
return direct.create(new SetOptionHandler(context));
}
throw new IllegalArgumentException("Must have a correct SQL Node for SET_OPTION case");
SetOptionHandler 内部处理
public List<SimpleCommandResult> toResult(String sql, SqlNode sqlNode) throws ValidationException, RelConversionException, IOException,
ForemanSetupException {
// 基于了OptionManager 里边包装的各种options 实现处理
final OptionManager options = context.getOptions();
final SqlSetOption option = SqlNodeUtil.unwrap(sqlNode, SqlSetOption.class);
final String name = option.getName().toString();
final SqlNode value = option.getValue();
if (value != null && !(value instanceof SqlLiteral)) {
throw UserException.validationError()
.message("Dremio does not support assigning non-literal values in SET statements.")
.build(logger);
}
final String scope = option.getScope();
final OptionValue.OptionType type;
if (scope == null) { // No scope mentioned assumed SESSION
type = OptionType.SESSION;
} else {
switch (scope.toLowerCase()) {
case "session":
type = OptionType.SESSION;
break;
case "system":
type = OptionType.SYSTEM;
break;
default:
throw UserException.validationError()
.message("Invalid OPTION scope %s. Scope must be SESSION or SYSTEM.", scope)
.build(logger);
}
}
// Currently, we convert multi-part identifier to a string.
if (value != null) { // SET option
final OptionValue optionValue = createOptionValue(name, type, (SqlLiteral) value);
options.setOption(optionValue);
} else { // RESET option
if ("ALL".equalsIgnoreCase(name)) {
session.setDefaultSchemaPath(null);
options.deleteAllOptions(type);
} else {
options.deleteOption(name, type);
}
}
return Collections.singletonList(SimpleCommandResult.successful("%s updated.", name));
}
OptionManager参考实现
实现子类,可以看到比较多,对于不同的实现内部处理上稍有不同
- SystemOptionManager 系统级实现简单说明
系统级实现是所有节点都可见的,因为配置需要持久化内部使用了kv,同时此服务是在那个节点都包含,实现了service 接口,在start 中
同时还包含了一个基于定时任务的数据刷新
数据刷新
if (scheduler.get() != null) {
scheduler.get().schedule(Schedule.Builder.everyMinutes(FETCH_SYSTEM_OPTION_POLLING_FREQUENCY_MIN).build(),
new FetchSystemOptionTask());
}
设置处理
public boolean setOption(final OptionValue value) {
checkArgument(value.getType() == OptionType.SYSTEM, "OptionType must be SYSTEM.");
final String name = value.getName().toLowerCase(Locale.ROOT);
final OptionValidator validator = optionValidatorListing.getValidator(name);
validator.validate(value); // validate the option
final Map<String, OptionValueProto> optionMap = new HashMap<>(); // temp map for convenient lookups
getOptionProtoList().forEach(optionProto -> optionMap.put(optionProto.getName(), optionProto));
// no need to set option if value is the same
if (optionMap.containsKey(name) && optionMap.get(name).equals(OptionValueProtoUtils.toOptionValueProto(value))) {
return true;
}
// Handle setting option to the default value
if (value.equals(validator.getDefault())) {
if (optionMap.containsKey(value.getName())) {
// If option was previously set, remove it
optionMap.remove(value.getName());
} else {
// If option was not set, skip the set completely
return true;
}
}
optionMap.put(name, OptionValueProtoUtils.toOptionValueProto(value));
// kv 存储设置
options.put(OPTIONS_KEY, OptionValueProtoUtils.toOptionValueProtoList(optionMap.values()));
// 通过OptionChangeBroadcaster 进行通知更新,通知所有协调节点
refreshAndNotifySiblings();
// 通知监听 主要是实时通知一些查询任务
notifyListeners();
return true;
}
notifyListeners 使用到的模块
说明
以上是对于SetOptionHandler的简单说明,系统的配置参数还是比较重要的,了解一些配置参数可以规避或者临时解决一些dremio 限制问题,对于
系统选项还包含了一个系统表sys.options
可以参考
参考资料
sabot/kernel/src/main/java/com/dremio/exec/planner/sql/handlers/direct/SetOptionHandler.java
sabot/kernel/src/main/java/com/dremio/exec/planner/sql/handlers/commands/CommandCreator.java
sabot/kernel/src/main/java/com/dremio/exec/server/options/SystemOptionManager.java
services/options/src/main/java/com/dremio/options/OptionManager.java
sabot/kernel/src/main/java/com/dremio/exec/server/options/OptionChangeBroadcaster.java