<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Chen Debra</title>
    <description>The latest articles on DEV Community by Chen Debra (@chen_debra_3060b21d12b1b0).</description>
    <link>https://dev.to/chen_debra_3060b21d12b1b0</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1533306%2Fc0ea3a94-ba17-47c8-9304-4571fb1adaf9.png</url>
      <title>DEV Community: Chen Debra</title>
      <link>https://dev.to/chen_debra_3060b21d12b1b0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chen_debra_3060b21d12b1b0"/>
    <language>en</language>
    <item>
      <title>💡 Open source isn't just for developers. Learn how anyone can contribute with docs, design, translation, and AI—no coding required!</title>
      <dc:creator>Chen Debra</dc:creator>
      <pubDate>Thu, 23 Jul 2026 02:06:46 +0000</pubDate>
      <link>https://dev.to/chen_debra_3060b21d12b1b0/open-source-isnt-just-for-developers-learn-how-anyone-can-contribute-with-docs-design-2cn4</link>
      <guid>https://dev.to/chen_debra_3060b21d12b1b0/open-source-isnt-just-for-developers-learn-how-anyone-can-contribute-with-docs-design-2cn4</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/you-dont-need-to-code-to-contribute-a-beginners-guide-to-open-source-2of8" class="crayons-story__hidden-navigation-link"&gt;You Don't Need to Code to Contribute: A Beginner's Guide to Open Source&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/chen_debra_3060b21d12b1b0" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1533306%2Fc0ea3a94-ba17-47c8-9304-4571fb1adaf9.png" alt="chen_debra_3060b21d12b1b0 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/chen_debra_3060b21d12b1b0" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Chen Debra
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Chen Debra
                
              
              &lt;div id="story-author-preview-content-4209980" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/chen_debra_3060b21d12b1b0" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1533306%2Fc0ea3a94-ba17-47c8-9304-4571fb1adaf9.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Chen Debra&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/you-dont-need-to-code-to-contribute-a-beginners-guide-to-open-source-2of8" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jul 23&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/you-dont-need-to-code-to-contribute-a-beginners-guide-to-open-source-2of8" id="article-link-4209980"&gt;
          You Don't Need to Code to Contribute: A Beginner's Guide to Open Source
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/nocode"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;nocode&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/beginners"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;beginners&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/you-dont-need-to-code-to-contribute-a-beginners-guide-to-open-source-2of8#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            11 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>You Don't Need to Code to Contribute: A Beginner's Guide to Open Source</title>
      <dc:creator>Chen Debra</dc:creator>
      <pubDate>Thu, 23 Jul 2026 02:06:14 +0000</pubDate>
      <link>https://dev.to/chen_debra_3060b21d12b1b0/you-dont-need-to-code-to-contribute-a-beginners-guide-to-open-source-2of8</link>
      <guid>https://dev.to/chen_debra_3060b21d12b1b0/you-dont-need-to-code-to-contribute-a-beginners-guide-to-open-source-2of8</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2cim7mj6w44w8gfpog47.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2cim7mj6w44w8gfpog47.jpg" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Many people assume that open source is a world reserved for elite programmers and seasoned developers. If you can't read code or write software, it can feel like there's no place for you.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The reality is very different.&lt;/p&gt;

&lt;p&gt;Countless contributors from non-technical backgrounds have faced the same challenges—feeling overwhelmed by GitHub, intimidated by unfamiliar terminology, or convinced they simply weren't "technical enough." Yet many of them have gone on to become trusted community members and invaluable contributors.&lt;/p&gt;

&lt;p&gt;If you've ever wanted to get involved in open source but didn't know where to begin, this guide is for you. Based on real-world experience and lessons learned along the way, it will help you understand how open source works, overcome the common hurdles, and discover meaningful ways to contribute—even if you never write a single line of code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Open Source Isn't as Intimidating as You Think
&lt;/h2&gt;

&lt;p&gt;Before contributing to an open source project, it's worth setting aside some of the myths that often surround open source.&lt;/p&gt;

&lt;p&gt;Open source software (OSS) is software whose source code is made publicly available under an open source license. These licenses allow anyone to &lt;strong&gt;view, study, modify, and redistribute the source code&lt;/strong&gt;, provided they comply with the terms of the license.&lt;/p&gt;

&lt;p&gt;At its core, open source is about collaboration. It's not just a way to develop software—it's a model for building technology in the open, where people from around the world can improve projects together.&lt;/p&gt;

&lt;p&gt;A few key ideas help explain what open source really means.&lt;/p&gt;

&lt;h3&gt;
  
  
  Freedom to Use, Learn, and Build
&lt;/h3&gt;

&lt;p&gt;Open source licenses don't mean that software has "no owner." Copyright remains with the original author or organization. What the license does is grant others the right to use, modify, and distribute the software under clearly defined conditions.&lt;/p&gt;

&lt;p&gt;Depending on the license, you may be free to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the software for personal or commercial purposes&lt;/li&gt;
&lt;li&gt;Study how it works&lt;/li&gt;
&lt;li&gt;Modify the source code&lt;/li&gt;
&lt;li&gt;Share your own versions with others&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As long as you follow the license requirements, these freedoms are protected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open Collaboration at Scale
&lt;/h3&gt;

&lt;p&gt;Unlike traditional proprietary software, open source projects are developed in public.&lt;/p&gt;

&lt;p&gt;Developers, technical writers, designers, translators, community managers, and users from around the world all contribute through discussions, documentation, code reviews, bug reports, feature requests, and countless other forms of collaboration.&lt;/p&gt;

&lt;p&gt;In many ways, open source resembles community-driven knowledge platforms: everyone has the opportunity to make the project better.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where the Term "Open Source" Came From
&lt;/h3&gt;

&lt;p&gt;The term &lt;strong&gt;"open source software"&lt;/strong&gt; emerged in the late 1990s as a way to make the principles of free software more accessible to businesses and the broader technology industry.&lt;/p&gt;

&lt;p&gt;While the philosophy has evolved over time, the goal remains the same: encouraging innovation through openness, collaboration, and shared knowledge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Do Open Source Foundations Matter?
&lt;/h2&gt;

&lt;p&gt;If an open source project were a startup, an open source foundation would be the organization responsible for ensuring that the project can thrive over the long term.&lt;/p&gt;

&lt;p&gt;Beyond providing visibility and credibility, foundations play a critical role in project governance. They act as independent legal entities that manage trademarks, intellectual property, and other shared assets, helping ensure that no single company can take unilateral control of the project. This vendor-neutral governance model is one of the defining characteristics of many successful open source communities.&lt;/p&gt;

&lt;p&gt;Today, several foundations have become pillars of the global open source ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apache Software Foundation (ASF)
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Apache Software Foundation (ASF)&lt;/strong&gt; is home to hundreds of influential open source projects, particularly in the big data ecosystem. Beyond hosting projects, ASF is widely recognized for its mature community governance model and its emphasis on meritocracy, openness, and collaborative decision-making.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linux Foundation
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Linux Foundation&lt;/strong&gt; stewards the Linux kernel while supporting some of the world's largest collaborative open source initiatives. It also plays a major role in advancing industry standards and fostering innovation across cloud computing, networking, security, AI, and many other technology domains.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloud Native Computing Foundation (CNCF)
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Cloud Native Computing Foundation (CNCF)&lt;/strong&gt; focuses on cloud-native technologies such as Kubernetes, Prometheus, Envoy, and many other projects that power modern infrastructure. It has become one of the most influential organizations in the cloud-native ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  OpenAtom Foundation
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;OpenAtom Foundation&lt;/strong&gt; is one of China's leading open source foundations. It supports the development of domestic open source projects while promoting collaboration between Chinese open source communities and the global ecosystem.&lt;/p&gt;

&lt;p&gt;But foundations do much more than simply host projects.&lt;/p&gt;

&lt;p&gt;They provide governance frameworks, establish community standards, help projects adopt sustainable operating models, and create opportunities for collaboration across communities. For emerging projects, joining a foundation often means gaining access to proven governance practices, experienced mentors, and a broader developer ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Source Licenses: The Legal Foundation of Every Project
&lt;/h2&gt;

&lt;p&gt;For many newcomers—especially those without a technical background—open source licenses can feel like an afterthought. In reality, they're one of the most important parts of the open source ecosystem.&lt;/p&gt;

&lt;p&gt;An open source license defines &lt;strong&gt;what you can do with the code, what obligations you have when using it, and how intellectual property is protected&lt;/strong&gt;. Whether you're building a commercial product, contributing to an existing project, or simply experimenting with an open source library, understanding the license is essential.&lt;/p&gt;

&lt;p&gt;A simple way to think about it is this: an open source license is similar to a content license for creative work. The author decides how others may use their work, and anyone who benefits from it must respect those terms.&lt;/p&gt;

&lt;p&gt;While dozens of open source licenses exist today, most fall into three broad categories.&lt;/p&gt;

&lt;h3&gt;
  
  
  MIT and BSD Licenses: Maximum Flexibility
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;MIT License&lt;/strong&gt; and &lt;strong&gt;BSD Licenses&lt;/strong&gt; are among the most permissive open source licenses available.&lt;/p&gt;

&lt;p&gt;As long as you retain the original copyright notice, you're generally free to use, modify, distribute, and even incorporate the code into proprietary commercial software.&lt;/p&gt;

&lt;p&gt;Their simplicity and flexibility have made them popular choices for libraries, frameworks, and developer tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apache License 2.0: Enterprise-Friendly by Design
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Apache License 2.0&lt;/strong&gt; strikes a balance between openness and legal clarity.&lt;/p&gt;

&lt;p&gt;In addition to allowing commercial use, modification, and redistribution, it explicitly addresses &lt;strong&gt;patent grants&lt;/strong&gt;, &lt;strong&gt;contributor protections&lt;/strong&gt;, and &lt;strong&gt;trademark usage&lt;/strong&gt;—areas that are especially important for organizations building products on top of open source software.&lt;/p&gt;

&lt;p&gt;That's one of the reasons why many widely adopted projects in big data, cloud computing, and distributed systems are released under Apache License 2.0.&lt;/p&gt;

&lt;h3&gt;
  
  
  GNU GPL: Share-Alike by Design
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;GNU General Public License (GPL)&lt;/strong&gt; follows a different philosophy.&lt;/p&gt;

&lt;p&gt;Often described as a &lt;strong&gt;strong copyleft license&lt;/strong&gt;, the GPL requires that if you distribute software derived from GPL-licensed code, the derivative work must also be released under the GPL.&lt;/p&gt;

&lt;p&gt;It's worth noting, however, that this obligation is generally triggered by &lt;strong&gt;distribution&lt;/strong&gt;. If GPL-licensed software is modified solely for internal use and never distributed outside your organization, those source code disclosure requirements typically do not apply.&lt;/p&gt;

&lt;p&gt;Each license reflects a different approach to collaboration, software freedom, and intellectual property. Understanding those differences helps you choose the right projects to use—and the right license if you ever publish software of your own.&lt;/p&gt;

&lt;h2&gt;
  
  
  You Don't Need to Write Code to Contribute
&lt;/h2&gt;

&lt;p&gt;One of the biggest misconceptions about open source is that &lt;strong&gt;every meaningful contribution must involve code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It doesn't.&lt;/p&gt;

&lt;p&gt;In fact, healthy open source communities depend on contributors with a wide range of skills. Documentation, design, education, community building, localization, and user support are all critical to a project's long-term success.&lt;/p&gt;

&lt;p&gt;That said, it's also fair to acknowledge that most open source communities are still designed primarily with developers in mind. For first-time contributors without a technical background, the learning curve can feel steep.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning the Workflow Can Be the Hardest Part
&lt;/h3&gt;

&lt;p&gt;For many newcomers, the biggest challenge isn't understanding the project itself—it's understanding the contribution workflow.&lt;/p&gt;

&lt;p&gt;Concepts like &lt;strong&gt;forking a repository&lt;/strong&gt;, &lt;strong&gt;creating a branch&lt;/strong&gt;, &lt;strong&gt;opening a pull request&lt;/strong&gt;, or &lt;strong&gt;syncing with the upstream repository&lt;/strong&gt; are second nature to experienced developers, but they can be overwhelming if you've never used GitHub before.&lt;/p&gt;

&lt;p&gt;It's not unusual for someone's very first contribution to be delayed simply because they're trying to figure out how Git works.&lt;/p&gt;

&lt;p&gt;And that's perfectly normal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Non-Code Contributions Matter More Than You Think
&lt;/h3&gt;

&lt;p&gt;Every successful open source project relies on much more than software engineering.&lt;/p&gt;

&lt;p&gt;Communities also need people who can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write and improve documentation&lt;/li&gt;
&lt;li&gt;Design diagrams, illustrations, and presentation materials&lt;/li&gt;
&lt;li&gt;Translate documentation into multiple languages&lt;/li&gt;
&lt;li&gt;Organize meetups, webinars, and community events&lt;/li&gt;
&lt;li&gt;Produce tutorial videos and educational content&lt;/li&gt;
&lt;li&gt;Share real-world use cases and success stories&lt;/li&gt;
&lt;li&gt;Moderate discussion forums and community channels&lt;/li&gt;
&lt;li&gt;Improve onboarding guides for new contributors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These contributions may not appear in the project's source code, but they often have an equally significant impact on community growth and user adoption.&lt;/p&gt;

&lt;p&gt;Many long-time community leaders built their reputation not through code contributions alone, but by consistently helping others, improving documentation, and strengthening the community over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trust Is Built Through Consistency
&lt;/h3&gt;

&lt;p&gt;Unlike a merged pull request, the impact of non-code contributions isn't always visible immediately.&lt;/p&gt;

&lt;p&gt;Community building is a long-term investment.&lt;/p&gt;

&lt;p&gt;Whether you're answering questions, improving documentation, translating tutorials, or organizing events, every contribution helps make the project more welcoming and accessible.&lt;/p&gt;

&lt;p&gt;Over time, those consistent efforts build trust—and trust is one of the most valuable forms of contribution in any open source community.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three Challenges Almost Every New Contributor Faces
&lt;/h2&gt;

&lt;p&gt;Whether you're joining Apache DolphinScheduler, Kubernetes, or virtually any other open source community, you'll likely encounter a few common obstacles when you're getting started.&lt;/p&gt;

&lt;p&gt;The good news? They're all part of the learning process.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Learning the Tooling
&lt;/h3&gt;

&lt;p&gt;Compared with the business applications most people use every day—such as office suites, knowledge bases, or CRM platforms—developer tools often feel much more intimidating.&lt;/p&gt;

&lt;p&gt;Applications like GitHub Desktop, Git clients, IDEs, and terminal environments introduce new concepts and workflows that can take time to learn.&lt;/p&gt;

&lt;p&gt;For many newcomers, simply becoming comfortable with these tools is the first major milestone.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Understanding Merge Conflicts
&lt;/h3&gt;

&lt;p&gt;Imagine this scenario: you've finally submitted your first pull request, only to discover that GitHub reports a &lt;strong&gt;merge conflict&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you've never encountered one before, the term alone can be discouraging.&lt;/p&gt;

&lt;p&gt;Fortunately, the concept is much simpler than it sounds.&lt;/p&gt;

&lt;p&gt;Think of it like two people editing the same paragraph in a shared document at the same time. Since both versions change the same content differently, Git can't automatically determine which version should be kept. Human intervention is needed to resolve the conflict.&lt;/p&gt;

&lt;p&gt;Once you understand the analogy, merge conflicts become far less intimidating.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Debugging Error Messages
&lt;/h3&gt;

&lt;p&gt;Error messages are another common source of frustration for new contributors.&lt;/p&gt;

&lt;p&gt;You know something has gone wrong—but you may have no idea where to start.&lt;/p&gt;

&lt;p&gt;A failed build, a Git error, or a confusing terminal message can feel like reading a foreign language. Without prior experience, identifying the root cause is often the most difficult part of solving the problem.&lt;/p&gt;

&lt;p&gt;The important thing to remember is that every experienced contributor has been in the same position.&lt;/p&gt;

&lt;p&gt;Learning to troubleshoot is a skill that develops over time—not something anyone is expected to master on day one.&lt;/p&gt;

&lt;h2&gt;
  
  
  How AI Is Lowering the Barrier to Open Source
&lt;/h2&gt;

&lt;p&gt;The rise of generative AI is transforming how people learn, contribute to, and collaborate within open source communities.&lt;/p&gt;

&lt;p&gt;For contributors without a software engineering background, AI isn't a replacement for learning—it's an accelerator. It helps newcomers overcome technical hurdles faster, understand unfamiliar concepts, and create high-quality contributions with greater confidence.&lt;/p&gt;

&lt;p&gt;Whether you're improving documentation, designing visual assets, translating content, or troubleshooting an issue, AI can dramatically reduce the time it takes to make meaningful contributions.&lt;/p&gt;

&lt;p&gt;Here are a few practical ways AI is making open source more accessible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Turn Complex Technical Concepts into Visuals
&lt;/h3&gt;

&lt;p&gt;One of the biggest challenges for newcomers is understanding architecture diagrams, system workflows, and technical documentation.&lt;/p&gt;

&lt;p&gt;AI-powered design tools can transform dense technical descriptions into clear, easy-to-understand diagrams, making complex systems far more approachable.&lt;/p&gt;

&lt;p&gt;For example, instead of asking new users to interpret a lengthy explanation of a distributed workflow engine, you can generate a simplified architecture diagram or request flow illustration that highlights the key components and interactions. Visual learning materials like these can significantly shorten the onboarding process for new community members.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Real-World Architecture and Solution Diagrams
&lt;/h3&gt;

&lt;p&gt;Open source projects often need more than technical documentation—they also need compelling ways to demonstrate real-world business value.&lt;/p&gt;

&lt;p&gt;With the right prompts, AI can generate polished architecture diagrams, workflow illustrations, and solution overviews tailored to specific industries or use cases.&lt;/p&gt;

&lt;p&gt;Imagine showcasing how an open source workflow orchestration platform supports a manufacturing production line, or illustrating how data flows through a modern data platform. These visuals make it much easier for prospective users, customers, and decision-makers to understand the practical value of a project.&lt;/p&gt;

&lt;p&gt;For community advocates and technical marketers, this can be just as valuable as writing code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use AI to Explain Error Messages
&lt;/h3&gt;

&lt;p&gt;Debugging can be one of the most intimidating parts of contributing to open source.&lt;/p&gt;

&lt;p&gt;Instead of struggling through pages of unfamiliar error logs, try asking an AI assistant to explain them in plain language.&lt;/p&gt;

&lt;p&gt;Rather than simply identifying the error, modern AI models can often:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explain what the message actually means&lt;/li&gt;
&lt;li&gt;Point out the likely root cause&lt;/li&gt;
&lt;li&gt;Recommend a step-by-step troubleshooting approach&lt;/li&gt;
&lt;li&gt;Suggest possible fixes&lt;/li&gt;
&lt;li&gt;Clarify why a merge conflict or build failure occurred&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For newcomers, having an "always-available mentor" dramatically reduces the frustration of solving technical problems independently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Translate and Localize Documentation
&lt;/h3&gt;

&lt;p&gt;Most successful open source communities are global communities.&lt;/p&gt;

&lt;p&gt;That means documentation, tutorials, release notes, and user guides often need to be available in multiple languages.&lt;/p&gt;

&lt;p&gt;AI can dramatically speed up translation while also helping contributors adapt content for local audiences. Instead of relying on literal machine translation, you can use AI to rewrite documentation in a way that feels natural to readers in different regions.&lt;/p&gt;

&lt;p&gt;Just as importantly, AI can help transform highly technical documentation into beginner-friendly tutorials—making projects more welcoming to first-time users around the world.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build Better Community Knowledge
&lt;/h3&gt;

&lt;p&gt;Every active open source community eventually encounters the same challenge: the same questions get asked over and over again.&lt;/p&gt;

&lt;p&gt;Issues, Discussions, Slack channels, Discord servers, and mailing lists all accumulate valuable knowledge—but much of it remains scattered across different platforms.&lt;/p&gt;

&lt;p&gt;AI can help identify recurring questions, summarize community discussions, and organize them into well-structured FAQs, troubleshooting guides, or onboarding documentation.&lt;/p&gt;

&lt;p&gt;This not only reduces the support burden on maintainers but also makes it much easier for newcomers to find answers on their own.&lt;/p&gt;

&lt;p&gt;In many communities, improving knowledge sharing is one of the highest-impact contributions anyone can make.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your First Contribution Doesn't Have to Be Code
&lt;/h2&gt;

&lt;p&gt;Open source has never been exclusively about software development.&lt;/p&gt;

&lt;p&gt;At its heart, it's about openness, collaboration, and the collective effort to build something that benefits everyone. Great communities thrive because they bring together people with different backgrounds, experiences, and skill sets—not because everyone writes code.&lt;/p&gt;

&lt;p&gt;If you're just getting started, you don't need to begin by submitting a complex pull request.&lt;/p&gt;

&lt;p&gt;A much simpler path is often the best one.&lt;/p&gt;

&lt;p&gt;Start by choosing a project you genuinely use or care about. Fix a typo in the documentation, improve an installation guide, or suggest a clearer explanation for new users. These small contributions are often the first step taken by long-time community members.&lt;/p&gt;

&lt;p&gt;Next, become part of the community itself. Join discussion forums, attend online meetups, participate in community events, or help organize local gatherings. Open source is built on relationships just as much as it is on repositories.&lt;/p&gt;

&lt;p&gt;Finally, look for ways to contribute using the skills you already have. Whether you're a designer, translator, technical writer, marketer, educator, product manager, or simply someone who enjoys helping others, your expertise can make a meaningful difference.&lt;/p&gt;

&lt;p&gt;The first few weeks may feel unfamiliar. Learning GitHub, understanding community workflows, and navigating technical terminology all take time.&lt;/p&gt;

&lt;p&gt;But with today's AI tools acting as learning companions—and with communities becoming more welcoming than ever—the barriers to entry are lower than they've ever been.&lt;/p&gt;

&lt;p&gt;Every thriving open source project needs developers.&lt;/p&gt;

&lt;p&gt;But it also needs writers.&lt;/p&gt;

&lt;p&gt;Designers.&lt;/p&gt;

&lt;p&gt;Translators.&lt;/p&gt;

&lt;p&gt;Educators.&lt;/p&gt;

&lt;p&gt;Community builders.&lt;/p&gt;

&lt;p&gt;Advocates.&lt;/p&gt;

&lt;p&gt;And people who are simply willing to help.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you've been waiting for the "right time" to join an open source community, this is it. Your first contribution doesn't have to be code—it just has to be yours.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>nocode</category>
      <category>opensource</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🚀 Run Apache DolphinScheduler with Spark on Kubernetes! Learn cloud-native deployment, shared storage, and production-ready best practices. ☸️⚡ #ApacheDolphinScheduler #Kubernetes #ApacheSpark #CloudNative</title>
      <dc:creator>Chen Debra</dc:creator>
      <pubDate>Thu, 23 Jul 2026 01:50:02 +0000</pubDate>
      <link>https://dev.to/chen_debra_3060b21d12b1b0/run-apache-dolphinscheduler-with-spark-on-kubernetes-learn-cloud-native-deployment-shared-llm</link>
      <guid>https://dev.to/chen_debra_3060b21d12b1b0/run-apache-dolphinscheduler-with-spark-on-kubernetes-learn-cloud-native-deployment-shared-llm</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/running-apache-dolphinscheduler-with-spark-on-kubernetes-a-practical-deployment-guide-4j7c" class="crayons-story__hidden-navigation-link"&gt;Running Apache DolphinScheduler with Spark on Kubernetes: A Practical Deployment Guide&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/chen_debra_3060b21d12b1b0" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1533306%2Fc0ea3a94-ba17-47c8-9304-4571fb1adaf9.png" alt="chen_debra_3060b21d12b1b0 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/chen_debra_3060b21d12b1b0" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Chen Debra
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Chen Debra
                
              
              &lt;div id="story-author-preview-content-4209916" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/chen_debra_3060b21d12b1b0" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1533306%2Fc0ea3a94-ba17-47c8-9304-4571fb1adaf9.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Chen Debra&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/running-apache-dolphinscheduler-with-spark-on-kubernetes-a-practical-deployment-guide-4j7c" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jul 23&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/running-apache-dolphinscheduler-with-spark-on-kubernetes-a-practical-deployment-guide-4j7c" id="article-link-4209916"&gt;
          Running Apache DolphinScheduler with Spark on Kubernetes: A Practical Deployment Guide
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/apachedolphinscheduler"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;apachedolphinscheduler&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/spark"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;spark&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/kubernetes"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;kubernetes&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/running-apache-dolphinscheduler-with-spark-on-kubernetes-a-practical-deployment-guide-4j7c#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            9 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Running Apache DolphinScheduler with Spark on Kubernetes: A Practical Deployment Guide</title>
      <dc:creator>Chen Debra</dc:creator>
      <pubDate>Thu, 23 Jul 2026 01:46:59 +0000</pubDate>
      <link>https://dev.to/chen_debra_3060b21d12b1b0/running-apache-dolphinscheduler-with-spark-on-kubernetes-a-practical-deployment-guide-4j7c</link>
      <guid>https://dev.to/chen_debra_3060b21d12b1b0/running-apache-dolphinscheduler-with-spark-on-kubernetes-a-practical-deployment-guide-4j7c</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frj27siv7c3wyl8vvp72d.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frj27siv7c3wyl8vvp72d.jpg" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As enterprise data volumes continue to grow, deploying Apache DolphinScheduler on traditional physical servers or virtual machines is becoming increasingly challenging. Complex environment setup, low resource utilization, and limited scalability often make operations difficult. Running Spark and other big data workloads further amplifies these issues, requiring teams to maintain multiple runtime environments, resolve dependency conflicts, and handle unpredictable traffic spikes.&lt;/p&gt;

&lt;p&gt;Deploying DolphinScheduler on Kubernetes provides a cloud-native approach to solving these challenges. Containerization ensures consistent runtime environments, shared storage simplifies the distribution of Spark binaries and other dependencies, and Kubernetes enables elastic resource scaling to maximize infrastructure efficiency.&lt;/p&gt;

&lt;p&gt;In this guide, you'll learn how to deploy Apache DolphinScheduler on Kubernetes and integrate Spark workloads step by step. By the end, you'll have a highly available, scalable, and cloud-native workflow orchestration platform ready for production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Environment Preparation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;Before getting started, ensure your environment meets the following requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kubernetes cluster (v1.19 or later)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;kubectl&lt;/code&gt; command-line tool&lt;/li&gt;
&lt;li&gt;Helm 3.x&lt;/li&gt;
&lt;li&gt;A storage class that supports the &lt;strong&gt;ReadWriteMany (RWX)&lt;/strong&gt; access mode (required for shared storage)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Deployment Architecture
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F35mw5coubbx7sdivn2iw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F35mw5coubbx7sdivn2iw.jpg" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Deployment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1. Add the Helm Repository
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add dolphinscheduler https://dolphinscheduler.apache.org/helm
helm repo update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2. Create a Namespace
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace dolphinscheduler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3. Configure &lt;code&gt;values.yaml&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Create a custom &lt;code&gt;values.yaml&lt;/code&gt; file with the following key configurations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Shared storage configuration&lt;/span&gt;
&lt;span class="c1"&gt;# Required for storing Spark binaries and other shared resources&lt;/span&gt;
&lt;span class="na"&gt;common&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;sharedStoragePersistence&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/opt/soft"&lt;/span&gt;
    &lt;span class="na"&gt;accessModes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ReadWriteMany"&lt;/span&gt;
    &lt;span class="na"&gt;storageClassName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-storage-class"&lt;/span&gt;   &lt;span class="c1"&gt;# Replace with your storage class&lt;/span&gt;
    &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;20Gi"&lt;/span&gt;

  &lt;span class="na"&gt;configmap&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Spark environment variables&lt;/span&gt;
    &lt;span class="na"&gt;SPARK_HOME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/opt/soft/spark"&lt;/span&gt;
    &lt;span class="na"&gt;HADOOP_HOME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/opt/soft/hadoop"&lt;/span&gt;
    &lt;span class="na"&gt;HADOOP_CONF_DIR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/opt/soft/hadoop/etc/hadoop"&lt;/span&gt;
    &lt;span class="na"&gt;JAVA_HOME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/opt/java/openjdk"&lt;/span&gt;

&lt;span class="c1"&gt;# External database configuration&lt;/span&gt;
&lt;span class="na"&gt;externalDatabase&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-mysql-host"&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3306"&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dolphinscheduler"&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;root"&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-password"&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mysql"&lt;/span&gt;

&lt;span class="c1"&gt;# Worker configuration&lt;/span&gt;
&lt;span class="na"&gt;worker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;WORKER_EXEC_THREADS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key configuration notes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shared Storage&lt;/strong&gt; must be enabled to support Spark integration.&lt;/li&gt;
&lt;li&gt;The shared directory is mounted at &lt;code&gt;/opt/soft&lt;/code&gt;, where Spark and Hadoop binaries will be stored.&lt;/li&gt;
&lt;li&gt;Ensure your Kubernetes storage class supports the &lt;strong&gt;ReadWriteMany (RWX)&lt;/strong&gt; access mode so that all Worker Pods can access the same files.&lt;/li&gt;
&lt;li&gt;Using an external MySQL database is recommended for production deployments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4. Deploy Apache DolphinScheduler
&lt;/h3&gt;

&lt;p&gt;Install DolphinScheduler using Helm.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm &lt;span class="nb"&gt;install &lt;/span&gt;dolphinscheduler dolphinscheduler/dolphinscheduler &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; dolphinscheduler &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--values&lt;/span&gt; values.yaml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--version&lt;/span&gt; 3.2.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;It is recommended to specify an explicit chart version to ensure deployment consistency.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 5. Verify the Deployment
&lt;/h3&gt;

&lt;p&gt;After installation, verify that all components are running correctly.&lt;/p&gt;

&lt;p&gt;Check the Pod status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; dolphinscheduler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; dolphinscheduler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the Persistent Volume Claims:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pvc &lt;span class="nt"&gt;-n&lt;/span&gt; dolphinscheduler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all Pods are in the &lt;strong&gt;Running&lt;/strong&gt; state and the PVC has been successfully bound, your Apache DolphinScheduler deployment is ready for Spark integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spark Integration
&lt;/h2&gt;

&lt;p&gt;Once Apache DolphinScheduler has been successfully deployed, the next step is to integrate Apache Spark so that Spark applications can be scheduled and executed directly from DolphinScheduler.&lt;/p&gt;

&lt;p&gt;Since the shared storage has already been mounted at &lt;code&gt;/opt/soft&lt;/code&gt;, Spark only needs to be installed once. All Worker Pods can then access the same binaries through the shared volume.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1. Download the Spark Binary Package
&lt;/h3&gt;

&lt;p&gt;In this example, we'll use &lt;strong&gt;Apache Spark 3.2.1&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://archive.apache.org/dist/spark/spark-3.2.1/spark-3.2.1-bin-hadoop2.7.tgz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2. Copy Spark to a Worker Pod
&lt;/h3&gt;

&lt;p&gt;Because the shared storage is mounted under &lt;code&gt;/opt/soft&lt;/code&gt;, you only need to copy the Spark package into &lt;strong&gt;one&lt;/strong&gt; Worker Pod. The extracted files will automatically become available to all Workers through the shared volume.&lt;/p&gt;

&lt;p&gt;Copy the Spark package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;cp &lt;/span&gt;spark-3.2.1-bin-hadoop2.7.tgz dolphinscheduler-worker-0:/opt/soft &lt;span class="nt"&gt;-n&lt;/span&gt; dolphinscheduler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Log in to the Worker container and extract the package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; dolphinscheduler-worker-0 &lt;span class="nt"&gt;-n&lt;/span&gt; dolphinscheduler bash

&lt;span class="nb"&gt;cd&lt;/span&gt; /opt/soft

&lt;span class="nb"&gt;tar &lt;/span&gt;zxf spark-3.2.1-bin-hadoop2.7.tgz

&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; spark-3.2.1-bin-hadoop2.7.tgz

&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; spark-3.2.1-bin-hadoop2.7 spark
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify that Spark has been installed successfully:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$SPARK_HOME&lt;/span&gt;/bin/spark-submit &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the Spark version information is displayed correctly, the installation has completed successfully.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3. Configure Hadoop (Optional for Spark on YARN)
&lt;/h3&gt;

&lt;p&gt;If you plan to run Spark jobs in &lt;strong&gt;YARN&lt;/strong&gt; mode, Hadoop also needs to be installed and configured.&lt;/p&gt;

&lt;p&gt;Download the Hadoop binary package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://archive.apache.org/dist/hadoop/common/hadoop-3.3.1/hadoop-3.3.1.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy it into the Worker Pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;cp &lt;/span&gt;hadoop-3.3.1.tar.gz dolphinscheduler-worker-0:/opt/soft &lt;span class="nt"&gt;-n&lt;/span&gt; dolphinscheduler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Extract and configure Hadoop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; dolphinscheduler-worker-0 &lt;span class="nt"&gt;-n&lt;/span&gt; dolphinscheduler bash

&lt;span class="nb"&gt;cd&lt;/span&gt; /opt/soft

&lt;span class="nb"&gt;tar &lt;/span&gt;zxf hadoop-3.3.1.tar.gz

&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; hadoop-3.3.1.tar.gz

&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; hadoop-3.3.1 hadoop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set the Hadoop environment variables (these have already been configured in &lt;code&gt;values.yaml&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HADOOP_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/opt/soft/hadoop

&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;HADOOP_CONF_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/opt/soft/hadoop/etc/hadoop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the symbolic link is created and the environment variables are configured, DolphinScheduler Workers can locate the Hadoop installation automatically when submitting Spark jobs to YARN.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify Spark Jobs
&lt;/h2&gt;

&lt;p&gt;Once Spark has been installed, it's recommended to verify the environment before running production workloads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 1. Verify with a Shell Task
&lt;/h3&gt;

&lt;p&gt;The quickest way to validate your Spark environment is by creating a &lt;strong&gt;Shell Task&lt;/strong&gt; in the DolphinScheduler Web UI.&lt;/p&gt;

&lt;p&gt;Run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$SPARK_HOME&lt;/span&gt;/bin/spark-submit &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--class&lt;/span&gt; org.apache.spark.examples.SparkPi &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;$SPARK_HOME&lt;/span&gt;/examples/jars/spark-examples_2.12-3.2.1.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the task finishes, review the execution logs.&lt;/p&gt;

&lt;p&gt;If you see output similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pi is roughly 3.14...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;your Spark runtime has been configured successfully.&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 2. Verify with a Spark Task
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Upload the Example JAR
&lt;/h4&gt;

&lt;p&gt;Before creating a Spark task, upload the example JAR through the &lt;strong&gt;DolphinScheduler Resource Center&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Upload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spark-examples_2.12-3.2.1.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Create a Spark Task
&lt;/h4&gt;

&lt;p&gt;Configure the Spark task with the following settings.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Program Type&lt;/td&gt;
&lt;td&gt;Java&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Main Class&lt;/td&gt;
&lt;td&gt;&lt;code&gt;org.apache.spark.examples.SparkPi&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Main Program Package&lt;/td&gt;
&lt;td&gt;&lt;code&gt;spark-examples_2.12-3.2.1.jar&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy Mode&lt;/td&gt;
&lt;td&gt;&lt;code&gt;local&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Master&lt;/td&gt;
&lt;td&gt;&lt;code&gt;local[*]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Execute the workflow and confirm that the task completes successfully.&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 3. Verify with a Spark SQL Task
&lt;/h3&gt;

&lt;p&gt;You can also validate the Spark SQL engine by creating a Spark SQL task.&lt;/p&gt;

&lt;p&gt;Use the following SQL statements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Create a test table&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="n"&gt;test_table&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;STRING&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;USING&lt;/span&gt; &lt;span class="n"&gt;parquet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Insert sample data&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;test_table&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'test'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'dolphinscheduler'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Query the data&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;test_table&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure the task using these parameters:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Program Type&lt;/td&gt;
&lt;td&gt;SQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy Mode&lt;/td&gt;
&lt;td&gt;&lt;code&gt;local&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Master&lt;/td&gt;
&lt;td&gt;&lt;code&gt;local[*]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If the SQL statements execute successfully and return the expected results, the Spark SQL environment has been configured correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported Spark Deployment Modes
&lt;/h2&gt;

&lt;p&gt;According to the current Apache DolphinScheduler implementation, Kubernetes deployments support different Spark execution modes to varying degrees.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Deployment Mode&lt;/th&gt;
&lt;th&gt;Support Status&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Spark Local (client)&lt;/td&gt;
&lt;td&gt;Supported (via shared storage)&lt;/td&gt;
&lt;td&gt;Requires Spark binaries to be installed in the shared volume&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spark on YARN (cluster)&lt;/td&gt;
&lt;td&gt;Supported (with additional configuration)&lt;/td&gt;
&lt;td&gt;Requires a properly configured Hadoop environment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spark Standalone (cluster)&lt;/td&gt;
&lt;td&gt;Not Supported&lt;/td&gt;
&lt;td&gt;Currently unavailable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spark on Kubernetes (cluster)&lt;/td&gt;
&lt;td&gt;Not Supported&lt;/td&gt;
&lt;td&gt;Native Kubernetes deployment mode has not yet been implemented&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Although native &lt;strong&gt;Spark on Kubernetes&lt;/strong&gt; is not currently available, the shared-storage approach provides an effective solution for running Spark Local and Spark on YARN workloads within a Kubernetes-based DolphinScheduler deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Production-Ready Configuration
&lt;/h3&gt;

&lt;p&gt;While manually copying Spark binaries into the shared volume is sufficient for evaluation and testing, production deployments typically package Spark directly into the Worker image. This approach simplifies operations, shortens deployment time, and guarantees a consistent runtime environment across every Worker Pod.&lt;/p&gt;

&lt;h4&gt;
  
  
  Build a Custom Worker Image
&lt;/h4&gt;

&lt;p&gt;Create a custom Worker image with Spark pre-installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; dolphinscheduler.docker.scarf.sh/apache/dolphinscheduler-worker:3.2.0&lt;/span&gt;

&lt;span class="c"&gt;# Install Apache Spark&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;wget https://archive.apache.org/dist/spark/spark-3.2.1/spark-3.2.1-bin-hadoop2.7.tgz &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;tar &lt;/span&gt;zxf spark-3.2.1-bin-hadoop2.7.tgz &lt;span class="nt"&gt;-C&lt;/span&gt; /opt/soft &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; spark-3.2.1-bin-hadoop2.7.tgz &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /opt/soft/spark-3.2.1-bin-hadoop2.7 /opt/soft/spark

&lt;span class="c"&gt;# Configure environment variables&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; SPARK_HOME=/opt/soft/spark&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build and push the image to your container registry.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; your-registry/dolphinscheduler-worker:spark &lt;span class="nb"&gt;.&lt;/span&gt;
docker push your-registry/dolphinscheduler-worker:spark
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then update your &lt;code&gt;values.yaml&lt;/code&gt; file to use the custom Worker image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;worker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;your-registry/dolphinscheduler-worker&lt;/span&gt;
    &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;spark&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this approach, every newly created Worker Pod comes with Spark pre-installed, eliminating manual setup after deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure Resource Requests and Limits
&lt;/h3&gt;

&lt;p&gt;Proper resource allocation is essential for maintaining stable task execution, especially when multiple Spark jobs are running concurrently.&lt;/p&gt;

&lt;p&gt;Configure CPU and memory limits for Worker Pods as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;worker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8Gi"&lt;/span&gt;
      &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4"&lt;/span&gt;
    &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4Gi"&lt;/span&gt;
      &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In production environments, it's recommended to configure resource &lt;strong&gt;requests&lt;/strong&gt; and &lt;strong&gt;limits&lt;/strong&gt; based on your workload characteristics. This helps Kubernetes schedule Pods more efficiently while preventing individual tasks from consuming excessive cluster resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enable Worker Auto Scaling with KEDA
&lt;/h3&gt;

&lt;p&gt;Workload volumes often fluctuate throughout the day. Instead of provisioning a fixed number of Workers, Apache DolphinScheduler supports &lt;strong&gt;KEDA (Kubernetes Event-driven Autoscaling)&lt;/strong&gt;, allowing Worker Pods to scale automatically based on workload demand.&lt;/p&gt;

&lt;h4&gt;
  
  
  Install KEDA
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace keda

helm &lt;span class="nb"&gt;install &lt;/span&gt;keda kedacore/keda &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; keda &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--version&lt;/span&gt; v2.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Enable Auto Scaling
&lt;/h4&gt;

&lt;p&gt;After KEDA is installed, enable auto scaling when upgrading your DolphinScheduler deployment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm upgrade dolphinscheduler dolphinscheduler/dolphinscheduler &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; dolphinscheduler &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--set&lt;/span&gt; worker.keda.enabled&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--set&lt;/span&gt; worker.keda.minReplicaCount&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--set&lt;/span&gt; worker.keda.maxReplicaCount&lt;span class="o"&gt;=&lt;/span&gt;10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Worker deployment scales down to &lt;strong&gt;1&lt;/strong&gt; replica during idle periods.&lt;/li&gt;
&lt;li&gt;It can automatically scale up to &lt;strong&gt;10&lt;/strong&gt; replicas when task volume increases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This elasticity helps reduce infrastructure costs while ensuring sufficient computing capacity during peak workloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting Common Issues
&lt;/h2&gt;

&lt;p&gt;If a Spark task fails to execute, the following checks can help identify the root cause.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check Worker Logs
&lt;/h3&gt;

&lt;p&gt;Worker logs are usually the first place to investigate execution failures.&lt;/p&gt;

&lt;p&gt;View the live logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl logs dolphinscheduler-worker-0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; dolphinscheduler &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Search for logs related to a specific task:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl logs dolphinscheduler-worker-0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; dolphinscheduler | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"task"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify the Shared Storage
&lt;/h3&gt;

&lt;p&gt;Ensure the shared volume has been mounted correctly and is accessible from the Worker Pods.&lt;/p&gt;

&lt;p&gt;Check the Persistent Volume Claim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pvc &lt;span class="nt"&gt;-n&lt;/span&gt; dolphinscheduler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the mounted directory inside the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; dolphinscheduler-worker-0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; dolphinscheduler bash

&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;opt/soft

&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /opt/soft
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm that the Spark and Hadoop directories are present and accessible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Verify Environment Variables
&lt;/h3&gt;

&lt;p&gt;Check whether the required runtime environment variables have been configured correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; dolphinscheduler-worker-0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; dolphinscheduler bash

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$SPARK_HOME&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$HADOOP_HOME&lt;/span&gt;

&lt;span class="nv"&gt;$SPARK_HOME&lt;/span&gt;/bin/spark-submit &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the environment variables return the expected paths and &lt;code&gt;spark-submit&lt;/code&gt; reports the installed Spark version, the runtime environment has been configured successfully.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Spark Commands Cannot Be Found
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Worker reports errors such as &lt;code&gt;spark-submit: command not found&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Possible Causes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SPARK_HOME&lt;/code&gt; is not configured correctly.&lt;/li&gt;
&lt;li&gt;Spark was not extracted into the shared storage directory.&lt;/li&gt;
&lt;li&gt;The symbolic link to the Spark installation is missing or incorrect.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Resolution&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify that &lt;code&gt;SPARK_HOME&lt;/code&gt; points to the correct installation path.&lt;/li&gt;
&lt;li&gt;Confirm that Spark has been extracted under &lt;code&gt;/opt/soft&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Recreate the symbolic link if necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Shared Storage Fails to Mount
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Worker Pods cannot access files stored in &lt;code&gt;/opt/soft&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Possible Causes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The selected StorageClass does not support the &lt;strong&gt;ReadWriteMany (RWX)&lt;/strong&gt; access mode.&lt;/li&gt;
&lt;li&gt;The PersistentVolumeClaim is not bound successfully.&lt;/li&gt;
&lt;li&gt;The storage configuration in &lt;code&gt;values.yaml&lt;/code&gt; is incorrect.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Resolution&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify that your storage backend supports RWX.&lt;/li&gt;
&lt;li&gt;Check the status of the PVC and PersistentVolume.&lt;/li&gt;
&lt;li&gt;Review the storage configuration in your Helm values file.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Spark on YARN Jobs Fail
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Spark applications fail during submission or cannot connect to the YARN cluster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Possible Causes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hadoop is not installed correctly.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HADOOP_CONF_DIR&lt;/code&gt; points to an incorrect location.&lt;/li&gt;
&lt;li&gt;Network connectivity to the YARN cluster is unavailable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Resolution&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify the Hadoop installation.&lt;/li&gt;
&lt;li&gt;Confirm that &lt;code&gt;HADOOP_CONF_DIR&lt;/code&gt; contains the correct configuration files.&lt;/li&gt;
&lt;li&gt;Check connectivity between the Worker Pods and the YARN cluster.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Best Practices for Production Deployments
&lt;/h2&gt;

&lt;p&gt;The following recommendations can help improve reliability, scalability, and operational efficiency in production environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use High-Performance Shared Storage
&lt;/h3&gt;

&lt;p&gt;Since Spark binaries and shared resources are accessed by all Worker Pods, choose a high-performance storage backend—such as SSD-backed network storage—to minimize startup latency and improve overall job performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Define Appropriate Resource Quotas
&lt;/h3&gt;

&lt;p&gt;Configure CPU and memory requests and limits according to your workload profile. Proper resource management improves cluster utilization and reduces resource contention between concurrent jobs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement Monitoring and Alerting
&lt;/h3&gt;

&lt;p&gt;Monitor both the Kubernetes infrastructure and DolphinScheduler workloads. Collect metrics for Pod health, resource consumption, task execution status, and workflow success rates, and configure alerts for abnormal conditions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploy for High Availability
&lt;/h3&gt;

&lt;p&gt;Run multiple replicas for critical components to eliminate single points of failure. In production, it's generally recommended to deploy at least &lt;strong&gt;two Master replicas and two Worker replicas&lt;/strong&gt; to improve service availability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Establish a Backup Strategy
&lt;/h3&gt;

&lt;p&gt;Regularly back up the DolphinScheduler metadata database as well as workflow resources and configuration files. A well-defined backup and recovery strategy helps minimize downtime during unexpected failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;p&gt;This guide is based on &lt;strong&gt;Apache DolphinScheduler 3.2.0&lt;/strong&gt;. Configuration options and supported features may vary across releases.&lt;/p&gt;

&lt;p&gt;At the time of writing, &lt;strong&gt;native Spark on Kubernetes (cluster mode)&lt;/strong&gt; is not yet supported by DolphinScheduler. If your workload depends on this capability, keep an eye on future project releases for updates.&lt;/p&gt;

&lt;p&gt;Finally, remember to tailor the deployment to your own infrastructure. In particular, review environment-specific settings such as the storage class, external database configuration, networking, and cluster resource allocation before moving into production.&lt;/p&gt;

</description>
      <category>apachedolphinscheduler</category>
      <category>spark</category>
      <category>kubernetes</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Apache DolphinScheduler Zombie Tasks Explained: Safe Recovery Strategies Across Versions</title>
      <dc:creator>Chen Debra</dc:creator>
      <pubDate>Fri, 17 Jul 2026 06:37:35 +0000</pubDate>
      <link>https://dev.to/chen_debra_3060b21d12b1b0/apache-dolphinscheduler-zombie-tasks-explained-safe-recovery-strategies-across-versions-14fk</link>
      <guid>https://dev.to/chen_debra_3060b21d12b1b0/apache-dolphinscheduler-zombie-tasks-explained-safe-recovery-strategies-across-versions-14fk</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Have you ever encountered a task in Apache DolphinScheduler that remains stuck in the &lt;strong&gt;Running&lt;/strong&gt; state, even though the underlying process has already terminated?&lt;/p&gt;

&lt;p&gt;This "zombie task" scenario creates a mismatch between the UI and the actual execution state, preventing downstream tasks and workflows from progressing normally.&lt;/p&gt;

&lt;p&gt;The good news is that the solution depends on your DolphinScheduler version. In this guide, we'll explain why zombie tasks occur and walk through the recommended cleanup methods for both legacy and modern releases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Do Zombie Tasks Occur?
&lt;/h2&gt;

&lt;p&gt;A task that remains in the &lt;strong&gt;Running&lt;/strong&gt; state usually results from one of the following situations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Database latency&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Delayed database writes can prevent task status updates from being persisted, causing the UI to display an outdated execution state.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Worker node failure&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A Worker process unexpectedly stops, but the Master has not yet detected the failure.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Network instability&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ZooKeeper heartbeat timeouts trigger node removal events even though the task process may still be running.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Missing task instance&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The logs indicate that the task instance is &lt;code&gt;null&lt;/code&gt;, while the task status remains &lt;strong&gt;Running&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution for Legacy Versions (Earlier than 1.2.1)
&lt;/h2&gt;

&lt;p&gt;Versions prior to &lt;strong&gt;Apache DolphinScheduler 1.2.1&lt;/strong&gt; require manual cleanup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1. Clear the ZooKeeper Task Queue
&lt;/h3&gt;

&lt;p&gt;First, remove the stuck task from the ZooKeeper task queue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clear the ZooKeeper task queue&lt;/span&gt;
delete /dolphinscheduler/task_queue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents the stale task from continuously blocking the scheduling queue.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2. Update the Task Status in the Database
&lt;/h3&gt;

&lt;p&gt;Modify the task instance status directly in the database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Change the stuck task status to FAILURE (state = 6)&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;t_ds_task_instance&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="k"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;task_instance_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;STUCK_TASK_ID&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;State definitions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1&lt;/strong&gt; — RUNNING_EXECUTION&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;6&lt;/strong&gt; — FAILURE&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3. Resume the Workflow from the Failed Node
&lt;/h3&gt;

&lt;p&gt;In the DolphinScheduler UI:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Locate the corresponding workflow instance.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Recover from Failure&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The workflow resumes execution from the failed task instead of starting over.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Solution for Modern Versions (1.2.1 and Later)
&lt;/h2&gt;

&lt;p&gt;Starting with &lt;strong&gt;Apache DolphinScheduler 1.2.1&lt;/strong&gt;, the platform introduced an automatic fault-tolerance mechanism, eliminating the need for manual cleanup in most scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic Fault-Tolerance Mechanism
&lt;/h3&gt;

&lt;p&gt;The new fault-tolerance framework is built on ZooKeeper's &lt;strong&gt;Watcher&lt;/strong&gt; mechanism.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn2e9z5b1i8rkoo2sj8pc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn2e9z5b1i8rkoo2sj8pc.jpg" width="800" height="741"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Worker Failover Workflow
&lt;/h3&gt;

&lt;p&gt;When a Worker node receives a &lt;strong&gt;remove event&lt;/strong&gt;, the Master performs the following logic:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Handle only &lt;strong&gt;task instances&lt;/strong&gt;, not workflow instances.&lt;/li&gt;
&lt;li&gt;Compare the task instance start time with the Worker service startup time.&lt;/li&gt;
&lt;li&gt;If the task started &lt;strong&gt;after&lt;/strong&gt; the Worker restarted, skip failover.&lt;/li&gt;
&lt;li&gt;Otherwise, mark the task as &lt;strong&gt;NEED_FAULT_TOLERANCE&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The Master Scheduler thread automatically resubmits the task for execution.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This mechanism significantly improves cluster resilience during Worker failures and transient network issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  Task State Machine
&lt;/h3&gt;

&lt;p&gt;Modern versions also introduce a state machine to manage the complete task lifecycle, including pause and kill operations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Task kill event handler&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onKilledEvent&lt;/span&gt;&lt;span class="o"&gt;(...)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;releaseTaskInstanceResourcesIfNeeded&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;taskExecutionRunnable&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;persistentTaskInstanceKilledEventToDB&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;taskExecutionRunnable&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;taskInstanceKillEvent&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;taskExecutionRunnable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWorkflowExecutionGraph&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;markTaskExecutionRunnableChainKill&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;taskExecutionRunnable&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;publishWorkflowInstanceTopologyLogicalTransitionEvent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;taskExecutionRunnable&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The state machine ensures task transitions remain consistent while automatically releasing resources and updating workflow topology.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Before 1.2.1&lt;/th&gt;
&lt;th&gt;1.2.1 and Later&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fault tolerance&lt;/td&gt;
&lt;td&gt;Manual recovery&lt;/td&gt;
&lt;td&gt;Automatic failover&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ZooKeeper queue cleanup&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Task state updates&lt;/td&gt;
&lt;td&gt;Database modification required&lt;/td&gt;
&lt;td&gt;Managed by state machine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Worker failure recovery&lt;/td&gt;
&lt;td&gt;Manual intervention&lt;/td&gt;
&lt;td&gt;Automatic resubmission&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network jitter handling&lt;/td&gt;
&lt;td&gt;Service restart required&lt;/td&gt;
&lt;td&gt;Automatic detection and failover&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Best Practices for Safe Cleanup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Verify the Task Is Actually Dead
&lt;/h3&gt;

&lt;p&gt;Before performing any cleanup, confirm that the task process has indeed terminated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check the Worker process&lt;/span&gt;
jps | &lt;span class="nb"&gt;grep &lt;/span&gt;WorkerServer

&lt;span class="c"&gt;# Check the task process&lt;/span&gt;
ps &lt;span class="nt"&gt;-ef&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &amp;lt;task_keyword&amp;gt;

&lt;span class="c"&gt;# Review task logs&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /path/to/task.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Use the UI Whenever Possible
&lt;/h3&gt;

&lt;p&gt;For newer versions of DolphinScheduler, always prefer built-in UI operations before modifying the database.&lt;/p&gt;

&lt;p&gt;Recommended actions include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Stop&lt;/strong&gt; to terminate the task.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Recover from Failure&lt;/strong&gt; to restart execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Be Careful with Database Operations
&lt;/h3&gt;

&lt;p&gt;If direct database updates are unavoidable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Back up the database first.&lt;/li&gt;
&lt;li&gt;Verify the task instance ID carefully.&lt;/li&gt;
&lt;li&gt;Update only the task status field.&lt;/li&gt;
&lt;li&gt;Never delete task records directly.&lt;/li&gt;
&lt;li&gt;Verify the workflow state after the operation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Exercise Caution When Cleaning ZooKeeper
&lt;/h3&gt;

&lt;p&gt;If ZooKeeper cleanup is required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirm the target path is correct:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/dolphinscheduler/task_queue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use a trusted ZooKeeper client.&lt;/li&gt;
&lt;li&gt;Avoid deleting unrelated coordination nodes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Monitor and Prevent Future Issues
&lt;/h3&gt;

&lt;p&gt;To minimize zombie task occurrences in production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monitor database latency.&lt;/li&gt;
&lt;li&gt;Configure appropriate ZooKeeper session timeout values.&lt;/li&gt;
&lt;li&gt;Regularly check Master and Worker health.&lt;/li&gt;
&lt;li&gt;Deploy monitoring scripts to automatically restart failed services.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The correct approach to cleaning up tasks stuck in the &lt;strong&gt;Running&lt;/strong&gt; state depends largely on your DolphinScheduler version.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;versions earlier than 1.2.1&lt;/strong&gt;, manual cleanup is required by clearing the ZooKeeper task queue, updating the task state in the database, and recovering the workflow from the failed node.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;version 1.2.1 and later&lt;/strong&gt;, the built-in fault-tolerance mechanism automatically detects and recovers most failures, dramatically reducing operational effort.&lt;/p&gt;

&lt;p&gt;If you're still running an older release, upgrading to the latest version is strongly recommended. Modern DolphinScheduler versions provide a more resilient scheduling architecture, automatic failover, and significantly improved cluster reliability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;p&gt;This article is based on the official Apache DolphinScheduler FAQ and architecture documentation. The task state transition logic can be found in the &lt;code&gt;AbstractTaskStateAction.java&lt;/code&gt; implementation.&lt;/p&gt;

&lt;p&gt;For production environments, always validate the recovery procedure in a testing environment before applying it to live workloads.&lt;/p&gt;

</description>
      <category>apachedolphinscheduler</category>
      <category>programming</category>
      <category>developers</category>
      <category>opensource</category>
    </item>
    <item>
      <title>🚀 Stop running incremental syncs manually! Automate daily data pipelines with Apache SeaTunnel + Apache DolphinScheduler for reliable scheduling and effortless data integration. ⚡</title>
      <dc:creator>Chen Debra</dc:creator>
      <pubDate>Fri, 17 Jul 2026 06:32:10 +0000</pubDate>
      <link>https://dev.to/chen_debra_3060b21d12b1b0/stop-running-incremental-syncs-manually-automate-daily-data-pipelines-with-apache-seatunnel--2nf7</link>
      <guid>https://dev.to/chen_debra_3060b21d12b1b0/stop-running-incremental-syncs-manually-automate-daily-data-pipelines-with-apache-seatunnel--2nf7</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/stop-running-data-syncs-manually-automate-incremental-pipelines-with-apache-seatunnel--417a" class="crayons-story__hidden-navigation-link"&gt;Stop Running Data Syncs Manually: Automate Incremental Pipelines with Apache SeaTunnel &amp;amp; DolphinScheduler&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/chen_debra_3060b21d12b1b0" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1533306%2Fc0ea3a94-ba17-47c8-9304-4571fb1adaf9.png" alt="chen_debra_3060b21d12b1b0 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/chen_debra_3060b21d12b1b0" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Chen Debra
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Chen Debra
                
              
              &lt;div id="story-author-preview-content-4163366" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/chen_debra_3060b21d12b1b0" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1533306%2Fc0ea3a94-ba17-47c8-9304-4571fb1adaf9.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Chen Debra&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/stop-running-data-syncs-manually-automate-incremental-pipelines-with-apache-seatunnel--417a" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jul 17&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/stop-running-data-syncs-manually-automate-incremental-pipelines-with-apache-seatunnel--417a" id="article-link-4163366"&gt;
          Stop Running Data Syncs Manually: Automate Incremental Pipelines with Apache SeaTunnel &amp;amp; DolphinScheduler
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/database"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;database&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/datascience"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;datascience&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/apachedolphinscheduler"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;apachedolphinscheduler&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/stop-running-data-syncs-manually-automate-incremental-pipelines-with-apache-seatunnel--417a#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Stop Running Data Syncs Manually: Automate Incremental Pipelines with Apache SeaTunnel &amp; DolphinScheduler</title>
      <dc:creator>Chen Debra</dc:creator>
      <pubDate>Fri, 17 Jul 2026 06:28:13 +0000</pubDate>
      <link>https://dev.to/chen_debra_3060b21d12b1b0/stop-running-data-syncs-manually-automate-incremental-pipelines-with-apache-seatunnel--417a</link>
      <guid>https://dev.to/chen_debra_3060b21d12b1b0/stop-running-data-syncs-manually-automate-incremental-pipelines-with-apache-seatunnel--417a</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhx717285fa2ucjtea4oh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhx717285fa2ucjtea4oh.jpg" width="799" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Still spending time manually synchronizing new data every day? Combine Apache SeaTunnel with Apache DolphinScheduler to build a fully automated incremental data pipeline that runs on schedule—so you can focus on building applications instead of maintaining scripts.&lt;/p&gt;

&lt;p&gt;Is this a challenge your team faces?&lt;/p&gt;

&lt;p&gt;Your production database grows every day, and yesterday's newly generated data needs to be synchronized to another database or data warehouse for reporting, analytics, or downstream business applications.&lt;/p&gt;

&lt;p&gt;Running the synchronization manually every day? That's tedious—and it's easy to forget.&lt;/p&gt;

&lt;p&gt;Writing cron jobs? They work, but they quickly become difficult to maintain as your workloads grow.&lt;/p&gt;

&lt;p&gt;Fortunately, there's a much better approach.&lt;/p&gt;

&lt;p&gt;In this tutorial, we'll show you how to use &lt;strong&gt;Apache SeaTunnel&lt;/strong&gt; as your data integration engine and &lt;strong&gt;Apache DolphinScheduler&lt;/strong&gt; as your workflow orchestration platform. Together, they create a reliable, fully automated solution for daily incremental data synchronization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Combine SeaTunnel and DolphinScheduler?
&lt;/h2&gt;

&lt;p&gt;Simply put, this open-source combination automates recurring data synchronization jobs.&lt;/p&gt;

&lt;p&gt;Imagine a common enterprise scenario.&lt;/p&gt;

&lt;p&gt;Your business database is continuously receiving new records. Every day, those new records need to be synchronized to another database or data warehouse for dashboards, analytics, or downstream services.&lt;/p&gt;

&lt;p&gt;There are two ways to solve this problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using SeaTunnel alone&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SeaTunnel can easily perform both full and incremental data synchronization. However, you'll still need to execute the job manually every day or rely on external scheduling tools such as &lt;code&gt;crontab&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding DolphinScheduler&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Everything becomes much simpler.&lt;/p&gt;

&lt;p&gt;Configure the workflow once, and DolphinScheduler automatically triggers your SeaTunnel job on schedule every day. It also provides centralized monitoring, execution history, retry mechanisms, and alert notifications whenever a task fails.&lt;/p&gt;

&lt;p&gt;The biggest value of this architecture is straightforward:&lt;/p&gt;

&lt;p&gt;It transforms repetitive data synchronization into an automated, visualized, and manageable workflow, freeing engineers from repetitive operational work.&lt;/p&gt;

&lt;p&gt;In this article, we'll walk through a practical example that synchronizes yesterday's data from a MySQL table into another table automatically every day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before building the automation pipeline, let's prepare the environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Environment
&lt;/h3&gt;

&lt;p&gt;The following software versions are used in this example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apache DolphinScheduler 3.4.0 (Workflow Scheduler)&lt;/li&gt;
&lt;li&gt;Apache SeaTunnel 2.3.12 (Data Integration Engine)&lt;/li&gt;
&lt;li&gt;MySQL 5.7 (Source and Target Database)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Prepare Test Data
&lt;/h3&gt;

&lt;p&gt;First, create a simple table in MySQL and insert a few records to simulate daily incremental data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="nv"&gt;`paramtest`&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nv"&gt;`id`&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="n"&gt;AUTO_INCREMENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nv"&gt;`name`&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;CHARACTER&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;utf8mb4&lt;/span&gt; &lt;span class="k"&gt;COLLATE&lt;/span&gt; &lt;span class="n"&gt;utf8mb4_general_ci&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nv"&gt;`rq`&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;USING&lt;/span&gt; &lt;span class="n"&gt;BTREE&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;ENGINE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;InnoDB&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;CHARSET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;utf8mb4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="nv"&gt;`paramtest`&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'张三'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2026-02-06'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="nv"&gt;`paramtest`&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'李四'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2026-02-05'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our objective is simple:&lt;/p&gt;

&lt;p&gt;Synchronize all records whose &lt;strong&gt;&lt;code&gt;rq&lt;/code&gt; equals yesterday's date&lt;/strong&gt; automatically every day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Apache DolphinScheduler
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Install the SeaTunnel Plugin
&lt;/h3&gt;

&lt;p&gt;First, DolphinScheduler needs to recognize SeaTunnel as one of its task types.&lt;/p&gt;

&lt;p&gt;Open the following configuration file under your DolphinScheduler installation directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vi conf/plugins_configdolphinscheduler-task-seatunnel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then install the plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash ./bin/install-plugins.sh 3.4.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Configure the SeaTunnel Environment Variable
&lt;/h3&gt;

&lt;p&gt;Next, tell DolphinScheduler where SeaTunnel is installed.&lt;/p&gt;

&lt;p&gt;If you're using the &lt;strong&gt;Standalone Server&lt;/strong&gt; deployment mode, configuring the environment variable is required so that DolphinScheduler can locate the SeaTunnel installation correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Required environment variable&lt;/span&gt;

&lt;span class="c"&gt;# Add the following to your system environment&lt;/span&gt;
&lt;span class="c"&gt;# (for example, /etc/profile)&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;SEATUNNEL_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/your/path/to/apache-seatunnel-2.3.12

&lt;span class="c"&gt;# Reload the environment&lt;/span&gt;
&lt;span class="nb"&gt;source&lt;/span&gt; /etc/profile

&lt;span class="c"&gt;# The following two files were also configured in this example.&lt;/span&gt;
&lt;span class="c"&gt;# Depending on your deployment, they may or may not be required.&lt;/span&gt;

&lt;span class="c"&gt;# ${SEATUNNEL_HOME}/bin/env/dolphinscheduler_env.sh&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;SEATUNNEL_HOME&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;SEATUNNEL_HOME:/your/path/to/apache-seatunnel-2.3.12&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# ${SEATUNNEL_HOME}/standalone-server/conf/dolphinscheduler_env.sh&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;SEATUNNEL_HOME&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;SEATUNNEL_HOME:/your/path/to/apache-seatunnel-2.3.12&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After completing the configuration, restart the DolphinScheduler services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Create the Workflow
&lt;/h3&gt;

&lt;p&gt;Now it's time to create the scheduled workflow.&lt;/p&gt;

&lt;p&gt;In the DolphinScheduler Web UI:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Data Integration → Create SeaTunnel Task&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Configure the following parameters.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Startup Script&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;seatunnel.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Command Options&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where the dynamic date parameter comes into play.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"1 day ago"&lt;/span&gt; +&lt;span class="s2"&gt;"%Y-%m-%d"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every time the workflow executes, this Bash command automatically calculates yesterday's date and passes it into the workflow as the variable &lt;strong&gt;&lt;code&gt;date&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment Mode&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Select:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Script&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Paste the following SeaTunnel configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Magic: SeaTunnel Configuration
&lt;/h2&gt;

&lt;p&gt;The configuration below defines both the data source and the destination.&lt;/p&gt;

&lt;p&gt;The key is the &lt;code&gt;${date}&lt;/code&gt; variable, which is injected dynamically by DolphinScheduler at runtime so that only yesterday's records are queried.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hocon"&gt;&lt;code&gt;&lt;span class="nl"&gt;env&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;parallelism&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;job.mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"BATCH"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nl"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;Jdbc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jdbc:mysql://10.0.12.100:3306/cdc?serverTimezone=UTC"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;driver&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"com.mysql.cj.jdbc.Driver"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;connection_check_timeout_sec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"root"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;password&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"root"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"select * from paramtest where rq = '&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;date&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;'"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nl"&gt;sink&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;Jdbc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jdbc:mysql://10.0.12.100:3306/cdc?serverTimezone=UTC"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;driver&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"com.mysql.cj.jdbc.Driver"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"root"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;password&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"root"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;generate_sink_sql&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;database&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cdc&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"paramtest2"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;primary_keys&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After saving the task:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Publish the workflow.&lt;/li&gt;
&lt;li&gt;Configure a schedule (for example, every day at &lt;strong&gt;1:00 AM&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;Enable the schedule.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once completed, the entire synchronization process becomes fully automated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitor and Manage Your Workflows
&lt;/h2&gt;

&lt;p&gt;After the workflow is online, DolphinScheduler takes care of everything automatically.&lt;/p&gt;

&lt;p&gt;Open the &lt;strong&gt;Workflow Instance&lt;/strong&gt; page to view the execution history of every scheduled run.&lt;/p&gt;

&lt;p&gt;You can easily monitor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Execution Status&lt;/strong&gt; — Running, Successful, or Failed at a glance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execution Logs&lt;/strong&gt; — If a task fails, simply open the task instance, right-click it, and select &lt;strong&gt;View Log&lt;/strong&gt;. You'll quickly identify whether the problem is related to networking, SQL, or configuration, making troubleshooting significantly easier.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Data synchronization is part of every data engineer's daily work—but it doesn't have to be repetitive.&lt;/p&gt;

&lt;p&gt;By combining &lt;strong&gt;Apache SeaTunnel&lt;/strong&gt; with &lt;strong&gt;Apache DolphinScheduler&lt;/strong&gt;, you can transform manual, error-prone synchronization tasks into reliable, fully automated workflows with built-in scheduling, monitoring, retries, and centralized management.&lt;/p&gt;

&lt;p&gt;The result is fewer operational errors, higher productivity, and more time to focus on what really matters—building better data platforms and delivering business value.&lt;/p&gt;

&lt;p&gt;If your team is still running incremental synchronization jobs manually, now is the perfect time to modernize your workflow with this powerful open-source combination.&lt;/p&gt;

</description>
      <category>database</category>
      <category>datascience</category>
      <category>apachedolphinscheduler</category>
      <category>opensource</category>
    </item>
    <item>
      <title>🚀 Apache DolphinScheduler June Update is here! Stronger failover, safer logs, S3 improvements, Helm fixes, and enhanced production stability. 💪🔒☁️⚡ Thanks to every contributor! ❤️ #ApacheDolphinScheduler #OpenSource #DataEngineering #DevOps #CloudNative</title>
      <dc:creator>Chen Debra</dc:creator>
      <pubDate>Thu, 09 Jul 2026 09:16:16 +0000</pubDate>
      <link>https://dev.to/chen_debra_3060b21d12b1b0/apache-dolphinscheduler-june-update-is-here-stronger-failover-safer-logs-s3-improvements-helm-57la</link>
      <guid>https://dev.to/chen_debra_3060b21d12b1b0/apache-dolphinscheduler-june-update-is-here-stronger-failover-safer-logs-s3-improvements-helm-57la</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/apache-dolphinscheduler-june-community-update-strengthening-stability-across-the-entire-workflow-25j3" class="crayons-story__hidden-navigation-link"&gt;Apache DolphinScheduler June Community Update: Strengthening Stability Across the Entire Workflow Operations Lifecycle&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/chen_debra_3060b21d12b1b0" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1533306%2Fc0ea3a94-ba17-47c8-9304-4571fb1adaf9.png" alt="chen_debra_3060b21d12b1b0 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/chen_debra_3060b21d12b1b0" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Chen Debra
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Chen Debra
                
              
              &lt;div id="story-author-preview-content-4103802" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/chen_debra_3060b21d12b1b0" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1533306%2Fc0ea3a94-ba17-47c8-9304-4571fb1adaf9.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Chen Debra&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/apache-dolphinscheduler-june-community-update-strengthening-stability-across-the-entire-workflow-25j3" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jul 9&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/apache-dolphinscheduler-june-community-update-strengthening-stability-across-the-entire-workflow-25j3" id="article-link-4103802"&gt;
          Apache DolphinScheduler June Community Update: Strengthening Stability Across the Entire Workflow Operations Lifecycle
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/apachedolphinscheduler"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;apachedolphinscheduler&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/datascience"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;datascience&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/apache-dolphinscheduler-june-community-update-strengthening-stability-across-the-entire-workflow-25j3#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            7 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Apache DolphinScheduler June Community Update: Strengthening Stability Across the Entire Workflow Operations Lifecycle</title>
      <dc:creator>Chen Debra</dc:creator>
      <pubDate>Thu, 09 Jul 2026 09:14:37 +0000</pubDate>
      <link>https://dev.to/chen_debra_3060b21d12b1b0/apache-dolphinscheduler-june-community-update-strengthening-stability-across-the-entire-workflow-25j3</link>
      <guid>https://dev.to/chen_debra_3060b21d12b1b0/apache-dolphinscheduler-june-community-update-strengthening-stability-across-the-entire-workflow-25j3</guid>
      <description>&lt;p&gt;Hi, Community!&lt;/p&gt;

&lt;p&gt;Our June community report is here! Instead of focusing on major feature releases, the community spent the month strengthening the platform's foundation and production readiness.&lt;/p&gt;

&lt;p&gt;Throughout June, contributors concentrated on improving operational stability by finalizing the 3.4.2 maintenance release, enhancing task failover capabilities, fixing high-concurrency edge cases, introducing sensitive data masking for logs, and addressing numerous production issues across deployment, storage, CI, and engineering workflows.&lt;/p&gt;

&lt;p&gt;In this report, we'll walk you through the most important production-ready improvements delivered in June, provide upgrade recommendations for production environments, and recognize our top community contributors. Let's dive in! ✨&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Highlights
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Reporting Period:&lt;/strong&gt; June 1, 2026 – July 1, 2026&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Merged Pull Requests:&lt;/strong&gt; 22&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contributors:&lt;/strong&gt; 9&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code Changes:&lt;/strong&gt; +630 / -473&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Major Components:&lt;/strong&gt; Master, API, Storage, Helm, UI, Documentation &amp;amp; Project Governance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;June was primarily a &lt;strong&gt;maintenance and platform hardening&lt;/strong&gt; release cycle. Alongside the Apache DolphinScheduler 3.4.2 release and follow-up fixes, the community delivered meaningful improvements in concurrency safety, log security, Helm deployment, S3 storage handling, and documentation quality.&lt;/p&gt;

&lt;p&gt;This update is especially valuable for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;End users and platform owners&lt;/strong&gt; who want to quickly understand whether June introduced important stability or usability improvements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform engineers and DevOps teams&lt;/strong&gt; who should pay close attention to failover behavior, Helm deployment, S3 storage improvements, and logging security.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contributors and developers&lt;/strong&gt; interested in seeing how the community continues investing in long-term platform reliability and technical governance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Six Improvements That Matter Most to Users
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Apache DolphinScheduler 3.4.2 Is Fully Released and Maintained
&lt;/h3&gt;

&lt;p&gt;June included both the official &lt;strong&gt;3.4.2 release&lt;/strong&gt; and follow-up documentation corrections, representing a typical maintenance release cycle focused on polishing production quality.&lt;/p&gt;

&lt;p&gt;Related PRs: &lt;strong&gt;#18317, #18319&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Safer Worker Logs with Password Masking
&lt;/h3&gt;

&lt;p&gt;Worker logs now prevent plaintext passwords from being written to log files.&lt;/p&gt;

&lt;p&gt;This improvement is particularly important in enterprise and multi-tenant environments, where credential exposure through logs can become a far greater security risk than ordinary software bugs.&lt;/p&gt;

&lt;p&gt;Related PR: &lt;strong&gt;#18333&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Improved Helm Deployment Experience
&lt;/h3&gt;

&lt;p&gt;Several deployment-related improvements landed in June, including fixes for duplicate ConfigMap labels and an updated MySQL Helm chart version.&lt;/p&gt;

&lt;p&gt;These changes directly improve deployment reliability and long-term maintainability for Kubernetes users.&lt;/p&gt;

&lt;p&gt;Related PRs: &lt;strong&gt;#18341, #18336&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Better Concurrency Safety
&lt;/h3&gt;

&lt;p&gt;A key stability improvement replaces &lt;code&gt;HashMap&lt;/code&gt; with &lt;code&gt;ConcurrentHashMap&lt;/code&gt;, eliminating potential &lt;code&gt;ConcurrentModificationException&lt;/code&gt; issues under high-concurrency workloads.&lt;/p&gt;

&lt;p&gt;Although these failures were relatively rare, they could have significant production impact when they occurred.&lt;/p&gt;

&lt;p&gt;Related PR: &lt;strong&gt;#18331&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Smarter Task Failover
&lt;/h3&gt;

&lt;p&gt;A new failover enhancement allows Apache DolphinScheduler to automatically terminate external applications when task failover occurs.&lt;/p&gt;

&lt;p&gt;This is particularly valuable for Yarn and Kubernetes deployments, preventing orphaned applications from continuing to consume cluster resources after failover.&lt;/p&gt;

&lt;p&gt;Related PR: &lt;strong&gt;#18353&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6. S3 Resource Listings No Longer Stop at 1,000 Objects
&lt;/h3&gt;

&lt;p&gt;Users relying on Amazon S3-compatible storage will no longer encounter incomplete resource listings once object counts exceed 1,000.&lt;/p&gt;

&lt;p&gt;This fixes a long-standing usability issue that directly affected storage visibility and operational correctness.&lt;/p&gt;

&lt;p&gt;Related PR: &lt;strong&gt;#18381&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Upgrade Recommendations
&lt;/h2&gt;

&lt;p&gt;If you're running Apache DolphinScheduler in production, we recommend validating this release from two perspectives: &lt;strong&gt;maintenance updates&lt;/strong&gt; and &lt;strong&gt;platform stability improvements&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Priority validation areas include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log masking to ensure sensitive credentials are never persisted.&lt;/li&gt;
&lt;li&gt;High-concurrency workload stability.&lt;/li&gt;
&lt;li&gt;S3 resource visibility.&lt;/li&gt;
&lt;li&gt;Helm deployment and upgrade workflows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also recommend verifying release documentation and upgrade guides, especially if your organization maintains internal deployment documentation or embedded platform references.&lt;/p&gt;

&lt;p&gt;Before incorporating June's updates, we recommend keeping your development environment synchronized using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git fetch origin dev
git checkout dev
git pull &lt;span class="nt"&gt;--rebase&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  June Contributors
&lt;/h2&gt;

&lt;p&gt;Based on Git author names, nine community members contributed code during June:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;eye-gu&lt;/li&gt;
&lt;li&gt;Jarek Potiuk&lt;/li&gt;
&lt;li&gt;luxiaolong&lt;/li&gt;
&lt;li&gt;njnu-seafish&lt;/li&gt;
&lt;li&gt;suyc&lt;/li&gt;
&lt;li&gt;Victor Laborie&lt;/li&gt;
&lt;li&gt;Wenjun Ruan&lt;/li&gt;
&lt;li&gt;xiangzihao&lt;/li&gt;
&lt;li&gt;Yanjun Qiu&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwvydcmn8tlqywo0x0952.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwvydcmn8tlqywo0x0952.jpg" width="800" height="1421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Deep Dive
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Concurrency Safety: Fixing the Root Cause Instead of the Symptoms
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Representative PR:&lt;/strong&gt; #18331&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;UserGroupInformationFactory&lt;/code&gt; cache has been upgraded from &lt;code&gt;HashMap&lt;/code&gt; to &lt;code&gt;ConcurrentHashMap&lt;/code&gt;, accompanied by dedicated concurrency test cases.&lt;/p&gt;

&lt;p&gt;The real challenge with concurrency issues isn't that they happen—it's that they occur only under specific high-load conditions and are extremely difficult to reproduce.&lt;/p&gt;

&lt;p&gt;When Hive authentication and Kerberos renewal threads accessed the same cache simultaneously, a standard &lt;code&gt;HashMap&lt;/code&gt; could trigger &lt;code&gt;ConcurrentModificationException&lt;/code&gt; during concurrent iteration and modification.&lt;/p&gt;

&lt;p&gt;Instead of applying a temporary synchronization workaround, the community addressed the underlying design by replacing the shared data structure with a thread-safe implementation and introducing dedicated tests that simulate concurrent &lt;code&gt;forEach&lt;/code&gt; and &lt;code&gt;logout/login&lt;/code&gt; operations.&lt;/p&gt;

&lt;p&gt;This fundamentally eliminates the issue rather than masking its symptoms.&lt;/p&gt;

&lt;p&gt;For production environments using Hive, Kerberos authentication, or long-lived sessions, this significantly reduces intermittent failures that disappear after retries but remain difficult to diagnose.&lt;/p&gt;

&lt;p&gt;Recommended validation focuses on Hive workloads, Kerberos renewal scenarios, and high-concurrency datasource access.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Smarter Failover That Cleans Up External Applications
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Representative PR:&lt;/strong&gt; #18353&lt;/p&gt;

&lt;p&gt;June introduces a new configuration option, &lt;code&gt;kill-application-when-task-failover&lt;/code&gt;, integrated into &lt;code&gt;MasterConfig&lt;/code&gt;, task execution logic, and multiple deployment configurations.&lt;/p&gt;

&lt;p&gt;Historically, failover primarily ensured scheduling continuity.&lt;/p&gt;

&lt;p&gt;However, for external execution engines such as Yarn and Kubernetes, the larger operational risk often comes from orphaned applications that continue consuming resources even after the scheduler has recovered.&lt;/p&gt;

&lt;p&gt;This enhancement expands failover beyond scheduler metadata management to include cleanup of execution environments.&lt;/p&gt;

&lt;p&gt;The implementation spans core Master logic as well as &lt;code&gt;application.yaml&lt;/code&gt;, Docker Compose configurations, Kubernetes Helm values, and documentation, demonstrating that this is a production-ready capability rather than an experimental feature.&lt;/p&gt;

&lt;p&gt;For organizations running Yarn or Kubernetes clusters, this provides a unified mechanism for preventing resource leakage after failover events.&lt;/p&gt;

&lt;p&gt;Recommended validation includes Master failover testing, interrupted task execution, and verification that legitimate applications remain untouched while orphaned applications are correctly terminated.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. S3 Pagination Support That Scales Beyond Development Environments
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Representative PR:&lt;/strong&gt; #18381&lt;/p&gt;

&lt;p&gt;&lt;code&gt;S3StorageOperator.listStorageEntity()&lt;/code&gt; has been enhanced to iterate through paginated results using &lt;code&gt;ContinuationToken&lt;/code&gt; instead of relying on a single &lt;code&gt;ListObjectsV2&lt;/code&gt; request.&lt;/p&gt;

&lt;p&gt;This addresses a classic production issue.&lt;/p&gt;

&lt;p&gt;Development environments rarely exceed 1,000 objects, making the limitation difficult to detect. Once production storage grows beyond that threshold, however, users encounter missing resources even though the underlying files still exist.&lt;/p&gt;

&lt;p&gt;Rather than implementing a workaround at the application layer, the community fixed pagination directly within the storage plugin.&lt;/p&gt;

&lt;p&gt;Listing now continues until &lt;code&gt;isTruncated()&lt;/code&gt; returns false, ensuring every object is returned.&lt;/p&gt;

&lt;p&gt;As a result, resource centers, file management interfaces, and directory browsers all benefit automatically.&lt;/p&gt;

&lt;p&gt;For organizations using large S3 buckets or treating DolphinScheduler as a centralized resource management platform, this restores correctness—not just convenience.&lt;/p&gt;

&lt;p&gt;Recommended validation includes directories containing more than 1,000 objects, mixed folder structures, and confirmation that UI and API results match the actual contents of the storage bucket.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Small Change, Major Security Improvement: Log Desensitization
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Representative PR:&lt;/strong&gt; #18333&lt;/p&gt;

&lt;p&gt;From a code perspective, this pull request modifies only a small portion of &lt;code&gt;PasswordUtils&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Its impact, however, is far greater than the size of the code change suggests.&lt;/p&gt;

&lt;p&gt;Security improvements should never be measured by the number of modified lines.&lt;/p&gt;

&lt;p&gt;Plaintext credentials appearing in logs don't usually cause immediate system failures. Instead, they silently propagate through centralized logging platforms, troubleshooting systems, backups, and collaborative workflows, dramatically increasing the attack surface.&lt;/p&gt;

&lt;p&gt;This update reflects the community's continued investment in secure-by-default behavior.&lt;/p&gt;

&lt;p&gt;Many real-world security incidents originate not from broken authentication systems, but from sensitive information accidentally exposed through ordinary application logs.&lt;/p&gt;

&lt;p&gt;For organizations already aggregating Worker logs into ELK, Alibaba Cloud SLS, Amazon CloudWatch, or similar platforms, this enhancement provides even greater value because centralized logging significantly amplifies the potential impact of leaked credentials.&lt;/p&gt;

&lt;p&gt;When upgrading, verify that sensitive information is properly masked while ensuring logs still retain sufficient detail for effective troubleshooting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development Focus
&lt;/h2&gt;

&lt;p&gt;Looking across all 22 merged pull requests, June represents a classic platform hardening cycle focused on resolving numerous high-frequency production issues that affect reliability over time.&lt;/p&gt;

&lt;p&gt;Key investment areas included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Release Management &amp;amp; Project Governance:&lt;/strong&gt; #18310, #18317, #18319, #18363, #18374, #18375&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime Stability:&lt;/strong&gt; #18331, #18347, #18351, #18352, #18353&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud-Native Deployment:&lt;/strong&gt; #18336, #18341, #18355, #18360&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security &amp;amp; Compliance:&lt;/strong&gt; #18310, #18333, #18363&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage &amp;amp; Ecosystem:&lt;/strong&gt; #18381&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation &amp;amp; User Experience:&lt;/strong&gt; #18321, #18323, #18327, #18308&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we had to summarize Apache DolphinScheduler's June development in a single sentence, it would be this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;June wasn't about shipping major new features—it was about making Apache DolphinScheduler more reliable, more secure, and better prepared for production by strengthening the operational details that matter most.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Appendix A: Merged Pull Requests in June 2026
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;2026-06-02&lt;/code&gt; &lt;code&gt;#18310&lt;/code&gt; Add AGENTS.md + SECURITY.md to make the security model discoverable&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-04&lt;/code&gt; &lt;code&gt;#18317&lt;/code&gt; Release 3.4.2&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-04&lt;/code&gt; &lt;code&gt;#18319&lt;/code&gt; Hotfix 3.4.2 doc error&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-05&lt;/code&gt; &lt;code&gt;#18321&lt;/code&gt; Update the parameter priority explanation in the docs&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-05&lt;/code&gt; &lt;code&gt;#18323&lt;/code&gt; Add a note to the parameter priority documentation specifying and fix some issues&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-07&lt;/code&gt; &lt;code&gt;#18316&lt;/code&gt; Remove dead code after &lt;code&gt;t_ds_relation_user_alertgroup&lt;/code&gt; table dropped&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-10&lt;/code&gt; &lt;code&gt;#18331&lt;/code&gt; Replace HashMap with ConcurrentHashMap in &lt;code&gt;UserGroupInformationFactory&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-12&lt;/code&gt; &lt;code&gt;#18341&lt;/code&gt; Fix duplicate &lt;code&gt;app.kubernetes.io/name&lt;/code&gt; label on ConfigMap&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-12&lt;/code&gt; &lt;code&gt;#18333&lt;/code&gt; Remove plaintext passwords from the logs&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-12&lt;/code&gt; &lt;code&gt;#18336&lt;/code&gt; Update mysql helm chart version&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-15&lt;/code&gt; &lt;code&gt;#18347&lt;/code&gt; &lt;code&gt;countTaskInstanceStateByProjectCodes&lt;/code&gt; uses &lt;code&gt;submit_time&lt;/code&gt; filtering&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-16&lt;/code&gt; &lt;code&gt;#18327&lt;/code&gt; Fix and enrich the documentation for parameter priority&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-16&lt;/code&gt; &lt;code&gt;#18355&lt;/code&gt; Change the description field to optional&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-17&lt;/code&gt; &lt;code&gt;#18353&lt;/code&gt; Add &lt;code&gt;kill-application-when-task-failover&lt;/code&gt; logic&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-17&lt;/code&gt; &lt;code&gt;#18352&lt;/code&gt; Fix rerun workflow instance should follow the specified &lt;code&gt;workerGroup&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-18&lt;/code&gt; &lt;code&gt;#18360&lt;/code&gt; Change the description field to optional in k8s config&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-22&lt;/code&gt; &lt;code&gt;#18351&lt;/code&gt; Fix &lt;code&gt;forceTaskSuccess&lt;/code&gt; cannot reset the last unsuccessful workflow instance to success&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-22&lt;/code&gt; &lt;code&gt;#18363&lt;/code&gt; Fix sonar token leak&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-23&lt;/code&gt; &lt;code&gt;#18374&lt;/code&gt; Remove sonar check&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-23&lt;/code&gt; &lt;code&gt;#18375&lt;/code&gt; Fix auto labeler error&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-23&lt;/code&gt; &lt;code&gt;#18308&lt;/code&gt; Frontend correctly uses the preferred values of the associated project for task creating and workflow scheduling&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-06-26&lt;/code&gt; &lt;code&gt;#18381&lt;/code&gt; Fix list resources returned only 1000 records in s3 storage type&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Appendix B: References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PR #18308: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18308" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18308&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18310: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18310" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18310&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18316: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18316" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18316&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18317: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18317" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18317&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18319: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18319" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18319&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18321: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18321" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18321&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18323: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18323" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18323&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18327: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18327" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18327&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18331: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18331" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18331&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18333: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18333" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18333&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18336: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18336" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18336&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18341: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18341" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18341&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18347: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18347" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18347&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18351: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18351" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18351&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18352: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18352" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18352&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18353: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18353" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18353&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18355: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18355" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18355&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18360: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18360" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18360&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18363: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18363" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18363&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18374: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18374" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18374&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18375: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18375" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18375&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PR #18381: &lt;a href="https://github.com/apache/dolphinscheduler/pull/18381" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler/pull/18381&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>apachedolphinscheduler</category>
      <category>opensource</category>
      <category>programming</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Talk to your workflows! 💬⚡ We integrated Apache DolphinScheduler CLI into Tencent Music's SuperSonic via Java SPI for AI-powered workflow orchestration. 🚀🤖 #ApacheDolphinScheduler #AI #DataEngineering #OpenSource</title>
      <dc:creator>Chen Debra</dc:creator>
      <pubDate>Thu, 09 Jul 2026 07:55:20 +0000</pubDate>
      <link>https://dev.to/chen_debra_3060b21d12b1b0/talk-to-your-workflows-we-integrated-apache-dolphinscheduler-cli-into-tencent-musics-4587</link>
      <guid>https://dev.to/chen_debra_3060b21d12b1b0/talk-to-your-workflows-we-integrated-apache-dolphinscheduler-cli-into-tencent-musics-4587</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/from-headless-bi-to-workflow-operations-integrating-apache-dolphinscheduler-cli-with-tencent-4lm6" class="crayons-story__hidden-navigation-link"&gt;From Headless BI to Workflow Operations: Integrating Apache DolphinScheduler CLI with Tencent Music's SuperSonic&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/chen_debra_3060b21d12b1b0" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1533306%2Fc0ea3a94-ba17-47c8-9304-4571fb1adaf9.png" alt="chen_debra_3060b21d12b1b0 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/chen_debra_3060b21d12b1b0" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Chen Debra
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Chen Debra
                
              
              &lt;div id="story-author-preview-content-4103155" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/chen_debra_3060b21d12b1b0" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1533306%2Fc0ea3a94-ba17-47c8-9304-4571fb1adaf9.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Chen Debra&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/from-headless-bi-to-workflow-operations-integrating-apache-dolphinscheduler-cli-with-tencent-4lm6" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jul 9&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/from-headless-bi-to-workflow-operations-integrating-apache-dolphinscheduler-cli-with-tencent-4lm6" id="article-link-4103155"&gt;
          From Headless BI to Workflow Operations: Integrating Apache DolphinScheduler CLI with Tencent Music's SuperSonic
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/bigdata"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;bigdata&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/apachedolphinscheduler"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;apachedolphinscheduler&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cli"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cli&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tencent"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tencent&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/chen_debra_3060b21d12b1b0/from-headless-bi-to-workflow-operations-integrating-apache-dolphinscheduler-cli-with-tencent-4lm6#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            18 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>From Headless BI to Workflow Operations: Integrating Apache DolphinScheduler CLI with Tencent Music's SuperSonic</title>
      <dc:creator>Chen Debra</dc:creator>
      <pubDate>Thu, 09 Jul 2026 07:54:45 +0000</pubDate>
      <link>https://dev.to/chen_debra_3060b21d12b1b0/from-headless-bi-to-workflow-operations-integrating-apache-dolphinscheduler-cli-with-tencent-4lm6</link>
      <guid>https://dev.to/chen_debra_3060b21d12b1b0/from-headless-bi-to-workflow-operations-integrating-apache-dolphinscheduler-cli-with-tencent-4lm6</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff7or3qykeuql2vr8fvhu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff7or3qykeuql2vr8fvhu.jpg" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Project Overview
&lt;/h1&gt;

&lt;h2&gt;
  
  
  SuperSonic
&lt;/h2&gt;

&lt;p&gt;SuperSonic is Tencent Music's open-source &lt;strong&gt;next-generation AI-powered Business Intelligence (AI + BI) platform&lt;/strong&gt;, bringing together two complementary paradigms in a single architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chat BI&lt;/strong&gt;, powered by Large Language Models (LLMs)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headless BI&lt;/strong&gt;, powered by a semantic layer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By combining conversational AI with semantic modeling, SuperSonic enables both business users and analytics engineers to interact with data more efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Chat BI Interface&lt;/strong&gt;&lt;br&gt;
Business users can ask questions in natural language and receive instant visualized insights through charts and dashboards.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Headless BI Interface&lt;/strong&gt;&lt;br&gt;
Analytics engineers can build semantic data models by defining metrics, dimensions, tags, and their relationships, allowing the platform to understand business context rather than raw tables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Extensible Architecture&lt;/strong&gt;&lt;br&gt;
Built on Java SPI (Service Provider Interface), SuperSonic allows developers to extend the platform through custom parsers, executors, and plugins.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Semantic Enhancement&lt;/strong&gt;&lt;br&gt;
Business terminology, schema metadata, and column values are injected into LLM prompts, significantly reducing hallucinations and improving answer accuracy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;LLM Workload Reduction&lt;/strong&gt;&lt;br&gt;
Complex SQL logic—including joins, aggregations, and business formulas—is handled by the semantic layer instead of the language model, resulting in more reliable SQL generation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Core Architecture
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Knowledge Base&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Extracts metadata from semantic models and builds dictionaries and indexes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Schema Mapper&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Identifies schema entities referenced in user queries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Semantic Parser&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Converts natural language into semantic queries using rules and LLMs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Semantic Corrector&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Validates and refines generated semantic queries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Semantic Translator&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Translates semantic queries into executable SQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Chat Plugin&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Extends capabilities through third-party integrations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Chat Memory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stores conversation history for few-shot prompting&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/tencentmusic/supersonic" rel="noopener noreferrer"&gt;https://github.com/tencentmusic/supersonic&lt;/a&gt; (⭐ 4.9K)&lt;/p&gt;

&lt;h2&gt;
  
  
  Apache DolphinScheduler
&lt;/h2&gt;

&lt;p&gt;Apache DolphinScheduler is a modern &lt;strong&gt;open-source workflow orchestration platform&lt;/strong&gt; under the Apache Software Foundation, purpose-built for orchestrating complex data pipelines and task dependencies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easy Deployment&lt;/strong&gt;&lt;br&gt;
Supports Standalone, Cluster, Docker, and Kubernetes deployment modes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Developer Friendly&lt;/strong&gt;&lt;br&gt;
Create and manage workflows through the Web UI, Python SDK, or Open API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Highly Reliable&lt;/strong&gt;&lt;br&gt;
Decentralized architecture with multiple Masters and Workers, providing native horizontal scalability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;High Performance&lt;/strong&gt;&lt;br&gt;
Processes tens of millions of tasks per day while delivering significantly higher throughput than traditional workflow schedulers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cloud Native&lt;/strong&gt;&lt;br&gt;
Orchestrates workflows across multiple cloud environments and data centers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Version Control&lt;/strong&gt;&lt;br&gt;
Supports version management for both workflows and task definitions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexible Workflow Lifecycle Management&lt;/strong&gt;&lt;br&gt;
Pause, stop, resume, or rerun workflows at any time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multi-Tenant Architecture&lt;/strong&gt;&lt;br&gt;
Designed for enterprise environments with built-in tenant isolation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/apache/dolphinscheduler" rel="noopener noreferrer"&gt;https://github.com/apache/dolphinscheduler&lt;/a&gt; (⭐ 14.3K)&lt;/p&gt;

&lt;h3&gt;
  
  
  dsctl (DolphinScheduler CLI)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;dsctl&lt;/strong&gt; is the official command-line interface for managing Apache DolphinScheduler resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Major Capabilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Project Management (&lt;code&gt;project&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Workflow Management (&lt;code&gt;workflow&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Task Management (&lt;code&gt;task&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Data Source Management (&lt;code&gt;datasource&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Environment Management (&lt;code&gt;environment&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;User Management (&lt;code&gt;user&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Monitoring &amp;amp; Auditing (&lt;code&gt;monitor&lt;/code&gt; / &lt;code&gt;audit&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example Commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dsctl project list                    &lt;span class="c"&gt;# List all projects&lt;/span&gt;
dsctl workflow run daily-etl          &lt;span class="c"&gt;# Run a workflow&lt;/span&gt;
dsctl workflow-instance watch 123     &lt;span class="c"&gt;# Monitor a workflow instance&lt;/span&gt;
dsctl task-instance log 456 &lt;span class="nt"&gt;--raw&lt;/span&gt;     &lt;span class="c"&gt;# View raw task logs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Why Integrate SuperSonic with DolphinScheduler?
&lt;/h1&gt;

&lt;p&gt;Although DolphinScheduler already provides a powerful Web UI, many operational tasks still require multiple manual steps. By integrating &lt;strong&gt;dsctl&lt;/strong&gt; into SuperSonic through its SPI extension mechanism, users can manage workflows directly through natural language conversations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before vs. After Integration
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Traditional Workflow&lt;/th&gt;
&lt;th&gt;With SuperSonic + dsctl&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Run a workflow&lt;/td&gt;
&lt;td&gt;Open the DolphinScheduler Web UI → Locate the workflow → Click &lt;strong&gt;Run&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;"Run the &lt;strong&gt;daily-etl&lt;/strong&gt; workflow."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitor an instance&lt;/td&gt;
&lt;td&gt;Open the Web UI → Navigate to workflow instances → Find the target instance&lt;/td&gt;
&lt;td&gt;"Monitor workflow instance &lt;strong&gt;123&lt;/strong&gt;."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View logs&lt;/td&gt;
&lt;td&gt;Locate the task instance in the UI → Open logs&lt;/td&gt;
&lt;td&gt;"Show the logs for task &lt;strong&gt;456&lt;/strong&gt;."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Batch operations&lt;/td&gt;
&lt;td&gt;Repeat multiple UI operations&lt;/td&gt;
&lt;td&gt;Execute multiple actions through a single conversation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Business Value
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Improved Productivity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reduce repetitive UI interactions and execute complex workflow operations with a single natural-language command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lower Learning Curve&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even non-technical users can manage workflows without understanding the DolphinScheduler interface or CLI syntax.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unified User Experience&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Users can perform both &lt;strong&gt;data analytics&lt;/strong&gt; and &lt;strong&gt;workflow orchestration&lt;/strong&gt; within the same conversational interface, eliminating context switching between multiple systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture Design
&lt;/h2&gt;

&lt;p&gt;The integration leverages SuperSonic's SPI (Service Provider Interface) extension mechanism, enabling seamless integration with DolphinScheduler CLI without modifying the framework's core code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Natural Language Input
            │
            ▼
WorkflowParser (ChatQueryParser SPI)
    ├── accept(): Check whether the Agent is configured with the DolphinScheduler CLI tool
    └── parse(): Invoke the LLM to translate natural language into a dsctl subcommand
                 Store the parsed result in SemanticParseInfo.properties
            │
            ▼
WorkflowExecutor (ChatQueryExecutor SPI)
    ├── accept(): Check whether queryMode == "WORKFLOW_CTL"
    └── execute(): Execute the dsctl command using ProcessBuilder
                   Inject DS_API_URL and DS_API_TOKEN as environment variables
                   Return QueryResult.textResult in Markdown format
            │
            ▼
Frontend ChatItem
    └── Extend the rendering whitelist to support the WORKFLOW_CTL query mode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Request Flow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The user submits a natural-language request through the SuperSonic Chat interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WorkflowParser&lt;/strong&gt; receives the request and invokes the LLM to generate the corresponding &lt;strong&gt;dsctl&lt;/strong&gt; command.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WorkflowExecutor&lt;/strong&gt; executes the generated command by launching a &lt;strong&gt;dsctl&lt;/strong&gt; process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;dsctl&lt;/strong&gt; communicates with the Apache DolphinScheduler REST API.&lt;/li&gt;
&lt;li&gt;The execution result is formatted as Markdown and rendered in the chat interface.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Backend Implementation
&lt;/h1&gt;

&lt;h2&gt;
  
  
  File 1: &lt;code&gt;AgentToolType.java&lt;/code&gt; (Modified)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Location&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chat/server/src/main/java/com/tencent/supersonic/chat/server/agent/AgentToolType.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.tencent.supersonic.chat.server.agent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.HashMap&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;AgentToolType&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;DATASET&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Text2SQL Dataset"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="no"&gt;PLUGIN&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Third-party Plugin"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="no"&gt;WORK_FLOW_CTL&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Workflow CLI"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;AgentToolType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AgentToolType&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getToolTypes&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AgentToolType&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DATASET&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;DATASET&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;PLUGIN&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;PLUGIN&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;WORK_FLOW_CTL&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;WORK_FLOW_CTL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After registering the new tool type, the frontend automatically retrieves it through the &lt;strong&gt;getToolTypes()&lt;/strong&gt; API. As a result, &lt;strong&gt;DolphinScheduler CLI&lt;/strong&gt; becomes available in the Agent configuration page without requiring any frontend changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  File 2: &lt;code&gt;WorkflowTool.java&lt;/code&gt; (New)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Location&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chat/server/src/main/java/com/tencent/supersonic/chat/server/agent/WorkflowTool.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.tencent.supersonic.chat.server.agent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;lombok.AllArgsConstructor&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;lombok.Data&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;lombok.NoArgsConstructor&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Data&lt;/span&gt;
&lt;span class="nd"&gt;@NoArgsConstructor&lt;/span&gt;
&lt;span class="nd"&gt;@AllArgsConstructor&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WorkflowTool&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AgentTool&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="cm"&gt;/** Path to the dsctl executable (default: "dsctl") */&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;dsctlPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"dsctl"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="cm"&gt;/** Default DolphinScheduler project */&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;defaultProject&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="cm"&gt;/** DolphinScheduler API endpoint */&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;dsApiUrl&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="cm"&gt;/** DolphinScheduler API token */&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;dsToken&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="cm"&gt;/** Example questions used for semantic retrieval */&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;exampleQuestions&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  File 3: &lt;code&gt;WorkflowParser.java&lt;/code&gt; (New)
&lt;/h2&gt;

&lt;p&gt;Path：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chat/server/src/main/java/com/tencent/supersonic/chat/server/parser/WorkflowParser.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.tencent.supersonic.chat.server.parser;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.tencent.supersonic.chat.server.agent.AgentToolType;
import com.tencent.supersonic.chat.server.agent.WorkflowTool;
import com.tencent.supersonic.chat.server.pojo.ParseContext;
import com.tencent.supersonic.common.pojo.ChatApp;
import com.tencent.supersonic.common.pojo.enums.AppModule;
import com.tencent.supersonic.common.util.ChatAppManager;
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.headless.api.pojo.response.ParseResp;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;
import dev.langchain4j.model.output.structured.Description;
import dev.langchain4j.provider.ModelProvider;
import dev.langchain4j.service.AiServices;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;

/**
 * Agent Management Page
 * └── Add Tool:
 *     type = WORK_FLOW_CTL
 *     dsctlPath = /usr/bin/dsctl
 *     defaultProject = etl-prod
 *         ↓ Stored in
 * Agent.toolConfig (JSON)
 *
 * WorkflowParser.accept()
 * └── Activate when
 *     agent.getTools(AgentToolType.WORK_FLOW_CTL) is not empty
 *
 * WorkflowParser.parse()
 * └── Read the WorkflowTool configuration
 * └── Use the LLM to generate a dsctl command
 * └── Write the result into parseInfo.properties
 *
 * WorkflowExecutor.execute()
 * └── Read dsctl_path + dsctl_cmd
 * └── Execute the command through Runtime.exec()
 * └── Return the execution result
 */
@Slf4j
public class WorkflowParser implements ChatQueryParser {

    public static final String QUERY_MODE = "WORKFLOW_CTL";
    public static final String APP_KEY = "WORKFLOW_PARSER";

    /** Cache the dsctl schema to avoid repeated execution. */
    private static volatile String cachedSchema;
    private static volatile long schemaCacheTime;
    private static final long SCHEMA_CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes

    private static final String INSTRUCTION =
            """
            # Role: You are a DolphinScheduler CLI expert using dsctl.

            # Task: Convert user's natural language into dsctl commands.

            # dsctl Usage:
            {{dsctl_help}}

            # Available Commands:
            {{dsctl_commands}}

            # Command Generation Rules:
            1. Match user intent to the appropriate command
            2. For resource selectors, use discovery commands listed below
            3. Include required arguments and options
            4. Output ONLY the dsctl command

            # Intent Patterns:
            - "list/view/show" + resource → dsctl &amp;lt;resource&amp;gt; list
            - "get/detail" + resource → dsctl &amp;lt;resource&amp;gt; get &amp;lt;selector&amp;gt;
            - "create/new" + resource → dsctl &amp;lt;resource&amp;gt; create --name &amp;lt;name&amp;gt;
            - "delete/remove" + resource → dsctl &amp;lt;resource&amp;gt; delete &amp;lt;selector&amp;gt; --force
            - "run/execute" + workflow → dsctl workflow run &amp;lt;workflow&amp;gt;
            - "stop" + instance → dsctl workflow-instance stop &amp;lt;id&amp;gt;
            - "watch/monitor" + instance → dsctl workflow-instance watch &amp;lt;id&amp;gt;
            - "log" + task → dsctl task-instance log &amp;lt;id&amp;gt; --raw

            # Resource Selectors:
            - project: name or code (discover: dsctl project list)
            - workflow: name or code (discover: dsctl workflow list)
            - task: name or code (discover: dsctl task list)
            - workflow-instance: numeric id (discover: dsctl workflow-instance list)
            - task-instance: numeric id (discover: dsctl task-instance list)

            # Output Rules:
            1. Output ONLY the dsctl command
            2. If intent is unclear, output: unknown
            3. Do NOT include explanations

            # Question: {{question}}
            # Command:
            """;

    public WorkflowParser() {
        ChatAppManager.register(
                APP_KEY,
                ChatApp.builder()
                        .prompt(INSTRUCTION)
                        .name("Workflow CLI")
                        .appModule(AppModule.CHAT)
                        .description("Convert natural language into DolphinScheduler workflow commands")
                        .enable(true)
                        .build());
    }

    /** Structured output model. @Description provides field semantics to AiServices. */
    @Data
    static class DsctlCommand {

        @Description("the dsctl subcommand without 'dsctl' prefix, e.g. 'workflow run daily-etl'")
        private String command;

        @Description("brief explanation of what this command does")
        private String thought;
    }

    /** Extraction interface. AiServices automatically generates the implementation. */
    interface DsctlCommandExtractor {
        DsctlCommand extractCommand(String text);
    }

    @Override
    public boolean accept(ParseContext parseContext) {
        // Activate only when the Agent has a Workflow CLI tool configured.
        List&amp;lt;String&amp;gt; tools = parseContext.getAgent().getTools(AgentToolType.WORK_FLOW_CTL);
        return !CollectionUtils.isEmpty(tools);
    }

    @Override
    public void parse(ParseContext parseContext) {

        // Load the first WorkflowTool configured for the Agent.
        List&amp;lt;String&amp;gt; toolJsonList =
                parseContext.getAgent().getTools(AgentToolType.WORK_FLOW_CTL);
        WorkflowTool workflowTool =
                JSONObject.parseObject(toolJsonList.getFirst(), WorkflowTool.class);

        // Load the ChatApp configuration, including the LLM binding and prompt template.
        ChatApp chatApp =
                parseContext.getAgent().getChatAppConfig().get(APP_KEY);

        if (Objects.isNull(chatApp) || !chatApp.isEnable()) {
            log.warn("WorkflowParser ChatApp [{}] is not enabled, skip.", APP_KEY);
            return;
        }

        // Build the prompt by replacing template variables.
        Map&amp;lt;String, Object&amp;gt; variables = new HashMap&amp;lt;&amp;gt;();

        // 1. Execute "dsctl --help" to retrieve CLI usage information.
        String dsctlHelp =
                executeDsctlCommand(workflowTool.getDsctlPath(), workflowTool, "--help");

        // 2. Execute "dsctl schema" to retrieve and format the command list (cached).
        String dsctlSchema = getCachedOrExecuteSchema(workflowTool);
        String formattedCommands = formatCommandsFromSchema(dsctlSchema);

        variables.put("dsctl_help", dsctlHelp);
        variables.put("dsctl_commands", formattedCommands);
        variables.put("question", parseContext.getRequest().getQueryText());

        Prompt prompt =
                PromptTemplate.from(chatApp.getPrompt()).apply(variables);

        // Invoke the LLM using AiServices for structured output.
        ChatModel model =
                ModelProvider.getChatModel(chatApp.getChatModelConfig());

        DsctlCommandExtractor extractor =
                AiServices.create(DsctlCommandExtractor.class, model);

        DsctlCommand cmd =
                extractor.extractCommand(prompt.toUserMessage().singleText());

        log.info(
                "WorkflowParser input=[{}] -&amp;gt; command=[{}] thought=[{}]",
                parseContext.getRequest().getQueryText(),
                cmd == null ? "null" : cmd.getCommand(),
                cmd == null ? "null" : cmd.getThought());

        if (cmd == null || "unknown".equalsIgnoreCase(cmd.getCommand())) {
            // Intent not recognized. Skip this parser and continue with the remaining parsers.
            return;
        }

        // Store the parsing result in parseInfo for WorkflowExecutor.
        SemanticParseInfo parseInfo = new SemanticParseInfo();
        parseInfo.setQueryMode(QUERY_MODE);
        parseInfo.setId(1);

        Map&amp;lt;String, Object&amp;gt; props = new HashMap&amp;lt;&amp;gt;();

        // e.g. "workflow run daily-etl"
        props.put("workflow_ctl_cmd", cmd.getCommand());

        // LLM-generated explanation
        props.put("workflow_ctl_thought", cmd.getThought());

        // Path to the dsctl executable
        props.put("workflow_ctl_path", workflowTool.getDsctlPath());

        if (workflowTool.getDefaultProject() != null) {
            props.put("default_project", workflowTool.getDefaultProject());
        }

        if (workflowTool.getDsApiUrl() != null) {
            props.put("ds_api_url", workflowTool.getDsApiUrl());
        }

        if (workflowTool.getDsToken() != null) {
            props.put("ds_token", workflowTool.getDsToken());
        }

        parseInfo.setProperties(props);

        parseContext.getResponse().getSelectedParses().add(parseInfo);
        parseContext.getResponse().setState(ParseResp.ParseState.COMPLETED);
    }

    /**
     * Execute a dsctl command and return its output.
     *
     * @param dsctlPath Path to the dsctl executable
     * @param workflowTool Workflow tool configuration (including environment variables)
     * @param args Command arguments
     * @return Command output
     */
    private String executeDsctlCommand(
            String dsctlPath,
            WorkflowTool workflowTool,
            String... args) {

        try {
            String[] cmdArray = new String[args.length + 1];
            cmdArray[0] = dsctlPath;
            System.arraycopy(args, 0, cmdArray, 1, args.length);

            ProcessBuilder pb = new ProcessBuilder(cmdArray);
            pb.redirectErrorStream(true);

            // Inject environment variables.
            Map&amp;lt;String, String&amp;gt; env = pb.environment();

            if (workflowTool.getDsApiUrl() != null) {
                env.put("DS_API_URL", workflowTool.getDsApiUrl());
            }

            if (workflowTool.getDsToken() != null) {
                env.put("DS_API_TOKEN", workflowTool.getDsToken());
            }

            Process process = pb.start();

            String output;

            try (BufferedReader reader =
                    new BufferedReader(
                            new InputStreamReader(process.getInputStream()))) {

                output = reader.lines().collect(Collectors.joining("\n"));
            }

            boolean finished = process.waitFor(30, TimeUnit.SECONDS);

            if (!finished) {
                process.destroyForcibly();
                log.warn("dsctl command timed out: {}", String.join(" ", cmdArray));
                return "";
            }

            if (process.exitValue() != 0) {
                log.warn(
                        "dsctl command failed with exit code {}: {}",
                        process.exitValue(),
                        output);
            }

            return output;

        } catch (Exception e) {
            log.error("Failed to execute dsctl command: {}", e.getMessage(), e);
            return "";
        }
    }

    /**
     * Retrieve the cached schema or execute a new schema command.
     *
     * @param workflowTool Workflow tool configuration
     * @return dsctl schema JSON
     */
    private String getCachedOrExecuteSchema(WorkflowTool workflowTool) {

        long now = System.currentTimeMillis();

        if (cachedSchema != null
                &amp;amp;&amp;amp; (now - schemaCacheTime) &amp;lt; SCHEMA_CACHE_TTL_MS) {

            log.debug("Using cached dsctl schema");
            return cachedSchema;
        }

        synchronized (WorkflowParser.class) {

            // Double-check locking.
            if (cachedSchema != null
                    &amp;amp;&amp;amp; (now - schemaCacheTime) &amp;lt; SCHEMA_CACHE_TTL_MS) {

                return cachedSchema;
            }

            String schema =
                    executeDsctlCommand(
                            workflowTool.getDsctlPath(),
                            workflowTool,
                            "schema");

            if (schema != null &amp;amp;&amp;amp; !schema.isBlank()) {
                cachedSchema = schema;
                schemaCacheTime = now;
            }

            return schema;
        }
    }

    /**
     * Format the command list from the dsctl schema JSON.
     *
     * @param schemaJson JSON output from "dsctl schema"
     * @return Formatted command list
     */
    private String formatCommandsFromSchema(String schemaJson) {

        if (schemaJson == null || schemaJson.isBlank()) {
            return getDefaultCommands();
        }

        try {

            JSONObject schema = JSON.parseObject(schemaJson);
            JSONObject data = schema.getJSONObject("data");

            if (data == null) {
                return getDefaultCommands();
            }

            JSONArray commands = data.getJSONArray("commands");

            if (commands == null) {
                return getDefaultCommands();
            }

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i &amp;lt; commands.size(); i++) {

                JSONObject group = commands.getJSONObject(i);

                if (!"group".equals(group.getString("kind"))) {
                    continue;
                }

                String groupName = group.getString("name");
                String groupSummary = group.getString("summary");

                sb.append("\n## ").append(groupName).append("\n");
                sb.append("# ").append(groupSummary).append("\n");

                JSONArray cmdList = group.getJSONArray("commands");

                if (cmdList != null) {

                    for (int j = 0; j &amp;lt; cmdList.size(); j++) {

                        JSONObject cmd = cmdList.getJSONObject(j);

                        String cmdName = cmd.getString("name");
                        String summary = cmd.getString("summary");

                        // Build the command syntax.
                        StringBuilder syntax = new StringBuilder();

                        syntax.append("dsctl ")
                                .append(groupName)
                                .append(" ")
                                .append(cmdName);

                        // Append required arguments.
                        JSONArray args = cmd.getJSONArray("arguments");

                        if (args != null) {

                            for (int k = 0; k &amp;lt; args.size(); k++) {

                                JSONObject arg = args.getJSONObject(k);

                                if (arg.getBooleanValue("required")) {

                                    syntax.append(" &amp;lt;")
                                            .append(arg.getString("name"))
                                            .append("&amp;gt;");
                                }
                            }
                        }

                        sb.append("- ")
                                .append(syntax)
                                .append(": ")
                                .append(summary)
                                .append("\n");

                        // Append the discovery command if available.
                        if (args != null) {

                            for (int k = 0; k &amp;lt; args.size(); k++) {

                                JSONObject arg = args.getJSONObject(k);

                                String discovery =
                                        arg.getString("discovery_command");

                                if (discovery != null &amp;amp;&amp;amp; !discovery.isEmpty()) {

                                    sb.append("  Discovery: ")
                                            .append(discovery)
                                            .append("\n");

                                    break;
                                }
                            }
                        }
                    }
                }
            }

            return sb.toString();

        } catch (Exception e) {

            log.error("Failed to parse dsctl schema: {}", e.getMessage(), e);

            return getDefaultCommands();
        }
    }
    /**
     * Returns the default command list.
     * This is used as a fallback when parsing the schema fails.
     *
     * @return Default command list
     */
    private String getDefaultCommands() {

        return """
            - dsctl project list: List projects
            - dsctl project get &amp;lt;project&amp;gt;: Get one project
            - dsctl project create --name &amp;lt;name&amp;gt;: Create a project
            - dsctl project update &amp;lt;project&amp;gt;: Update a project
            - dsctl project delete &amp;lt;project&amp;gt;: Delete a project
            - dsctl workflow list: List workflows
            - dsctl workflow get &amp;lt;workflow&amp;gt;: Get workflow details
            - dsctl workflow run &amp;lt;workflow&amp;gt;: Run a workflow
            - dsctl workflow delete &amp;lt;workflow&amp;gt;: Delete a workflow
            - dsctl workflow-instance list: List workflow instances
            - dsctl workflow-instance get &amp;lt;id&amp;gt;: Get workflow instance details
            - dsctl workflow-instance watch &amp;lt;id&amp;gt;: Monitor a workflow instance
            - dsctl workflow-instance stop &amp;lt;id&amp;gt;: Stop a workflow instance
            - dsctl workflow-instance digest &amp;lt;id&amp;gt;: View workflow instance summary
            - dsctl task list --workflow &amp;lt;workflow&amp;gt;: List tasks in a workflow
            - dsctl task get &amp;lt;task&amp;gt;: Get task details
            - dsctl task-instance list --workflow-instance &amp;lt;id&amp;gt;: List task instances
            - dsctl task-instance log &amp;lt;id&amp;gt;: View task logs
            - dsctl cluster list: List clusters
            - dsctl datasource list: List data sources
            - dsctl environment list: List environments
            - dsctl user list: List users
            - dsctl tenant list: List tenants
            - dsctl schedule list: List schedules
            - dsctl doctor: Run diagnostics
            """;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Design Highlights
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ChatAppManager.register()&lt;/strong&gt; registers the prompt template during initialization, making it configurable from the Agent management UI and allowing different LLMs to be bound without changing code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AiServices.create()&lt;/strong&gt; automatically injects a JSON schema into the prompt and deserializes the LLM response into a strongly typed &lt;code&gt;DsctlCommand&lt;/code&gt; object, eliminating manual output parsing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;accept()&lt;/strong&gt; activates the parser only when the Agent is configured with a &lt;code&gt;WORK_FLOW_CTL&lt;/code&gt; tool, enabling fine-grained, Agent-level feature control.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  File 4: &lt;code&gt;WorkflowExecutor.java&lt;/code&gt; (New)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Location&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chat/server/src/main/java/com/tencent/supersonic/chat/server/executor/WorkflowExecutor.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;WorkflowExecutor&lt;/code&gt; is responsible for executing the &lt;code&gt;dsctl&lt;/code&gt; command generated by &lt;code&gt;WorkflowParser&lt;/code&gt;. It serves as the execution layer of the entire integration, receiving parsed commands, launching the DolphinScheduler CLI, and returning execution results to the SuperSonic chat interface.&lt;/p&gt;

&lt;p&gt;Unlike SQL execution, which queries databases directly, &lt;code&gt;WorkflowExecutor&lt;/code&gt; delegates workflow operations to the official &lt;code&gt;dsctl&lt;/code&gt; CLI. This approach ensures that all existing DolphinScheduler authentication, permission management, and API interactions remain unchanged while allowing users to control workflows through natural language.&lt;/p&gt;

&lt;h3&gt;
  
  
  Execution Flow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SemanticParseInfo
        │
        ▼
Read workflow_ctl_cmd
        │
        ▼
WorkflowExecutor.accept()
        │
        ▼
WorkflowExecutor.execute()
        │
        ├── Build ProcessBuilder
        ├── Inject environment variables
        ├── Execute dsctl
        ├── Capture stdout/stderr
        └── Return Markdown result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The executor first retrieves the following properties generated by &lt;code&gt;WorkflowParser&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;workflow_ctl_path&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;workflow_ctl_cmd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;workflow_ctl_thought&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ds_api_url&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ds_token&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It then launches a child process using Java's &lt;code&gt;ProcessBuilder&lt;/code&gt; to execute the corresponding &lt;code&gt;dsctl&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;For example, if the user asks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Run the daily-etl workflow.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the parser generates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;workflow run daily-etl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the executor actually runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dsctl workflow run daily-etl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Environment Variable Injection
&lt;/h3&gt;

&lt;p&gt;One important implementation detail is that Java child processes do &lt;strong&gt;not always inherit shell environment variables&lt;/strong&gt;, especially in containerized or service environments.&lt;/p&gt;

&lt;p&gt;To avoid configuration issues, the executor explicitly injects the required DolphinScheduler connection settings before launching the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DS_API_URL"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dsApiUrl&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DS_API_TOKEN"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dsToken&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This guarantees that every &lt;code&gt;dsctl&lt;/code&gt; invocation communicates with the correct DolphinScheduler cluster regardless of how SuperSonic itself was started.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unified Output Handling
&lt;/h3&gt;

&lt;p&gt;Both standard output (&lt;code&gt;stdout&lt;/code&gt;) and error output (&lt;code&gt;stderr&lt;/code&gt;) are merged into a single stream:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;redirectErrorStream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of handling two separate streams, the executor captures all command output through one reader, simplifying both logging and error reporting.&lt;/p&gt;

&lt;p&gt;The complete output is then returned to the chat interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  Timeout Protection
&lt;/h3&gt;

&lt;p&gt;Workflow-related operations such as monitoring instances may take longer than ordinary commands.&lt;/p&gt;

&lt;p&gt;To prevent hanging processes from occupying server resources indefinitely, every CLI invocation has a timeout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;waitFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TimeUnit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SECONDS&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If execution exceeds 60 seconds, the child process is terminated automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;destroyForcibly&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents zombie processes from accumulating and protects the stability of the SuperSonic service.&lt;/p&gt;

&lt;h3&gt;
  
  
  Markdown Rendering
&lt;/h3&gt;

&lt;p&gt;Instead of returning raw terminal output, the executor formats the response as Markdown.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gs"&gt;**Execute the specified workflow**&lt;/span&gt;

&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;bash
&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;dsctl workflow run daily-etl
Workflow submitted successfully.

Instance ID: 12345
Status: RUNNING
&lt;span class="p"&gt;```&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because the frontend already supports Markdown rendering, users receive CLI output in a clean, readable format directly within the chat window.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Design Highlights
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Uses &lt;strong&gt;ProcessBuilder&lt;/strong&gt; instead of &lt;code&gt;Runtime.exec()&lt;/code&gt; for greater flexibility and better process control.&lt;/li&gt;
&lt;li&gt;Explicitly injects &lt;code&gt;DS_API_URL&lt;/code&gt; and &lt;code&gt;DS_API_TOKEN&lt;/code&gt;, avoiding dependency on shell environments.&lt;/li&gt;
&lt;li&gt;Merges standard output and error output into a unified stream for simplified processing.&lt;/li&gt;
&lt;li&gt;Enforces a 60-second timeout to prevent long-running or stalled processes.&lt;/li&gt;
&lt;li&gt;Formats CLI output as Markdown for an improved conversational experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  File 5: &lt;code&gt;spring.factories&lt;/code&gt; (Modified)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Location&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;launchers/standalone/src/main/resources/META-INF/spring.factories
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To enable automatic discovery through Java SPI, both the parser and executor must be registered in &lt;code&gt;spring.factories&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Append the following entries to the existing configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;com.tencent.supersonic.chat.server.parser.ChatQueryParser&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="s"&gt;com.tencent.supersonic.chat.server.parser.NL2PluginParser,&lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="s"&gt;com.tencent.supersonic.chat.server.parser.NL2SQLParser,&lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="s"&gt;com.tencent.supersonic.chat.server.parser.WorkflowParser,&lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="s"&gt;com.tencent.supersonic.chat.server.parser.PlainTextParser&lt;/span&gt;

&lt;span class="py"&gt;com.tencent.supersonic.chat.server.executor.ChatQueryExecutor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="s"&gt;com.tencent.supersonic.chat.server.executor.PluginExecutor,&lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="s"&gt;com.tencent.supersonic.chat.server.executor.WorkflowExecutor,&lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="s"&gt;com.tencent.supersonic.chat.server.executor.SqlExecutor,&lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="s"&gt;com.tencent.supersonic.chat.server.executor.PlainTextExecutor&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Registration Order Matters
&lt;/h3&gt;

&lt;p&gt;The registration order is critical.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;WorkflowExecutor&lt;/code&gt; &lt;strong&gt;must appear before&lt;/strong&gt; &lt;code&gt;SqlExecutor&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is because &lt;code&gt;SqlExecutor.accept()&lt;/code&gt; always returns &lt;code&gt;true&lt;/code&gt;. If it is registered first, it will intercept every request before &lt;code&gt;WorkflowExecutor&lt;/code&gt; has an opportunity to process workflow-related commands.&lt;/p&gt;

&lt;p&gt;The correct execution pipeline is therefore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PluginExecutor
        │
        ▼
WorkflowExecutor
        │
        ▼
SqlExecutor
        │
        ▼
PlainTextExecutor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ordering guarantees that workflow commands are correctly routed to the CLI executor while SQL queries continue to be handled by the existing semantic query engine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why SPI?
&lt;/h3&gt;

&lt;p&gt;One of the biggest advantages of this integration is that &lt;strong&gt;no modifications are required to the SuperSonic framework itself&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By implementing the &lt;code&gt;ChatQueryParser&lt;/code&gt; and &lt;code&gt;ChatQueryExecutor&lt;/code&gt; interfaces and registering them through Java SPI, the Workflow CLI becomes a first-class capability that integrates seamlessly with the existing architecture.&lt;/p&gt;

&lt;p&gt;This plug-in design makes future extensions straightforward. Additional enterprise tools—such as Kubernetes CLI, Spark CLI, Flink CLI, Airflow CLI, or even custom internal command-line utilities—can be integrated using exactly the same extension pattern without changing the SuperSonic core.&lt;/p&gt;

&lt;p&gt;In the next section, we'll cover the &lt;strong&gt;Frontend Implementation&lt;/strong&gt;, including &lt;code&gt;type.ts&lt;/code&gt;, &lt;code&gt;ToolModal.tsx&lt;/code&gt;, &lt;code&gt;ChatItem&lt;/code&gt;, and &lt;code&gt;ExecuteItem&lt;/code&gt;, demonstrating how the new &lt;strong&gt;Workflow CLI&lt;/strong&gt; tool is exposed in the Agent UI and how Markdown command output is rendered in the chat interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frontend Implementation
&lt;/h2&gt;

&lt;p&gt;The frontend changes are intentionally lightweight. Since SuperSonic already supports a flexible plugin architecture, only a few components need to be extended to expose the new Workflow CLI capability.&lt;/p&gt;

&lt;p&gt;The implementation consists of four small modifications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a new tool type.&lt;/li&gt;
&lt;li&gt;Extend the Agent configuration dialog.&lt;/li&gt;
&lt;li&gt;Allow the new query mode to pass through the message pipeline.&lt;/li&gt;
&lt;li&gt;Render command output as Markdown.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No core frontend architecture needs to be modified.&lt;/p&gt;

&lt;h2&gt;
  
  
  File 6: &lt;code&gt;type.ts&lt;/code&gt; (Modified)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Location&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;webapp/packages/supersonic-fe/src/pages/Agent/type.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, introduce a new tool type named &lt;code&gt;WORK_FLOW_CTL&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;AgentToolTypeEnum&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;NL2SQL_RULE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;NL2SQL_RULE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;NL2SQL_LLM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;NL2SQL_LLM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;PLUGIN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PLUGIN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;DATASET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DATASET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;WORK_FLOW_CTL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WORK_FLOW_CTL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then extend the tool definition with the configuration required by DolphinScheduler CLI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AgentToolType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AgentToolTypeEnum&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;queryModes&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;QueryModeEnum&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;metricOptions&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;MetricOptionType&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;exampleQuestions&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;modelIds&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="nl"&gt;dsctlPath&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;dsApiUrl&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;dsToken&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;defaultProject&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These additional fields allow administrators to configure the CLI executable, API endpoint, authentication token, and default project directly from the Agent management interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  File 7: &lt;code&gt;ToolModal.tsx&lt;/code&gt; (Modified)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Location&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;webapp/packages/supersonic-fe/src/pages/Agent/ToolModal.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the existing &lt;strong&gt;PLUGIN&lt;/strong&gt; configuration form, add a new form section dedicated to &lt;strong&gt;WORK_FLOW_CTL&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;toolType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;AgentToolTypeEnum&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WORK_FLOW_CTL&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FormItem&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"dsApiUrl"&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"DS API URL"&lt;/span&gt;
      &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Please enter the DolphinScheduler API endpoint.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Input&lt;/span&gt;
        &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Example: http://ds-host:12345"&lt;/span&gt;
        &lt;span class="na"&gt;allowClear&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;FormItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FormItem&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"dsToken"&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"DS API Token"&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Password&lt;/span&gt;
        &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"DolphinScheduler API Token"&lt;/span&gt;
        &lt;span class="na"&gt;allowClear&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;FormItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FormItem&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"dsctlPath"&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"dsctl Path"&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Input&lt;/span&gt;
        &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Path to the dsctl executable (default: dsctl)"&lt;/span&gt;
        &lt;span class="na"&gt;allowClear&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;FormItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FormItem&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"defaultProject"&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Default Project"&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Input&lt;/span&gt;
        &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Default DolphinScheduler project"&lt;/span&gt;
        &lt;span class="na"&gt;allowClear&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;FormItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One advantage of this design is that the tool type dropdown requires &lt;strong&gt;no additional frontend changes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The available tool types are loaded dynamically through the backend &lt;code&gt;getToolTypes()&lt;/code&gt; API. Once &lt;code&gt;WORK_FLOW_CTL&lt;/code&gt; is added to the backend enum, &lt;strong&gt;DolphinScheduler CLI&lt;/strong&gt; automatically appears in the dropdown menu.&lt;/p&gt;

&lt;p&gt;This keeps the frontend completely data-driven.&lt;/p&gt;

&lt;h2&gt;
  
  
  File 8: &lt;code&gt;index.tsx&lt;/code&gt; (Modified)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Location&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;webapp/packages/chat-sdk/src/components/ChatItem/index.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, update the message processing logic to recognize the new query mode.&lt;/p&gt;

&lt;p&gt;Inside the &lt;code&gt;updateData()&lt;/code&gt; function, extend the response whitelist by adding &lt;code&gt;WORKFLOW_CTL&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;queryColumns&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;queryColumns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;queryResults&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="nx"&gt;queryMode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WEB_PAGE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="nx"&gt;queryMode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WEB_SERVICE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="nx"&gt;queryMode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PLAIN_TEXT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="nx"&gt;queryMode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WORKFLOW_CTL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;tip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the same time, make the component compatible with responses that return &lt;code&gt;code: 1&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;tip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SEARCH_EXCEPTION_TIP&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without these two changes, Workflow CLI responses would be treated as invalid and never reach the rendering layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  File 9: &lt;code&gt;ExecuteItem.tsx&lt;/code&gt; (Modified)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Location&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;webapp/packages/chat-sdk/src/components/ChatItem/ExecuteItem.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two small changes are required in this component.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update the Message Title
&lt;/h3&gt;

&lt;p&gt;Near the top of the file, modify the title prefix logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;titlePrefix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;queryMode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PLAIN_TEXT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="nx"&gt;queryMode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WEB_SERVICE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="nx"&gt;queryMode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WORKFLOW_CTL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Q&amp;amp;A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Workflow operations are conversational interactions rather than analytical queries, so they should be categorized as &lt;strong&gt;Q&amp;amp;A&lt;/strong&gt; instead of &lt;strong&gt;Data&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Render Markdown Output
&lt;/h3&gt;

&lt;p&gt;Next, add a rendering branch for the new query mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;queryMode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WORKFLOW_CTL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ReactMarkdown&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;textResult&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ReactMarkdown&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ChatMsg&lt;/span&gt;
        &lt;span class="err"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend already formats command output as Markdown, making &lt;code&gt;ReactMarkdown&lt;/code&gt; the ideal renderer.&lt;/p&gt;

&lt;p&gt;For example, when a user asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Run the daily-etl workflow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The chat interface displays:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gs"&gt;**Execute the specified workflow**&lt;/span&gt;

&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;bash
&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;dsctl workflow run daily-etl

Workflow submitted successfully.

Instance ID: 12345
Status: RUNNING
&lt;span class="p"&gt;```&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compared with rendering plain text, Markdown significantly improves readability by preserving code formatting and command output structure.&lt;/p&gt;

&lt;p&gt;Since &lt;code&gt;ReactMarkdown&lt;/code&gt; has already been imported into the component, no additional dependencies are required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frontend Extension Summary
&lt;/h2&gt;

&lt;p&gt;The frontend integration is intentionally minimal. Only four files require changes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;type.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Register the new &lt;code&gt;WORK_FLOW_CTL&lt;/code&gt; tool type and define its configuration fields.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ToolModal.tsx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Add a configuration form for DolphinScheduler CLI.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;index.tsx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Allow the new query mode to pass through the message processing pipeline.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ExecuteItem.tsx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Render Workflow CLI responses as Markdown in the chat interface.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;With these lightweight modifications, SuperSonic gains a fully conversational workflow orchestration capability while preserving its existing frontend architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage Configuration
&lt;/h2&gt;

&lt;p&gt;Before using the integration, make sure both &lt;strong&gt;dsctl&lt;/strong&gt; and &lt;strong&gt;Apache DolphinScheduler&lt;/strong&gt; are properly configured.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Install dsctl
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Configure Environment Variables
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;DS_API_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://your-dolphinscheduler-host:12345/dolphinscheduler
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;DS_API_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your-api-token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These environment variables enable &lt;code&gt;dsctl&lt;/code&gt; to communicate with the target DolphinScheduler cluster.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Verify the Installation
&lt;/h4&gt;

&lt;p&gt;Run the following command to ensure everything is configured correctly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dsctl doctor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the diagnostic completes successfully, the CLI is ready to be integrated with SuperSonic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring an Agent
&lt;/h2&gt;

&lt;p&gt;Once the backend and frontend have been deployed, the final step is to configure an Agent that can invoke the DolphinScheduler CLI.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step 1: Open the Agent Management Page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Navigate to the Agent management page and either create a new Agent or edit an existing one.&lt;/p&gt;

&lt;p&gt;(Screenshots omitted.)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step 2: Add a New Tool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open the &lt;strong&gt;Tools&lt;/strong&gt; tab and click &lt;strong&gt;Add Tool&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;(Screenshots omitted.)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step 3: Select &lt;strong&gt;Workflow CLI&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the &lt;strong&gt;Tool Type&lt;/strong&gt; dropdown, select &lt;strong&gt;Workflow CLI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;(Screenshots omitted.)&lt;/p&gt;

&lt;p&gt;This option becomes available automatically after the backend registers the &lt;code&gt;WORK_FLOW_CTL&lt;/code&gt; tool type.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step 4: Configure the Connection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fill in the required connection settings.&lt;/p&gt;

&lt;p&gt;(Screenshots omitted.)&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DS API URL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;DolphinScheduler REST API endpoint&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://ds-host:12345/dolphinscheduler&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DS API Token&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;API authentication token&lt;/td&gt;
&lt;td&gt;&lt;code&gt;your_token_here&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;dsctl Path&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Path to the &lt;code&gt;dsctl&lt;/code&gt; executable&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/usr/local/bin/dsctl&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Default Project&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Default DolphinScheduler project&lt;/td&gt;
&lt;td&gt;&lt;code&gt;etl-prod&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Once the configuration is saved, the Agent is ready to execute workflow operations through natural language.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step 5: Start Chatting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Users can now interact with DolphinScheduler directly from the SuperSonic chat interface.&lt;/p&gt;

&lt;p&gt;(Screenshots omitted.)&lt;/p&gt;

&lt;p&gt;Instead of navigating through multiple pages in the DolphinScheduler Web UI, users simply describe what they want to accomplish in plain language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported Natural Language Commands
&lt;/h2&gt;

&lt;p&gt;The following examples illustrate how natural-language requests are translated into &lt;code&gt;dsctl&lt;/code&gt; commands.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Natural Language Request&lt;/th&gt;
&lt;th&gt;Generated dsctl Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Run a health check.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dsctl doctor&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;List all projects.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dsctl project list&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Switch to the etl-prod project.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dsctl use project etl-prod&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;List all workflows.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dsctl workflow list&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Run the daily-etl workflow.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dsctl workflow run daily-etl&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Monitor workflow instance 123.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dsctl workflow-instance watch 123&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Show the summary of workflow instance 123.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dsctl workflow-instance digest 123&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;List tasks for workflow instance 123.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dsctl task-instance list --workflow-instance 123&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Show the raw log of task 456.&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dsctl task-instance log 456 --raw&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These examples demonstrate that users no longer need to memorize CLI syntax. Instead, they can interact with DolphinScheduler naturally while the LLM automatically translates their intent into executable commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extension Summary
&lt;/h2&gt;

&lt;p&gt;The entire integration is built around SuperSonic's SPI extension mechanism, making it highly modular and easy to maintain.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Extension Point&lt;/th&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Intent Parsing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChatQueryParser&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Converts natural-language requests into &lt;code&gt;dsctl&lt;/code&gt; commands&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Command Execution&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChatQueryExecutor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Executes the generated &lt;code&gt;dsctl&lt;/code&gt; command and returns the result&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tool Registration&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AgentToolType&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Registers the new Workflow CLI tool in the Agent management page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tool Configuration&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;AgentTool&lt;/code&gt; subclass&lt;/td&gt;
&lt;td&gt;Stores CLI configuration, API endpoint, authentication token, and project settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LLM Integration&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;AiServices&lt;/code&gt; + &lt;code&gt;ChatAppManager&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Generates structured commands while allowing prompts and models to be configured through the UI&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One of the biggest advantages of this approach is that &lt;strong&gt;no modifications to the SuperSonic framework itself are required&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By implementing the standard SPI interfaces and registering them in &lt;code&gt;spring.factories&lt;/code&gt;, developers can seamlessly integrate DolphinScheduler into SuperSonic while preserving the framework's pluggable architecture.&lt;/p&gt;

&lt;p&gt;More importantly, this pattern is not limited to DolphinScheduler. Any CLI-based system—including Kubernetes, Spark, Flink, Airflow, or internal enterprise tools—can be integrated using the same extension model, making SuperSonic a powerful conversational gateway for enterprise operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SuperSonic GitHub&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://github.com/apache/dolphinscheduler" rel="noopener noreferrer"&gt;Apache DolphinScheduler&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dsctl GitHub&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SuperSonic Documentation&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://dolphinscheduler.apache.org/en-us/docs/3.4.2" rel="noopener noreferrer"&gt;Apache DolphinScheduler Documentation&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>bigdata</category>
      <category>apachedolphinscheduler</category>
      <category>cli</category>
      <category>tencent</category>
    </item>
    <item>
      <title>How to Upgrade Apache DolphinScheduler from 1.3.6 to 3.2.2 Without Downtime</title>
      <dc:creator>Chen Debra</dc:creator>
      <pubDate>Thu, 09 Jul 2026 06:52:15 +0000</pubDate>
      <link>https://dev.to/chen_debra_3060b21d12b1b0/how-to-upgrade-apache-dolphinscheduler-from-136-to-322-without-downtime-57lp</link>
      <guid>https://dev.to/chen_debra_3060b21d12b1b0/how-to-upgrade-apache-dolphinscheduler-from-136-to-322-without-downtime-57lp</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgpt5rxnpsj2dcwgbwcye.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgpt5rxnpsj2dcwgbwcye.jpg" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Migrating a production Apache DolphinScheduler cluster across multiple major releases can be challenging, especially when upgrading from legacy versions such as &lt;strong&gt;v1.3.6&lt;/strong&gt; to the latest &lt;strong&gt;v3.2.2&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Because the database schema, task definition model, configuration files, and upgrade utilities have evolved significantly between releases, skipping intermediate versions is not recommended. This guide walks you through a verified upgrade path, highlights common pitfalls, and documents the fixes required during the migration process.&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Upgrade Overview
&lt;/h1&gt;

&lt;p&gt;Follow the upgrade sequence below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;v1.3.6
   ↓
v2.0.0
   ↓
v2.0.9
   ↓
v3.0.0
   ↓
v3.1.0
   ↓
v3.1.8
   ↓
v3.2.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Download the Binary Packages
&lt;/h2&gt;

&lt;p&gt;Download the binary distribution for each target version from the Apache archive.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://archive.apache.org/dist/dolphinscheduler/3.1.8/apache-dolphinscheduler-3.1.8-bin.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Prepare Independent Databases
&lt;/h2&gt;

&lt;p&gt;Create a dedicated MySQL database for each intermediate version.&lt;/p&gt;

&lt;p&gt;Example databases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dolphinscheduler_2_0_0
dolphinscheduler_2_0_9
dolphinscheduler_3_0_0
dolphinscheduler_3_1_0
dolphinscheduler_3_1_8
dolphinscheduler_3_2_2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example SQL statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;dolphinscheduler_3_2_2&lt;/span&gt;
&lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="nb"&gt;CHARACTER&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;utf8&lt;/span&gt;
&lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;COLLATE&lt;/span&gt; &lt;span class="n"&gt;utf8_general_ci&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using separate databases for every upgrade stage allows you to verify each migration independently and provides an easy rollback path if necessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extract Each Release
&lt;/h2&gt;

&lt;p&gt;Extract every binary package into the same working directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./upgrade_dolphin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After extraction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update the database connection configuration.&lt;/li&gt;
&lt;li&gt;Run the corresponding upgrade script.&lt;/li&gt;
&lt;li&gt;Verify that the upgrade completes successfully before proceeding to the next version.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  2. Upgrade from v1.3.6 to v2.0.0
&lt;/h1&gt;

&lt;p&gt;This is the most complex migration in the entire upgrade path because Apache DolphinScheduler introduced significant changes to its internal metadata model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1. Back Up the Existing Database
&lt;/h2&gt;

&lt;p&gt;Export the original &lt;strong&gt;v1.3.6&lt;/strong&gt; database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysqldump &lt;span class="nt"&gt;-uroot&lt;/span&gt; &lt;span class="nt"&gt;-pmysql&lt;/span&gt; dolphinscheduler &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .mysql_bak/dolphinscheduler.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2. Restore the Backup
&lt;/h2&gt;

&lt;p&gt;Import the exported data into the new database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dolphinscheduler_2_0_0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3. Extract the Binary Package
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-zxvf&lt;/span&gt; apache-dolphinscheduler-2.0.0-bin.tar.gz &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-C&lt;/span&gt; ./upgrade_dolphin/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4. Patch the Source Code
&lt;/h2&gt;

&lt;p&gt;During the migration from &lt;strong&gt;v1.3.6&lt;/strong&gt; to &lt;strong&gt;v2.0.0&lt;/strong&gt;, the task definition storage model changed significantly.&lt;/p&gt;

&lt;p&gt;Previously, every workflow stored all task definitions inside the&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;t_ds_process_definition.process_definition_json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;field.&lt;/p&gt;

&lt;p&gt;Starting with &lt;strong&gt;v2.0.0&lt;/strong&gt;, every task is migrated into the newly introduced&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;t_ds_task_definition
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;table.&lt;/p&gt;

&lt;p&gt;During this conversion process, several edge cases may trigger &lt;strong&gt;NullPointerExceptions (NPEs)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvuolx3lk3z24twkhmums.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvuolx3lk3z24twkhmums.jpg" width="799" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To resolve these issues, four locations in the upgrade source code were patched by adding null checks to safely handle task and dependency parsing during schema migration.&lt;/p&gt;

&lt;p&gt;Depending on the workflow definitions in your production environment, additional exceptions may occur. If so, update the corresponding migration logic, rebuild the project, and rerun the upgrade.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdg4rre0e9oy37r60akfy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdg4rre0e9oy37r60akfy.jpg" width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnlu7xc0cfievm8rwzd1n.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnlu7xc0cfievm8rwzd1n.jpg" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5. Replace the Patched DAO Library
&lt;/h2&gt;

&lt;p&gt;The modified source file is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UpgradeDao.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After rebuilding the project, replace the original DAO library in the &lt;strong&gt;lib&lt;/strong&gt; directory with the newly compiled JAR.&lt;/p&gt;

&lt;p&gt;The following files are included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apache DolphinScheduler v2.0.0 source code&lt;/li&gt;
&lt;li&gt;Rebuilt &lt;code&gt;dolphinscheduler-dao-2.0.0.jar&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 6. Run the Upgrade
&lt;/h2&gt;

&lt;p&gt;Update the database configuration.&lt;/p&gt;

&lt;p&gt;Navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apache-dolphinscheduler-2.0.0-bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;conf/datasource.properties
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure it to connect to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dolphinscheduler_2_0_0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy &lt;code&gt;mysql-connector-java-8.0.16.jar&lt;/code&gt; into the &lt;strong&gt;lib&lt;/strong&gt; directory.&lt;/li&gt;
&lt;li&gt;Run the upgrade script:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh script/upgrade-dolphinscheduler.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Monitor the output carefully and resolve any errors that occur during execution.&lt;/p&gt;

&lt;p&gt;After the script completes successfully, verify the database version by checking the &lt;strong&gt;t_ds_version&lt;/strong&gt; table.&lt;/p&gt;

&lt;p&gt;The version should now be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, the upgrade from &lt;strong&gt;v1.3.6&lt;/strong&gt; to &lt;strong&gt;v2.0.0&lt;/strong&gt; is complete.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Upgrade from v2.0.0 to v2.0.9
&lt;/h1&gt;

&lt;p&gt;Compared with the previous migration, upgrading from &lt;strong&gt;v2.0.0&lt;/strong&gt; to &lt;strong&gt;v2.0.9&lt;/strong&gt; is much more straightforward. No source code modifications are required, and the upgrade can be completed using the official upgrade scripts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1. Back Up the Database
&lt;/h2&gt;

&lt;p&gt;Export the upgraded &lt;strong&gt;v2.0.0&lt;/strong&gt; database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysqldump &lt;span class="nt"&gt;-uroot&lt;/span&gt; &lt;span class="nt"&gt;-pmysql&lt;/span&gt; dolphinscheduler_2_0_0 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .mysql_bak/dolphinscheduler_2_0_0.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2. Restore the Backup
&lt;/h2&gt;

&lt;p&gt;Import the backup into the target database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dolphinscheduler_2_0_9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3. Extract the Binary Package
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-zxvf&lt;/span&gt; apache-dolphinscheduler-2.0.9-bin.tar.gz &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-C&lt;/span&gt; ./upgrade_dolphin/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4. Run the Upgrade
&lt;/h2&gt;

&lt;p&gt;Update the database configuration.&lt;/p&gt;

&lt;p&gt;Navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apache-dolphinscheduler-2.0.9-bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit the following configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;conf/config/install_config.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure it to connect to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dolphinscheduler_2_0_9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9m3n9fyjwx1amd0n0gyt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9m3n9fyjwx1amd0n0gyt.jpg" width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy &lt;strong&gt;mysql-connector-java-8.0.16.jar&lt;/strong&gt; into the &lt;strong&gt;lib&lt;/strong&gt; directory.&lt;/li&gt;
&lt;li&gt;Run the upgrade script:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh script/upgrade-dolphinscheduler.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Monitor the upgrade logs and resolve any errors if they occur.&lt;/p&gt;

&lt;p&gt;Once the upgrade finishes successfully, verify the schema version in the &lt;strong&gt;t_ds_version&lt;/strong&gt; table.&lt;/p&gt;

&lt;p&gt;The version should now be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2.0.9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The upgrade from &lt;strong&gt;v2.0.0&lt;/strong&gt; to &lt;strong&gt;v2.0.9&lt;/strong&gt; is now complete.&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Upgrade from v2.0.9 to v3.0.0
&lt;/h1&gt;

&lt;p&gt;Apache DolphinScheduler &lt;strong&gt;v3.0.0&lt;/strong&gt; introduces a new database upgrade mechanism. Unlike previous releases, schema migrations are executed using the &lt;strong&gt;upgrade-schema.sh&lt;/strong&gt; utility located under the &lt;strong&gt;tools&lt;/strong&gt; directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1. Back Up the Database
&lt;/h2&gt;

&lt;p&gt;Export the &lt;strong&gt;v2.0.9&lt;/strong&gt; database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysqldump &lt;span class="nt"&gt;-uroot&lt;/span&gt; &lt;span class="nt"&gt;-pmysql&lt;/span&gt; dolphinscheduler_2_0_9 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .mysql_bak/dolphinscheduler_2_0_9.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2. Restore the Backup
&lt;/h2&gt;

&lt;p&gt;Import the backup into the new database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dolphinscheduler_3_0_0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3. Extract the Binary Package
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-zxvf&lt;/span&gt; apache-dolphinscheduler-3.0.0-bin.tar.gz &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-C&lt;/span&gt; ./upgrade_dolphin/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4. Run the Upgrade
&lt;/h2&gt;

&lt;p&gt;Update the database configuration.&lt;/p&gt;

&lt;p&gt;Navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apache-dolphinscheduler-3.0.0-bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/env/dolphinscheduler_env.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure the database connection to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dolphinscheduler_3_0_0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foel6oy3pia1yfhmb45np.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foel6oy3pia1yfhmb45np.jpg" width="800" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy &lt;strong&gt;mysql-connector-java-8.0.16.jar&lt;/strong&gt; into the &lt;strong&gt;lib&lt;/strong&gt; directory.&lt;/li&gt;
&lt;li&gt;Modify the database upgrade script by removing the SQL statement that adds the &lt;strong&gt;alert_type&lt;/strong&gt; column.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;File location:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tools/sql/sql/upgrade/3.0.0_schema/mysql/dolphinscheduler_ddl.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After updating the SQL file, execute the schema upgrade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh tools/bin/upgrade-schema.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Review the output carefully and fix any reported errors before rerunning the script.&lt;/p&gt;

&lt;p&gt;After a successful upgrade, verify that the &lt;strong&gt;t_ds_version&lt;/strong&gt; table reports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The migration to &lt;strong&gt;v3.0.0&lt;/strong&gt; is now complete.&lt;/p&gt;

&lt;h1&gt;
  
  
  5. Upgrade from v3.0.0 to v3.1.0
&lt;/h1&gt;

&lt;p&gt;The upgrade procedure for &lt;strong&gt;v3.1.0&lt;/strong&gt; follows the same workflow as previous releases, with one additional adjustment to the database migration script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1. Back Up the Database
&lt;/h2&gt;

&lt;p&gt;Export the upgraded &lt;strong&gt;v3.0.0&lt;/strong&gt; database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysqldump &lt;span class="nt"&gt;-uroot&lt;/span&gt; &lt;span class="nt"&gt;-pmysql&lt;/span&gt; dolphinscheduler_3_0_0 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .mysql_bak/dolphinscheduler_3_0_0.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2. Restore the Backup
&lt;/h2&gt;

&lt;p&gt;Import the backup into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dolphinscheduler_3_1_0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3. Extract the Binary Package
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-zxvf&lt;/span&gt; apache-dolphinscheduler-3.1.0-bin.tar.gz &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-C&lt;/span&gt; ./upgrade_dolphin/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4. Run the Upgrade
&lt;/h2&gt;

&lt;p&gt;Navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apache-dolphinscheduler-3.1.0-bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update the database connection in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/env/dolphinscheduler_env.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure it to use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dolphinscheduler_3_1_0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmk3a8xzklkckj323ux1m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmk3a8xzklkckj323ux1m.jpg" width="799" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy &lt;strong&gt;mysql-connector-java-8.0.16.jar&lt;/strong&gt; into the &lt;strong&gt;lib&lt;/strong&gt; directory.&lt;/li&gt;
&lt;li&gt;Edit the schema upgrade script and remove the SQL statement that adds the &lt;strong&gt;other_params_json&lt;/strong&gt; column.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;File location:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tools/sql/sql/upgrade/3.1.0_schema/mysql/dolphinscheduler_ddl.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the upgrade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh tools/bin/upgrade-schema.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Monitor the execution logs for any errors.&lt;/p&gt;

&lt;p&gt;After the migration completes successfully, verify the schema version in &lt;strong&gt;t_ds_version&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Expected version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The upgrade from &lt;strong&gt;v3.0.0&lt;/strong&gt; to &lt;strong&gt;v3.1.0&lt;/strong&gt; is now complete.&lt;/p&gt;

&lt;h1&gt;
  
  
  6. Upgrade from v3.1.0 to v3.1.8
&lt;/h1&gt;

&lt;p&gt;The upgrade from &lt;strong&gt;v3.1.0&lt;/strong&gt; to &lt;strong&gt;v3.1.8&lt;/strong&gt; follows the standard Apache DolphinScheduler schema migration workflow.&lt;/p&gt;

&lt;p&gt;Before upgrading, always create a complete backup of the current database to ensure rollback capability in case of unexpected issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1. Back Up the Database
&lt;/h2&gt;

&lt;p&gt;Export the upgraded &lt;strong&gt;v3.1.0&lt;/strong&gt; database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysqldump &lt;span class="nt"&gt;-uroot&lt;/span&gt; &lt;span class="nt"&gt;-pmysql&lt;/span&gt; dolphinscheduler_3_1_0 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .mysql_bak/dolphinscheduler_3_1_0.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2. Restore the Backup
&lt;/h2&gt;

&lt;p&gt;Import the backup into the target database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dolphinscheduler_3_1_8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3. Extract the Binary Package
&lt;/h2&gt;

&lt;p&gt;Extract the Apache DolphinScheduler v3.1.8 distribution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-zxvf&lt;/span&gt; apache-dolphinscheduler-3.1.8-bin.tar.gz &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-C&lt;/span&gt; ./upgrade_dolphin/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4. Run the Upgrade
&lt;/h2&gt;

&lt;p&gt;Navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apache-dolphinscheduler-3.1.8-bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update the database connection configuration in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/env/dolphinscheduler_env.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure the database as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dolphinscheduler_3_1_8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7skp902v187dvqpxmm3a.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7skp902v187dvqpxmm3a.jpg" width="799" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy &lt;code&gt;mysql-connector-java-8.0.16.jar&lt;/code&gt; into the &lt;strong&gt;lib&lt;/strong&gt; directory.&lt;/li&gt;
&lt;li&gt;Execute the schema upgrade script:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh tools/bin/upgrade-schema.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Carefully monitor the upgrade process and check the logs for any errors.&lt;/p&gt;

&lt;p&gt;After successful execution, verify the schema version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;t_ds_version&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The expected version should be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3.1.8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The upgrade from &lt;strong&gt;v3.1.0&lt;/strong&gt; to &lt;strong&gt;v3.1.8&lt;/strong&gt; is now complete.&lt;/p&gt;

&lt;h1&gt;
  
  
  7. Upgrade from v3.1.8 to v3.2.2
&lt;/h1&gt;

&lt;p&gt;Apache DolphinScheduler &lt;strong&gt;v3.2.2&lt;/strong&gt; is the final target version in this upgrade path.&lt;/p&gt;

&lt;p&gt;The migration process is similar to the previous upgrades.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1. Back Up the Database
&lt;/h2&gt;

&lt;p&gt;Export the upgraded &lt;strong&gt;v3.1.8&lt;/strong&gt; database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysqldump &lt;span class="nt"&gt;-uroot&lt;/span&gt; &lt;span class="nt"&gt;-pmysql&lt;/span&gt; dolphinscheduler_3_1_8 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .mysql_bak/dolphinscheduler_3_1_8.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2. Restore the Backup
&lt;/h2&gt;

&lt;p&gt;Import the backup into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dolphinscheduler_3_2_2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3. Extract the Binary Package
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-zxvf&lt;/span&gt; apache-dolphinscheduler-3.2.2-bin.tar.gz &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-C&lt;/span&gt; ./upgrade_dolphin/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4. Run the Upgrade
&lt;/h2&gt;

&lt;p&gt;Navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apache-dolphinscheduler-3.2.2-bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update the database configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/env/dolphinscheduler_env.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure it to connect to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dolphinscheduler_3_2_2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fykv6f1f8txlk52vp29ir.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fykv6f1f8txlk52vp29ir.jpg" width="799" height="196"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy &lt;code&gt;mysql-connector-java-8.0.16.jar&lt;/code&gt; into the &lt;strong&gt;lib&lt;/strong&gt; directory.&lt;/li&gt;
&lt;li&gt;Execute the schema migration script:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh tools/bin/upgrade-schema.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Monitor the output carefully and resolve any migration errors if necessary.&lt;/p&gt;

&lt;p&gt;After successful completion, verify the version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3.2.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;by checking the &lt;code&gt;t_ds_version&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;The upgrade from &lt;strong&gt;v3.1.8&lt;/strong&gt; to &lt;strong&gt;v3.2.2&lt;/strong&gt; is now complete.&lt;/p&gt;

&lt;h1&gt;
  
  
  8. Post-Upgrade Configuration and Troubleshooting
&lt;/h1&gt;

&lt;p&gt;After completing the upgrade, additional configuration adjustments may be required to ensure all existing workflows and data sources continue working correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  8.1 Update Script Dependencies
&lt;/h2&gt;

&lt;p&gt;After upgrading to v3.2.2, update the script dependency configuration.&lt;/p&gt;

&lt;p&gt;Edit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/env/dolphinscheduler_env.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update paths for dependencies such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DataX&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Other external execution environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7h1qfmftv4t5sjqwjq3i.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7h1qfmftv4t5sjqwjq3i.jpg" width="799" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure all environment variables point to the correct installation paths after the upgrade.&lt;/p&gt;

&lt;h2&gt;
  
  
  8.2 Fix MySQL Data Source Configuration
&lt;/h2&gt;

&lt;p&gt;After upgrading, clicking &lt;strong&gt;Edit Data Source&lt;/strong&gt; for an existing MySQL data source may result in errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Root Cause
&lt;/h3&gt;

&lt;p&gt;The issue is caused by an incompatible format in the:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;t_ds_datasource.connection_params
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;field.&lt;/p&gt;

&lt;p&gt;The connection parameter structure changed between versions.&lt;/p&gt;

&lt;p&gt;Existing records created in older versions may not match the format expected by &lt;strong&gt;Apache DolphinScheduler v3.2.2&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Manually update the &lt;code&gt;connection_params&lt;/code&gt; field in the &lt;code&gt;t_ds_datasource&lt;/code&gt; table according to the new v3.2.2 format.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"root"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"doris"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jdbc:mysql://127.0.0.1:9030"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"database"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PROD_ODS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jdbcUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jdbc:mysql://127.0.0.1:9030/PROD_ODS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"driverClassName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"com.mysql.cj.jdbc.Driver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"validationQuery"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"select 1"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After updating the connection parameters, the MySQL data source can be edited normally from the DolphinScheduler web interface.&lt;/p&gt;

&lt;h1&gt;
  
  
  Upgrade Completed Successfully 🎉
&lt;/h1&gt;

&lt;p&gt;Following this guide, you can safely migrate Apache DolphinScheduler from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;v1.3.6
      ↓
v2.0.0
      ↓
v2.0.9
      ↓
v3.0.0
      ↓
v3.1.0
      ↓
v3.1.8
      ↓
v3.2.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key lessons from this upgrade journey:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always perform database backups before every version migration.&lt;/li&gt;
&lt;li&gt;Use intermediate upgrade versions instead of skipping major releases.&lt;/li&gt;
&lt;li&gt;Review schema migration scripts carefully when moving across major versions.&lt;/li&gt;
&lt;li&gt;Be prepared to patch migration logic for customized workflows or legacy metadata.&lt;/li&gt;
&lt;li&gt;Validate data source configurations after completing the upgrade.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A carefully planned migration process can significantly reduce risks when upgrading production Apache DolphinScheduler environments across multiple major releases.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>dataengineering</category>
      <category>apachedolphinscheduler</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
