Apache DolphinScheduler 1.3.4升级至3.1.2版本过程中的踩坑纪录 ...

打印 上一主题 下一主题

主题 1725|帖子 1725|积分 5175

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
因为在工作中需要推动Apache DolphinScheduler的升级,经过预研,从1.3.4到3.1.2有的体验了很大的提升,在性能和功能性有了很多的改善,推荐升级。
检察官方的升级文档,可知有提供升级脚本,如果只是跨小版本的更新那么只用执行脚本就好了,但跨多个大版本升级时依然容易出现各种题目,特此总结
旧版本:1.3.4
新版本:3.1.2
题目合集

1.资源中心报错

升级完成后利用资源中心报错 IllegalArgumentException: Failed to specify server's Kerberos principal name
资源中心利用的HDFS,开启了kerberos认证
解决方法:
编辑 dolphinscheduler/api-server/conf/hdfs-site.xml 添加以下内容
  1. <property>
  2.     <name>dfs.namenode.kerberos.principal.pattern</name>
  3.     <value>*</value>
  4. </property>
复制代码
2.任务实例日记丢失

升级完成后检察任务实例的日记,报错未找到日记,检察报错信息,检查新版本的目次结构和表里的日记路径,发现缘故原由是新版本的日记路径有变动。
升级前的日记路径在   /logs/ 下。
升级后的日记路径在 /worker-server/logs/ 下。
因此需要修改这里的目次
解决方法:
执行SQL修改日记路径
  1. update t_ds_task_instance set log_path=replace(log_path,'/logs/','/worker-server/logs/');
复制代码
然后将原日记文件copy到新的日记路径
  1. cp -r {旧版本dolphinscheduler目录}/logs/[1-9]* {新版本dolphinscheduler目录}/worker-server/logs/*
复制代码
3.升级完创建工作流报错

检察报错信息,缘故原由是 t_ds_process_definition_log 和 t_ds_process_definition 主键的初始值不一致,那么修改成一致的就好了!
解决方法:
执行SQL
  1. # 查出主键自增值
  2. select AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'dolphinscheduler' AND TABLE_NAME = 't_ds_process_definition' limit 1
  3. # 将上面SQL的执行结果填写到下方参数处执行
  4. alter table dolphinscheduler_bak1.t_ds_process_definition_log auto_increment = {max_id};
复制代码
4.升级后任务实例列表为空

检查查询的SQL
在 dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/TaskInstanceMapper.xml 文件里,select id="queryTaskInstanceListPaging"的SQL
  1.                select
  2.         <include refid="baseSqlV2">
  3.             <property name="alias" value="instance"/>
  4.         </include>
  5.         ,
  6.         process.name as process_instance_name
  7.         from t_ds_task_instance instance
  8.         left join t_ds_task_definition_log define on define.code=instance.task_code and define.version=instance.task_definition_version
  9.         left join t_ds_process_instance process on process.id=instance.process_instance_id
  10.         where define.project_code = #{projectCode}
  11.         <if test="startTime != null">
  12.             and instance.start_time <![CDATA[ >=]]> #{startTime}
  13.         </if>
  14.                 ......省略多余部分
复制代码
查询任务实例列表的SQL会关联 t_ds_task_definition_log 表,经检查发现是 define.code=instance.task_code 这一句关联不上。
结合下面的查询条件 define.project_code = #{projectCode} 可知,关联 t_ds_task_definition_log 重要是为了过滤 projectCode,那么来修改下这个SQL:
解决方法:
  1.             select
  2.         <include refid="baseSqlV2">
  3.             <property name="alias" value="instance"/>
  4.         </include>
  5.         ,
  6.         process.name as process_instance_name
  7.         from t_ds_task_instance instance
  8. --         left join t_ds_task_definition_log define
  9. --                                on define.code=instance.task_code and
  10. --                                        define.version=instance.task_definition_version
  11.         join t_ds_process_instance process
  12.                 on process.id=instance.process_instance_id
  13.         join t_ds_process_definition define
  14.                 on define.code=process.process_definition_code
  15.         where define.project_code = #{projectCode}
  16.         <if test="startTime != null">
  17.             and instance.start_time <![CDATA[ >=]]> #{startTime}
  18.         </if>
  19.                 ......省略多余部分
复制代码
直接用 t_ds_process_definition 关联,也有 project_code 字段可以用来关联过滤,这里修改后就能查出数据了。
5.执行升级脚本的过程中报空指针

(1)分析日记,定位到 UpgradeDao.java 517行

检察代码
  1. 513 if (TASK_TYPE_SUB_PROCESS.equals(taskType)) {
  2. 514                       JsonNode jsonNodeDefinitionId = param.get("processDefinitionId");
  3. 515                       if (jsonNodeDefinitionId != null) {
  4. 516                           param.put("processDefinitionCode",
  5. 517                                  processDefinitionMap.get(jsonNodeDefinitionId.asInt()).getCode());
  6. 518                            param.remove("processDefinitionId");
  7. 519                        }
  8. 520                    }
复制代码
很明显是 processDefinitionMap.get(jsonNodeDefinitionId.asInt()) 返回了null,加个null判定,如果返回null直接跳过,并将相干信息打印出来,升级结束后可以根据日记核对。
解决方法:
修改后:
  1. if (jsonNodeDefinitionId != null) {
  2.     if (processDefinitionMap.get(jsonNodeDefinitionId.asInt()) != null) {
  3.         param.put("processDefinitionCode",processDefinitionMap.get(jsonNodeDefinitionId.asInt()).getCode());
  4.         param.remove("processDefinitionId");
  5.     } else {
  6.         logger.error("*******************error");
  7.         logger.error("*******************param:" + param);
  8.         logger.error("*******************jsonNodeDefinitionId:" + jsonNodeDefinitionId);
  9.     }
  10. }
复制代码
(2)分析日记,定位到 UpgradeDao.java 675行

检察代码
  1. 669 if (mapEntry.isPresent()) {
  2. 670                            Map.Entry<Long, Map<String, Long>> processCodeTaskNameCodeEntry = mapEntry.get();
  3. 671                            dependItem.put("definitionCode", processCodeTaskNameCodeEntry.getKey());
  4. 672                            String depTasks = dependItem.get("depTasks").asText();
  5. 673                            long taskCode =
  6. 674                                    "ALL".equals(depTasks) || processCodeTaskNameCodeEntry.getValue() == null ? 0L
  7. 675                                            : processCodeTaskNameCodeEntry.getValue().get(depTasks);
  8. 676                            dependItem.put("depTaskCode", taskCode);
  9. 677                        }
复制代码
很明显是 processCodeTaskNameCodeEntry.getValue().get(depTasks) 返回了null,修改下逻辑,不为null才赋值并打印相干日记。
解决方法:
修改后:
  1. long taskCode =0;
  2.                             if (processCodeTaskNameCodeEntry.getValue() != null
  3.                                     &&processCodeTaskNameCodeEntry.getValue().get(depTasks)!=null){
  4.                                 taskCode =processCodeTaskNameCodeEntry.getValue().get(depTasks);
  5.                             }else{
  6.                                 logger.error("******************** depTasks:"+depTasks);
  7.                                 logger.error("******************** taskCode not in "+JSONUtils.toJsonString(processCodeTaskNameCodeEntry));
  8.                             }
  9.                             dependItem.put("depTaskCode", taskCode);
复制代码
6.接入LDAP后登岸失败,不知道Email字段名

可在 api-server/conf/application.yaml 配置接入LDAP
  1. security:
  2.   authentication:
  3.     # Authentication types (supported types: PASSWORD,LDAP)
  4.     type: LDAP
  5.     # IF you set type `LDAP`, below config will be effective
  6.     ldap:
  7.       # ldap server config
  8.       urls: xxx
  9.       base-dn: xxx
  10.       username: xxx
  11.       password: xxx
  12.       user:
  13.         # admin userId when you use LDAP login
  14.         admin: xxx
  15.         identity-attribute: xxx
  16.         email-attribute: xxx
  17.         # action when ldap user is not exist (supported types: CREATE,DENY)
  18.         not-exist-action: CREATE
复制代码
要成功接入LDAP至少需要urls,base-dn,username,password,identity和email正确填写,不知道email字段名可以按下面的方式处置惩罚,email先空着
启动服务后用LDAP用户登录
解决办法:
LDAP 认证的代码在 dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapService.java 的 ldapLogin()
[code]ctx = new InitialLdapContext(searchEnv, null);SearchControls sc = new SearchControls();sc.setReturningAttributes(new String[]{ldapEmailAttribute});sc.setSearchScope(SearchControls.SUBTREE_SCOPE);EqualsFilter filter = new EqualsFilter(ldapUserIdentifyingAttribute, userId);NamingEnumeration results = ctx.search(ldapBaseDn, filter.toString(), sc);if (results.hasMore()) {    // get the users DN (distinguishedName) from the result    SearchResult result = results.next();    NamingEnumeration
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

种地

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表