<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Apache StreamPark Blog</title>
        <link>https://streampark.apache.org/zh-CN/blog</link>
        <description>Apache StreamPark Blog</description>
        <lastBuildDate>Mon, 09 Feb 2026 02:32:43 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <item>
            <title><![CDATA[Apache StreamPark™ Flink on Kubernetes 实践]]></title>
            <link>https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s</link>
            <guid>https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s</guid>
            <pubDate>Mon, 09 Feb 2026 02:32:43 GMT</pubDate>
            <description><![CDATA[雾芯科技创立于2018年1月。目前主营业务包括 RELX 悦刻品牌产品的研发、设计、制造及销售。凭借覆盖全产业链的核心技术与能力，RELX 悦刻致力于为用户提供兼具高品质和安全性的产品。]]></description>
            <content:encoded><![CDATA[<p>雾芯科技创立于2018年1月。目前主营业务包括 RELX 悦刻品牌产品的研发、设计、制造及销售。凭借覆盖全产业链的核心技术与能力，RELX 悦刻致力于为用户提供兼具高品质和安全性的产品。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="为什么选择-native-kubernetes"><strong>为什么选择 Native Kubernetes</strong><a class="hash-link" aria-label="为什么选择-native-kubernetes的直接链接" title="为什么选择-native-kubernetes的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s#%E4%B8%BA%E4%BB%80%E4%B9%88%E9%80%89%E6%8B%A9-native-kubernetes">​</a></h2>
<p>Native Kubernetes 具有以下优势：</p>
<ul>
<li>更短的 Failover 时间</li>
<li>可以实现资源托管，不需要手动创建 TaskManager 的 Pod，可以自动完成销毁</li>
<li>具有更加便捷的 HA，Flink 1.12 版本之后在 Native Kubernetes 模式下，可以依赖于原生 Kubernetes 的 Leader选举机制来完成 JobManager 的 HA</li>
</ul>
<p>Native Kubernetes 和 Standalone Kubernetes 主要区别在于 Flink 与 Kubernetes 交互的方式不同以及由此产生的一系列优势。Standalone Kubernetes 需要用户自定义 JobManager 和 TaskManager 的 Kubernetes 资源描述文件，提交作业时需要用 kubectl 结合资源描述文件启动 Flink 集群。而 Native Kubernetes 模式 Flink Client 里面集成了一个 Kubernetes Client，它可以直接和 Kubernetes API Server 进行通讯，完成 JobManager Deployment 以及 ConfigMap 的创建。JobManager Development 创建完成之后，它里面的 Resource Manager 模块可以直接和 Kubernetes API Server 进行通讯，完成 TaskManager pod 的创建和销毁工作以及 Taskmanager 的弹性伸缩。因此生产环境中推荐使用 Flink on Native Kubernetes 模式部署 Flink 任务。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/nativekubernetes_architecture-ad376f8ae79ab66d90d95742e8335d53.png" width="1080" height="401" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="当-flink-on-kubernetes-遇见-apache-streampark"><strong>当 Flink On Kubernetes 遇见 Apache StreamPark™</strong><a class="hash-link" aria-label="当-flink-on-kubernetes-遇见-apache-streampark的直接链接" title="当-flink-on-kubernetes-遇见-apache-streampark的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s#%E5%BD%93-flink-on-kubernetes-%E9%81%87%E8%A7%81-apache-streampark">​</a></h2>
<p>Flink on Native Kubernetes 目前支持 Application 模式和 Session 模式，两者对比 Application 模式部署规避了 Session 模式的资源隔离问题、以及客户端资源消耗问题，因此**生产环境更推荐采用 Application Mode 部署 Flink 任务。**下面我们分别看看使用原始脚本的方式和使用 StreamPark 开发部署一个 Flink on Native Kubernetes 作业的流程。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="使用脚本方式部署kubernetes"><em><strong>使用脚本方式部署Kubernetes</strong></em><a class="hash-link" aria-label="使用脚本方式部署kubernetes的直接链接" title="使用脚本方式部署kubernetes的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s#%E4%BD%BF%E7%94%A8%E8%84%9A%E6%9C%AC%E6%96%B9%E5%BC%8F%E9%83%A8%E7%BD%B2kubernetes">​</a></h3>
<p>在没有一个支持 Flink on Kubernetes 任务开发部署的平台的情况下，需要使用脚本的方式进行任务的提交和停止，这也是 Flink 提供的默认的方式，具体步骤如下:</p>
<ol>
<li>在 Flink 客户端节点准备 kubectl 和 Docker 命令运行环境，创建部署 Flink 作业使用的 Kubernetes Namespace 和 Service Account 以及进行 RBAC</li>
<li>编写 Dockerfile 文件，将 Flink 基础镜像和用户的作业 Jar 打包到一起</li>
</ol>
<div class="language-dockerfile codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-dockerfile codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">FROM flink:1.13.6-scala_2.11</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">RUN mkdir -p $FLINK_HOME/usrlib</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">COPY my-flink-job.jar $FLINK_HOME/usrlib/my-flink-job.jar</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ol start="3">
<li>使用 Flink 客户端脚本启动 Flink 任务</li>
</ol>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">./bin/flink run-application \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    --target kubernetes-application \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    -Dkubernetes.namespace=flink-cluster \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    -Dkubernetes.jobmanager.service-account=default \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    -Dkubernetes.cluster-id=my-first-application-cluster \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    -Dkubernetes.container.image=relx_docker_url/streamx/relx_flink_1.13.6-scala_2.11:latest \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    -Dkubernetes.rest-service.exposed.type=NodePort \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    local:///opt/flink/usrlib/my-flink-job.jar</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ol start="4">
<li>使用 Kubectl 命令获取到 Flink 作业的 WebUI 访问地址和 JobId</li>
</ol>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">kubectl -n flink-cluster get svc</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ol start="5">
<li>使用Flink命令停止作业</li>
</ol>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">./bin/flink cancel</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    --target kubernetes-application</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    -Dkubernetes.cluster-id=my-first-application-cluster</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    -Dkubernetes.namespace=flink-cluster &lt;jobId&gt;</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>以上就是使用 Flink 提供的最原始的脚本方式把一个 Flink 任务部署到 Kubernetes 上的过程，只做到了最基本的任务提交，如果要达到生产使用级别，还有一系列的问题需要解决，如：方式过于原始无法适配大批量任务、无法记录任务checkpoint 和实时状态跟踪、任务运维和监控困难、无告警机制、 无法集中化管理等等。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="使用-apache-streampark-部署-flink-on-kubernetes"><strong>使用 Apache StreamPark™ 部署 Flink on Kubernetes</strong><a class="hash-link" aria-label="使用-apache-streampark-部署-flink-on-kubernetes的直接链接" title="使用-apache-streampark-部署-flink-on-kubernetes的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s#%E4%BD%BF%E7%94%A8-apache-streampark-%E9%83%A8%E7%BD%B2-flink-on-kubernetes">​</a></h2>
<hr>
<p>对于企业级生产环境使用 Flink on Kubernetes 会有着更高的要求，一般会选择自建平台或者购买相关商业产品，不论哪种方案在产品能力上满足: <strong>大批量任务开发部署、状态跟踪、运维监控、失败告警、任务统一管理、高可用性</strong> 等这些是普遍的诉求。</p>
<p>针对以上问题我们调研了开源领域支持开发部署 Flink on Kubernetes 任务的开源项目，调研的过程中也不乏遇到了其他优秀的开源项目，在综合对比了多个开源项目后得出结论: **StreamPark 不论是完成度还是使用体验、稳定性等整体表现都非常出色，因此最终选择了 StreamPark 作为我们的一站式实时计算平台。**下面我们看看 StreamPark 是如何支持 Flink on Kubernetes :</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="基础环境配置"><strong>基础环境配置</strong><a class="hash-link" aria-label="基础环境配置的直接链接" title="基础环境配置的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s#%E5%9F%BA%E7%A1%80%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE">​</a></h3>
<p>基础环境配置包括 Kubernetes 和 Docker 仓库信息以及 Flink 客户端的信息配置。对于 Kubernetes 基础环境最为简单的方式是直接拷贝 Kubernetes 节点的 .kube/config 到 StreamPark 节点用户目录，之后使用 kubectl 命令创建 Flink 专用的 Kubernetes Namespace 以及进行 RBAC 配置。</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 创建Flink作业使用的k8s namespace</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">kubectl create ns flink-cluster</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 对default用户进行RBAC资源绑定</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">kubectl create clusterrolebinding flink-role-binding-default --clusterrole=edit --serviceaccount=flink-cluster:default</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Docker 账户信息直接在 Docker Setting 界面配置即可：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/docker_setting-80acf43cf64fd390e4d50da8830671c0.png" width="1080" height="586" class="img_iwx1"></p>
<p>StreamPark 可适配多版本 Flink 作业开发，Flink 客户端直接在 StreamPark Setting 界面配置即可：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flinkversion_setting-b170a43882590683ea0c7f109f909396.png" width="1080" height="352" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="作业开发"><strong>作业开发</strong><a class="hash-link" aria-label="作业开发的直接链接" title="作业开发的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s#%E4%BD%9C%E4%B8%9A%E5%BC%80%E5%8F%91">​</a></h3>
<p>StreamPark 做好基础环境配置之后只需要三步即可开发部署一个 Flink 作业:</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/development_process-476918cfd29159983fe26b36ef487895.png" width="1080" height="271" class="img_iwx1"></p>
<p>StreamPark 既支持 Upload Jar 也支持直接编写 Flink SQL 作业, <strong>Flink SQL 作业只需要输入SQL 和 依赖项即可, 该方式大大提升了开发体验,</strong> **并且规避了依赖冲突等问题，**对此部分本文不重点介绍。</p>
<p>这里需要选择部署模式为 kubernetes application, 并且需要在作业开发页面进行以下参数的配置：红框中参数为 Flink on Kubernetes 基础参数。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/kubernetes_base_parameters-1a28fec8d9d3dc57744324db4ef58551.png" width="1080" height="1104" class="img_iwx1"></p>
<p>下面参数为 Flink 作业和资源相关的参数，Resolve Order 的选择与代码加载模式有关，对于 DataStream API 开发的 Upload Jar上传的作业选择使用 Child-first，Flink SQL 作业选择使用 Parent-first 加载。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_parameters-ff7790882a753bd88fbf5db9b775a0e3.png" width="1080" height="1133" class="img_iwx1"></p>
<p>最后就是下面这两个重量级参数了，对于 Native Kubernetes 而言，k8s-pod-template 一般只需要进行 pod-template 配置即可，Dynamic Option 是 pod-template 参数的补充，对于一些个性化配置可以在 Dynamic Option 中配置。更多 Dynamic Option 直接参考 Flink 官网即可。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/pod_template-722285f448ec8adc0fa939d0baea2d10.png" width="1080" height="1104" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="作业上线"><strong>作业上线</strong><a class="hash-link" aria-label="作业上线的直接链接" title="作业上线的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s#%E4%BD%9C%E4%B8%9A%E4%B8%8A%E7%BA%BF">​</a></h3>
<p>作业开发完成之后是作业上线环节，在这一环节中 StreamPark 做了大量的工作，具体如下:</p>
<ul>
<li>准备环境</li>
<li>作业中的依赖下载</li>
<li>构建作业(打JAR包)</li>
<li>构建镜像</li>
<li>推送镜像到远程仓库</li>
</ul>
<p><strong>对于用户来说: 只需要点击任务列表中的云状的上线按钮即可。</strong></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/operation-067a84b9b5b1491206780076f98e6f8d.png" width="1080" height="573" class="img_iwx1"></p>
<p>在镜像构建和推送的时候我们可以看到 StreamPark 做的一系列工作: <strong>读取配置、构建镜像、推送镜像到远程仓库...</strong> 这里要给StreamPark 一个大大的赞！</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/step_details-301b14f2dbfa9c41f4c0e75a9086f0a4.png" width="948" height="1866" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="作业提交"><strong>作业提交</strong><a class="hash-link" aria-label="作业提交的直接链接" title="作业提交的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s#%E4%BD%9C%E4%B8%9A%E6%8F%90%E4%BA%A4">​</a></h3>
<p>最后只需要点击 Operation 里 start Application 按钮便可启动一个 Flink on Kubernetes 作业，作业启动成功之后点击作业名便可跳转到 Jobmanager WebUI 页面、整个过程非常简单丝滑。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/homework_submit-1f05dacf0fedfd1423f89ca2dec28437.png" width="1080" height="698" class="img_iwx1"></p>
<p>整个过程仅需上述三步，即可完成在 StreamPark 上开发和部署一个Flink on Kubernetes 作业。而 StreamPark 对于 Flink on Kubernetes 的支持远远不止提交个任务这么简单。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="作业管理"><strong>作业管理</strong><a class="hash-link" aria-label="作业管理的直接链接" title="作业管理的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s#%E4%BD%9C%E4%B8%9A%E7%AE%A1%E7%90%86">​</a></h3>
<p><strong>在作业提交之后，StreamPark 能实时获取到任务的最新 checkpoint 地址、任务的运行状态、集群实时的资源消耗信息，针对运行的任务可以非常方便的一键启停, 在停止作业时支持记录 savepoint 的位置, 以及再次启动时从 savepoint 恢复状态等功能，从而保证了生产环境的数据一致性，真正具备 Flink on Kubernetes 的 一站式开发、部署、运维监控的能力。</strong></p>
<p>接下来我们来看看这一块的能力 StreamPark 是如何进行支持的:</p>
<ul>
<li><strong>实时记录checkpoint</strong></li>
</ul>
<hr>
<p>在作业提交之后，有时候需要更改作业逻辑但是要保证数据的一致性，那么就需要平台具有实时记录每一次 checkpoint 位置的能力, 以及停止时记录最后的 savepoint 位置的能力，StreamPark 在 Flink on Kubernetes 上很好的实现了该功能。默认会每隔5秒获取一次 checkpoint 信息记录到对应的表中，并且会按照 Flink 中保留 checkpoint 数量的策略，只保留 state.checkpoints.num-retained 个，超过的部分则删除。在任务停止时有勾选 savepoint 的选项，如勾选了savepoint 选项，在任务停止时会做 savepoint 操作，同样会记录 savepoint 具体位置到表中。</p>
<p>默认 savepoint 的根路径只需要在 Flink Home flink-conf.yaml 文件中配置即可自动识别，除了默认地址，在停止时也可以自定义指定 savepoint 的根路径。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/savepoint-b0288f5293875d156f20dbe768384076.png" width="1080" height="446" class="img_iwx1"></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/checkpoint-acf7379b24a3bac6695a517b425f466b.png" width="1080" height="479" class="img_iwx1"></p>
<ul>
<li><strong>实时跟踪运行状态</strong></li>
</ul>
<hr>
<p>对于生产环境的挑战，很重要的一点就是监控是否到位，Flink on Kubernetes 更是如此。这点很重要, 也是最基本需要具备的能力，StreamPark 可实时监控 Flink on Kubernetes 作业的运行状态并在平台上展示给用户，在页面上可以很方便的根据各种运行状态来检索任务。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/run_status-5a663d9169c0bce8f4cfb993db77ae59.png" width="1080" height="617" class="img_iwx1"></p>
<ul>
<li><strong>完善的告警机制</strong></li>
</ul>
<hr>
<p>除此之外 StreamPark 还具备完善的报警功能: 支持邮件、钉钉、微信和短信 等。这也是当初公司调研之后选择 StreamPark 作为 Flink on Kubernetes 一站式平台的重要原因。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/alarm-c2104c1839a1b4bb668d48f092f25faa.png" width="1080" height="393" class="img_iwx1"></p>
<p>通过以上我们看到 StreamPark 在支持 Flink on Kubernetes 开发部署过程中具备的能力, 包括：<strong>作业的开发能力、部署能力、监控能力、运维能力、异常处理能力等，StreamPark 提供的是一套相对完整的解决方案。 且已经具备了一些 CICD/DevOps 的能力，整体的完成度还在持续提升。是在整个开源领域中对于 Flink on Kubernetes 一站式开发部署运维工作全链路都支持的产品，StreamPark 是值得被称赞的。</strong></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="apache-streampark-在雾芯科技的落地实践"><strong>Apache StreamPark™ 在雾芯科技的落地实践</strong><a class="hash-link" aria-label="apache-streampark-在雾芯科技的落地实践的直接��链接" title="apache-streampark-在雾芯科技的落地实践的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s#apache-streampark-%E5%9C%A8%E9%9B%BE%E8%8A%AF%E7%A7%91%E6%8A%80%E7%9A%84%E8%90%BD%E5%9C%B0%E5%AE%9E%E8%B7%B5">​</a></h2>
<p>StreamPark 在雾芯科技落地较晚，目前主要用于实时数据集成作业和实时指标计算作业的开发部署，有 Jar 任务也有 Flink SQL 任务，全部使用 Native Kubernetes 部署；数据源有CDC、Kafka 等，Sink 端有 Maxcompute、kafka、Hive 等，以下是公司开发环境StreamPark 平台截图：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/screenshot-2906914515b810aadb10db951d4f02bd.png" width="1080" height="706" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="遇到的问题">遇到的问题<a class="hash-link" aria-label="遇到的问题的直接链接" title="遇到的问题的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s#%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98">​</a></h2>
<p>任何新技术都有探索与踩坑的过程，失败的经验是宝贵的，这里介绍下 StreamPark 在雾芯科技落地过程中踩的一些坑和经验，<strong>这块的内容不仅仅关于 StreamPark 的部分, 相信会带给所有使用 Flink on Kubernetes 的小伙伴一些参考</strong>。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="常见问题总结如下"><strong>常见问题总结如下</strong><a class="hash-link" aria-label="常见问题总结如下的直接链接" title="常见问题总结如下的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E6%80%BB%E7%BB%93%E5%A6%82%E4%B8%8B">​</a></h3>
<ul>
<li><strong>kubernetes pod 拉取镜像失败</strong></li>
</ul>
<p>这个问题主要在于 Kubernetes pod-template 缺少 docker的 imagePullSecrets</p>
<ul>
<li><strong>scala 版本不一致</strong></li>
</ul>
<p>由于 StreamPark 部署需要 Scala 环境，而且 Flink SQL 运行需要用到 StreamPark 提供的 Flink SQL Client，因此一定要保证 Flink 作业的 Scala 版本和 StreamPark 的 Scala 版本保持一致。</p>
<ul>
<li><strong>注意类冲突</strong></li>
</ul>
<p>进行 Flink SQL 作业开发的时候需要注意 Flink 镜像和 Flink connector 及 UDF 中有没有类冲突，最好的避免类冲突的办法是将 Flink 镜像和常用的 Flink connector 及用户 UDF 打成一个可用的基础镜像，之后其他 Flink SQL 作业直接复用即可。</p>
<ul>
<li><strong>没有 Hadoop 环境怎么存储 checkpoint?</strong></li>
</ul>
<p>HDFS 阿里云 OSS/AWS S3 都可以进行 checkpoint 和 savepoint 存储，Flink 基础镜像已经有了对于 OSS 和 S3 的支持，如果没有 HDFS 可以使用阿里云 OSS 或者 S3存储状态和 checkpoint 和 savepoint 数据，只需要在 Flink 动态参数中简单配置一下即可。</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dstate.backend=rocksdb</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dcontainerized.master.env.ENABLE_BUILT_IN_PLUGINS=flink-oss-fs-hadoop-1.13.6.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dcontainerized.taskmanager.env.ENABLE_BUILT_IN_PLUGINS=flink-oss-fs-hadoop-1.13.6.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dfs.oss.endpoint=xxyy.aliyuncs.com</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dfs.oss.accessKeyId=xxxxxxxxxx</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dfs.oss.accessKeySecret=xxxxxxxxxx</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dstate.checkpoints.dir=oss://realtime-xxx/streamx/dev/checkpoints/</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dstate.savepoints.dir=oss://realtime-xxx/streamx/dev/savepoints/</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li><strong>改了代码重新发布后并未生效</strong></li>
</ul>
<p>该问题与 Kubernetes pod 镜像拉取策略有关，建议将 Pod 镜像拉取策略设置为 Always：</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">‍-Dkubernetes.container.image.pull-policy=Always</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li><strong>任务每次重启都会导致多出一个 Job 实例</strong></li>
</ul>
<p>在配置了基于 kubernetes 的HA的前提条件下，当需要停止 Flink 任务时，需要通过 StreamPark 的 cancel 来进行，不要直接通过 kubernetes 集群删除 Flink 任务的 Deployment。因为 Flink 的关闭有其自有的关闭流程，在删除 pod 同时 Configmap 中的相应配置文件也会被一并删除，而直接删除 pod 会导致 Configmap 的残留。当相同名称的任务重启时，会出现两个相同 Job 现象，因为在启动时，任务会加载之前残留的配置文件，尝试将已经关闭的任务恢复。</p>
<ul>
<li><strong>kubernetes pod 域名访问怎么实现</strong></li>
</ul>
<p>域名配置只需要按照 Kubernetes 资源在 pod-template 中配置即，可针对以上问题给大家分享一个本人总结的一个 pod-template.yaml 模板：</p>
<div class="language-yaml codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-yaml codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> v1</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> Pod</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> pod</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">template</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">serviceAccount</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> default</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">containers</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> flink</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">main</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">container</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">imagePullSecrets</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> regsecret</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">hostAliases</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> </span><span class="token key atrule">ip</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">"192.168.0.1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token key atrule">hostnames</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">"node1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> </span><span class="token key atrule">ip</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">"192.168.0.2"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token key atrule">hostnames</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">"node2"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> </span><span class="token key atrule">ip</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">"192.168.0.3"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token key atrule">hostnames</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">"node3"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="最佳实践"><strong>最佳实践</strong><a class="hash-link" aria-label="最佳实践的直接链接" title="最佳实践的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s#%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5">​</a></h3>
<p>悦刻的大数据组件很多基于阿里云，比如 Maxcompute、阿里云 Redis，同时我们这边 Flink SQL 作业需要用到一些 UDF。最开始我们是采用使用 Flink Base image + maven dependency + upload udf jar 的方式，但是实践过程中遇到了一些比如版本冲突、类冲突的问题，同时如果是大批量作业的话这种方式开发效率比较低，最后我们采取将公司级别的常用的 Flink connector 和 udf 和 Flink base image 打包成公司级别的基础镜像，新 Flink SQL 作业使用该基础镜像之后直接写 Flink SQL 即可，大大提高了开发效率。</p>
<p><strong>下面分享一个制作基础镜像的简单步骤：</strong></p>
<p><strong>1. 准备需要的 JAR</strong></p>
<p>将常用 Flink Connector Jar 和用户 Udf Jar 放置在同一文件夹 lib 下，以下都是Flink 1.13.6 常用的一些 connector 包</p>
<div class="language-jar codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-jar codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">bigdata-udxf-1.0.0-shaded.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">flink-connector-jdbc_2.11-1.13.6.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">flink-sql-connector-kafka_2.11-1.13.6.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">flink-sql-connector-mysql-cdc-2.0.2.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">hudi-flink-bundle_2.11-0.10.0.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">ververica-connector-odps-1.13-vvr-4.0.7.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">ververica-connector-redis-1.13-vvr-4.0.7.jar</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>2. 准备 Dockerfile</strong></p>
<p>创建 Dockerfile 文件，并将 Dockerfile 文件跟上面文件夹放置在同一文件夹下</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">FROM flink:1.13.6-scala_2.11COPY lib $FLINK_HOME/lib/</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>3. 基础镜像制作并推送私有仓库</strong></p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">docker login --username=xxxdocker \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">build -t udf_flink_1.13.6-scala_2.11:latest \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">.docker tag udf_flink_1.13.6-scala_2.11:latest \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">k8s-harbor.xxx.com/streamx/udf_flink_1.13.6-scala_2.11:latestdocker \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">push k8s-harbor.xxx.com/streamx/udf_flink_1.13.6-scala_2.11:latest</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="未来期待"><strong>未来期待</strong><a class="hash-link" aria-label="未来期待的直接链接" title="未来期待的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-on-k8s#%E6%9C%AA%E6%9D%A5%E6%9C%9F%E5%BE%85">​</a></h2>
<ul>
<li><strong>StreamPark 对于 Flink 作业 Metric 监控的支持</strong></li>
</ul>
<p>StreamPark 如果可以对接 Flink Metric 数据而且可以在 StreamPark 平台上展示每时每刻 Flink 的实时消费数据情况就太棒了</p>
<ul>
<li><strong>StreamPark 对于Flink 作业日志持久化的支持</strong></li>
</ul>
<p>对于部署到 YARN 的 Flink 来说，如果 Flink 程序挂了，我们可以去 YARN 上看历史日志，但是对于 Kubernetes 来说，如果程序挂了，那么 Kubernetes 的 pod 就消失了，就没法查日志了。所以用户需要借助 Kubernetes 上的工具进行日志持久化，如果 StreamPark 支持 Kubernetes 日志持久化接口就更好了。</p>
<ul>
<li><strong>镜像过大的问题改进</strong></li>
</ul>
<p>StreamPark 目前对于 Flink on Kubernetes 作业的镜像支持是将基础镜像和用户代码打成一个 Fat 镜像推送到 Docker 仓库，这种方式存在的问题就是镜像过大的时候耗时比较久，希望未来基础镜像可以复用不需要每次都与业务代码打到一起，这样可以极大地提升开发效率和节约成本。</p>]]></content:encoded>
            <category>StreamPark</category>
            <category>生产实践</category>
            <category>FlinkSQL</category>
            <category>Kubernetes</category>
        </item>
        <item>
            <title><![CDATA[Flink 开发利器 Apache StreamPark™]]></title>
            <link>https://streampark.apache.org/zh-CN/blog/flink-development-framework-streampark</link>
            <guid>https://streampark.apache.org/zh-CN/blog/flink-development-framework-streampark</guid>
            <pubDate>Mon, 09 Feb 2026 02:32:43 GMT</pubDate>
            <description><![CDATA[Hadoop 体系虽然在目前应用非常广泛，但架构繁琐、运维复杂度过高、版本升级困难，且由于部门原因，数据中台需求排期较长，我们急需探索敏捷性开发的数据平台模式。在目前云原生架构的普及和湖仓一体化的大背景下，我们已经确定了将 Doris 作为离线数据仓库，将 TiDB（目前已经应用于生产）作为实时数据平台，同时因为 Doris 具有 on MySQL 的 ODBC 能力，所以又可以对外部数据库资源进行整合，统一对外输出报表]]></description>
            <content:encoded><![CDATA[<br>
<p>Hadoop 体系虽然在目前应用非常广泛，但架构繁琐、运维复杂度过高、版本升级困难，且由于部门原因，数据中台需求排期较长，我们急需探索敏捷性开发的数据平台模式。在目前云原生架构的普及和湖仓一体化的大背景下，我们已经确定了将 Doris 作为离线数据仓库，将 TiDB（目前已经应用于生产）作为实时数据平台，同时因为 Doris 具有 on MySQL 的 ODBC 能力，所以又可以对外部数据库资源进行整合，统一对外输出报表</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/doris-4baaea78343b928b0a798ae9238c489f.png" width="1200" height="738" class="img_iwx1"></p>
<p>Hadoop 体系虽然在目前应用非常广泛，但架构繁琐、运维复杂度过高、版本升级困难，且由于部门原因，数据中台需求排期较长，我们急需探索敏捷性开发的数据平台模式。在目前云原生架构的普及和湖仓一体化的大背景下，我们已经确定了将 Doris 作为离线数据仓库，将 TiDB（目前已经应用于生产）作为实时数据平台，同时因为 Doris 具有 on MySQL 的 ODBC 能力，所以又可以对外部数据库资源进行整合，统一对外输出报表</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/doris-4baaea78343b928b0a798ae9238c489f.png" width="1200" height="738" class="img_iwx1"></p>
<center style="color:gray">(这里借用一下 Doris 官方的架构图)</center>
<br>
<br>
<h1>2. 遇到的问题</h1>
<p>在数据引擎上，我们确定使用 Spark 和 Flink</p>
<ul>
<li>使用 Spark on K8s client 客户端模式做离线数据处理</li>
<li>使用 Flink on K8s Native-Application/Session 模式做实时任务流管理</li>
</ul>
<p>在这里，实际上有一些问题我们一直没有彻底解决：</p>
<p>用过 Native-Application 模式的朋友都知道，每提交一个任务，都需要打包新的镜像，提交到私有仓库，然后再调用 Flink Run 指令沟通 K8s，去拉取镜像运行 Pod。任务提交之后，还需要去 K8s 查看 log，但是：</p>
<ol>
<li>任务运行监控怎么处理？</li>
<li>使用 Cluster 模式还是 NodePort 暴露端口访问 Web UI？</li>
<li>提交任务能否简化打包镜像的流程?</li>
<li>如何减少开发压力？</li>
</ol>
<br>
<br>
<h1>3. 解决问题的过程</h1>
<p>以上的这些其实都是需要解决的问题，如果单纯地使用命令行去提交每个任务，是不现实的，任务量大了，会变得不可维护。如何解决这些问题变成一个不得不面对的问题。</p>
<br>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="简化镜像构建">简化镜像构建<a class="hash-link" aria-label="简化镜像构建的直接链接" title="简化镜像构建的直接链接" href="https://streampark.apache.org/zh-CN/blog/flink-development-framework-streampark#%E7%AE%80%E5%8C%96%E9%95%9C%E5%83%8F%E6%9E%84%E5%BB%BA">​</a></h2>
<p>首先，针对 Flink 原生镜像需要二次 build 的问题：我们利用了 MinIO 作为外部存储，并使用 s3-fuse 通过 DaemonSet 的方式直接挂载在了每个宿主节点上，我们所需要提交的 jar 包都可以放到上面统一管理。这样的话，即使扩缩容 Flink 节点，也能实现 S3 挂载自动伸缩。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/k8s-9a28cd8f0e9c996501193f591ebe22b0.png" width="1141" height="582" class="img_iwx1"></p>
<p>Flink 从 1.13 版本开始，就支持 Pod Template，我们可以在 Pod Template 中利用数据卷挂载的方式再将宿主机目录挂载到每个 pod 中，从而无需镜像打包而直接在 K8s 上运行 Flink 程序。如上图，我们将 S3 先通过 s3-fuse Pod 挂载在 Node 1、Node 2 的 <code>/mnt/data-s3fs</code> 目录下，然后再将 <code>/mnt/data-s3fs</code> 挂载到 Pod A 中。</p>
<p>但是，因为对象存储随机写入或追加文件需要重写整个对象，导致这种方式仅适合于频繁读。而这刚好满足我们现在的场景。</p>
<br>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="引入-apache-streampark">引入 Apache StreamPark™<a class="hash-link" aria-label="引入 Apache StreamPark™的直接链接" title="引入 Apache StreamPark™的直接链接" href="https://streampark.apache.org/zh-CN/blog/flink-development-framework-streampark#%E5%BC%95%E5%85%A5-apache-streampark">​</a></h2>
<p>之前我们写 Flink SQL 基本上都是使用 Java 包装 SQL，打 jar 包，提交到 S3 平台上。通过命令行方式提交代码，但这种方式始终不友好，流程繁琐，开发和运维成本太大。我们希望能够进一步简化流程，将 Flink TableEnvironment 抽象出来，有平台负责初始化、打包运行 Flink 任务，实现 Flink 应用程序的构建、测试和部署自动化。</p>
<p>这是个开源兴起的时代，我们自然而然的将目光投向开源领域中：在一众开源项目中，经过对比各个项目综合评估发现 <span style="color:red"> Zeppelin </span> 和 <span style="color:red"> StreamPark </span> 这两个项目对 Flink 的支持较为完善，都宣称支持 <span style="color:red"> Flink on K8s </span>，最终进入到我们的目标选择范围中，以下是两者在 K8s 相关支持的简单比较（目前如果有更新，麻烦批评指正）。</p>
<table><thead><tr><td>功能</td><td>Zeppelin</td><td>StreamPark</td></tr></thead><tbody><tr><td>任务状态监控</td><td><span style="color:red"> 稍低 </span>，不能作为任务状态监控工具</td><td><span style="color:red"> 较高 </span></td></tr><tr><td>任务资源管理</td><td><span style="color:red"> 无 </span></td><td><span style="color:red"> 有 </span>，但目前版本还不是很健全</td></tr><tr><td>本地化部署</td><td><span style="color:red"> 稍低 </span>，on K8s 模式只能将 Zeppelin 部署在 K8s 中，否则就需要打通 Pod 和外部网络，但是这在生产环境中很少这样做的</td><td><span style="color:red"> 可以本地化部署 </span></td></tr><tr><td>多语言支持</td><td><span style="color:red"> 较高 </span>，支持 Python/Scala/Java 多语言</td><td><span style="color:red"> 一般 </span>，目前 K8s 模式和 YARN 模式同时支持 FlinkSQL，并可以根据自身需求，使用 Java/Scala 开发 DataStream</td></tr><tr><td>Flink WebUI 代理</td><td><span style="color:red"> 目前还支持的不是很完整 </span>，主开发大佬目前是考虑整合 Ingress</td><td><span style="color:red"> 较好 </span>，目前支持 ClusterIp/NodePort/LoadBalance 模式</td></tr><tr><td>学习成本</td><td><span style="color:red"> 成本较低 </span>，需要增加额外的参数学习，这个和原生的 FlinkSQL 在参数上有点区别</td><td><span style="color:red"> 无成本 </span>，K8s 模式下 FlinkSQL 为原生支持的 SQL 格式；同时支持 Custome-Code（用户编写代码开发Datastream/FlinkSQL 任务）</td></tr><tr><td>Flink 多版本支持</td><td><span style="color:red"> 支持 </span></td><td><span style="color:red"> 支持 </span></td></tr><tr><td>Flink 原生镜像侵入</td><td><span style="color:red"> 有侵入 </span>，需要在 Flink 镜像中提前部署 jar 包，会同 JobManager 启动在同一个 Pod 中，和 zeppelin-server 通信</td><td><span style="color:red"> 无侵入 </span>，但是会产生较多镜像，需要定时清理</td></tr><tr><td>代码多版本管理</td><td><span style="color:red"> 支持 </span></td><td><span style="color:red"> 支持 </span></td></tr></tbody></table>
<center style="color:gray">（PS: 此处仅从调研用户角度出发，我们对双方开发都保持极大的尊重）</center>
<br>
<p>调研过程中，我们与两者的主开发人员都进行了多次沟通。经过我们反复研究之后，还是决定将 StreamPark 作为我们目前的 Flink 开发工具来使用。</p>
<video src="http://assets.streamxhub.com/streamx-video.mp4" controls="" width="100%" height="100%"></video>
<center style="color:gray">(StreamPark 官网的闪屏)</center>
<br>
<p>经过开发同学长时间开发测试，StreamPark 目前已经具备：</p>
<ul>
<li>完善的<span style="color:red">SQL 校验功能</span></li>
<li>实现了<span style="color:red">自动 build/push 镜像</span></li>
<li>使用自定义类加载器，通过 Child-first 加载方式 <span style="color:red">解决了 YARN 和 K8s 两种运行模式</span>、<span style="color:red">支持了自由切换 Flink 多版本</span></li>
<li>与 Flink-Kubernetes 进行深度整合，提交任务后返回 WebUI，通过 remote rest api + remote K8s，<span style="color:red">追踪任务执行状态</span></li>
<li>同时支持了 <span style="color:red">Flink 1.12、1.13、1.14 等版本</span></li>
</ul>
<p>以上基本解决了我们目前开发和运维中存在的大部分问题。</p>
<video src="http://assets.streamxhub.com/streamx-1.2.0.mp4" controls="" width="100%" height="100%"></video>
<center style="color:gray">(StreamPark 对 Flink 多版本的支持演示视频)</center>
<br>
<p>在目前最新发布的 1.2.0 版本中，StreamPark 较为完善地支持了 K8s-Native-Application 和 K8s-Session-Application 模式。</p>
<video src="http://assets.streamxhub.com/streamx-k8s.mp4" controls="" width="100%" height="100%"></video>
<center style="color:gray">(StreamPark K8s 部署演示视频)</center>
<br>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="k8s-native-application-模式">K8s Native Application 模式<a class="hash-link" aria-label="K8s Native Application 模式的直接链接" title="K8s Native Application 模式的直接链接" href="https://streampark.apache.org/zh-CN/blog/flink-development-framework-streampark#k8s-native-application-%EF%BF%BD%EF%BF%BD%E6%A8%A1%E5%BC%8F">​</a></h3>
<p>在 StreamPark 中，我们只需要配置相应的参数，并在 Maven POM 中填写相应的依赖，或者上传依赖 jar 包，点击 Apply，相应的依赖就会生成。这就意味着我们也可以将所有使用的 UDF 打成 jar 包，以及各种 connector.jar，直接在 SQL 中使用。如下图:</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/dependency-a3b9ff29795acb8a1fd4ed6bb773d53e.png" width="1080" height="461" class="img_iwx1"></p>
<p>SQL 校验能力和 Zeppelin 基本一致:</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/sqlverify-7e12cf343c9c81fcbc2e20f8d7588f1b.png" width="1080" height="619" class="img_iwx1"></p>
<p>我们也可以指定资源，指定 Flink Run 中的动态参数 Dynamic Option，甚至参数可以整合 Pod Template</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/pod-d46370aaff2c34c4fe6a584c0524b28e.png" width="1080" height="574" class="img_iwx1"></p>
<p>程序保存后，点击运行时，也可以指定 savepoint。任务提交成功后，StreamPark 会根据 FlinkPod 网络 Exposed Type（loadBalancer/NodePort/ClusterIp），返回相应的 WebURL，从而自然的实现 WebUI 跳转。但是，目前因为线上私有 K8s 集群出于安全性考虑，尚未打通 Pod 与客户端节点网络（目前也没有这个规划）。所以么，我们只使用 NodePort。如果后续任务数过多，有使用 ClusterIP 的需求的话，我们可能会将 StreamPark 部署在 K8s，或者同 Ingress 做进一步整合。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/start-71fbb288851d022c450a6bd34e8b4dc2.png" width="1080" height="522" class="img_iwx1"></p>
<p>注意：K8s master 如果使用 vip 做均衡代理的情况下，Flink 1.13 版本会返回 vip 的 ip 地址，在 1.14 版本中已经修复该问题。</p>
<p>下面是 K8s Application 模式下具体提交流程</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flow-c2227ba0cc1f59f78e2164fdb3657223.png" width="1080" height="949" class="img_iwx1"></p>
<center style="color:gray">（以上是依据个人理解绘制的任务提交流程图，如有错误，敬请谅解）</center>
<br>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="k8s-native-session-模式">K8s Native Session 模式<a class="hash-link" aria-label="K8s Native Session 模式的直接链接" title="K8s Native Session 模式的直接链接" href="https://streampark.apache.org/zh-CN/blog/flink-development-framework-streampark#k8s-native-session-%E6%A8%A1%E5%BC%8F">​</a></h3>
<p>StreamPark 还较好地支持了 <span style="color:red"> K8s Native-Sesson 模式</span>，这为我们后续做离线 FlinkSQL 开发或部分资源隔离做了较好的技术支持。</p>
<p>Native-Session 模式需要事先使用 Flink 命令创建一个运行在 K8s 中的 Flink 集群。如下：</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">./kubernetes-session.sh \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.cluster-id=flink-on-k8s-flinkSql-test \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.context=XXX \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.namespace=XXXX \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.service-account=XXXX \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.container.image=XXXX \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.container.image.pull-policy=Always \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.taskmanager.node-selector=XXXX \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.rest-service.exposed.type=Nodeport</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flinksql-13b242feb3803b15e6698635a79065b4.png" width="1080" height="664" class="img_iwx1"></p>
<p>如上图，使用该 ClusterId 作为 StreamPark 的任务参数 Kubernetes ClusterId。保存提交任务后，任务会很快处于 Running 状态：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/detail-e9ee4c14e45068bea5e1edabec596bee.png" width="1080" height="529" class="img_iwx1"></p>
<p>我们顺着 application info 的 WebUI 点击跳转：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/dashboard-78745d8d3ebe422b166a17631bfbe622.png" width="1080" height="520" class="img_iwx1"></p>
<p>可以看到，其实 StreamPark 是将 jar 包通过 REST API 上传到 Flink 集群上，并调度执行任务的。</p>
<br>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="custom-code-模式">Custom Code 模式<a class="hash-link" aria-label="Custom Code 模式的直接链接" title="Custom Code 模式的直接链接" href="https://streampark.apache.org/zh-CN/blog/flink-development-framework-streampark#custom-code-%E6%A8%A1%E5%BC%8F">​</a></h3>
<p>另我们惊喜的是，StreamPark 还支持代码编写 DataStream/FlinkSQL 任务。对于特殊需求，我们可以自己写 Java/Scala 实现。可以根据 StreamPark 推荐的脚手架方式编写任务，也可以编写一个标准普通的 Flink 任务，通过这种方式我们可以将代码管理交由 git 实现，平台可以用来自动化编译打包与部署。当然，如果能用 SQL 实现的功能，我们会尽量避免自定义 DataStream，减少不必要的运维麻烦。</p>
<br>
<br>
<h1>4. 意见和规划</h1>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="改进意见">改进意见<a class="hash-link" aria-label="改进意见的直接链接" title="改进意见的直接链接" href="https://streampark.apache.org/zh-CN/blog/flink-development-framework-streampark#%E6%94%B9%E8%BF%9B%E6%84%8F%E8%A7%81">​</a></h2>
<p>当然 StreamPark 还有很多需要改进的地方，就目前测试来看：</p>
<ul>
<li><strong>资源管理还有待加强</strong>：多文件系统jar包等资源管理功能尚未添加，任务版本功能有待加强。</li>
<li><strong>前端 button 功能还不够丰富</strong>：比如任务添加后续可以增加复制等功能按钮。</li>
<li><strong>任务提交日志也需要可视化展示</strong>：任务提交伴随着加载 class 文件，打 jar 包，build 镜像，提交镜像，提交任务等过程，每一个环节出错，都会导致任务的失败，但是失败日志往往不明确，或者因为某种原因导致异常未正常抛出，没有转换任务状态，用户会无从下手改进。</li>
</ul>
<p>众所周知，一个新事物的出现一开始总会不是那么完美。尽管有些许问题和需要改进的 point，但是瑕不掩瑜，我们仍然选择 StreamPark 作为我们的 Flink DevOps，我们也将会和主开发人员一道共同完善 StreamPark，也欢迎更多的人来使用，为 StreamPark 带来更多进步。</p>
<br>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="未来规划">未来规划<a class="hash-link" aria-label="未来规划的直接链接" title="未来规划的直接链接" href="https://streampark.apache.org/zh-CN/blog/flink-development-framework-streampark#%E6%9C%AA%E6%9D%A5%E8%A7%84%E5%88%92">​</a></h2>
<ul>
<li>我们会继续跟进 Doris，并将业务数据 + 日志数据统一入 Doris，通过 Flink 实现湖仓一体；</li>
<li>我们也会逐步将探索 StreamPark 同 DolphinScheduler 2.x 进行整合，完善DolphinScheduler 离线任务，逐步用 Flink 替换掉 Spark，实现真正的流批一体；</li>
<li>基于我们自身在 S3 上的探索积累，fat-jar 包 build 完成之后不再构建镜像，直接利用 Pod Tempelet 挂载 PVC 到 Flink Pod 中的目录，进一步优化代码提交流程；</li>
<li>将 StreamPark 持续应用到我们生产中，并汇同社区开发人员，共同努力，增强 StreamPark 在 Flink 流上的开发部署能力与运行监控能力，努力把 StreamPark 打造成一个功能完善的流数据  DevOps。</li>
</ul>
<p>附：</p>
<p>StreamPark GitHub：<a href="https://github.com/apache/streampark" target="_blank" rel="noopener noreferrer">https://github.com/apache/streampark</a> <br>
Doris GitHub：<a href="https://github.com/apache/doris" target="_blank" rel="noopener noreferrer">https://github.com/apache/doris</a></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/author-c3dabbb31d7cea1b5164a75a94ca3008.png" width="900" height="500" class="img_iwx1"></p>]]></content:encoded>
            <category>StreamPark</category>
            <category>DataStream</category>
            <category>FlinkSQL</category>
        </item>
        <item>
            <title><![CDATA[自如基于 Apache StreamPark™ + Paimon 实现数据一键入湖最佳实践]]></title>
            <link>https://streampark.apache.org/zh-CN/blog/streampark-flink-with-paimon-in-ziru</link>
            <guid>https://streampark.apache.org/zh-CN/blog/streampark-flink-with-paimon-in-ziru</guid>
            <pubDate>Mon, 09 Feb 2026 02:32:43 GMT</pubDate>
            <description><![CDATA[导读：本文主要介绍了自如 MySQL 数据迁移至 Hive 的架构升级演进，原有架构涉及到的组件众多，链路复杂，遇到很多挑战，在使用 StreamPark + Paimon 这套组合方案后有效地解决了数据集成中遇到的困境和挑战，分享了 StreamPark + Paimon 在实际应用中具体的实践方案，以及这套新秀组合方案带来的优势和收益。]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/new_cover-5991f0d6d5ee86bc8716862748caf484.png" width="1080" height="460" class="img_iwx1"></p>
<p><strong>导读</strong>：本文主要介绍了自如 MySQL 数据迁移至 Hive 的架构升级演进，原有架构涉及到的组件众多，链路复杂，遇到很多挑战，在使用 StreamPark + Paimon 这套组合方案后有效地解决了数据集成中遇到的困境和挑战，分享了 StreamPark + Paimon 在实际应用中具体的实践方案，以及这套新秀组合方案带来的优势和收益。</p>
<p>StreamPark: <a href="https://github.com/apache/streampark" target="_blank" rel="noopener noreferrer">https://github.com/apache/streampark</a></p>
<p>Paimon: <a href="https://github.com/apache/paimon" target="_blank" rel="noopener noreferrer">https://github.com/apache/paimon</a></p>
<p>欢迎关注、Star、Fork，参与贡献</p>
<p>供稿单位｜北京自如信息科技有限公司</p>
<p>文章作者｜刘涛、梁研生、魏林子</p>
<p>文章整理｜杨林伟</p>
<p>内容校对｜潘月鹏</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="1数据集成业务背景"><strong>1.数据集成业务背景</strong><a class="hash-link" aria-label="1数据集成业务背景的直接链接" title="1数据集成业务背景的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-with-paimon-in-ziru#1%E6%95%B0%E6%8D%AE%E9%9B%86%E6%88%90%E4%B8%9A%E5%8A%A1%E8%83%8C%E6%99%AF">​</a></h2>
<p>自如租房业务的数据集成场景主要来源于各业务线的 MySQL 表同步到 Hive 表的需求。这一需求包含了每天同步的 MySQL 业务表数量超过 4400 个，以及超过 8000 多个的 Hive ETL 加工任务，每天新产生数据量有 50T，而且这些数字还在不断增长。根据数据的新鲜度需求分为低新鲜度（T+1 day）和高新鲜度（T+10 minutes）两种，每天同步调度 4000 多个低新鲜度数据表，以及每天同步调度 400 多个高新鲜度数据表，用以确保数据的及时性和准确性。</p>
<p>自如的数据集成方案根据业务使用场景主要可分为两种：</p>
<ul>
<li>
<p><strong>低新鲜度</strong>：低新鲜度对数据的时效性要求是 <strong>T+1day</strong>，每日定时凌晨 00:00 采用 Hive jdbc handler 进行 MySQL 数据的全量拉取至 Hive，其基本流程如下图所示：</p>
<p><img decoding="async" loading="lazy" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAWkAAAApCAYAAAD3VNiWAAAKCUlEQVR4Xu2dWahNbRjH9+25UOfi5EqdcuHChQullJSU5MiRRBIRKYSPZCzz8GUqGTJTh5BMIdJBIZllJvM8H9MxT+93fu/ez7L2e9be56y97OF8nl+97bXfNf/3+/zXs561HLFYMmUlJSWVRUVF1TXTRltyQxf0qZkuiymKEhb1lzStTn8pLi6uKC0tfbdmzRrz5MkTo9QGXdAHndDL1VBRlGDUX+omrb/QUV5e/s5dSUkNetUSUlGUWqi/hMf1lzKc211IqRt0Qz/feFQUJRn1lwzx/IUaCCm2Eh50S9SQFEUJQP0lczx/oVitNaLMQLfEQxBFUQJQf8kcv7+485QQoJ8zLhVF+Y0bMkoI0E9FjIiIqChKIG7IKCFAPxUxIiKioiiBuCGjhAD9VMSIiIiKogTihowSAvRTESMiIiqKEogbMkoI0E9FjIiIqChKIG7IKCFAPxUxIiKioiiBuCGjhAD9VMSIiIiKogTihowSAvRTESMiIiqKEogbMlnn169f5vv37253gwT98iJitjl69Khp3Lix250VRETlfziQCghX6waEeypZp7Ky0jRp0sTttkyZMsX069fP7S5Y0C8vImabI0eOmEaNGrndWUFEVOIDiQyGTCZf/Pz508uiMs2m/Nv4k0TZrqt1ATG6pjVyO324p5J10pn0nTt3zLVr19zuggX9si7i58+fTatWrczChQtNixYtTJs2bcz+/ftNr169bLbL56dPn8z8+fPN0KFDvfUuXLhg13v79q3Zvn27adeunTXevn37mnfv4n9U6/Lly3Z7TZs2NdOmTTMdOnQwN27cUJPOE+jRrFkzc+LECVcm23/s2DG3O2NGjBhhx4zLjh07TLdu3WwgpgrUuti2bZvp1KmT2x0ZOTZo2bKlveOrL67WBcTnmvatpv0bCzZr91SyDiaNt0yYMMGOAbQ+ffq0nbd69Wozc+ZM6xejRo3y1sFL8Js3b96Yp0+fmp49e9pt4Cnnzp3zlss16Jd1ET9+/Gh31Lx5c7NlyxZrtnwfNGiQ2blzp53evHmzNW6m379/b9dDRAz45cuXtp91ER+jX7BggV2GbTLoWZegYrnz58+rSecJ9Ehl0hcvXjTV1dVud8bcunXLPHr0yO32jPDq1asFb9KM0/rial1A/BOLG/XXmvYlVtus3VPJOvgE+0Xr3bt3m/bt21vfgcmTJ9tEj8SPZfAnmD59umnbtq29C8SsMWe2M378eLsc5p0P2HfWRRSTPnDggP1eUVGRZMZdunQxM2bMMN++fbPGiniAAS9dutTcv3/fLr948WIb5Hy/fv26efjwoe1/8eKFXf727dtq0nkGPTDp/v3727sb2q5du6xOZCbcHWF+e/bs8fTr3LmzOXz4sHn8+LHp3r27l71gsukgi16/fr2dZsxw8aaxHzFpxgB3anwOHz7cM3XMkmNjX2RTbnkGk2ZbXbt2tev26NEjKZg5RxoBD1VVVaZ169Y2oNkmQc4YhaBjAzHpL1++mDFjxngZH8cGaDJgwAB7/OPGjSv0MVYVi8cBzTVrez65REz6w4cP9vvevXs9PxCTFl9iHuA3ZNlnzpyx/Xfv3rX9jA1+061bt9rvuSahaXZFFDFu3rxpv5MRI4hAAEydOtVODxkyxAY4WRLrELhAQMogIKgpaRCgBIpAvY/5eTJpbbH4OOI3IWvh9541a5Y1J+mn3DFx4kRrPIBp8ztR7ho8eLBtXGwxJUyL3zQVlDvmzZtnA5F9c/HntlTurjBp+kkAGE9cAMaOHeslAwTygwcP7PFJAiFg0qy7YcMGc+XKFWvoZGTHjx+3x8X2+DOSbIfx9uzZM7v8pEmT7IWAxGP06NEpjw3EpDdt2mQNnvKMJDBowIWMae4o2aardQNolEC2Mp1rpNwhUFaS4xCTBryGMYefMJ+LLf4UcC5m2bJl3vZySWL/2RVRTJqCPaQz6YMHD9qBjynL7cmrV69swJNxHDp0yN6S9O7d22zcuDHphyCjZj95MmklFh9ImDHmBmSTiW7PpDE9+hgXmBoZrhgnT96XL19ulixZkjRmghCTxszkQgCMHb9JSwbMvjFYxhCZrkAi4P69Y0zaXyrp06ePPSYuGlxYVq5caQ2f7VNqE5Pm+QusW7fOHkOqYwMxabJ1LlqcN439koCwrj8J8etcgLyK/Ta0gsik/b9fKpPet2+f9ZA5c+Z4v4uUXflNGTs06tlyx55rEppmV8QwJs2Tb4KV5QkEOHv2rO0juwBEJpsWA2AwEzzchvJdTTp/oIe/Js3FNdGd9OAQkxQj5PaSCzHLzZ4925a4pJHZpEJMmv+9omPHjl7/ihUrPJP2X8RPnTplM2IMlHKK8Pr1a9v8uDVpMi7KbRg844rsljIG49hv0gIZMceQ6thATBoTZ/v+86Z+z7imlio4UhcS1KQ/xWqbs+CdQ66or0lLcsA8KWfIMzDG1tevX707Gh4s5gP2nXUR62PSDHqBzIrlCVz/MvQRdP5gX7Vqle1jHoHPJybNj6ImnXvQoz4mTcaIYfrHAWa2du1aO81yzOfuKRVi0mTB7IN9UTZhO/5MmhIFF39qz9R+eXJPP+ORIMQsMVo/qUyatwW4iwNqlmwnnUmnOjYQkyaLGzhwoD1GtoMmXLgakEkX5Nsd6Uza/570sGHD7Dy54wJeZKBPGslDvkgcQ+5FTAf1SLnS+bl3756tHblwNWQecC6YdC4REZX4QMKMT548abVJZdKSOS9atCihYtyYMS656FLOSoeYtEyzDhdmymQYITVevmP2fBK08lwk8SDO7ivoHzZg0tytCZg05Q6yKdbBSMmAqT3z6Zo05Qox46BjA3kFj3ILJQ8575EjR9r5DcikC+496T8BzxMuXbpU6y4r16BfwYjIKy5kKhxPpu8lsq6adP5wtckEjLQ+r+rxTr3/PWkervnvvgRKYbwR9OPHj6R+xpu8YRQGMl4eOArpSjJCqmPzg1k/f/7c7fZwtW5AuKeihAD9CkZE/oEKtWlq0Jkyd+5cm9XkEhFRyd1AomRGZsqDn78FV+sGhHsqSgjQT0WMiIio5G4gkW3znvzfhKt1A8I9FSUE6KciRkREVBQlEDdklBCgn4oYERFRUZRA3JBRQoB+KmJERERFUQJxQ0YJAfqpiBERERVFCcQNGSUE6KciRkREVBQlEDdklBCgn4oYERFRUZRA3JBRQoB+KmJERERFUQJxQ0YJAfrFioqKqt2/AqbUD3RDP3dUKooSR/0lczx/KSkpqeSvdSnhQTf0cwemoihx1F8yx+8vZaWlpfH/NFAJBbqhnzMuFUX5jfpLhiT5S3FxcUV5ebkKGQL0Qrfk8agoiov6S3gC/YUOnJsUW2tIwaAL+qBTLQEVRUmJ+kvd1NdfyqiBJB6GyZsL2hINXRI1Ii1xKEp41F/StFT+8h9jNXxbnGYLUQAAAABJRU5ErkJggg==" width="361" height="41" class="img_iwx1"></p>
</li>
<li>
<p><strong>高新鲜度</strong>：此场景中要求数据实效性是 <strong>T+10minutes</strong>，我们复用了低新鲜度场景的快照拉取方法来实现全量数据的获取，并且初始化至 MySQL，同步利用 Canal 解析日志收集到 Kafka，然后使用 Flink 读取 kafka 中的数据并写入到 HDFS，最后用 Airflow 进行调度以合并增量数据至 Hive，其基本逻辑如下所示：</p>
<p><img decoding="async" loading="lazy" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAnIAAAApCAYAAACx+MSIAAAO00lEQVR4Xu2dSagdRRuG7zaLQBbBlRBw4cKFC0EQRBDBhREjIoqIoiCCivKrwRHn6XdGUHGMiwgqEsUJRaKCijiLs+I8xilRYzSTQ/15ylMnfd97zr2p091fdd//e6C5p6u7z/n6faurvq6uc+7U1HSWLl68ePWCBQs2bHsdfJm+oAv6bHu9dKpbuG+zLO5bPxf3rZ+L+9atpcN+1MG9HMWiRYtWLlmyZP2KFSvCmjVrgjMTdEEfdEIv1bAE7tvcuG/9xH3rJ+5bt+iiH3VwL8d4ScGyZcvW60HOeNBrhpDGuG/5uG/9xH3rJ+5bt+iCH3VwL7ejXi4lu9OdnLlBN/Sr1DNL3LcJcd/6ifvWT9y3blHYjzq4l8LQS563MlTn5INug+fV5rhvk+O+9RP3rZ+4b92ipB91cC9nMvSSyXP/b8+ZmwLdBpMtzXHfJsd96yfuWz9x37pFST/q4F7OpOqlbnMyQD+pb1ZoKE4G6KeCGqGhOBmgnwpqhIbiZIB+KqgRGooTivpRBz0NJ2z3UsudDJKIBdBQnAzQTwU1QkNxMkA/FdQIDcXJAP1UUCM0FCcU9aMOehpO8ESuEZKIBdBQnAzQTwU1QkNxMkA/FdQIDcXJAP1UUCM0FCcU9aMOehpO8ESuEZKIBdBQnAzQTwU1QkNxMkA/FdQIDcXJAP1UUCM0FCcU9aMOehpO8ESuEZKIBdBQnAzQTwU1QkNxMkA/FdQIDcXJAP1UUCM0FCcU9aMOehpO8ESuEZKIBdBQnAzQTwU1QkNxMkA/FdQIDcXJAP1UUCM0FCcU9aMOehpO8ESuEZKIBdBQnAzQTwU1QkNxMkA/FdQIDcXJAP1UUCM0FCcU9aMOehpO8ESuEZKIBdBQnAzQTwU1QkNxMkA/FdQIDcXJAP1UUCM0FCcU9aMOehpO8ESuEZKIBdBQnAzQTwU1QkPpFJs3bw5//PGHFncG9FNBjdBQzMCPLnuyI6CfCmqEhmLOL7/8Ev78808tLgq6qFA9QE+jUf7555/O+bQjoEvr4pTg+eefDzvttJMWt0ISsQAaSq+5/PLLw1FHHaXFrYF+KqgRGkornH322eGMM87Q4lm58847w8KFC8Ntt9020fEWoJ8KaoSGYsINN9wQzxlPDj/88HD11VfHpI6yjz/+WHefRpc8JF7R0woNpVHm8uKYY46J29955514bb344ou6SxGISXTqA3oajbJ69eqw8847a3HkwgsvjF52EXRpXZwSPPfcc/GisSCJ2ALLty0LtbCChtJrLrvssnDkkUdqcWugnwraEJ3w7ayzzgrLly/X4lnZd999w5VXXhlfT3K8BeingjZEJ3xT9tlnn3DdddfF1yRyV111Vfj777/Ds88+O+coXZc8RD8VtCGK+jabF1u2bInn/corr8R1T+TmpKiXsyVyn332Wfjggw+0uBOgS+vibNq0Key5557xznL33XcPe++9d3jyySfDEUccEUfN+Ltx48Zw7bXXhpNOOml43FtvvRWP+/XXX8ODDz4YOxkuhKOPPjqsX78+7vPuu+/G99tll13CxRdfHPbff//w0UcfzZdEbtO2Zeu25b9Toyu3htIKDDVzN4JXu+22W7jxxhuH26644opYtuuuu4bTTjst/PXXX0O/Gd1hG97ccccdw2Meeuih2DnxfozAffPNN7F8HiVynfCt2olzLe21117xuoNRvlFGbPj1wAMPZB9vBTGqoA3RCd+qqCcpkePxN9fQ119/HV5++eVYTvtHJ7THHnsMk4XZPLSG81BBG8LMt1H1vurFG2+8EQ499NA4akpfd8ghh8Tzpj1kxK6ayD388MPxvSg7+OCD4/Hfffdd3PeLL76I+5x++unh+OOPj6/5HPwjoWgC4lKhOoCZl6MgkaNfOuecc4bX0quvvhq30Z/RR3Gd4X2CHATPeHyOf1yLvAe5CPXBAnRpXZw09Eylvf/++2NCxjoVlE6d1/fdd19sYHj922+/xeMQjCTtp59+iuUci9BcIOkOlffkYuHYAw44IO735ptvzpdE7j9T/1bsLduWzVMzK7eG0gq33npr1PKxxx4Ld999dzxfGpO33347Vlg85I6U1yTcyW8aO3w57rjj4joJHneo7HfTTTfFC4TKfuqpp8bPmUeJXCd8S534hx9+GP275JJLYvk437gB4no699xzw7fffpt9vBXoV9GySTrhWxX1JCVy6RpjO20ir2kHeU2bSWIB4zwsATFWtGwSE9/G1fuqF/Q7vKbt4+b1hRdeiOv0b+yXErn33nsvltP2vfTSS+HAAw+MvjFHiwTi3nvvja/Zn/1oN3kv1pu6aeJ9Kxp1BRMvx1G9lh599NGw3377xXwFLrjggjiIhOfsk0Zguaa43vCLhI4+jfdhWgP7keC1DZ/Tujipoj/11FNxfeXKlXE9JWwHHXRQuPTSS8PWrVtjRU2dAg3YzTffHL788su4PyNBGzZsiOs0TNzBUP7jjz/G/T/99NO4Po8SOVg39e/7s2jl1lBagcpJUp245ZZbYkP2/vvvx8aFhoU7SPa76KKLhn4/88wzcX98Zp1h6XXr1sWRBcC3k08+OTZgMI8SOSjuG5041xYdzimnnDIsH+cb0CBxfU56vAUDTduiuG9K1ZPZEjnaRnjiiSeGbd84D0sw0LQtWvdtXL0flcil+XKMorFO3wQpkWPEh9G1BG0j+9G3nXDCCdEr3g/fWBh1xXcSiaYYaNVFWvdyHOla+v333+P6448/PryWUiKX/GYbkKcwWvfaa6/F8s8//zyWk9jh3apVq+J6mwy0alccnQzKyBonnzjssMOGHcGJJ54Yjj322PDJJ5/EY7gLBR67JnO5e6GSMzrEnU+CuQpsL5TIWS4MPa/itQXoiGfKV199FSs2cbAPS7Vhq07+ZR1faNjOO++84Z0md5+FEznLxdQ3OvH02XTmiXG+gSZyucdbMELXthdT35QdSeToMBJpFAjGeViCEbq2vTTq27h6r4lctd8Zl8jhY/XxHFOL2I9kgBtdnjrRv/F5TLBnWhJPnChrihF6dXlp1Mtx6LXElybTZ6ZEDshRSLjxnO0MUNBHjog7Dny0zeCz2hUnVfT0bH+2RO7pp5+OlZ3ELQ1prl27NiYFXBSM8tCw0eHfc88900RnhIfPKZTItcXaqe2VwvTuJIHeNCQJGhoei/JYgLvKNJ8j+ah+A+v4koalabC4s2XEtXAi1xbFfaMTZ+4Nj4T4zEceeSSWj/MNNJHLPd6CgaZtUdw3ZUcSueoEbU3kRnlYgoGmbdG6b+Pq/SSJHE+gmEuXSP6wP/0dr3n/22+/Pdx1110xCacszSdugoFWXaR1L8eh19K4RI5Rb3IPrkUew0KaGvb999/HOsFCP5meGLbJQKt2xdGOfbZEjon1abSGSgyvv/56LEsXA4IyKsfjVfZj7hajcTyrZn0eJXLMF9g4NbMyJzSUVrj++uvjpE+GjJnYyefSaOEBj0YheXT++efP8BtYxxfmNuI9Pv/www/xfdMjhnmUyHXCt+pEd+7+aaDwZpxvoIlc7vEWoF9FyybphG9K3URulIclIKaKlk1i4tu4ej9JIpeOJ1EA5lNVR0x5bMtx/GRJGvWp9plNwHtWNOoKJl6OQ6+lcYlcmgbGtvToNM3lv+aaa+KcRvIS1ukz24bPaV0c7dhHJXLVOVjMD2B/7kyq+1BGFszjVBorYEIpZWxLlZ+EAQPmQSJX9Bs8iZRw8XloyqNR4A6EdRa+VUcjxz5M3uWvJnJ8a45H5eybjksTQvmNrHn0O3Kd8I1OPP2G2M8//xz15tvH43zjuiFpSI9vJjneAj5L9GyKTvimVD3RRI4nFdr5aCI3ysMSEJPo2RQmvo2r96m9wwvtd9LPj6S2kG0kcsyf4tca2EZZmgeXwCPKGaBIc63OPPPM4fYm4LOnqdQNTLwch15LmshVf0cu+V+9MeJLLZSlhW85WzD4vHbFyYXGZ9SkToa0uTtRyI7TcDfnYtWhJJKILVD0N3UUvlxCw1SFO04aKRobYBh5rm9VsS+NXvoFbX5ehjki1qCfCtoQnfJtFJP4VqXu8XVAPxW0ITrvW59BPxW0Icx8a7rec2PLk6US/00AXVSoDmDmZVvwRQlGUrlxsgJdOiMOX9Pl2zzEM+nvr3DsPErk5kJDcTJAPxXUCA3FyQD9VFAjNBQnA/RTQY3QUJxQ1I866Gk4oWOJHD/yy1w55g9MCj/EyGRDS5KIBdBQnAzQTwU1QkNxMkA/FdQIDcXJAP1UUCM0FCcU9aMOehpO6Fgi11eSiAXQUJwM0E8FNUJDcTJAPxXUCA3FyQD9VFAjNBQnFPWjDnoaTvBErhGSiAXQUJwM0E8FNUJDcTJAPxXUCA3FyQD9VFAjNBQnFPWjDnoaTvBErhGSiAXQUJwM0E8FNUJDcTJAPxXUCA3FyQD9VFAjNBQnFPWjDnoaTvBErhGSiAXQUJwM0E8FNUJDcTJAPxXUCA3FyQD9VFAjNBQnFPWjDnoaTvBErhGSiAXQUJwM0E8FNUJDcTJAPxXUCA3FyQD9VFAjNBQnFPWjDnoaTvBErhGSiAXQUJwM0E8FNUJDcTJAPxXUCA3FyQD9VFAjNBQnFPWjDnoaTvBErhGSiAXQUJwM0E8FNUJDcTJAPxXUCA3FyQD9VFAjNBQnFPWjDnoaTvBErhGSiAXQUJwM0E8FNUJDcTJAPxXUCA3FyQD9VFAjNBQnFPWjDnoaThh4uWDBgg1r1qzRbc4OgG7op7XNAvdtcty3fuK+9RP3rVuU9KMO7uVMhl4uXrx49YoVK3S7swOgG/pphbPAfZsc962fuG/9xH3rFiX9qIN7OZOql0uXLFmyXndw5gbd0E/qmxXu24S4b/3Efesn7lu3KOxHHdxLYZqXixYtWrls2TIXKAP0Qrfp9cwW9y0f962fuG/9xH3rFl3wow7u5XZGekkB2R1Ddf4cejTogj7oNEPAQrhvc+O+9RP3rZ+4b92ii37Uwb2c28ulPG8dTIRM32zxZbCgy+B5dNeGpd23WRb3rZ+L+9bPxX3r1tJhP+rgXlb4H4X4OwILlsZhAAAAAElFTkSuQmCC" width="626" height="41" class="img_iwx1"></p>
</li>
</ul>
<p>然而，当前架构存在着多方面的挑战和压力。首先是运维成本高昂，其次是计算压力、存储压力和网络压力都非常大。另外，虽然系统运行时间从 0:00 到 1:00 期间资源利用不充分，但其他时间段却面临着资源不足的情况。对此自如决定更新数据集成架构以提高系统的效率和稳定性。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="2遇到的挑战"><strong>2.遇到的挑战</strong><a class="hash-link" aria-label="2遇到的挑战的直接链接" title="2遇到的挑战的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-with-paimon-in-ziru#2%E9%81%87%E5%88%B0%E7%9A%84%E6%8C%91%E6%88%98">​</a></h2>
<p>在上述的两种场景中，我们在数据集成过程中遇到了以下挑战：</p>
<ul>
<li>
<p><strong>网络带宽超负荷问题</strong>：由于拉取任务达到 <strong>4000+</strong>，过多的镜像全量数据拉取对数据库网络带宽产生了巨大压力。</p>
</li>
<li>
<p><strong>资源利用率低效</strong>：上游数据从 MySQL 同步到 ODS 层表后，下游的加工表才能启动，导致在 0:00 到 1:00 之间，Hadoop 集群的 CPU 和内存资源并未得到充分利用。</p>
</li>
<li>
<p><strong>维护成本高昂</strong>：当数据库表结构发生改变时，需要同步修改 Airflow 脚本。否则，会出现不完整的字段，引起线上数据异常问题。</p>
</li>
<li>
<p><strong>问题排查困难</strong>：数据链路较长，当出现数据异常时，问题排查成本较高，问题可能出现在 Canal、Kafka、Flink、Airflow 调度中的任何一个环节，导致问题恢复时间长。</p>
</li>
<li>
<p><strong>Flink 作业难以统一管理</strong>：Flink 本身没有提供很好的部署和开发能力，在 Flink 任务数量增多后，管理和维护的时间成本也随之上升。</p>
</li>
</ul>
<p>为了解决上述问题，我们经过一系列调研后，决定采用 “<strong>StreamPark+Paimon</strong>” 的策略，那么选择它们的原因是什么呢？我们可以先看看它们的特性。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="paimon-的核心特性"><strong>Paimon 的核心特性</strong><a class="hash-link" aria-label="paimon-的核心特性的直接链接" title="paimon-的核心特性的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-with-paimon-in-ziru#paimon-%E7%9A%84%E6%A0%B8%E5%BF%83%E7%89%B9%E6%80%A7">​</a></h3>
<p><strong>在经过对 Apache Hudi / Iceberg / Paimon 几个数据湖框架的调研和综合评估之后，我们决定使用 Apache Paimon</strong>，Apache Paimon 是一项流式数据湖存储技术，可以为用户提供高吞吐低延时的数据摄入，流式订阅和实时查询能力，支持使用 Flink 和 Spark 构建实时 Lakehouse 架构，支持批/流数据处理操作，创新性地将 Lake 格式与 LSM 结构相结合，将实时流式更新引入 Lake 架构中，具有以下优点：</p>
<ul>
<li>
<p><strong>统一的批处理和流处理</strong>：Paimon 支持批量写入、批量读取和流式操作，提供了灵活的数据处理方式。</p>
</li>
<li>
<p><strong>数据湖功能</strong>：作为数据湖存储系统，Paimon 具有低成本、高可靠性和可扩展的元数据等特性。</p>
</li>
<li>
<p><strong>丰富的合并引擎</strong>：Paimon 提供了多种合并引擎，可以根据需求选择保留最新数据、进行局部更新或进行聚合操作。</p>
</li>
<li>
<p><strong>自动生成变更日志</strong>：Paimon 支持多种 Changelog 生产者，能够自动生成正确完整的变更日志，简化流式任务分析。</p>
</li>
<li>
<p><strong>丰富的表类型</strong>：Paimon 支持主键表和仅追加表，以及多种表类型，如内部表、外部表、分区表和临时表。</p>
</li>
<li>
<p><strong>支持表结构变更同步</strong>：当数据源表结构发生变化时，Paimon 能自动识别并同步这些变化。</p>
</li>
</ul>
<p>Paimon 可以结合 Apache Spark™ 来使用，我们场景是 Paimon 结合 Flink 的方式，这样一来 “<strong>如何管理 4000+个 Flink 数据同步作业</strong>” 将会是我们面临的新问题。在全面调研了相关项目，经过各项维度综合评估后，<strong>我们决定采用 StreamPark</strong>，那么为什么选择 StremaPark 呢？</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="streampark-的核心特性"><strong>StreamPark 的核心特性</strong><a class="hash-link" aria-label="streampark-的核心特性的直接链接" title="streampark-的核心特性的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-with-paimon-in-ziru#streampark-%E7%9A%84%E6%A0%B8%E5%BF%83%E7%89%B9%E6%80%A7">​</a></h3>
<p>Apache StreamPark 是一个流处理开发管理框架，提供了一套快捷的API 用来开发 Flink/Spark 作业，此外还提供了一个一站式的流处理作业开发管理平台，从流处理作业开发到上线全生命周期都做了支持，StreamPark 主要包含下面这些核心特点：</p>
<ul>
<li>
<p><strong>流处理应用开发框架</strong>：基于 StreamPark，开发者可以轻松构建和管理流处理应用程序，更好地利用  Apache Flink® 去编写流处理应用程序。</p>
</li>
<li>
<p><strong>完善的作为管理能力</strong>：StreamPark 提供一站式流任务开发管理平台，支持了 Flink / Spark 从应用开发到调试、部署、运维等全生命周期的能力支持，让 Flink / Spark 作业变得简单。</p>
</li>
<li>
<p><strong>完成度高</strong>：StreamPark 支持了 Flink 多版本，可以做到一个平台灵活切换，同时支持 Flink 所的部署模式，有效解决了 Flink on YARN / K8s 部署过于繁琐的问题，通过自动化流程，简化了任务的构建、测试和部署流程，并提高了开发效率。</p>
</li>
<li>
<p><strong>丰富的管理 API</strong>：StreamPark 提供了作业操作的 API，包括作业创建、拷贝、构建、部署、基于 checkpoint/savepoint 的停止和启动等功能，使外部系统调用 Apache Flink® 任务变得易于实现。</p>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="3-streampark--paimon-实践"><strong>3. StreamPark + Paimon 实践</strong><a class="hash-link" aria-label="3-streampark--paimon-实践的直接链接" title="3-streampark--paimon-实践的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-with-paimon-in-ziru#3-streampark--paimon-%E5%AE%9E%E8%B7%B5">​</a></h2>
<p>接下来，我们将继续分享自如是如何基于 <strong>StreamPark + Paimon</strong> 进行架构优化改造的，我们先看架构升级前后的对比。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="31-架构升级前"><strong>3.1 架构升级前</strong><a class="hash-link" aria-label="31-架构升级前的直接链接" title="31-架构升级前的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-with-paimon-in-ziru#31-%E6%9E%B6%E6%9E%84%E5%8D%87%E7%BA%A7%E5%89%8D">​</a></h3>
<p>数据集成模块在改造之前的系统交互流程如下：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/system_interaction_process-0fa72272598ce1fbf180e4f859cf59dc.png" width="1080" height="291" class="img_iwx1"></p>
<p><strong>Step1</strong>（用户发起接入申请）：首先用户在数据接入平台选择一个表，然后点击申请接入按钮：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/data_access_platform-a2d62b477382c15128b76c60e9c6be53.png" width="1080" height="245" class="img_iwx1"></p>
<p><strong>Step2</strong>（发起OA系统审批流程）：OA 系统接收到接入申请，会发起工作流审批，如审批失败会驳回申请，审批通过才会继续下一步。</p>
<p><strong>Step3</strong>（数据接入平台处理审批通过事件）：数据接入平台调用 Canal 接口部署 Canal 任务，将表中的 Binlog 数据传入 Kafka ：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/canal_job-fbfcee343ac2473e1b22d199da463ad4.png" width="1041" height="760" class="img_iwx1"></p>
<p><strong>Step4</strong>（Flink 任务部署）：人工使用 Flink Session Submit UI 部署 Flink 模板作业，负责解析 Kafka 中的 Binlog 变化数据，并将数据写入 HDFS，同时映射成 Hive 外部增量表：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_job-2769695ec6b0a9446b8d5f4828976b7d.png" width="946" height="331" class="img_iwx1"></p>
<p><strong>Step5</strong>（Airflow调度初始化表）：创建 Hive 映射增量表和全量表并用 Airflow 调度完成首次初始化:</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/first_initialization-f270b827e85b0ff840bf3db25686349c.png" width="1080" height="884" class="img_iwx1"></p>
<p><strong>Step6</strong>（数据合并到 Hive 全量表）：配置调度通过 Hive Merge 方式将 Hive 外部增量表的数据合并到 Hive 全量表中</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/data_merging-b8ac385c5de9f96c13163aa65e382496.png" width="1075" height="972" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="32-架构升级后"><strong>3.2 架构升级后</strong><a class="hash-link" aria-label="32-架构升级后的直接链接" title="32-架构升级后的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-with-paimon-in-ziru#32-%E6%9E%B6%E6%9E%84%E5%8D%87%E7%BA%A7%E5%90%8E">​</a></h3>
<p>改造后的系统交互流程图如下：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/after_the_transformation-8b3717c58b603d12e8e87c8267068672.png" width="1080" height="291" class="img_iwx1"></p>
<p>对比改造前和改造后的交互流程图，可以看出前两个步骤的流程（表接入申请与审批）是一样的，只是审批通过之后的事件<strong>监听处理方式</strong>的差异。</p>
<ul>
<li>
<p><strong>改造前</strong>：调用 Canal 接口去部署Canal 任务（旧的逻辑）；</p>
</li>
<li>
<p><strong>改造后</strong>：调用 StreamPark 的 API 接口完成 Flink Paimon 的任务部署。</p>
</li>
</ul>
<p>接下来看看使用 Paimon 来完成数据的集成的。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="33-paimon-实现一键入-hive"><strong>3.3 Paimon 实现一键入 Hive</strong><a class="hash-link" aria-label="33-paimon-实现一键入-hive的直接链接" title="33-paimon-实现一键入-hive的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-with-paimon-in-ziru#33-paimon-%E5%AE%9E%E7%8E%B0%E4%B8%80%E9%94%AE%E5%85%A5-hive">​</a></h3>
<p>在 Apache Paimon 0.5 版本后，提供了 CDC 数据集成能力，通过官方提供的 paimon-action jar 可以很方便的将 MySQL、Kafka、Mongo 等中的数据实时摄入到 Paimon 中，我们正在使用的是 paimon-flink-action ，采用了 <strong>mysql-sync-database（整库同步）</strong>，并通过“<strong>—including_tables</strong>” 参数选择要同步的表。这种同步模式有效地节省了大量资源开销，相比每个表启动一个 Flink 任务而言，避免了资源的大量浪费。</p>
<p>paimon-flink-action 提供了自动创建 Paimon 表的功能，并支持 Schema Evolution（例如，当 MySQL 表字段发生变化时，Paimon 表会相应变化，无需额外操作）。整个操作流程高效而顺畅，解决了原始架构因添加字段而产生的不必要运维成本，paimon-action 具体使用如下，更多请参考Paimon 官网文档。</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">&lt;FLINK_HOME&gt;/bin/flink run \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    /path/to/paimon-flink-action-0.8-SNAPSHOT.jar \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    mysql_sync_table</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    --warehouse &lt;warehouse-path&gt; \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    --database &lt;database-name&gt; \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    --table &lt;table-name&gt; \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    [--partition_keys &lt;partition_keys&gt;] \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    [--primary_keys &lt;primary-keys&gt;] \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    [--type_mapping &lt;option1,option2...&gt;] \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    [--computed_column &lt;'column-name=expr-name(args[, ...])'&gt; [--computed_column ...]] \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    [--metadata_column &lt;metadata-column&gt;] \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    [--mysql_conf &lt;mysql-cdc-source-conf&gt; [--mysql_conf &lt;mysql-cdc-source-conf&gt; ...]] \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    [--catalog_conf &lt;paimon-catalog-conf&gt; [--catalog_conf &lt;paimon-catalog-conf&gt; ...]] \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    [--table_conf &lt;paimon-table-sink-conf&gt; [--table_conf &lt;paimon-table-sink-conf&gt; ...]]</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>引入 Paimon 后缩短了整个数据接入链路，消除了对 Canal、Kafka、Airflow 的依赖，使得 MySQL 直接以分钟级速度与 Hive 对接，整体环境清爽高效。此外，Paimon 完全兼容 Hive 端数据读取，转换成本极低，对原始架构脚本的使用也具备良好的兼容性，Paimon 还支持 Tag 功能，可以视为轻量级的快照，大幅降低了存储成本。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="34-streampark--paimon-落地实践"><strong>3.4 StreamPark + Paimon 落地实践</strong><a class="hash-link" aria-label="34-streampark--paimon-落地实践的直接链接" title="34-streampark--paimon-落地实践的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-with-paimon-in-ziru#34-streampark--paimon-%E8%90%BD%E5%9C%B0%E5%AE%9E%E8%B7%B5">​</a></h3>
<p>StreamPark 在 2.1.2 版本中更好的支持了 JAR 类型的作业，使得 Paimon 类型的数据集成作业更简单了，下面的示例，演示了如何使用 StreamPark 快速开发 Paimon 数据迁移类型的作业：</p>
<p>//视频链接 (StreamPark 部署 Paimon 数据集成作业示例 )</p>
<p>诚然 StreamPark 在 2.1.2 版本之后已经特别针对 Paimon 数据集成类作业做了支持，但是这种手动创建作业，输入作业参数的方式还是不满足我们的实际需求，我们需要更灵活的作业创建，可以通过调用 API 的方式快速完成作业创建、启动... 经过我们的调研发现 StreamPark 已经完整的开放了作业的各项操作 API，如作业的复制、创建、部署、启动、停止等，这样一来，我们通过定时调度就可以非常方便和 StreamPark 组合，来快速完成作业的开发和运行，具体方式如下：</p>
<p><strong>Step1</strong>：首先，会调用api copy 模版接口，并传入参数，相关截图如下：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/api_copy-ceff34954a24abe2b3e04bc6d10d4f26.png" width="737" height="484" class="img_iwx1"></p>
<p>这样该作业就快速创建完成，参数会通过 copy 接口传入，具体参数如下：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/parameter-d7feafe0cd25f249bec4b2115d64ec00.png" width="780" height="959" class="img_iwx1"></p>
<p><strong>Step2</strong>：接着，调用api构建作业镜像：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/job_mirroring-8cbc7decc438aa15ca8166ba9a0bd7c1.png" width="870" height="522" class="img_iwx1"></p>
<p><strong>Step3</strong>：继续调用api启动作业：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/start_the_job-036fdf864d022cf8de2282af72d4b3ca.png" width="855" height="641" class="img_iwx1"></p>
<p>最后，任务启动成功后，可以在 StreamPark 平台看到任务的相关状态信息以及整体任务的资源概况：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/resource_overview-b7f0b5ccafd202f82c515c64e48cd377.png" width="1080" height="618" class="img_iwx1"></p>
<p>并可以点击Application Name 调度Flink Web UI：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_ui-1a5557a19b30e92802eab1b75cc4a574.png" width="1080" height="702" class="img_iwx1"></p>
<p>最后可以直接在 Hive 端查询 Paimon 表，获取所需的数据，其中 Paimon 表是经过 Flink 处理的、延时较低的数据同步目标表。Hue 中 Hive 查询 Paimon 表截图如下</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/hive_query_paimon-9203a5f6debb35ce41f9f51be06e1446.png" width="2000" height="1346" class="img_iwx1"></p>
<p>通过以上步骤，业务方可以方便地发起接入申请，经过审批流程后，通过 StreamPark 创建部署 Flink 作业，数据通过 Flink 作业入  Paimon 表，使用户能够轻松地在 Hive 端进行查询操作，整个流程简化了用户操作，提高了数据接入的效率和可维护性。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="4-带来的收益"><strong>4. 带来的收益</strong><a class="hash-link" aria-label="4-带来的收益的直接链接" title="4-带来的收益的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-with-paimon-in-ziru#4-%E5%B8%A6%E6%9D%A5%E7%9A%84%E6%94%B6%E7%9B%8A">​</a></h2>
<p>自如通过使用 Paimon 和 StreamPark ，带来了如下优势和效益：</p>
<ul>
<li>
<p><strong>网络资源和数据库压力优化</strong>：通过直接从 Paimon 表获取数据快照，解决了凌晨从业务数据库拉取数据导致的网络资源紧张和数据库压力过大问题，同时降低了数据存储成本。</p>
</li>
<li>
<p><strong>作业管理接口提升效率</strong>：使用 StreamPark 的作业管理接口轻松解决了手动部署 Flink 任务的问题，消除了人员依赖时间导致任务不及时部署的情况，提高了效率，同时减少了沟通成本，提升了 Flink 作业的管理效率。</p>
</li>
<li>
<p><strong>降低开发、维护成本</strong>：解决了之前方案链路长导致的维护成本高和问题定位慢的问题，同时解决了字段变化导致的字段不一致问题，实现了数据接入的流批统一，降低了开发和维护的成本。</p>
</li>
<li>
<p><strong>降低了数据集成调度资源和计算资源的使用成本</strong>：不再依赖外部调度系统进行增量数据的合并，减少了调度资源的使用。也不再依赖 Hive 资源进行合并操作，降低了合并增量数据对 Hive 计算资源的花销成本。</p>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="5-结语与期望"><strong>5. 结语与期望</strong><a class="hash-link" aria-label="5-结语与期望的直接链接" title="5-结语与期望的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-flink-with-paimon-in-ziru#5-%E7%BB%93%E8%AF%AD%E4%B8%8E%E6%9C%9F%E6%9C%9B">​</a></h2>
<p>我们衷心地感谢 <strong>Apache StreamPark</strong> 社区在我们使用 StreamPark API 时提供的无私帮助。他们专业的服务精神和以用户为本的态度，使我们得以更加高效、流畅地运用这一强大框架。作为一套卓越的框架，StreamPark 不但拥有出色的功能，而且能支持一系列如任务复制、创建、部署、启动、停止以及状态监控的操作，并在简化 Flink 任务的管理与维护方面显著地发挥了其价值。</p>
<p>同时，对 <strong>Apache Paimon</strong> 社区在自如 MySQL 入 Paimon 测试阶段给予我们的耐心与专业指导表示感谢，这是我们能够顺利完成测试的重要支持。Paimon 作为一项富有潜力的项目，无论是在功能实现还是团队协作方面，都展现了非凡的素质。</p>
<p>最后，我们对 Apache StreamPark 和 Apache Paimon 的未来之路满怀期待和信心，坚信它们能在未来会成为 Apache 的优秀项目。它们卓越的功能和和睦的社区合作模式，都为其在开源社区的成熟之路打下了坚实的基础。我们期待 StreamPark 和 Paimon 社区能一如既往地保持专业态度和良好的团队协作精神，不断推进项目发展，成为近年来新晋 Apache 项目的典范，以便对更广大的开发者社区产生更大的影响。</p>]]></content:encoded>
            <category>StreamPark</category>
            <category>生产实践</category>
        </item>
        <item>
            <title><![CDATA[Apache StreamPark™ 助力天眼查实时平台建设｜效率数倍提升]]></title>
            <link>https://streampark.apache.org/zh-CN/blog/streampark-usercase-tianyancha</link>
            <guid>https://streampark.apache.org/zh-CN/blog/streampark-usercase-tianyancha</guid>
            <pubDate>Mon, 09 Feb 2026 02:32:43 GMT</pubDate>
            <description><![CDATA[导读：本文主要介绍天眼查在实时计算业务近千个 Flink 作业运维时面临作业开发和管理上的挑战，通过引入 Apache StreamPark 来解决这些挑战，介绍了在引入 StreamPark 落地过程中遇到的一些问题以及如何解决这些问题并成功落地，最后极大地降低运维成本，显著地提升人效。]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/new_cover-4883e1aa52dc856ae160abd142daf867.png" width="1080" height="460" class="img_iwx1"></p>
<p><strong>导读</strong>：本文主要介绍天眼查在实时计算业务近千个 Flink 作业运维时面临作业开发和管理上的挑战，通过引入 Apache StreamPark 来解决这些挑战，介绍了在引入 StreamPark 落地过程中遇到的一些问题以及如何解决这些问题并成功落地，最后极大地降低运维成本，显著地提升人效。</p>
<p>Github: <a href="https://github.com/apache/streampark" target="_blank" rel="noopener noreferrer">https://github.com/apache/streampark</a></p>
<p>欢迎关注、Star、Fork，参与贡献</p>
<p>供稿单位 | 北京天眼查</p>
<p>文章作者 | 李治霖</p>
<p>文章整理 | 杨林伟</p>
<p>内容校对 | 潘月鹏</p>
<p>天眼查是中国领先的商业查询平台。自 2014 年创立以来，天眼查持续保持高速增长，行业渗透率超过 77%，月活跃用户数高达 3500 万，累计用户数 6 亿+，“天眼一下”已成为商业领域的超级符号，是首批获得央行备案企业征信资质的公司之一。经过公司多年深耕，平台共收录全国 3.4 亿、全球 6.4 亿社会实体，1000 多种商查信息维度实时更新，成为企业客户和个人用户商业查询的首选品牌。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/enterprise-c8641726b9205b14e3e330d10e73bb68.png" width="1080" height="748" class="img_iwx1"></p>
<p>本文将介绍天眼查实时计算业务面临的挑战，如何通过 Apache StreamPark 平台来解决这些挑战，以及带来的显著效益和未来规划。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="业务背景与挑战"><strong>业务背景与挑战</strong><a class="hash-link" aria-label="业务背景与挑战的直接链接" title="业务背景与挑战的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-tianyancha#%E4%B8%9A%E5%8A%A1%E8%83%8C%E6%99%AF%E4%B8%8E%E6%8C%91%E6%88%98">​</a></h2>
<p>天眼查有着庞大的用户基础和多样的业务维度，我们通过 Apache Flink® 这一强大的实时计算引擎，为用户提供更优质的产品和服务体验，我们的实时计算业务主要涵盖以下几个场景：</p>
<ul>
<li>
<p>实时数据 ETL 处理和数据传输。</p>
</li>
<li>
<p>C 端维度数据统计，包括用户行为、PV/UV 分析。</p>
</li>
<li>
<p>C 端业务数据与工商信息、风险信息、产权、股权、股东、案件等信息的实时关联分析。</p>
</li>
</ul>
<p>随着天眼查业务的快速发展，实时作业目前已增至 800 +，未来很快会上千，面对这么大体量的作业、在开发和管理上都遇到了挑战，大致如下：</p>
<ul>
<li>
<p><strong>作业运维困难</strong>：作业覆盖多个 Flink 版本，多版本 Flink 作业的运行和升级因 API 变动而成本高昂，且作业提交和参数调优依赖于复杂脚本，极大增加了维护难度和成本。</p>
</li>
<li>
<p><strong>作业开发低效</strong>：从本地 IDE 调试到测试环境部署，需经过编译、文件传输和命令执行等繁琐步骤，耗时且影响效率。</p>
</li>
<li>
<p><strong>缺乏自动重试机制</strong>：实时业务的多表关联操作易受网络和 IO 波动影响，导致 Flink 程序故障，需手动或额外程序介入恢复，增加了开发和维护成本。</p>
</li>
<li>
<p><strong>维护成本高昂</strong>：缺少集中化的日志、版本控制和配置管理工具，随着任务量上升，维护大量 JAR 包、提交脚本和 Flink 客户端配置变得日益复杂。</p>
</li>
</ul>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/challenges-2c1babbcd18fc83fb47c4447fa413a95.png" width="1069" height="982" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="streampark-落地实践"><strong>StreamPark 落地实践</strong><a class="hash-link" aria-label="streampark-落地实践的直接链接" title="streampark-落地实践的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-tianyancha#streampark-%E8%90%BD%E5%9C%B0%E5%AE%9E%E8%B7%B5">​</a></h2>
<p>为了解决上述问题，我司决定引入 StreamPark。我们在 StreamPark 项目刚开源的时候就开始关注，当时项目名还是 StreamX，此后也在一直密切关注着项目的发展，见证了其从开源到加入 Apache 软件基金会孵化的过程，其社区活跃度、用户口碑、发版次数等各项表现都很不错，有大量企业的真实使用案例，这增强了我们对 StreamPark 信心，因此引入 StreamPark 是自然而然的事情，我们尤其关注以下可以解决我们痛点的能力：</p>
<ul>
<li>
<p><strong>Git 式项目管理</strong>：为作业提供了便捷的版本控制和部署流程。</p>
</li>
<li>
<p><strong>强大的作业运维能力</strong>：显著提升了作业的管理和维护效率。</p>
</li>
<li>
<p><strong>精确的秒级告警系统</strong>：提供了实时监控和快速响应能力。</p>
</li>
<li>
<p><strong>一站式任务开发平台</strong>：为开发、测试和部署提供有力保障</p>
</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="1-git-式项目管理"><strong>1. Git 式项目管理</strong><a class="hash-link" aria-label="1-git-式项目管理的直接链接" title="1-git-式项目管理的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-tianyancha#1-git-%E5%BC%8F%E9%A1%B9%E7%9B%AE%E7%AE%A1%E7%90%86">​</a></h3>
<p>天眼查 90% 以上都是 JAR 作业，管理几百个JAR 作业是很头疼的问题，为了方便维护和管理先前我们通过 “开发人员名称-项目名称-模块-环境” 进行命名 JAR 文件名，这样带来了另一个问题，没办法直观区分要维护的作业在那个模块，如果非 owner 维护此作业得通过项目文档和代码来查看逻辑，需要找到项目代码与对应分支、作业的启动脚本等，这样大幅度增加开发人员工作量。</p>
<p>在 StreamPark 中我们惊喜地发现有项目管理功能，类似于 Git 集成，可以很好的解决了我们的痛点，我们通过简化的命名规范，实现了项目、人员、分支和环境的隔离。现在，我们能够瞬间定位到任意作业的代码和文档，极大提高了作业的可维护性和开发效率，显著提升了我们的运维效率。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/git-90b5c4fc3c5c732e3e2757fc83ecb1d4.png" width="1080" height="525" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="2-秒级精确告警和自动运维"><strong>2. 秒级精确告警和自动运维</strong><a class="hash-link" aria-label="2-秒级精确告警和自动运维的直接链接" title="2-秒级精确告警和自动运维的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-tianyancha#2-%E7%A7%92%E7%BA%A7%E7%B2%BE%E7%A1%AE%E5%91%8A%E8%AD%A6%E5%92%8C%E8%87%AA%E5%8A%A8%E8%BF%90%E7%BB%B4">​</a></h3>
<p>下面是我们一个 Flink 线上的任务，在查询过程中访问第三方端时，发生 Connection Time out 等错误（备注：本身 Flink 设置重启策略间隔重启三次，但最终还是失败）</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/alarm-609ca86190f86b8ad9a8c4d212705add.png" width="1080" height="904" class="img_iwx1"></p>
<p>如上图，当收到任务告警时，我们开发同学在群里回复 1 的时候，我们发现<strong>作业已经成功被 StreamPark 拉起，只用不到 15 秒就完成了作业的重新提交和运行</strong>！</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="3-平台用户权限管控"><strong>3. 平台用户权限管控</strong><a class="hash-link" aria-label="3-平台用户权限管控的直接链接" title="3-平台用户权限管控的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-tianyancha#3-%E5%B9%B3%E5%8F%B0%E7%94%A8%E6%88%B7%E6%9D%83%E9%99%90%E7%AE%A1%E6%8E%A7">​</a></h3>
<p>StreamPark 提供了一套完善的权限管理机制，使得我们可以在 StreamPark 平台上对作业和用户进行精细的权限管理，有效避免了因用户权限过大而可能发生的误操作，减少了对作业运行稳定性和环境配置准确性的影响，对于企业级用户来说，这样的管理机制是非常必要的。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/permissions-5879a5913ed1c6f93481b0951b139fc3.png" width="1080" height="525" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="4-flink-sql-在线开发"><strong>4. Flink SQL 在线开发</strong><a class="hash-link" aria-label="4-flink-sql-在线开发的直接链接" title="4-flink-sql-在线开发的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-tianyancha#4-flink-sql-%E5%9C%A8%E7%BA%BF%E5%BC%80%E5%8F%91">​</a></h3>
<p>对于许多开发场景中需要提交 Flink SQL 作业的情况，现在我们可以完全摆脱在 IDEA 中编写代码的繁琐步骤。只需使用 StreamPark 平台，<strong>就能轻松实现  Flink SQL 作业的开发</strong>，以下是一个简单的案例。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/sql_job-8e9bfa3d04866e5bf5e05103048f0e09.png" width="1080" height="651" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="5-完善的作业管理能力"><strong>5. 完善的作业管理能力</strong><a class="hash-link" aria-label="5-完善的作业管理能力的直接链接" title="5-完善的作业管理能力的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-tianyancha#5-%E5%AE%8C%E5%96%84%E7%9A%84%E4%BD%9C%E4%B8%9A%E7%AE%A1%E7%90%86%E8%83%BD%E5%8A%9B">​</a></h3>
<p>StreamPark 还有更加完善的作业操作记录，对于一些提交时异常的作业，现可完全通过平台化查看失败日志，包括历史日志信息等。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/historical_logs-815b75ba2fe1a1d1d90c284999e35f3d.png" width="1080" height="525" class="img_iwx1"></p>
<p>当然，StreamPark 还为我们提供了更加完善且友好的任务管理界面，可以直观地看到任务的运行情况。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/task_management-d7b65ce685ba87d759bcae290b0cbbe1.png" width="1080" height="525" class="img_iwx1"></p>
<p>我们企业内部实时项目是高度抽象化代码开发的作业，每次开发新作业只需要修改一些外部传入的参数即可，通过 StreamPark 复制作业功能让我们告别了很多重复性工作，只需要在平台上复制已有作业，略微修改程序运行参数就可以提交一个新的作业！</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/successful-5bef1e14d16c3e90b504d99e28e70d2e.png" width="552" height="520" class="img_iwx1"></p>
<p>当然还有更多，这里就不一一列举了，StreamPark 在使用上足够的简单易用，分钟内即可上手使用，功能上足够的专注可靠，引入 StreamPark 以来解决了我们管理 Flink 作业面临的难题，带来了实实在在的方便，显著地提高了人效，给主创团队一个大大的赞！</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="遇到的问题"><strong>遇到的问题</strong><a class="hash-link" aria-label="遇到的问题的直接链接" title="遇到的问题的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-tianyancha#%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98">​</a></h2>
<p>在 StreamPark 落地实践中，我们也遇到了一些问题，这里记录下来，期望给社区的用户带来一些输入和参考。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="华为云与开源-hadoop-存在兼容问题"><strong>华为云与开源 Hadoop 存在兼容问题</strong><a class="hash-link" aria-label="华为云与开源-hadoop-存在兼容问题的直接链接" title="华为云与开源-hadoop-存在兼容问题的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-tianyancha#%E5%8D%8E%E4%B8%BA%E4%BA%91%E4%B8%8E%E5%BC%80%E6%BA%90-hadoop-%E5%AD%98%E5%9C%A8%E5%85%BC%E5%AE%B9%E9%97%AE%E9%A2%98">​</a></h3>
<p>我们的作业都是 Flink on Yarn 模式，部署在华为云。在使用 StreamPark 部署作业的过程中发现作业可以成功部署到华为 Hadoop 集群，但是获取作业状态信息时请求 Yarn ResourceManager 被拒绝，我们及时和社区沟通，寻求解决方案，并且记录了 issue:
<a href="https://github.com/apache/streampark/issues/3566" target="_blank" rel="noopener noreferrer">https://github.com/apache/streampark/issues/3566</a></p>
<p>最后在社区 PMC 成员华杰老师和华为云同学的协助下，成功解决了问题：由于云产品本身内部的安全认证机制导致 StreamPark 无法正常访问云 ResourceManager。</p>
<p>解决方案 (仅供参考 - 根据不同环境添加不同依赖)</p>
<p>将 STREAMPARK_HOME/lib 目录中 HADOOP 相关两个包删除：</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">hadoop-client-api-3.3.4.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">hadoop-client-runtime-3.3.4.jar</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>替换以下华为云 HADOOP 依赖:</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">commons-configuration2-2.1.1.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">commons-lang-2.6.0.wso2v1.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">hadoop-auth-3.1.1-hw-ei-xxx.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">hadoop-common-3.1.1-hw-ei-xxx.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">hadoop-hdfs-client-3.1.1-hw-ei-xxx.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">hadoop-plugins-8.1.2-xxx.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">hadoop-yarn-api-3.1.1-hw-ei-xxx.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">hadoop-yarn-client-3.1.1-hw-ei-xxx.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">hadoop-yarn-common-3.1.1-hw-ei-xxx.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">httpcore5-h2-5.1.5.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">jaeger-core-1.6.0.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">mysql-connector-java-8.0.28.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">opentracing-api-0.33.0.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">opentracing-noop-0.33.0.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">opentracing-util-0.33.0.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">protobuf-java-2.5.0.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">re2j-1.7.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">stax2-api-4.2.1.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">woodstox-core-5.0.3.jar</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="其他-bug"><strong>其他 BUG</strong><a class="hash-link" aria-label="其他-bug的直接链接" title="其他-bug的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-tianyancha#%E5%85%B6%E4%BB%96-bug">​</a></h3>
<p>在深入使用的过程中，我们也发现了一些问题。为了更好地改善与优化 StreamPark 的功能，我们提出了一些具体的建议和解决方案，例如：</p>
<ul>
<li>
<p><strong>依赖冲突</strong>：加载 Flink 依赖时出现冲突的解决（详见：Pull Request #3568）。</p>
</li>
<li>
<p><strong>服务稳定性</strong>：拦截用户程序 JVM 退出，防止 StreamPark 平台因用户程序异常退出（详见：Pull Request #3659）。</p>
</li>
<li>
<p><strong>资源优化</strong>：为减轻资源负担，限制 StremaPark 构建项目的并发数，通过配置参数来控制项目最大构建数量（详见：Pull Request #3696）。</p>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="带来的收益"><strong>带来的收益</strong><a class="hash-link" aria-label="带来的收益的直接链接" title="带来的收益的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-tianyancha#%E5%B8%A6%E6%9D%A5%E7%9A%84%E6%94%B6%E7%9B%8A">​</a></h2>
<p>Apache StreamPark 为我们带来了显著的收益，<strong>主要体现在其一站式服务能力，使得业务开发人员能够在一个统一的平台上完成 Flink 作业的开发、编译、提交和管理</strong>。极大地节省了我们在 Flink 作业开发和部署上的时间，显著地提升了开发效率，并实现了从用户权限管理到 Git 部署、任务提交、告警、自动恢复的全流程自动化，有效解决了 Apache Flink® 运维的复杂性。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/earnings-40d9739c55527d669e4f90c739571049.png" width="1080" height="989" class="img_iwx1"></p>
<p>目前在天眼查平台，StreamPark 带来的具体成效包括：</p>
<ul>
<li>
<p>实时作业上线和测试部署流程简化了 <strong>70%</strong> 。</p>
</li>
<li>
<p>实时作业的运维成本降低了 <strong>80%</strong>，开发人员可以更专注于代码逻辑 。</p>
</li>
<li>
<p>告警时效性提高了 <strong>5倍</strong> 以上，从分钟级降低到秒级，实现了 <strong>5秒内</strong> 感知并处理任务异常。</p>
</li>
<li>
<p>对于任务失败，StreamPark 能够自动恢复，无需人工干预。</p>
</li>
<li>
<p>通过 GitLab 与 StreamPark 的集成，简化了编译项目和作业提交流程，大幅降低了开发和维护成本。</p>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="未来规划"><strong>未来规划</strong><a class="hash-link" aria-label="未来规划的直接链接" title="未来规划的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-tianyancha#%E6%9C%AA%E6%9D%A5%E8%A7%84%E5%88%92">​</a></h2>
<p>未来我们计划将内部自研实时计算平台上部署的 300+ Flink 作业和其他方式维护的 500+ Flink 作业全部迁移至 StreamPark 进行统一管理维护，后续遇到一些可优化或可增强功能点，我们会及时与社区开发人员沟通并回馈贡献社区，让 StreamPark 变得更易用、更好用。</p>
<p>在本文的最后，我们衷心感谢 Apache Streampark 社区，特别是 PMC 成员华杰老师，在我们使用 StreamPark 过程中持续地跟进，提供了宝贵的技术支持，我们深刻感受到 Apache StreamPark 社区认真的态度和热情。同时也非常感谢华为云同学在云部署上支持与问题排查。</p>
<p>我们期待未来与 StreamPark 社区继续合作，共同推动实时计算技术的发展，期望 StreamPark 在未来做得越来越好，早日毕业成为新晋 Apache 项目的代表！</p>]]></content:encoded>
            <category>StreamPark</category>
            <category>生产实践</category>
        </item>
        <item>
            <title><![CDATA[Apache StreamPark™ 在欢乐互娱的云原生平台实践]]></title>
            <link>https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker</link>
            <guid>https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker</guid>
            <pubDate>Mon, 09 Feb 2026 02:32:43 GMT</pubDate>
            <description><![CDATA[导读：本文主要详细介绍欢乐互娱在实战中对大数据技术架构的应用，阐述为何选择  “Kubernetes + StreamPark” 来持续优化和增强现有的架构。不仅系统地阐述了如何在实际环境中部署并运用这些关键技术，更是深入地讲解了 StreamPark 的实践使用，强调理论与实践的完美融合，相信读者通过阅读这篇文章，将有助于理解和掌握相关技术，并能在实践中进步，从而取得显著的学习效果。]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/new_cover-4a6114b4487e3e397951de8ff4abe8f9.png" width="1080" height="460" class="img_iwx1"></p>
<p><strong>导读</strong>：本文主要详细介绍欢乐互娱在实战中对大数据技术架构的应用，阐述为何选择  “Kubernetes + StreamPark” 来持续优化和增强现有的架构。不仅系统地阐述了如何在实际环境中部署并运用这些关键技术，更是深入地讲解了 StreamPark 的实践使用，强调理论与实践的完美融合，相信读者通过阅读这篇文章，将有助于理解和掌握相关技术，并能在实践中进步，从而取得显著的学习效果。</p>
<p>Github: <a href="https://github.com/apache/streampark" target="_blank" rel="noopener noreferrer">https://github.com/apache/streampark</a></p>
<p>欢迎关注、Star、Fork，参与贡献</p>
<p>供稿单位 | 欢乐互娱</p>
<p>文章作者 | 杜遥</p>
<p>文章整理 | 杨林伟</p>
<p>内容校对 | 潘月鹏</p>
<p>欢乐互娱，是一家全球游戏研发和发行公司；公司产品聚焦在 MMORPG 和 MMOACT 两大品类；欢乐产品理念：“宁做100人尖叫的产品，不做1万人叫好的产品”；欢乐出品，必属精品。《RO仙境传说：爱如初见》上线东南亚，预约期间达成了 1000 万预约的里程碑，上线首日取得五国畅销榜第一，并在日韩美、港澳台等地都有发行，取得了不错的成绩。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="1-业务背景与挑战"><strong>1. 业务背景与挑战</strong><a class="hash-link" aria-label="1-业务背景与挑战的直接链接" title="1-业务背景与挑战的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#1-%E4%B8%9A%E5%8A%A1%E8%83%8C%E6%99%AF%E4%B8%8E%E6%8C%91%E6%88%98">​</a></h2>
<p>欢乐互娱目前使用的大数据底座是腾讯云的 EMR，数仓架构主要分为了如下几类：</p>
<ul>
<li>
<p><strong>离线数仓架构</strong>：Hadoop + Hive + Dolphinscheduler + Trino</p>
</li>
<li>
<p><strong>实时数仓架构</strong>：Kafka + Flink + StreamPark + Doris</p>
</li>
<li>
<p><strong>流式数仓架构（规划中）</strong>：Paimon + Flink + StreamPark + Doris</p>
</li>
</ul>
<p>其中，流式数仓架构是我们 2024 年的重点计划之一，目标是基于 Kubernetes 的弹性特点以提高大数据分析能力及各种数据产品的价值输出。然而，由于早前的架构原因（主要是 Apache Doris 和 EMR 核心节点的混部署），让我们遇到了许多问题，例如：</p>
<ul>
<li>
<p><strong>资源争夺</strong>：在 YARN 资源调度平台下，Apache Doris、Apache Flink 实时任务、Hive 的离线任务以及 Spark 的 SQL 任务经常争抢 CPU 和内存资源，导致 Doris 查询稳定性下降，查询错误频繁。</p>
</li>
<li>
<p><strong>资源不足</strong>：YARN 的机器资源使用率大部分时间位于 70％ 至 80％ 之间，特别是在大量的补数的场景下，集群资源往往不足。</p>
</li>
<li>
<p><strong>人工干预</strong>：实时 Flink 的任务越来越多，各游戏的数据在一天内有明显的波峰波谷变化，特别是在周末进行的挂机活动，数据量翻倍，甚至增加至每天超过 100 亿条，而且这需要频繁地手动调整并行度来适应计算压力，以保证数据消费能力。</p>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="2-解决方案选型"><strong>2. 解决方案选型</strong><a class="hash-link" aria-label="2-解决方案选型的直接链接" title="2-解决方案选型的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#2-%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88%E9%80%89%E5%9E%8B">​</a></h2>
<p>为了解决以上问题，我们寻求能够进行 “<strong>资源弹性伸缩</strong>” 和 “<strong>任务管理</strong>” 的相关组件，同时考虑到大数据云原生的趋势，采用云原生的架构迫在眉睫， Kubernetes 架构下能为大数据运维减负、提供高可用、负载均衡、灰度更新等更好更稳定的能力。</p>
<p>同时简化 Apache Flink 实时任务的开发和运维也是不得不面对的问题，自 2022 年中旬开始，就重点研究 Flink 相关的开源和商业化相关的项目，在进行技术选型时，公司主要从几个关键维度进行了深入考察，包括：<strong>Kubernetes 容器化部署、轻量程度、多 Flink版本的支持、功能的完备性、多种部署模式、对 CI/CD 的支持以及稳定性、成熟度等，最终不出意外的选择了 Apache StreamPark。</strong></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/cover-14b4d616ef68e17a584a773b097ea107.png" width="1080" height="496" class="img_iwx1"></p>
<p>我们在使用 StreamPark 的过程中，对其进行了深入的应用和探索，已经成功实现了100+ Flink 任务轻松部署到 Kubernetes，可以十分方便地进行作业管理。</p>
<p>接下来，将详述我们是如何使用 StreamPark 实现 Flink on kubernetes 在生产环境中的实践过程，尽管内容较长，但是干货满满，内容主要分为以下的几个部分：</p>
<ul>
<li>
<p><strong>环境准备篇</strong>：这部分介绍 Kubernetes、StreamPark、Maven、Docker、kubectl 工具和 Flink 的安装与配置过程。</p>
</li>
<li>
<p><strong>StreamPark 使用篇</strong>：这部分介绍如何使用 StreamPark 启动 Session 集群，以及部署 SQL、JAR 作业的流程等。</p>
</li>
<li>
<p><strong>Flink 任务应用场景篇</strong>：在这一部分，将分享欢乐互娱实际运用 Flink 任务的实践场景。</p>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="3-落地实践---环境准备篇"><strong>3. 落地实践 - 环境准备篇</strong><a class="hash-link" aria-label="3-落地实践---环境准备篇的直接链接" title="3-落地实践---环境准备篇的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#3-%E8%90%BD%E5%9C%B0%E5%AE%9E%E8%B7%B5---%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87%E7%AF%87">​</a></h2>
<p>接下来我们将从安装开始详细介绍 StreamPark 的落地实践,关于腾讯云产品的一些使用步骤，将在文末简要介绍，此处主要分享核心的步骤。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="31-准备-kubernetes-环境"><strong>3.1. 准备 Kubernetes 环境</strong><a class="hash-link" aria-label="31-准备-kubernetes-环境的直接链接" title="31-准备-kubernetes-环境的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#31-%E5%87%86%E5%A4%87-kubernetes-%E7%8E%AF%E5%A2%83">​</a></h3>
<p>欢乐互娱的 Kubernetes 环境使用的是腾讯云容器服务产品，其中 Kubernetes 命名空间主要划分如下：</p>
<ul>
<li>
<p><strong>Apache Doris</strong>：Doris 集群 + 3 FE（标准节点） + CN（1 台超级节点）。</p>
</li>
<li>
<p><strong>Apache Flink</strong>：Flink 集群由一个超级节点组成，这个节点相当于一台超大资源的机器，使用起来非常简单，并且可以迅速弹性扩展到数以万计的 pod。</p>
</li>
<li>
<p><strong>BigData</strong>：包含各种大数据组件。</p>
</li>
</ul>
<p>另外，我们还有两台原生节点，主要用于部署 StreamPark、Dolphinscheduler 以及 Prometheus + Grafana。集群信息相关截图如下：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/clusters-dd6a35ed22d17b2020d7301f273d3c2f.png" width="1080" height="580" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="32-安装-streampark"><strong>3.2. 安装 StreamPark</strong><a class="hash-link" aria-label="32-安装-streampark的直接链接" title="32-安装-streampark的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#32-%E5%AE%89%E8%A3%85-streampark">​</a></h3>
<p>我们采用的是 StreamPark 2.1.4 最新的稳定版本，该版本修复了一些 Bug，并增加了一些新的特性，如支持 Flink 1.18、Jar 任务支持通过 pom 或者上传依赖等。</p>
<p>虽然 StreamPark 支持 Docker 和 Kubernetes 部署，但是出于节省时间和对所有大数据组件需要进行顶层设计容器化的考虑，我们当前选择了<strong>在云上的 CVM 上进行 StreamPark 的快速搭建</strong>，以下是 StreamPark 的安装部署脚本：</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">#使用 root 用户进入安装目录（需先有 java 环境）和 k8s 环境同一个网段！！！可以省事</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">cd /data     </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#下载二进制安装包</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">wget https://dlcdn.apache.org/incubator/streampark/2.1.4/apache-streampark_2.12-2.1.4-incubating-bin.tar.gz   </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#与提供的值进行比较、保证包的完成性</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">sha512sum apache-streampark_2.12-2.1.2-incubating-bin.tar.gz  #解压缩</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">tar -xzvf apache-streampark_2.12-2.1.2-incubating-bin.tar.gz  #改名</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">mv apache-streampark_2.12-2.1.2-incubating-bin streampark_2.12-2.1.2 #创建软链</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">ln -s streampark_2.12-2.1.2  streampark</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#修改数据库配置</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">vim /data/streampark/conf/application-mysql.ymlspring:</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  datasource:</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    username: root</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    password: xxxxx</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    driver-class-name: com.mysql.cj.jdbc.Driver</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    url: jdbc:mysql://10.16.x.x:3306/streampark_k8s?...</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 修改 streampark 核心配置 可以修改下端口（因为 k8s nodeport 端口范围  30000-32767） 故可以配置这个范围 省去端口对外开发再配置  或者账号密码  我们存储用 cos 故不配置 hdfs</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">vim /data/streampark/conf/application.yml      workspace:</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   local: /data/streampark/streampark_workspace #创建需要的目录</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">mkdir -p  vim /data/streampark/conf/application.yml</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#初始化 streampark 的数据库表 要求环境有 mysql 客户端  执行完可以去 mysql 中看下库表是否存在</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">mysql -u root -p xxxxx &lt; /data/streampark/script/schema/mysql-schema.sql</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#添加依赖的 mysql-connector 包 因为 streampark lib下面没有  在 /data/streampark/lib下执行</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">wget https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/8.0.33/mysql-connector-j-8.0.33.jar </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#启动并登陆 可以先验证下 java  环境  java -version 确保没问题   在 /data/streampark/lib下执行</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> ./startup.sh </span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="33-安装-maven"><strong>3.3. 安装 Maven</strong><a class="hash-link" aria-label="33-安装-maven的直接链接" title="33-安装-maven的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#33-%E5%AE%89%E8%A3%85-maven">​</a></h3>
<p>在 StreamPark 上配置 Flink 任务时可以通过 maven 下载相关依赖，下面是 Maven 的安装配置：</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">#下载 maven 同 root 用户操作</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">cd /data &amp;&amp; wget https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#检验安装包完整</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">sha512sum apache-maven-3.9.6-bin.tar.gz </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#解压  软连</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">tar -xzvf apache-maven-3.9.6-bin.tar.gz </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">ln -s apache-maven-3.9.6 maven</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 设置阿里云仓库 maven mirror，加速下载</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">vim /data/maven/conf/settings.xml</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">&lt;mirror&gt;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   &lt;id&gt;alimaven&lt;/id&gt;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  &lt;mirrorOf&gt;central&lt;/mirrorOf&gt;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  &lt;name&gt;aliyun maven&lt;/name&gt;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  &lt;url&gt;https://maven.aliyun.com/repository/central&lt;/url&gt;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">&lt;/mirror&gt;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">&lt;mirror&gt;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  &lt;id&gt;alimaven&lt;/id&gt;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  &lt;name&gt;aliyun maven&lt;/name&gt;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  &lt;url&gt;http://maven.aliyun.com/nexus/content/groups/public/&lt;/url&gt;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  &lt;mirrorOf&gt;central&lt;/mirrorOf&gt;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> &lt;/mirror&gt;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#环境变量 最后添加</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">vim /etc/profile</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">export MAVEN_HOME=/data/maven</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">PATH=$MAVEN_HOME/bin:$PATH</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#生效 验证</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">source /etc/profile  &amp;&amp; mvn -version</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="34-安装-docker"><strong>3.4 安装 Docker</strong><a class="hash-link" aria-label="34-安装-docker的直接链接" title="34-安装-docker的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#34-%E5%AE%89%E8%A3%85-docker">​</a></h3>
<p>因为 StreamPark 使用 Kubernetes 时，可以使用 Docker 来构建和上传镜像到公司常用的 Harbor 镜像服务中，以下是 Docker 的安装脚本</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">#卸载旧版本 如果有</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">sudo yum remove docker \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">          docker-client \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">          docker-client-latest \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">          docker-common \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">          docker-latest \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">          docker-latest-logrotate \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">          docker-logrotate \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">          docker-engine</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#下载镜像仓库</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo      #阿里云docker-ce 镜像</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#更新软件包索引 </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">yum makecache     </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#下载安装</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">yum install docker-ce docker-ce-cli containerd.io -y # docker-ce 社区版 ee 企业版</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#启动 查看 </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">systemctl start docker &amp;&amp; docker version</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#开机自启</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">systemctl enable docker</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="35-kubectl-工具安装"><strong>3.5. Kubectl 工具安装</strong><a class="hash-link" aria-label="35-kubectl-工具安装的直接链接" title="35-kubectl-工具安装的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#35-kubectl-%E5%B7%A5%E5%85%B7%E5%AE%89%E8%A3%85">​</a></h3>
<p>为了方便与 Kubernetes 集群进行交互、进行配置查看、访问日志等，我们还安装了kubectl 工具。安装 kubectl 前，首先需要先从这里获取 Kubernetes 集群的访问凭证，下载方式如下图：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/access_credential-5672963a435919d770ca7eb6210a2375.png" width="1080" height="536" class="img_iwx1"></p>
<p>接着下载配置拷贝到 root 用户目录，指定目录并改名：</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 1）创建默认隐藏目录</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">mkdir -p /root/.kube   </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 2）上传 k8s 内网访问凭证             </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">rz cls-dtyxxxxl-config</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 3）修改凭证默认名字              </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">mv cls-dtyxxxxl-config config  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 4）将凭证放到指定位置</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">mv config /root/.kube </span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>具体安装 kubetcl 客户端命令如下（当然也可以安装 <strong>kubectx</strong> ，更加方便地去访问多个 kubernetes 集群和切换固定的命名空间）：</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 1）下载最新版</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 2）添加执行权限</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">chmod +x kubectl</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 3）移动到常用的工具命令位置</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">mv ./kubectl /usr/local/bin/kubectl</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 4）可以在 /etc/profile 或者 root用户家目录的  .bashrc 中配置</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">vim /root/.bashrc</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">export JAVA_HOME=/usr/local/jdk1.8.0_391</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">PATH=/usr/local/bin:$JAVA_HOME/bin:$PATH</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 5）验证客户端和集群密钥</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">kubectl cluster-info</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>最后，还需要创建一个 Flink 专用的账户凭证（后面会用到）：</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 1）创建命名空间</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">kubectl create namespace flink</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 2）创建 flink 访问 k8s 的账号  记得带命名空间！</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">kubectl  create serviceaccount flink-service-account -n flink</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"># 3）给该账号绑定容器操作的一些权限 记得带命名空间！！！</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">kubectl  create clusterrolebinding flink-role-binding-flink --clusterrole=edit --serviceaccount=flink:flink-service-account -n flink  </span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="36-安装配置-flink"><strong>3.6. 安装配置 Flink</strong><a class="hash-link" aria-label="36-安装配置-flink的直接链接" title="36-安装配置-flink的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#36-%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE-flink">​</a></h3>
<p>我们 Kubernetes 环境选择了 Flink1.17-scala2.12 Java11 的镜像，因为当时 Flink 1.18 有些依赖包不好找。</p>
<p>下载并解压 flink-1.17.2-bin-scala_2.12.tgz 安装包，脚本如下：</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">cd /data &amp;&amp; wget https://dlcdn.apache.org/flink/flink-1.17.2/flink-1.17.2-bin-scala_2.12.tgz</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#完整性校验</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">sha512sum flink-1.17.2-bin-scala_2.12.tgz</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#解压</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">tar -xzvf flink-1.17.2-bin-scala_2.12.tgz</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#改名</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">mv flink-1.17.2-bin-scala_2.12 flink-1.17.2</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#软连</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">ln -s flink-1.17.2 flink</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#旧二进制包收纳</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">mv flink-1.17.2-bin-scala_2.12.tgz /data/softbag   </span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>至此，我们已经把环境搭建好了，下面继续按步骤详细讲解 StreamPark 的使用。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="4-落地实践---streampark-使用篇"><strong>4. 落地实践 - StreamPark 使用篇</strong><a class="hash-link" aria-label="4-落地实践---streampark-使用篇的直接链接" title="4-落地实践---streampark-使用篇的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#4-%E8%90%BD%E5%9C%B0%E5%AE%9E%E8%B7%B5---streampark-%E4%BD%BF%E7%94%A8%E7%AF%87">​</a></h2>
<p>想快速了解 StreamPark 运行作业至 Kubernetes 的读者，可以观看下面的视频：</p>
<p>//视频链接 (Flink On Kubernetes Application 上手教程)</p>
<p>//视频链接 (Flink On Kubernetes Session 上手教程)</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="41-配置-flink-home"><strong>4.1. 配置 Flink Home</strong><a class="hash-link" aria-label="41-配置-flink-home的直接链接" title="41-配置-flink-home的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#41-%E9%85%8D%E7%BD%AE-flink-home">​</a></h3>
<p>登录 StreamPark 之后，切换至 Flink Home 菜单，配置我们在前面解压的 Flink 安装包目录，截图如下：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_home-35bb262214d42ca4276c3e8152b1f20b.png" width="1080" height="386" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="42-创建-flink-session"><strong>4.2. 创建 Flink Session</strong><a class="hash-link" aria-label="42-创建-flink-session的直接链接" title="42-创建-flink-session的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#42-%E5%88%9B%E5%BB%BA-flink-session">​</a></h3>
<p>接着切换到 FlinkCluster，Add New 新增一个 Flink 集群：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_cluster-7ee9edd1b1777a91e7c5225ecebf9550.png" width="1080" height="508" class="img_iwx1"></p>
<p>配置详情如下，以下是第一部分的配置内容：</p>
<p><strong>配置详解</strong>：集群名字和 Kubernetes 集群 ID 我们通常写一样，填写正确的 Kubernetes 服务账号，这里的镜像使用腾讯云 tcr 中的镜像，并使用 lb 作为对外访问 Flink UI 的方式。这里的槽一般设置为 2，任务并行度一般是 2 的倍数，这样就可以让 Session 集群没有闲置的资源）</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/first_configuration-d41d93c20abd21359a8b24a9b75b7ea4.png" width="933" height="564" class="img_iwx1"></p>
<p>第二部分的配置内容：</p>
<p><strong>配置详解</strong>：我们采取的是 Session 模式，一个 JobManager 管理着很多任务，故资源可以稍微大一些，我们给 2G，经观察可以满足，但是由于任务多，JobManager 的内存分配中 metaspace 消耗比较大，故可以将默认的 256M，改到 500M，经过观察，一个 Session 管理 10 个任务以下，这个配置合理。</p>
<p>TaskManager 内存在 session 配置给出后，在 StreamPark 程序配置页将无法修改，故可以对 Session 项目数据量进行预估，数据量大就可以 把 “CPU : 内存” 调整到 “1 核 : 2G”，当然也可以更大，因为数据处理还有 TaskManager 数量有关，也就是并行度有关，这样基本就可以避免一些 OOM 问题，我们 “1 : 2” Session 集群项目一天处理数据量 60 亿，18 个并行度，仅供参考。默认 cpu: 内存 1 : 1 基本 ok。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/second_configuration-4dbfe7fdf6dc5297c9763e8847d95461.png" width="1080" height="468" class="img_iwx1"></p>
<p>最后一部分的内容如下：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/third_configuration-f2cc57a25457ffab62730c1609ef3ec9.png" width="1080" height="486" class="img_iwx1"></p>
<p>这里贴出具体的文本内容：</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">#访问方式  复用lb+port lb可以提前创建 不用k8s创建  这样ip固定。复用后更加方便</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Drest.port=8091</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.rest-service.annotations=service.kubernetes.io/qcloud-share-existed-lb:true,service.kubernetes.io/tke-existed-lbid:lb-iv9ixxxxx</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.rest-service.exposed.type=LoadBalancer</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#cp sp  使用s3协议访问腾讯云cos  插件方式依赖包  s3的cos认证</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dcontainerized.master.env.ENABLE_BUILT_IN_PLUGINS=flink-s3-fs-hadoop-1.17.2.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dcontainerized.taskmanager.env.EANABLE_BUILT_IN_PLUGINS=flink-s3-fs-hadoop-1.17.2.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dstate.checkpoints.dir=s3://k8s-bigdata-xxxxxx/flink-checkpoints</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dstate.savepoints.dir=s3://k8s-bigdata-xxxxx/flink-savepoints</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#k8s中的任务调度策略、节点选择策略，因为flink命名空间是逻辑的，而节点选择策略可以让其跑在flink专用的物理超级节点上去</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.jobmanager.node-selector=usefor:flink</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.taskmanager.node-selector=usefor:flink</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#开启jobmanager高可用 使用 k8s实现方式、 使用cos的目录存储  整体就不用hdfs</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dhigh-availability.type=kubernetes</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dhigh-availability.storageDir=s3://k8s-bigdata-xxx/flink-recovery</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.cluster-id=streampark-share-session</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.jobmanager.replicas=2</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#pod镜像拉取策略和flink取消cp的保留 时区</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.container.image.pull-policy=Always</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dexecution.checkpointing.externalized-checkpoint-retention=RETAIN_ON_CANCELLATION</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dtable.local-time-zone=Asia/Shanghai</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#镜像拉取缓存加速  详细下文有解释</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.taskmanager.annotations=eks.tke.cloud.tencent.com/use-image-cache: imc-6iubofdt</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.jobmanager.annotations=eks.tke.cloud.tencent.com/use-image-cache: imc-6iubofdt  </span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="�复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>备注：Flink 基础信息的可以配置到 conf 文件中，更多程序通用的建议在 session 中写好，StreamPark 中填写 并行度/cp/sp/容错/main 参数等比较合适。</p>
<p>最后启动 Session 集群即可，可以通过 kubectl 命令来查看 Flink kubernetes session 集群是否成功启动：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/session_cluster-c4d11c15302e9cdbe70786b8ae6177c1.png" width="653" height="81" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="43-任务配置"><strong>4.3. 任务配置</strong><a class="hash-link" aria-label="43-任务配置的直接链接" title="43-任务配置的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#43-%E4%BB%BB%E5%8A%A1%E9%85%8D%E7%BD%AE">​</a></h3>
<p>这里将继续展示使用 StreamPark 提交3种类型的任务，分别是 <strong>SQL任务、Jar任务 以及 Application 模式任务</strong>。</p>
<ul>
<li><strong>提交 Flink SQL 任务</strong></li>
</ul>
<p>Flink Sql 作业的配置截图如下：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/sql_configuration-cf75e4e90e78db9a2e05a286fd8cf54c.png" width="1080" height="556" class="img_iwx1"></p>
<p>其中的 kubernetes clusterid 填写对应的项目 session 名就行：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/kubernetes_configuration-50a637b897415c1d26f17d1ebb0fd690.png" width="1080" height="532" class="img_iwx1"></p>
<p>动态参数配置如下：</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dstate.checkpoints.dir=s3://k8s-bigdata-12xxxxx/flink-checkpoints/ro-cn-sync</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dstate.savepoints.dir=s3://k8s-bigdata-12xxxxxxx/flink-savepoints/ro-cn-sync</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.container.image.pull-policy=Always</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.service-account=flink-service-account</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dexecution.checkpointing.interval=25s</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dexecution.checkpointing.mode=EXACTLY_ONCE</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dtable.local-time-zone=Asia/Shanghai</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Drestart-strategy.fixed-delay.attempts=10</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Drestart-strategy.fixed-delay.delay=3min  </span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li><strong>提交 Flink JAR 任务</strong></li>
</ul>
<p>Jar 任务基本和 Sql 任务基本一样，配置截图如下：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/jar_configuration-fc88df4ae67c670f62de8eb0a51db10d.png" width="1080" height="552" class="img_iwx1"></p>
<p>动态参数如下（如果有配置模版，这里就可以更加精简，因为 StreamPark 支持很好的任务复制，故可以写一标准的 Jar 和 SQL 的任务 demo，剩下任务都采用复制，可大大提高任务开发效率）：</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dstate.checkpoints.dir=s3://k8s-bigdata-1xxxx/flink-checkpoints/ro-cn-shushu</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dstate.savepoints.dir=s3://k8s-bigdata-1xxxx/flink-savepoints/ro-cn-shushu</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.container.image.pull-policy=Always</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.service-account=flink-service-account</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dexecution.checkpointing.interval=60s</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dexecution.checkpointing.mode=EXACTLY_ONCE</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dstate.checkpoints.num-retained=2</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Drestart-strategy.type=failure-rate</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Drestart-strategy.failure-rate.delay=3min</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Drestart-strategy.failure-rate.failure-rate-interval=30min</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Drestart-strategy.failure-rate.max-failures-per-interval=8</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li><strong>提交 Flink Application 任务</strong></li>
</ul>
<p>当然也可以部署 Application 模式的任务至 Kubernetes，这里贴上示例，首先是第一部分的配置内容：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/application_first_configuration-354324b7b32b467a43dbc1d97ec40053.png" width="1012" height="395" class="img_iwx1"></p>
<p>这是第二部分的配置内容如下：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/application_second_configuration-29d9a7c1e9af25d1c07fdf5cb7e22eb4.png" width="1080" height="716" class="img_iwx1"></p>
<p>第三部分的配置内容如下：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/application_third_configuration-c7983a9c4c7acfe53268d98a44b4237c.png" width="1080" height="386" class="img_iwx1"></p>
<p>动态参数：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/dynamic_parameter-2d1c54c8137ab01e9437f8b6fbbb13de.png" width="954" height="603" class="img_iwx1"></p>
<p>详细的配置内容：</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dcontainerized.master.env.ENABLE_BUILT_IN_PLUGINS=flink-s3-fs-hadoop-1.17.2.jar </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dcontainerized.taskmanager.env.ENABLE_BUILT_IN_PLUGINS=flink-s3-fs-hadoop-1.17.2.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dstate.checkpoints.dir=s3://k8s-bigdata-xxx/flink-checkpoints/Kafka2Rocketmq2Kafka</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dstate.savepoints.dir=s3://k8s-bigdata-xxx/flink-savepoints/Kafka2Rocketmq2Kafka</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.container.image.pull-policy=Always</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.service-account=flink-service-account</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dexecution.checkpointing.interval=60s</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dexecution.checkpointing.mode=EXACTLY_ONCE</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dstate.checkpoints.num-retained=2</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Drest.port=8092</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.jobmanager.node-selector=usefor:flink</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.taskmanager.node-selector=usefor:flink</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.rest-service.annotations=service.kubernetes.io/qcloud-share-existed-lb:true,service.kubernetes.io/tke-existed-lbid:lb-xxx</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dkubernetes.rest-service.exposed.type=LoadBalancer</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-Dfs.allowed-fallback-filesystems=s3</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="44-构建任务"><strong>4.4. 构建任务</strong><a class="hash-link" aria-label="44-构建任务的直接链接" title="44-构建任务的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#44-%E6%9E%84%E5%BB%BA%E4%BB%BB%E5%8A%A1">​</a></h3>
<p>接着对任务进行构建，这里可以很清晰的看到任务构建的每一步骤：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/task_construction-1376844f54646571bf10a8dbfd729fac.png" width="437" height="902" class="img_iwx1"></p>
<p>最终可以跑起来观察到任务正在运行：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/running-0e6a0f7e492c6d62638f8a255200e8be.png" width="581" height="235" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="45-通知告警配置非必选"><strong>4.5. 通知告警配置（非必选）</strong><a class="hash-link" aria-label="45-通知告警配置非必选的直接链接" title="45-通知告警配置非必选的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#45-%E9%80%9A%E7%9F%A5%E5%91%8A%E8%AD%A6%E9%85%8D%E7%BD%AE%E9%9D%9E%E5%BF%85%E9%80%89">​</a></h3>
<p>当然 StreamPark 支持多种通知告警方式（例如：邮箱和飞书等），我们使用的是邮箱的方式，直接界面配置即可：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/alarm_configuration-3fd492650cb0a7ec81104a9f4fdd8379.png" width="1080" height="622" class="img_iwx1"></p>
<p>至此，我们已经分享了如何在 StremPark 中成功地去部署运行在 kubernetes 不同类型的 Flink任务，十分的丝滑！</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="5-落地实践---作业应用场景篇"><strong>5. 落地实践 - 作业应用场景篇</strong><a class="hash-link" aria-label="5-落地实践---作业应用场景篇的直接链接" title="5-落地实践---作业应用场景篇的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#5-%E8%90%BD%E5%9C%B0%E5%AE%9E%E8%B7%B5---%E4%BD%9C%E4%B8%9A%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%E7%AF%87">​</a></h2>
<p>接下来，继续针对作业进行剖析，从调优、实操等场景中让我们更进一步地去了解 Flink 任务的应用。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="51-调优建议"><strong>5.1. 调优建议</strong><a class="hash-link" aria-label="51-调优建议的直接链接" title="51-调优建议的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#51-%E8%B0%83%E4%BC%98%E5%BB%BA%E8%AE%AE">​</a></h3>
<p><strong>建议一（时区）</strong>：容器中需要以utc+8方便看日志，我们可以在conf配置中添加如下：</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">env.java.opts.jobmanager: -Duser.timezone=GMT+08</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">env.java.opts.taskmanager: -Duser.timezone=GMT+08</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>建议二（StreamPark变量管理）</strong>：StreamPark 提供变量管理、让我们可以管理一些配置，提高安全和便捷性：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/variable_management-1213e43f16736c78f9f8b1c85c537926.png" width="1071" height="197" class="img_iwx1"></p>
<p><strong>建议三（StreamPark传参）</strong>：在 on YARN 上使用 Flink自带的工具类传参数，参数难传递到 Flink 环境去，我们也没深究。我们选择通过 StreamPark 传入程序参数，这样在 YARN 和 kubernetes 都可以用，<strong>同时在 kubernetes 的 application 和 session 方式也都可以用，变得更加通用且改动方便，强烈推荐</strong>！</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/incoming_parameter-4fbd6146a85b569ddae19dd005922038.png" width="670" height="290" class="img_iwx1"></p>
<p><strong>建议四（使用Session模式）</strong>：尽管 Yarn-application模式提供了高度的任务隔离，但其每个任务都需要独立的 jobmanager 资源，这导致资源消耗过高。此外，合并任务虽然可以减少资源消耗，但会带来工作量大、数据不稳定等问题。相比之下，session 模式允许任务在一个 session 中共享一个 jobmanager 资源，这可以最大限度地节约计算资源，虽然它可能存在单点问题，但可以通过使用两个 jobmanager 实例实现高可用性来解决。更重要的是，session 模式还可以更方便地查看因任务失败而产生的日志，有助于提高故障诊断的效率。因此，鉴于其在资源利用、高可用性和任务故障处理方面的优势，选择 session 模式成为了一种更为理想的选择。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="52-数据cdc同步"><strong>5.2. 数据CDC同步</strong><a class="hash-link" aria-label="52-数据cdc同步的直接链接" title="52-数据cdc同步的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#52-%E6%95%B0%E6%8D%AEcdc%E5%90%8C%E6%AD%A5">​</a></h3>
<p><strong>【MySQL → Doris】</strong>：下面代码主要演示了 <strong>MySQL 数据同步至 Apache Doris</strong> 的 Flink sql 流水线：</p>
<div class="language-sql codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-sql codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">IF</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">EXISTS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">login_log_mysql</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> login_log_id      </span><span class="token keyword" style="color:rgb(86, 156, 214)">bigint</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">not</span><span class="token plain"> </span><span class="token boolean">null</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> account_id        </span><span class="token keyword" style="color:rgb(86, 156, 214)">bigint</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> long_account_id   string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> short_account_id  string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> game_code         string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> package_code      string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> channel_id        </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> login_at          </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> login_ip          string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">    </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> device_ua         string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> device_id         string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> device_net        string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> device_ratio      string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> device_os         string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> device_carrier    string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> ext               string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">        </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> created_at        </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> updated_at        </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> deleted_at        </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">KEY</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">login_log_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> ENFORCED</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">with</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'connector'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'mysql-cdc'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'hostname'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'10.xxx.xxx.xxx'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'port'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'3306'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'username'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'http_readxxxxx'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'password'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'xxxx@)'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'database-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'player_user_center'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token comment" style="color:rgb(106, 153, 85)">-- 'scan.startup.mode' = 'latest-offset',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'scan.startup.mode'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'earliest-offset'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'table-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'login_log_202[3-9][0-9]{2}'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'server-time-zone'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'+07:00'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">create</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">table</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">if</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">not</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">EXISTS</span><span class="token plain"> login_log_doris</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain">    </span><span class="token keyword" style="color:rgb(86, 156, 214)">date</span><span class="token plain">              </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">    </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   login_log_id    </span><span class="token keyword" style="color:rgb(86, 156, 214)">bigint</span><span class="token plain">     </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   account_id    </span><span class="token keyword" style="color:rgb(86, 156, 214)">bigint</span><span class="token plain">       </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   long_account_id    string  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   short_account_id    string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   game_code    string        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">package_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain">    string    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">channel_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain">    </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain">         </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   login_at     string      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   login_ip    string         </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   device_ua    string        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   device_id    string        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   device_net    string       </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   device_ratio    string     </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   device_os    string        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   device_carrier    string   </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   ext        string          </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   created_at      string   </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   updated_at      string   </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   deleted_at      string   </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token keyword" style="color:rgb(86, 156, 214)">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">KEY</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">login_log_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> ENFORCED</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   </span><span class="token string" style="color:rgb(206, 145, 120)">'connector'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'doris'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'jdbc-url'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'jdbc:mysql://xxx.xx.xx.xx:9030,xxx.xxx.xxx.xxx:9030,xxx.xxx.xxx.xxx:9030'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'load-url'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'xxx.xx.xx.xx:8030;xxx.xx.xx.xx:8030;xxx.xx.xx.xx:8030'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'database-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ro_sea_player_user_center'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'table-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ods_login_log'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'username'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'root'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'password'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'root123'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'sink.semantic'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'exactly-once'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'sink.max-retries'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'10'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">create</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">view</span><span class="token plain"> login_log_flink_trans </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">select</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> to_date</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">to_timestamp_ltz</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">login_at</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> login_log_id     </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> account_id       </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> long_account_id  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> short_account_id </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> game_code        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> package_code     </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> channel_id</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">to_timestamp_ltz</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">login_at</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> login_at</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> login_ip         </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">    </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> device_ua        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> device_id        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> device_net       </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> device_ratio     </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> device_os        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> device_carrier   </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> ext              </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">to_timestamp_ltz</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">created_at</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> created_at</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">to_timestamp_ltz</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">updated_at</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> updated_at</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">to_timestamp_ltz</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">deleted_at</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> deleted_at</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">from</span><span class="token plain"> login_log_mysql</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">insert</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">into</span><span class="token plain"> login_log_doris </span><span class="token keyword" style="color:rgb(86, 156, 214)">select</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">from</span><span class="token plain"> login_log_flink_trans</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">IF</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">EXISTS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">account_mysql</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> account_id        </span><span class="token keyword" style="color:rgb(86, 156, 214)">bigint</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> open_id   string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> dy_openid  string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> dy_ios_openid  string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> ext               string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">        </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> last_channel      </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> last_login_time   </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> last_login_ip     string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> created_at        </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> updated_at        </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> deleted_at        string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">KEY</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">account_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> ENFORCED</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">with</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'connector'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'mysql-cdc'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'hostname'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'xxx.xx.xx.xx'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'port'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'3306'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'username'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'http_readxxxx'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'password'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'xxxxx@)'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'database-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'player_user_center'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token comment" style="color:rgb(106, 153, 85)">-- 'scan.startup.mode' = 'latest-offset',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'scan.startup.mode'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'earliest-offset'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'table-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'account_[0-9]+'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'server-time-zone'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'+07:00'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">create</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">table</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">if</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">not</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">EXISTS</span><span class="token plain"> account_doris</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain">    </span><span class="token keyword" style="color:rgb(86, 156, 214)">date</span><span class="token plain">              </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">    </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   account_id    </span><span class="token keyword" style="color:rgb(86, 156, 214)">bigint</span><span class="token plain">     </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   open_id    string  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   dy_openid    string </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   dy_ios_openid    string        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   ext        string          </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">last_channel</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain">    </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain">         </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   last_login_time     string      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   last_login_ip    string         </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   created_at      string   </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   updated_at      string   </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   deleted_at      string   </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   </span><span class="token keyword" style="color:rgb(86, 156, 214)">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">KEY</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">account_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> ENFORCED</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   </span><span class="token string" style="color:rgb(206, 145, 120)">'connector'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'doris'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'jdbc-url'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'jdbc:mysql://xxx.xx.xx.xx:9030,xxx.xx.xx.xx:9030,xxx.xx.xx.xx:9030'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'load-url'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'xxx.xx.xx.xx:8030;xxx.xx.xx.xx:8030;xxx.xx.xx.xx:8030'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'database-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ro_sea_player_user_center'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'table-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ods_account_log'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'username'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'root'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'password'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'root123'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'sink.semantic'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'exactly-once'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'sink.max-retries'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'10'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">create</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">view</span><span class="token plain"> account_flink_trans </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">select</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> to_date</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">to_timestamp_ltz</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">created_at</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> account_id     </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> open_id  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> dy_openid </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> dy_ios_openid        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> ext              </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> last_channel</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">to_timestamp_ltz</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">last_login_time</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> last_login_time</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> last_login_ip         </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">    </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">to_timestamp_ltz</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">created_at</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> created_at</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">to_timestamp_ltz</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">updated_at</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> updated_at</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> deleted_at</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">from</span><span class="token plain"> account_mysql</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">insert</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">into</span><span class="token plain"> account_doris </span><span class="token keyword" style="color:rgb(86, 156, 214)">select</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">from</span><span class="token plain"> account_flink_trans</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>【游戏数据同步】</strong>：将海外 <strong>filebeat 采集的 kafka 数据拉到国内 kafka</strong>，并进行处理元数据加工：</p>
<div class="language-sql codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-sql codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token comment" style="color:rgb(106, 153, 85)">--创建hmt 的kafka source 表</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> kafka_in </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">env</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'游戏环境 hdf  /qc/cbt/obt/prod'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">host</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'日志所在游戏服务器'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">tags</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'日志标签 normal | fix'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">log</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain">  STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'日志所在文件及偏移量'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">topic</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING METADATA VIRTUAL </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'kafka的topic'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">partition_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> METADATA </span><span class="token keyword" style="color:rgb(86, 156, 214)">FROM</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'partition'</span><span class="token plain"> VIRTUAL </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'日志所在的kafka分区'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">offset</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> METADATA VIRTUAL </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'kafka分区的偏移量'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">uuid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain">  STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'filebeat生成的uuid'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">message</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'tlog信息'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">@timestamp</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'filebeat采集时间'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ts</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">3</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> METADATA </span><span class="token keyword" style="color:rgb(86, 156, 214)">FROM</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'timestamp'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'kafka存储消息时间'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'connector'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'kafka'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'topic'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ro_sea_tlog'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.bootstrap.servers'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'sea-kafka-01:9092,sea-kafka-02:9092,sea-kafka-03:9092'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.group.id'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'streamx-ro-sea-total'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.client.id'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'streamx-ro-sea-total'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.session.timeout.ms'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'60000'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.request.timeout.ms'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'60000'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'scan.startup.mode'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'group-offsets'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token comment" style="color:rgb(106, 153, 85)">--'scan.startup.mode' = 'earliest-offset',\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.fetch.max.bytes'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'123886080'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.max.partition.fetch.bytes'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'50388608'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.fetch.max.wait.ms'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2000'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.max.poll.records'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'1000'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'format'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'json'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'json.ignore-parse-errors'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'false'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">--创建emr 的kafka 正式表</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> kafka_out_sea </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">env</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'游戏环境 qc/cbt/obt/prod'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">hostname</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'日志所在游戏服务器'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">tags</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'日志标签 normal | fix'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">log_offset</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain">  STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'日志所在文件及偏移量'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">uuid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain">  STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'filebeat生成的uuid'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">topic</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'kafka的topic'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">partition_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'日志所在的kafka分区'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">kafka_offset</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'kafka分区的偏移量'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> eventname string </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'事件名'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">message</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'tlog信息'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">filebeat_ts</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'filebeat采集时间'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">kafka_ts</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">3</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'kafka存储消息时间'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">flink_ts</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">3</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'flink处理的消息时间'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'connector'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'kafka'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'topic'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ro_sea_tlog'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token comment" style="color:rgb(106, 153, 85)">--'properties.client.id' = 'flinkx-ro-sea-prod-v2',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.bootstrap.servers'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'emr_kafka1:9092,emr_kafka2:9092,emr_kafka3:9092'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'format'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'json'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token comment" style="color:rgb(106, 153, 85)">--'sink.partitioner'= 'fixed',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'sink.delivery-guarantee'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'exactly-once'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'sink.transactional-id-prefix'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ro_sea_kafka_sync_v10'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.compression.type'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'zstd'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.transaction.timeout.ms'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'600000'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.message.max.bytes'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'13000000'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.max.request.size'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'13048576'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token comment" style="color:rgb(106, 153, 85)">--'properties.buffer.memory' = '83554432',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.acks'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'-1'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">--etl 创建目标视图</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">create</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">view</span><span class="token plain"> kafka_sea_in_view  </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">select</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">env</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">host</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> hostname</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">tags</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">log</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> log_offset</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">uuid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">       </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">topic</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">partition_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">offset</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> kafka_offset</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">     lower</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> eventname</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">message</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">     CONVERT_TZ</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">REPLACE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">REPLACE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">@timestamp</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'T'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">' '</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'Z'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">''</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'UTC'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Asia/Bangkok'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> filebeat_ts</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ts</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> kafka_ts </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token keyword" style="color:rgb(86, 156, 214)">CURRENT_TIMESTAMP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> flink_ts</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">from</span><span class="token plain"> kafka_in</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">--写数据到emr  sea topic</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">insert</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">into</span><span class="token plain"> kafka_out_sea</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">select</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">from</span><span class="token plain"> kafka_sea_in_view </span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>【实时数仓】</strong>：分流 Jar 程序和 ods -&gt; dwd sql 加工函数，部分代码截图如下：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/jar-bf657c3fbc9aebd6022efea71b10c160.png" width="918" height="660" class="img_iwx1"></p>
<p>以及相关的 Flink sql：</p>
<div class="language-sql codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-sql codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token comment" style="color:rgb(106, 153, 85)">--2 dwd_moneyflow_log</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> kafka_in_money </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">env</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING   </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'游戏环境 qc/cbt/obt/prod'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">hostname</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'日志所在游戏服务器'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">uuid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'日志唯一id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">message</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'tlog信息'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">filebeat_ts</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'filebeat采集时间'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'connector'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'kafka'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'topic'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ro_sea_tlog_split_moneyflow'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.bootstrap.servers'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'emr_kafka1:9092,emr_kafka2:9092,emr_kafka3:9092'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.group.id'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'flinksql_kafka_in_moneyflow_v2'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'scan.startup.mode'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'group-offsets'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token comment" style="color:rgb(106, 153, 85)">--'scan.startup.mode' = 'earliest-offset',</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.isolation.level'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'read_committed'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'format'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'json'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'json.ignore-parse-errors'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'false'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> kafka_out_money</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> string </span><span class="token operator" style="color:rgb(212, 212, 212)">not</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'日期'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">vroleid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'角色ID'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">moneytype</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'货币类型'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">env</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> string </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'游戏环境 hdf  /qc/cbt/obt/prod'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">hostname</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> string </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'日志所在游戏服务器'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">uuid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain">  string </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'filebeat 采集生成的uuid'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">filebeat_ts</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> string </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'filebeat采集时间'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   flink_ts string </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'flink写入的消息时间'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">gamesvrid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain">  </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'登录游戏服务器编号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">dteventtime</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> string </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'游戏事件的时间, 格式 YYYY-MM-DD HH:MM:SS'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">vgameappid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> string </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'游戏APPID'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">platid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ios 0 /android 1'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">izoneareaid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'针对分区分服的游戏填写分区id，用来唯一标示一个区；非分区分服游戏请填写0'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">vopenid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> string </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'用户OPENID号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">vrolename</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> string </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'角色姓名'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">jobid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain">  </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'角色职业   0=巫师 1=……'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">gender</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'角色性别 0=男  1=女'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ilevel</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'角色基础等级'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ijoblevel</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'角色职业等级'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">playerfriendsnum</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'玩家好友数量'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">chargegold</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'角色充值经历（累计充值）'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">iviplevel</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'角色VIP等级'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">createtime</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> string </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'账号创建时间'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">irolece</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'战力/评分'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">unionid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'公会ID'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">unionname</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain">  string </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'公会名称'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">regchannel</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'注册渠道'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">loginchannel</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'登录渠道'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">sequence</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'用于关联一次动作产生多条不同类型的货币流动日志'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">reason</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'行为（货币流动一级原因）'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">subreason</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'流向（物品流向定义）'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">imoney</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'货币变更数量'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">aftermoney</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'动作后的金钱数'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">afterboundmoney</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'动作后的绑定金钱数'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">addorreduce</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'增加或减少: 0是增加; 1是减少'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">serialnum</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> string </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'流水号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">sourceid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'渠道号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">cmd</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> string </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'命令字'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">orderid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> string </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'订单id(包含喵果增加和喵果减少，也包含现金充值订单id)'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">imoneytype</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'货币类型2'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">distincid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> string </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'访客ID'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">deviceuid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> string </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'设备ID'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">guildjob</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'公会职位'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">regtime</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> string </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'账号注册时间'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   </span><span class="token string" style="color:rgb(206, 145, 120)">'connector'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'doris'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'jdbc-url'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'jdbc:mysql://xxx:9030,xxx:9030,xxx:9030'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'load-url'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'xx:8030;xxx:8030;xxx:8030'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'database-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ro_sea'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'table-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'dwd_moneyflow_log'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'username'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'root'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'password'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'root123'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'sink.semantic'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'exactly-once'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">create</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">view</span><span class="token plain"> kafka_out_money_view1  </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">select</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">IF</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">to_date</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">2</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">CURRENT_DATE</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">+</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">interval</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'1'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">day</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token keyword" style="color:rgb(86, 156, 214)">CURRENT_DATE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">to_date</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">2</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">env</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">hostname</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> hostname</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">uuid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">1</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> gamesvrid               </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">2</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> dteventtime             </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">3</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> vgameappid              </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">4</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> platid                  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">5</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> izoneareaid             </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">6</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> vopenid                 </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">7</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> vroleid                 </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">8</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> vrolename               </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">9</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> jobid                   </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">10</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> gender                  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">11</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> ilevel                  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">12</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> ijoblevel               </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">13</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> playerfriendsnum        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">14</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> chargegold              </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">15</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> iviplevel               </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">16</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> createtime              </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">17</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> irolece                 </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">18</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> unionid                 </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">19</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> unionname               </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">20</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> regchannel              </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">21</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> loginchannel            </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">22</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">sequence</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain">                </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">23</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">reason</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain">                 </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">24</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> subreason               </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">25</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> moneytype               </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">26</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> imoney                  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">27</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> aftermoney              </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">28</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> afterboundmoney         </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">29</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> addorreduce             </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">30</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> serialnum               </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">31</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> sourceid                </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">32</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">cmd</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain">                    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">33</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> orderid                 </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">34</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> imoneytype              </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">35</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> distincid               </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">36</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> deviceuid               </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        try_cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">37</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> guildjob                </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">                                  </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        SPLIT_INDEX</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'|'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token number" style="color:rgb(181, 206, 168)">38</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> regtime </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      filebeat_ts</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token keyword" style="color:rgb(86, 156, 214)">CURRENT_TIMESTAMP</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> flink_ts</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">from</span><span class="token plain"> kafka_in_money</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">insert</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">into</span><span class="token plain"> kafka_out_money</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">select</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">vroleid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">moneytype</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">env</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">hostname</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">uuid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">filebeat_ts</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">flink_ts</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> flink_ts</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">gamesvrid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">dteventtime</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">vgameappid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">platid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">izoneareaid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">vopenid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">vrolename</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">jobid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">gender</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ilevel</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ijoblevel</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">playerfriendsnum</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">chargegold</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">iviplevel</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">createtime</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">irolece</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">unionid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">unionname</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">regchannel</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">loginchannel</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">sequence</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">reason</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">subreason</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">imoney</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">aftermoney</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">afterboundmoney</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">addorreduce</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">serialnum</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">sourceid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">cmd</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">orderid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">imoneytype</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">distincid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">deviceuid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">guildjob</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">regtime</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">from</span><span class="token plain"> kafka_out_money_view1</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>【广告系统】：使用 Flink SQL 将一行日志数据进行切分解析出各个字段的数据并完成业务计算:</strong></p>
<div class="language-sql codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-sql codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">IF</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">EXISTS</span><span class="token plain"> ods_adjust_in </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  log STRING</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'connector'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'kafka'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'topic'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ad_adjust_callback'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.bootstrap.servers'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'emr_kafka1:9092,emr_kafka2:9092,emr_kafka3:9092'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.group.id'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ods_adjust_etl_20231011'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.max.partition.fetch.bytes'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'4048576'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'scan.startup.mode'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'group-offsets'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.isolation.level'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'read_committed'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'format'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'raw'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">IF</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">EXISTS</span><span class="token plain"> ods_af_in </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  log STRING</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'connector'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'kafka'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'topic'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ad_af_callback'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.bootstrap.servers'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'emr_kafka1:9092,emr_kafka2:9092,emr_kafka3:9092'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.max.partition.fetch.bytes'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'4048576'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.group.id'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ods_af_etl_20231011'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'scan.startup.mode'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'group-offsets'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.isolation.level'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'read_committed'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'format'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'raw'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">IF</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">EXISTS</span><span class="token plain"> ods_mmp_out </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">DATE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">mmp_type</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">app_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">event_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">event_time</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">3</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">mmp_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">distinct_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">open_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">account_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">os_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">-- platform</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">country_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">install_time</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">3</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">bundle_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">media</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">channel</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">campaign</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">campaign_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">adgroup</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">adgroup_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ad</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ad_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">flink_ts</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">3</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">comment</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'flink处理的消息时间'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">device_properties</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">log</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'connector'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'kafka'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'topic'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ods_mmp_log'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.bootstrap.servers'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'emr_kafka1:9092,emr_kafka2:9092,emr_kafka3:9092'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'scan.topic-partition-discovery.interval'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'60000'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'properties.group.id'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'mmp2etl-out'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">'format'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'json'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">INTO</span><span class="token plain"> ods_mmp_out</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SELECT</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'Adjust'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">mmp_type</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">app_token</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">app_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">event_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">event_time</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">adid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">mmp_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">distinct_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">open_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">account_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">os_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">country_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">install_time</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">''</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">bundle_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">''</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">media</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">network</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">channel</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">campaign</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">REGEXP_EXTRACT</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">campaign</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'([\\(=])([a-z0-9]+)'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(181, 206, 168)">2</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">campaign_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">adgroup</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">REGEXP_EXTRACT</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">adgroup</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'([\\(=])([a-z0-9]+)'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(181, 206, 168)">2</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">adgroup_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">creative</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ad</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">REGEXP_EXTRACT</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">creative</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'([\\(=])([a-z0-9]+)'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(181, 206, 168)">2</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ad_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">flink_ts</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">device_properties</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">log</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">FROM</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">SELECT</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">     to_date</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">FROM_UNIXTIME</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.created_at'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">bigint</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.app_token'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">app_token</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.adid'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">adid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">REPLACE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"> TRIM</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COALESCE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.event_name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.activity_kind'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">' '</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'_'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">event_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">TO_TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">FROM_UNIXTIME</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.created_at'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">bigint</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">event_time</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">TO_TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">FROM_UNIXTIME</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.installed_at'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">bigint</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">install_time</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">CASE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WHEN</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.network_name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Unattributed'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">THEN</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COALESCE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.fb_install_referrer_publisher_platform'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'facebook'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">ELSE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.network_name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">END</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">network</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">CASE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WHEN</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.network_name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Unattributed'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">THEN</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">concat</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.fb_install_referrer_campaign_group_name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'('</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.fb_install_referrer_campaign_group_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">')'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">ELSE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.campaign_name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">END</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">campaign</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">CASE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WHEN</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.network_name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Unattributed'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">THEN</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">concat</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.fb_install_referrer_campaign_name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'('</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.fb_install_referrer_campaign_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">')'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">ELSE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.adgroup_name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">END</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">adgroup</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">CASE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WHEN</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.network_name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Unattributed'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">THEN</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">concat</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.fb_install_referrer_adgroup_name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'('</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.fb_install_referrer_adgroup_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">')'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">ELSE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.creative_name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">END</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">creative</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.os_name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">os_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.country_code'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">country_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.publisher_parameters'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'$.ta_distinct_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">distinct_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.publisher_parameters'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'$.open_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">open_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.publisher_parameters'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'$.ta_account_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">account_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token keyword" style="color:rgb(86, 156, 214)">CURRENT_TIMESTAMP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">flink_ts</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">JSON_OBJECT</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">       </span><span class="token string" style="color:rgb(206, 145, 120)">'ip'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.ip'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'ua'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.ua'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'idfa'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.idfa'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'idfv'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.idfv'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'gps_adid'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.gps_adid'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'android_id'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.android_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'mac_md5'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.mac_md5'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'oaid'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.oaid'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'gclid'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.gclid'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'gbraid'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.gbraid'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'dcp_wbraid'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.dcp_wbraid'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">device_properties</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">log</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">FROM</span><span class="token plain"> ods_adjust_in </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">WHERE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COALESCE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.activity_kind'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.event_name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">not</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">in</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token string" style="color:rgb(206, 145, 120)">'impression'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'click'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">UNION</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">ALL</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SELECT</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  to_date</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">CONVERT_TZ</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.event_time'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'UTC'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Asia/Shanghai'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'AppsFlyer'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">mmp_type</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.app_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">app_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">REPLACE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"> TRIM</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.event_name'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">' '</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'-'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">event_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">TO_TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">CONVERT_TZ</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.event_time'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'UTC'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Asia/Shanghai'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">event_time</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.appsflyer_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">mmp_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.custom_data'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'$.ta_distinct_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">distinct_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.custom_data'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'$.open_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">open_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.custom_data'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'$.ta_account_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">account_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.platform'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">os_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.country_code'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">country_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">TO_TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">CONVERT_TZ</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.install_time'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'UTC'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Asia/Shanghai'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">install_time</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.bundle_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">bundle_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.media_source'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">media</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.af_channel'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">channel</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">CONCAT</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.campaign'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">' ('</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.af_c_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">')'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">campaign</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.af_c_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">campaign_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">CONCAT</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.af_adset'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">' ('</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.af_adset_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">')'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">adgroup</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.af_adset_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">adgroup_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">CONCAT</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.af_ad'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">' ('</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.af_ad_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">')'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ad</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">LOWER</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.af_ad_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ad_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token keyword" style="color:rgb(86, 156, 214)">CURRENT_TIMESTAMP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">flink_ts</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">JSON_OBJECT</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">     </span><span class="token string" style="color:rgb(206, 145, 120)">'ip'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.ip'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'ua'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.user_agent'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'idfa'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.idfa'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'idfv'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.idfv'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'gps_adid'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.advertising_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'android_id'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.android_id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'oaid'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">VALUE</span><span class="token plain"> JSON_VALUE</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token string" style="color:rgb(206, 145, 120)">'$.oaid'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">device_properties</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">log</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">FROM</span><span class="token plain"> ods_af_in</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>数据上报</strong>：类似于神策</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/data_reporting-92cd1a36c4317a3bf33835a6df917c6d.png" width="976" height="325" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="6--落地实践---腾讯云环境篇"><strong>6.  落地实践 - 腾讯云环境篇</strong><a class="hash-link" aria-label="6--落地实践---腾讯云环境篇的直接链接" title="6--落地实践---腾讯云环境篇的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#6--%E8%90%BD%E5%9C%B0%E5%AE%9E%E8%B7%B5---%E8%85%BE%E8%AE%AF%E4%BA%91%E7%8E%AF%E5%A2%83%E7%AF%87">​</a></h2>
<p>本文的 Flink 任务是运行在腾讯的 kubernetes 环境，其中包括一些相关的知识点，这里就不再详述了，例如：</p>
<ul>
<li>
<p><strong>镜像同步</strong>：harbor 配置自动同步镜像到腾讯云镜像服务 TCR 中。</p>
</li>
<li>
<p><strong>镜像配置</strong>：如免密拉取、缓存加速。</p>
</li>
<li>
<p><strong>Flink webui 外网访问</strong>：需要从外网lb购买以便于访问 Flink UI。</p>
</li>
<li>
<p><strong>环境打通</strong>：因为 kubernetes 集群主要是一个偏封闭的内网计算环境、与各系统网络、安全组、权限、路由等都需要很好的配置和测试，才能让任务真正比较好的跑在该生产环境。</p>
</li>
<li>
<p><strong>安全组配置</strong>：为了实现海外游戏实时数据的拉取处理和写入国内 Kafka 集群，确保数据流程的平稳，我们使用专线并且通过给 kubernetes Flink超级节点开通专线外网访问权来实现。</p>
</li>
</ul>
<p><strong>相关截图</strong>：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/cloud_environment-b4dd173f9edbb32b1af136e9474bf494.png" width="1080" height="315" class="img_iwx1"></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/instance_management-90be7742bb44cdf79195444a45a79126.png" width="1080" height="490" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="7--收益与期望"><strong>7.  收益与期望</strong><a class="hash-link" aria-label="7--收益与期望的直接链接" title="7--收益与期望的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joymaker#7--%E6%94%B6%E7%9B%8A%E4%B8%8E%E6%9C%9F%E6%9C%9B">​</a></h2>
<p><strong>使用 Apache StreamPark 之后，给我们最大的感受就是 StreamPark 用起来十分地简单，通过简单的配置就能很快地把 Flink 任务部署到任意的集群，且可以实时的去监控并管理成千上万的作业，十分的 nice！收益如下：</strong></p>
<ul>
<li>
<p>大量的实时任务通过 StreamPark 很快速地就迁移到了 Kubernetes，下掉 YARN 后，早期混部的 Apache Doris 集群没有资源争抢后，变得十分稳定。</p>
</li>
<li>
<p>补数据时，可快速借用 TKE 中超级节点的能力，通过 StreamPark 平台，很容易进行上千个 pod 的一分钟弹缩，补数特别高效。</p>
</li>
<li>
<p>技术栈变得更加先进和统一。大数据时代的一堆组件，变的越来越高效和统一。目前欢乐大数据已经完成了 Doris、Flink、Spark、Hive、Grafana、Prometheus 等一系列组件的 Kubernetes 云原生化，运维起来更加简单和高效，StreamPark 在 Flink 容器化进程中起到了很大的作用。</p>
</li>
<li>
<p>StreamPark 平台操作简单、功能完备、性能稳定、社区响应积极，真正让流处理作业开发越来越简单，为我们带来了很多便利，让我们更加专注于业务，点赞~</p>
</li>
</ul>
<p>在这里，我们也期望 StreamPark 能做得越来越好，这里提出了一些优化的建议：</p>
<ul>
<li>
<p><strong>支持 Operator 部署</strong>：期望 Flink on kubernetes 支持 operator 部署方式，因为其可以自定义资源类型、指定调用顺序、监控指标等等好处。</p>
</li>
<li>
<p><strong>支持 autoscaler</strong>：因为实时流任务有业务高峰和波谷、特别周么活动、数据量翻倍、人为周期性调整并行度不是很合适。故结合 Kubernetes、期待 StreamPark 早日完成 operator 方式创建 Flink 集群、在 Flink 1.17以上、就可以比较好的设置阈值、利用自动弹缩、实现高峰期弹更多资源处理数据、低谷期收缩资源节约成本、非常期待。</p>
</li>
<li>
<p><strong>程序报错逻辑</strong>：当前 Flink 任务设置了固定次数或者比率重试，但当前 StreamPark 邮件告警特别频繁、不是期待的任务失败一次进行一次告警，故希望其进一步提升。</p>
</li>
</ul>
<p>最后，我们衷心地感谢 <strong>Apache StreamPark</strong> 社区在我们使用 StreamPark 时提供的无私帮助。他们专业的服务精神和以用户为本的态度，使我们得以更加高效、流畅地运用这一强大框架。期望 StreamPark 越来越好，成为新晋 Apache 项目的典范！</p>]]></content:encoded>
            <category>StreamPark</category>
            <category>生产实践</category>
        </item>
        <item>
            <title><![CDATA[联通 Flink 实时计算平台化运维实践]]></title>
            <link>https://streampark.apache.org/zh-CN/blog/streampark-usercase-chinaunion</link>
            <guid>https://streampark.apache.org/zh-CN/blog/streampark-usercase-chinaunion</guid>
            <pubDate>Mon, 09 Feb 2026 02:32:43 GMT</pubDate>
            <description><![CDATA[摘要：本文整理自联通数科实时计算团队负责人、Apache StreamPark Committer 穆纯进在 Flink Forward Asia 2022 平台建设专场的分享，本篇内容主要分为四个部分：]]></description>
            <content:encoded><![CDATA[<p>**摘要：**本文整理自联通数科实时计算团队负责人、Apache StreamPark Committer 穆纯进在 Flink Forward Asia 2022 平台建设专场的分享，本篇内容主要分为四个部分：</p>
<ul>
<li>实时计算平台背景介绍</li>
<li>Flink 实时作业运维挑战</li>
<li>基于 StreamPark 一体化管理</li>
<li>未来规划与演进</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="实时计算平台背景介绍"><strong>实时计算平台背景介绍</strong><a class="hash-link" aria-label="实时计算平台背景介绍的直接链接" title="实时计算平台背景介绍的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-chinaunion#%E5%AE%9E%E6%97%B6%E8%AE%A1%E7%AE%97%E5%B9%B3%E5%8F%B0%E8%83%8C%E6%99%AF%E4%BB%8B%E7%BB%8D">​</a></h2>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/overall_architecture-efc4272dcb2fcdadac42d40cf1a6a931.png" width="1080" height="597" class="img_iwx1"></p>
<p>上图是实时计算平台的整体架构，最底层是数据源，由于一些敏感信息，没有将数据源的详细信息列出，它主要包含三部分，分别是业务数据库、用户行为日志、用户位置，联通的数据源非常多，业务数据库这一项就有几万张表；主要通过 Flink SQL 和 DataStream API 来处理数据 ，数据处理流程包括 Flink 对数据源的实时解析、规则的实时计算以及实时产品；用户在可视化订阅平台上进行实时数据订阅，用户可以在地图上画一个电子围栏，并设置一些规则，如来自于哪里，在围栏里驻留多长时间等，还可以筛选一些特征，符合这些规则的用户信息会实时进行推送，然后是实时安全部分，当某个用户连接了高危基站或是有异常操作行为时，我们会认为可能存在诈骗行为，会对手机号码进行关停等等，还有用户的一些实时特征以及实时大屏。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/data_processing_processes-6b611077be80fd421d883accd5acb423.png" width="1080" height="593" class="img_iwx1"></p>
<p>上图是数据处理的详细的流程。</p>
<p>第一部分是采集解析，我们的数据源来自于业务的数据库，包含 OGG 和 DTS 格式的消息、日志消息、用户行为和用户位置数据，总共 50 多种数据源，后续还会逐渐增加，所有数据源均使用 Flink 做实时解析；并增加了 Metrics 来监控数据源的延迟情况。</p>
<p>第二部分是实时计算，这个环节处理的数据量很大，数据量在万亿级别，支撑了 10000+的数据实时订阅，有 200 多个 Flink 任务，我们将某一种同类型的业务封装成一种场景，同一个 Flink 作业可以支持相同场景的多个订阅，目前 Flink 作业数还在不停的增长，后续可能会增加到 500 多个；其中面临的一个很大挑战是每天万亿级的数据实时关联电子围栏、用户特征等信息，电子围栏有几万个，用户特征涉及数亿用户，最初我们将电子围栏信息和用户特征放到 HBase，但这样会导致 HBase 压力很大，经常遇到性能问题造成数据延迟，而且一旦产生数据积压，需要很长的时间去消化，得益于 Flink State 的强大，我们将电子围栏信息和用户特征放到状态里，目前已经很好的支撑了大并发的场景，同时我们也增加了数据处理的性能监控；最后是实时产品和营销触达前端的一些应用。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/platform_evolution-9d3427a9bb13529e6a6540f6a77e152b.png" width="1080" height="483" class="img_iwx1"></p>
<p>2018 年采用了三方黑盒的计算引擎，不能支持灵活定制个性化功能，且依赖过多外部系统，导致外部系统负载高，运维复杂；2019 年使用了 Spark Streaming 的微批处理，2020 年开始使用 Flink 的流式计算，从 2021 年开始，几乎所有 Spark Streaming 的微批处理都被 Flink 替代了，同时上线了 Apache StreamPark 对我们的 Flink 作业进行管理。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/platform_background-e591fd5ed3391480217c668f70519d28.png" width="1080" height="493" class="img_iwx1"></p>
<p>总结一下平台背景，主要包含以下几部分：</p>
<ul>
<li>数据量大：日均万亿的数据处理。</li>
<li>数据源多：集成了 50 多种实时数据源。</li>
<li>订阅多：支撑了 10000+的数据服务订阅。</li>
<li>用户多：支撑了 30 多个内部和外部用户使用。</li>
</ul>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/operational_background-dd9ae29be9c5d959a649bb9dd8f7a1dc.png" width="1080" height="562" class="img_iwx1"></p>
<p>运维背景也可以分为以下几部分：</p>
<ul>
<li>支撑需求多：50 多种数据源，10000+的数据服务订阅。</li>
<li>实时作业多：现在有 200+Flink 生产作业，并且持续快速增长中，未来可达 500+。</li>
<li>上线频率高：每天都有新增的或增强的 Flink 作业上线操作。</li>
<li>开发人员多：50+研发人员参与开发 Flink 实时计算任务。</li>
<li>使用用户多：30+内部和外部组织的用户使用。</li>
<li>监控延迟低：一旦发现问题我们要立马进行处理，避免引起用户的投诉。</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="flink-实时作业运维挑战"><strong>Flink 实时作业运维挑战</strong><a class="hash-link" aria-label="flink-实时作业运维挑战的直接链接" title="flink-实时作业运维挑战的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-chinaunion#flink-%E5%AE%9E%E6%97%B6%E4%BD%9C%E4%B8%9A%E8%BF%90%E7%BB%B4%E6%8C%91%E6%88%98">​</a></h2>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/difficulties-81db2f256a9e39ae8c9ba9730aa37585.png" width="1080" height="481" class="img_iwx1"></p>
<p>基于平台和运维背景，尤其是 Flink 作业越来越多的情况下，遇到了很大的挑战，主要有两方面，分别是作业运维困境和业务支撑困境。</p>
<p>在作业运维困境上，首先作业部署流程长、效率低；在联通安全是第一红线下，在服务器上部署程序的时候，要连接 VPN、登录 4A、打包编译、部署、然后再启动，整个流程比较长，最初在开发 Flink 的时候，都是用脚本启动的，导致代码分支是不可控的，部署完之后也难以追溯，再就是脚本很难与 git 上的代码进行同步，因为对于脚本代码，开发人员更喜欢在服务器上直接改，很容易忘记上传 git。</p>
<p>由于作业运维困境上的种种因素，会产生业务支撑困境，如导致上线故障率高、影响数据质量、上线时间长、数据延迟高、告警漏发处理等，引起的投诉，此外，我们的业务影响不明确，一旦出现问题，处理问题会成为第一优先级。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="基于-apache-streampark-一体化管理"><strong>基于 Apache StreamPark™ 一体化管理</strong><a class="hash-link" aria-label="基于-apache-streampark-一体化管理的直接链接" title="基于-apache-streampark-一体化管理的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-chinaunion#%E5%9F%BA%E4%BA%8E-apache-streampark-%E4%B8%80%E4%BD%93%E5%8C%96%E7%AE%A1%E7%90%86">​</a></h2>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/job_management-57ac8eebee7ab32d4d55008faade15ff.png" width="1080" height="510" class="img_iwx1"></p>
<p>对于以上的两种困境，我们基于 StreamPark 一体化管理解决了很多问题，首先来看一下 StreamPark 的双线演进，分别是 Flink 作业管理和 Flink 作业 DevOps 平台；在作业管理上，StreamPark 支持将 Flink 实时作业部署到不同的集群里去，比如 Flink 原生自带的 Standalone 模式，Flink on Yarn 的 Session、Application、PerJob 模式，在最新的版本中将支持 Kubernetes Native Session 模式；中间层是项目管理、作业管理、集群管理、团队管理、变量管理、告警管理。</p>
<ul>
<li>项目管理：当部署 Flink 程序的时候，可以在项目管理里填写 git 地址，同时选择要部署的分支。</li>
<li>作业管理：可以指定 Flink 作业的执行模式，比如你要提交到什么类型的集群里去，同时还可以配置一些资源，比如 TaskManager 的数量、TaskManager/JobManager 的内存大小、并行度等等，还可以设置一些容错，比如 Flink 作业失败后，StreamPark 可以支持它自动拉起，同时支持传入一些动态参数。</li>
<li>集群管理：可以在界面上添加和管理大数据集群。</li>
<li>团队管理：在企业的实际生产过程中会有多个团队，团队之间是隔离的。</li>
<li>变量管理：可以把一些变量统一维护在一个地方，比如 Kafka 的 Broker 地址定义成一个变量，在配置 Flink 作业或者 SQL 的时候，就可以以变量的方式来替换 Broker 的 IP，且后续这个 Kafka 要下线的时候，也可以通过这个变量去查看到底哪些作业使用了这个集群，方便我们去做一些后续的流程。</li>
<li>告警管理：支持多种告警模式，如微信、钉钉、短信和邮件。</li>
</ul>
<p>StreamPark 支持 Flink SQL、Flink Jar 的提交，支持资源配置，支持状态跟踪，如状态是运行状态，失败状态等，同时支持指标大屏和各种日志查看。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/devops_platform-97e53d17c155a4d98431a1ab52a7bd13.png" width="1080" height="501" class="img_iwx1"></p>
<p>Flink 作业 DevOps 平台，主要包括以下几部分：</p>
<ul>
<li>团队：StreamPark 支持多个团队，每个团队都有团队的管理员，他拥有所有权限，同时还有团队的开发者，他只有少量的一部分权限。</li>
<li>编译、打包：在创建 Flink 项目时，可以把 git 地址、分支、打包的命令等配置在项目里，然后一键点击 build 按钮进行编译、打包。</li>
<li>发布、部署：发布和部署的时候会创建 Flink 作业，在 Flink 作业里可以选择执行模式、部署集群、资源设置、容错设置、变量填充，最后通过一键启动停止，启动 Flink 作业。</li>
<li>状态监测：Flink 作业启动完成之后，就是状态的实时跟踪，包括 Flink 的运行状态、运行时长、Checkpoint 信息等，并支持一键跳转到 Flink 的 Web UI。</li>
<li>日志、告警：包含构建的一些日志和启动日志，同时支持钉钉、微信、邮件、短信等告警方式。</li>
</ul>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/multi_team_support-ea9b19ef43d528e9be9016efa65f80fc.png" width="1080" height="477" class="img_iwx1"></p>
<p>企业一般有多个团队同时开发实时作业，在我们公司包含实时采集团队、数据处理团队和实时的营销团队，StreamPark 支持多个团队的资源隔离。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/platformized_management-f3f784103707c8e3b67a3bcdda5a3dd6.png" width="1080" height="600" class="img_iwx1"></p>
<p>Flink 作业平台化管理面临如下挑战：</p>
<ul>
<li>脚本数量多：平台有几百个脚本，分散在多个服务器上。</li>
<li>脚本类型多：在启动 Flink 作业时，会有启动脚本、停止脚本和守护脚本，而且操作权限很难控制。</li>
<li>脚本不一致：服务器上的脚本与 git 上的脚本不一致。</li>
<li>脚本确权难：Flink 作业的责任人，用途不明确。</li>
<li>分支不可控：启动作业的时候，需要在脚本里指定 git 分支，导致分支不可追溯的。</li>
</ul>
<p>基于以上的挑战，StreamPark 通过项目管理来解决了责任人不明确，分支不可追溯的问题，因为在创建项目的时候需要手动指定一些分支，一旦打包成功，这些分支是有记录的；通过作业管理对配置进行了集中化，避免了脚本太过于分散，而且作业启动、停止的权限有严格的控制，避免了脚本化权限不可控的状态，StreamPark 以接口的方式与集群进行交互来获取作业信息，这样做会让作业控制更加精细。</p>
<p>可以看一下上图中下面的图，通过项目管理进行打包，通过作业管理进行配置，然后发布，可以进行一键启停，通过 API 提交作业。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/development_efficiency-2b27930ac18721c40acb006c03806e69.png" width="1080" height="591" class="img_iwx1"></p>
<p>早期我们需要通过 7 步进行部署，包括连接 VPN、登录 4A、执行编译脚本、执行启动脚本、打开 Yarn、搜索作业名、进入 Flink UI 等 7 个步骤，StreamPark 可以支持 4 个一键进行部署，包括一键打包、一键发布、一键启动、一键到 Flink UI。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/submission_process-bb3efd39e3f2e76595995647327be75a.png" width="1080" height="548" class="img_iwx1"></p>
<p>上图是我们 StreamPark 的作业提交流程，首先 StreamPark 会将作业进行发布，发布的时候会上传一些资源，然后会进行作业的提交，提交的时候会带上配置的一些参数，以 Flink Submit 的方式调用接口发布到集群上；这里会有多个 Flink Submit 对应着不同的执行模式，比如 Yarn Session、Yarn Application、Kubernetes Session、Kubernetes Application 等都是在这里控制的，提交作业之后，如果是 Flink on Yarn 作业，会得到这个 Flink 作业的 Application ID 或者 Job ID，这个 ID 会保存在我们的数据库中，如果是基于 Kubernetes 执行的话，也会得到 Job ID，后面我们在跟踪作业状态的时候，主要就是通过保存的这些 ID 去跟踪作业的状态。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/status_acquisition_bottleneck-436fee79261994fd26eda735d2833e70.png" width="1080" height="599" class="img_iwx1"></p>
<p>如上所述，如果是 Flink on Yarn 作业，在提交作业的时候会获取两个 ID，Application ID 或者 Job ID，基于这两个 ID 可以获取我们的状态，但当 Flink 作业非常多的时候会遇到一些问题，StreamPark 它是有一个状态获取器，它会通过我们保存的数据库里的 Application ID 或者 Job ID，去向 ResourceManager 做一个请求，会做每五秒钟周期性的轮询，如果作业特别多，每次轮询 ResourceManager 会负责再去调用 Job Manager 的地址访问它的状态，这就会导致 ResourceManager 的连接数压力较大和连接数过高。</p>
<p>上图中 ResourceManager 的连接数阶段性、周期性的持续走高，可以看到 ResourceManager 处于比较红的状态，从主机上去监控的时候，它的连接数确实比较高。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/state_optimization-06c675fa387cb316cc225fb0b1576451.png" width="1080" height="596" class="img_iwx1"></p>
<p>针对上面的问题，我们做了一些优化，首先 StreamPark 保存了提交作业之后的 Application ID 或者 Job ID，同时也会获取 Job Manager 直接访问的地址，并保存在数据库中，每次轮询时不再通过 ResourceManager 获取作业的状态，它可以直接调用各个 Job Manager 的地址实时获取状态，极大的降低了 ResourceManager 的连接数；从上图最后的部分可以看到，基本不会产生太大的连接数，大大减轻了 ResourceManager 的压力，且后续当 Flink 作业越来越多时获取状态也不会遇到瓶颈的问题。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/state_recovery-7d0a5ecaf3c3af7ffe33f85abf3d51a8.png" width="1080" height="573" class="img_iwx1"></p>
<p>StreamPark 解决的另一个问题是 Flink 从状态恢复的保障，以前我们用脚本做运维的时候，在启动 Flink 的时候，尤其是在业务升级的时候，要从上一个最新的 Checkpoint 来恢复，但经常有开发人员忘记从上一个检查点进行恢复，导致数据质量产生很大的问题，遭到投诉，StreamPark 的流程是在首次启动的时候，每五秒钟轮询一次获取 Checkpoint 的记录，同时保存在数据库之中，在 StreamPark 上手动停止 Flink 作业的时候，可以选择做不做 Savepoint，如果选择了做 Savepoint，会将 Savepoint 的路径保存在数据库中，同时每次的 Checkpoint 记录也保存在数据库中，当下次启动 Flink 作业的时候，默认会选择最新的 Checkpoint 或者 Savepoint 记录，有效避免了无法从上一个检查点去恢复的问题，也避免了导致问题后要进行 offset 回拨重跑作业造成的资源浪费，同时也保证了数据处理的一致性。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/multiple_environments_and_components-85e9f3f218c9c5ef79d3792aec9540ac.png" width="1080" height="576" class="img_iwx1"></p>
<p>StreamPark 还解决了在多环境下多个组件的引用挑战，比如在企业中通常会有多套环境，如开发环境、测试环境、生产环境等，一般来说每套环境下都会有多个组件，比如 Kafka，HBase、Redis 等，而且在同一套环境里还可能会存在多个相同的组件，比如在联通的实时计算平台，从上游的 Kafka 消费数据的时候，将符合要求的数据再写到下游的 Kafka，这个时候同一套环境会涉及到两套 Kafka，单纯从 IP 很难判断是哪个环境哪个组件，所以我们将所有组件的 IP 地址都定义成一个变量，比如 Kafka 集群，开发环境、测试环境、生产环境都有 Kafka.cluster 这个变量，但它们指向的 Broker 的地址是不一样的，这样不管是在哪个环境下配置 Flink 作业，只要引用这个变量就可以了，大大降低了生产上的故障率。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/multiple_execution_modes-56bb5cc794122dd7ac987f57999afb33.png" width="1080" height="585" class="img_iwx1"></p>
<p>StreamPark 支持 Flink 多执行的模式，包括基于 on Yarn 的 Application/ Perjob / Session 三种部署模式，还支持 Kubernetes 的 Application 和 Session 两种部署模式，还有一些 Remote 的模式。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/versioning-641f09a5fcccd37dda2ed9d4cac14413.png" width="1080" height="389" class="img_iwx1"></p>
<p>StreamPark 也支持 Flink 的多版本，比如联通现在用的是 1.14.x，现在 1.16.x 出来后我们也想体验一下，但不可能把所有的作业都升级到 1.16.x，我们可以把新上线的升级到 1.16.x，这样可以很好的满足使用新版本的要求，同时也兼容老版本。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="未来规划与演进"><strong>未来规划与演进</strong><a class="hash-link" aria-label="未来规划与演进的直接链接" title="未来规划与演进的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-chinaunion#%E6%9C%AA%E6%9D%A5%E8%A7%84%E5%88%92%E4%B8%8E%E6%BC%94%E8%BF%9B">​</a></h2>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/contribution_and_enhancement-bbb20c198ecc048735b12e40157115e2.png" width="1080" height="418" class="img_iwx1"></p>
<p>未来我们将加大力度参与 StreamPark 建设，以下我们计划要增强的方向。</p>
<ul>
<li>高可用：StreamPark 目前不支持高可用，这方面还需要做一些加强。</li>
<li>状态的管理：在企业实践中 Flink 作业在上线时，每个算子会有 UID。如果 Flink UID 不做设置，做 Flink 作业的升级的时候，就有可能出现状态无法恢复的情况，目前通过平台还无法解决这个问题，所以我们想在平台上增加这个功能，在 Flink Jar 提交时，增加检测算子是否设置 UID 的功能，如果没有，会发出提醒，这样可以避免每次上线 Flink 作业时，作业无法恢复的问题；之前遇到这种情况的时候，我们需要使用状态处理的 API，从原来的状态里进行反序列化，然后再用状态处理 API 去制作新的状态，供升级后的 Flink 加载状态。</li>
<li>更细致的监控：目前支持 Flink 作业失败之后，StreamPark 发出告警。我们希望 Task 失败之后也可以发出告警，我们需要知道失败的原因；还有作业反压监控告警、Checkpoint 超时、失败告警性能指标采集，也有待加强。</li>
<li>流批一体：结合 Flink 流批一体引擎和数据湖流批一体存储探索流批一体平台。</li>
</ul>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/road_map-1a30ee719bdadf2e0ea31d6ea9e957bc.png" width="1080" height="488" class="img_iwx1"></p>
<p>上图是 StreamPark 的 Roadmap。</p>
<ul>
<li>数据源：StreamPark 会支持更多数据源的快速接入，达到数据一键入户。</li>
<li>运维中心：获取更多 Flink Metrics 进一步加强监控运维的能力。</li>
<li>K8S-operator：现有的 Flink on K8S 还是有点重，经历了打 Jar 包、打镜像、推镜像的过程，后续需要改进优化，积极拥抱上游对接的 K8S-operator。</li>
<li>流式数仓：增强对 Flink SQL 作业能力的支持，简化 Flink SQL 作业的提交，计划对接 Flink SQL Gateway；SQL 数仓方面的能力加强，包括元数据存储、统一建表语法校验、运行测试、交互式查询，积极拥抱 Flink 上游，探索实时数仓和流式数仓。</li>
</ul>]]></content:encoded>
            <category>StreamPark</category>
            <category>生产实践</category>
            <category>FlinkSQL</category>
        </item>
        <item>
            <title><![CDATA[海程邦达基于 Apache Paimon + Apache StreamPark™ 的流式数仓实践]]></title>
            <link>https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon</link>
            <guid>https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon</guid>
            <pubDate>Mon, 09 Feb 2026 02:32:43 GMT</pubDate>
            <description><![CDATA[导读：本文主要介绍作为供应链物流服务商海程邦达在数字化转型过程中采用 Paimon + StreamPark 平台实现流式数仓的落地方案。我们以 Apache StreamPark 流批一体平台提供了一个易于上手的生产操作手册，以帮助用户提交 Flink 任务并迅速掌握 Paimon 的使用方法。]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/Bondex-b9280a2451e6984d91f7747acaa10b97.png" width="1080" height="460" class="img_iwx1"></p>
<p>**导读：**本文主要介绍作为供应链物流服务商海程邦达在数字化转型过程中采用 Paimon + StreamPark 平台实现流式数仓的落地方案。我们以 Apache StreamPark 流批一体平台提供了一个易于上手的生产操作手册，以帮助用户提交 Flink 任务并迅速掌握 Paimon 的使用方法。</p>
<ul>
<li>公司业务情况介绍</li>
<li>大数据技术痛点以及选型</li>
<li>生产实践</li>
<li>问题排查分析</li>
<li>未来规划</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="01-公司业务情况介绍">01 公司业务情况介绍<a class="hash-link" aria-label="01 公司业务情况介绍的直接链接" title="01 公司业务情况介绍的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon#01-%E5%85%AC%E5%8F%B8%E4%B8%9A%E5%8A%A1%E6%83%85%E5%86%B5%E4%BB%8B%E7%BB%8D">​</a></h2>
<p>海程邦达集团一直专注于供应链物流领域，通过打造优秀的国际化物流平台，为客户提供端到端一站式智慧型供应链物流服务。集团现有员工 2000 余人，年营业额逾 120 亿人民币，网络遍及全球 200 余个港口，在海内外有超 80 家分、子公司，助力中国企业与世界互联互通。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="业务背景"><strong>业务背景</strong><a class="hash-link" aria-label="业务背景的直接链接" title="业务背景的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon#%E4%B8%9A%E5%8A%A1%E8%83%8C%E6%99%AF">​</a></h3>
<p>随着公司规模的不断扩大和业务复杂性的增加，为了更好地实现资源优化和流程改进，公司运营与流程管理部需要实时监控公司的业务运转情况，以确保业务流程的稳定性和高效性。</p>
<p>公司运营与流程管理部负责监督公司各类业务流程的执行，包括海运、空运、铁运各个大区和事业部的订单量，大客户的订单量，航线订单量，关务、仓储、陆运各个操作站点的委托量，公司当天各个大区和事业部实际收入和支出情况等。通过对这些流程的监控和分析，公司能够识别出潜在的问题和瓶颈，提出改进措施和建议，以优化公司运营效率。</p>
<p><strong>实时数仓架构：</strong></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/realtime_warehouse-418beb6d713966065d731eb8417b8a6e.png" width="1080" height="447" class="img_iwx1"></p>
<p>当前系统要求直接从生产系统收集实时数据，但存在多个数据源需要进行关联查询，而帆软报表在处理多个数据源时展示不够友好，且无法再次聚合多个数据源。定时查询生产系统会给生产系统数据库带来压力，影响生产系统的稳定运行。因此，我们需要引入一个可以通过 <a href="https://github.com/ververica/flink-cdc-connectors" target="_blank" rel="noopener noreferrer">Flink CDC</a> 技术实现流式处理的数仓，以解决实时数据处理的问题。这个数仓需要能够从多个数据源收集实时数据并在此基础上实现复杂的关联 SQL 查询、机器学习等操作，并且可以避免不定时查询生产系统，从而减轻生产系统的压力，保障生产系统的稳定运行。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="02-大数据技术痛点以及选型">02 大数据技术痛点以及选型<a class="hash-link" aria-label="02 大数据技术痛点以及选型的直接链接" title="02 大数据技术痛点以及选型的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon#02-%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%8A%80%E6%9C%AF%E7%97%9B%E7%82%B9%E4%BB%A5%E5%8F%8A%E9%80%89%E5%9E%8B">​</a></h2>
<p>海程邦达大数据团队建立以来一直以高效运维工具或平台来实现对人员的高效配置，优化重复劳动，手工作业。</p>
<p>在离线批数处理已能够支持集团基础驾驶舱和管理报表的情况下，集团运管部门提出了业务要实时统计订单数量，操作单量的需求，财务部门有现金流实时展示的需求，在这样的背景下，基于大数据的流批一体方案势在必行。</p>
<p>虽然大数据部门已经使用了 <a href="https://github.com/apache/doris" target="_blank" rel="noopener noreferrer">Apache Doris</a> 来实现湖仓一体的存储和计算，此前已在 Doris 社区发表湖仓一体建设的文章，但是有些问题有待解决，流式数据存储无法复用、中间层数据不可查、做不到实时聚合计算问题。</p>
<p>按照架构演进时间排序，近几年通用的架构解决方案如下：</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="hadoop架构"><strong>hadoop架构</strong><a class="hash-link" aria-label="hadoop架构的直接链接" title="hadoop架构的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon#hadoop%E6%9E%B6%E6%9E%84">​</a></h3>
<p>传统数仓和互联网数仓的分界点，在互联网早期的时候，大家对于数据分析的要求也不高，主要是做实时性不高的报表、支撑决策，对应的离线数据分析方案就产生了。</p>
<p>**优点：**数据类型支持丰富，支持海量运算，机器配置要求低，时效性低，容错</p>
<p>**缺点：**不支持实时；运维复杂；查询优化器不如 MPP，响应慢</p>
<p>选型依据：不支持实时；运维复杂，不符合人员精简配置原则；性能差</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="lambda架构"><strong>lambda架构</strong><a class="hash-link" aria-label="lambda架构的直接链接" title="lambda架构的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon#lambda%E6%9E%B6%E6%9E%84">​</a></h3>
<p>Lambda 架构是由 Storm 的作者 Nathan Marz 提出的一个实时大数据处理框架。Marz 在 Twitter 工作期间开发了著名的实时大数据处理框架 <a href="https://github.com/apache/storm" target="_blank" rel="noopener noreferrer">Apache Storm</a> ，Lambda 架构是其根据多年进行分布式大数据系统的经验总结提炼而成。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/lambda-e357a7e34ced4e82971d4b86acc790b4.png" width="764" height="413" class="img_iwx1"></p>
<p>数据流处理分为 ServingLayer、SpeedLayer、BatchLayer 三层：</p>
<ul>
<li>Batch层: 对离线数据进行处理，最后提供 view 服务给到业务；</li>
<li>Speed层: 对实时增量数据进行处理，最后提供 view 服务给到业务；</li>
<li>Serving层: 响应用户的请求，实现离线和增量数据的聚合计算，并最终提供服务；</li>
</ul>
<p>优点是：离线和实时分开计算，使用两套框架，架构稳定</p>
<p>缺点是：离线和实时数据很难保持一致性，运维人员需要维护两套框架三层架构，开发人员需要写三套代码</p>
<p>选型依据：数据一致性不可控；运维、开发工作量大，不符合人员精简配置的原则；</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="kappa架构"><strong>kappa架构</strong><a class="hash-link" aria-label="kappa架构的直接链接" title="kappa架构的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon#kappa%E6%9E%B6%E6%9E%84">​</a></h3>
<p>kappa 架构只用一套数据流处理架构来解决离线和实时数据，用实时流来解决所有问题，旨在提供快速可靠的查询访问结果。它非常适合各种数据处理工作负载，包括连续数据管道、实时数据处理、机器学习模型和实时数据分析、物联网系统以及许多其他具有单一技术堆栈的用例。</p>
<p>它通常使用流处理引擎实现，例如Apache Flink、Apache Storm、Apache Kinesis、 Apache Kafka，旨在处理大量数据流并提供快速可靠的查询访问结果。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/kappa-924eb8691ece5d996d9aa740e5b79230.png" width="1080" height="281" class="img_iwx1"></p>
<p>**优点是：**单数据流处理框架</p>
<p>**缺点是：**虽然它的架构相对 lamabda 架构简单，但是流式处理框架的设置和维护相对复杂，不具备真正意义上的离线数据处理能力；流平台中存储大数据成本高昂</p>
<p>选型依据：离线数据处理能力需要保留，控制成本</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="iceberg"><strong>Iceberg</strong><a class="hash-link" aria-label="iceberg的直接链接" title="iceberg的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon#iceberg">​</a></h3>
<p>为此我们也调研了 <a href="https://github.com/apache/Iceberg" target="_blank" rel="noopener noreferrer">Apache Iceberg</a> ，它的快照功能一定程度上能够实现流批一体，但是它的问题是基于 kafka 做的实时表中间层不可查或者无法复用已经存在的表，对 kafka 有强依赖，需要利用 kafka 将中间结果写到 iceberg 表，增加了系统的复杂度和可维护性。</p>
<p>选型依据：无 kafka 实时架构已落地，中间数据无法实现可查可复用</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="流式数仓kappa架构的延续"><strong>流式数仓（kappa架构的延续)</strong><a class="hash-link" aria-label="流式数仓kappa架构的延续的直接链接" title="流式数仓kappa架构的延续的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon#%E6%B5%81%E5%BC%8F%E6%95%B0%E4%BB%93kappa%E6%9E%B6%E6%9E%84%E7%9A%84%E5%BB%B6%E7%BB%AD">​</a></h3>
<p>海程邦达大数据团队自 FTS0.3.0 版本开始参与流式数仓建设，旨在进一步降低数据处理框架的复杂度和人员的精简配置，前期的宗旨是既然是趋势就要参与进来，过程中不断学习精进，向最前沿的技术靠拢，团队一致认为有坑就踩坑，摸着石头也要过河，好在经过几个版本的迭代，在社区的高效配合下，最开始出现的问题也慢慢得以解决</p>
<p><strong>流式数仓架构如下：</strong></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/streaming_warehouse-ab83b309ef461f3907c2df023143c817.png" width="854" height="494" class="img_iwx1"></p>
<p>延续了 kappa 架构的特点，一套流处理架构，好处在与，底层 Paimon 的技术支撑使得数据在全链路可查，数仓分层架构得以复用，同时兼顾了离线和实时的处理能力，减少存储和计算的浪费</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="03-生-产-实-践">03 生 产 实 践<a class="hash-link" aria-label="03 生 产 实 践的直接链接" title="03 生 产 实 践的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon#03-%E7%94%9F-%E4%BA%A7-%E5%AE%9E-%E8%B7%B5">​</a></h2>
<p>本方案采用 Flink Application On K8s 集群，Flink CDC 实时摄取业务系统关系型数据库数据，通过 StreamPark 任务平台提交 Flink + Paimon Streaming Data Warehouse 任务， 最后采用 Trino 引擎接入 Finereport 提供服务和开发人员的查询。Paimon 底层存储支持 S3 协议，因为公司大数据服务依赖于阿里云所以使用对象存储OSS作为数据文件系统。</p>
<p><a href="https://github.com/apache/streampark" target="_blank" rel="noopener noreferrer">StreamPark</a> 是一个实时计算平台，与 <a href="https://github.com/apache/incubator-paimon" target="_blank" rel="noopener noreferrer">Paimon</a> 结合使用其强大功能来处理实时数据流。此平台提供以下主要功能：</p>
<p>**实时数据处理：**StreamPark 支持提交实时数据流任务，能够实时获取、转换、过滤和分析数据。这对于需要快速响应实时数据的应用非常重要，例如实时监控、实时推荐和实时风控等领域。</p>
<p>**可扩展性：**可以高效处理大规模实时数据，具备良好的可扩展性。可以在分布式计算环境中运行，并能够自动处理并行化、故障恢复和负载均衡等问题，以确保高效且可靠地处理数据。</p>
<p>**Flink 集成：**基于 <a href="https://github.com/apache/flink" target="_blank" rel="noopener noreferrer">Apache Flink</a> 构建，利用 Flink 的强大流处理引擎来实现高性能和鲁棒性。用户可以充分利用 Flink 的特性和生态系统，如广泛的连接器、状态管理和事件时间处理等。</p>
<p>**易用性：**提供了直观的图形界面和简化的 API，可以轻松地构建和部署数据处理任务，而无需深入了解底层技术细节。</p>
<p>通过在 StreamPark 平台上提交 Paimon 任务，我们可以建立一个全链路实时流动、可查询和分层可复用的 Pipline。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/pipline-60b68a9487092b6866020ce983a85ac0.png" width="1080" height="496" class="img_iwx1"></p>
<p>主要采用组件版本如下：</p>
<ul>
<li>flink-1.16.0-scala-2.12</li>
<li>paimon-flink-1.16-0.4-20230424.001927-40.jar</li>
<li>apache-streampark_2.12-2.0.0</li>
<li>kubernetes v1.18.3</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="环境构建"><strong>环境构建</strong><a class="hash-link" aria-label="环境构建的直接链接" title="环境构建的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon#%E7%8E%AF%E5%A2%83%E6%9E%84%E5%BB%BA">​</a></h3>
<p>下载 flink-1.16.0-scala-2.12.tar.gz 可以在 flink官网 下载对应版本的安装包到StreamPark 部署服务器</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">#解压</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">tar zxvf flink-1.16.0-scala-2.12.tar.gz</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#修改 flink-conf 配置文件并启动集群</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">jobmanager.rpc.address: localhost</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">jobmanager.rpc.port: 6123</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">jobmanager.bind-host: localhost</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">jobmanager.memory.process.size: 4096m</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">taskmanager.bind-host: localhost</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">taskmanager.host: localhost</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">taskmanager.memory.process.size: 4096m</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">taskmanager.numberOfTaskSlots: 4</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">parallelism.default: 4</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">akka.ask.timeout: 100s</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">web.timeout: 1000000</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#checkpoints&amp;&amp;savepoints</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">state.checkpoints.dir: file:///opt/flink/checkpoints</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">state.savepoints.dir: file:///opt/flink/savepoints</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">execution.checkpointing.interval: 2min</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#当作业手动取消/暂停时，将会保留作业的 Checkpoint 状态信息</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">execution.checkpointing.externalized-checkpoint-retention: RETAIN_ON_CANCELLATION</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">state.backend: rocksdb</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#已完成的CP保存个数</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">state.checkpoints.num-retained: 2000</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">state.backend.incremental: true</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">execution.checkpointing.checkpoints-after-tasks-finish.enabled: true</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#OSS</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">fs.oss.endpoint: oss-cn-zhangjiakou-internal.aliyuncs.com</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">fs.oss.accessKeyId: xxxxxxxxxxxxxxxxxxxxxxx</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">fs.oss.accessKeySecret: xxxxxxxxxxxxxxxxxxxxxxx</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">fs.oss.impl: org.apache.hadoop.fs.aliyun.oss.AliyunOSSFileSystem</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">jobmanager.execution.failover-strategy: region</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">rest.port: 8081</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">rest.address: localhost</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>建议可以在本地添加 FLINK_HOME 方便在上 k8s 之前本地排查问题使用</p>
<p>vim /etc/profile</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">#FLINK</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">export FLINK_HOME=/data/src/flink-1.16.0-scala-2.12</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">export PATH=$PATH:$FLINK_HOME/bin</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">source /etc/profile</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>在 StreamPark 添加 Flink conf:</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_conf-1c8b9773c6678621a140320ae2a8525f.jpg" width="1080" height="427" class="img_iwx1"></p>
<p>构建 Flink 1.16.0 基础镜像从 dockerhub拉取对应版本的镜像</p>
<div class="language-dockerfile codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-dockerfile codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">#拉取镜像</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">docker pull flink:1.16.0-scala_2.12-java8</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#打上 tag</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">docker tagflink:1.16.0-scala_2.12-java8  registry-vpc.cn-zhangjiakou.aliyuncs.com/xxxxx/flink:1.16.0-scala_2.12-java8</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#push 到公司仓库</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">docker pushregistry-vpc.cn-zhangjiakou.aliyuncs.com/xxxxx/flink:1.16.0-scala_2.12-java8</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>创建 Dockerfile 文件 &amp; target 目录将 flink-oss-fs-hadoop JAR包放置在该目录 Shaded Hadoop OSS file system jar 包下载地址：</p>
<p><a href="https://repository.apache.org/snapshots/org/apache/paimon/paimon-oss/" target="_blank" rel="noopener noreferrer">https://repository.apache.org/snapshots/org/apache/paimon/paimon-oss/</a></p>
<p>.</p>
<p>├── Dockerfile</p>
<p>└── target</p>
<p>└── flink-oss-fs-hadoop-1.16.0.jar</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">touch Dockerfile</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">mkdir target</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#vim Dockerfile</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">FROM registry-vpc.cn-zhangjiakou.aliyuncs.com/xxxxx/flink:1.16.0-scala_2.12-java8</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">RUN mkdir /opt/flink/plugins/oss-fs-hadoop</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">COPY target/flink-oss-fs-hadoop-1.16.0.jar  /opt/flink/plugins/oss-fs-hadoop</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="build-基础镜像"><strong>build 基础镜像</strong><a class="hash-link" aria-label="build-基础镜像的直接链接" title="build-基础镜像的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon#build-%E5%9F%BA%E7%A1%80%E9%95%9C%E5%83%8F">​</a></h3>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">docker build -t flink-table-store:v1.16.0 .</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">docker tag flink-table-store:v1.16.0 registry-vpc.cn-zhangjiakou.aliyuncs.com/xxxxx/flink-table-store:v1.16.0</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">docker push registry-vpc.cn-zhangjiakou.aliyuncs.com/xxxxx/flink-table-store:v1.16.0</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>接下来准备 Paimon jar 包，可以在 Apache <a href="https://repository.apache.org/content/groups/snapshots/org/apache/paimon" target="_blank" rel="noopener noreferrer">Repository</a> 下载对应版本，需要注意的是要和 flink 大版本保持一致</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="使用-apache-streampark-管理作业"><strong>使用 Apache StreamPark™ 管理作业</strong><a class="hash-link" aria-label="使用-apache-streampark-管理作业的直接链接" title="使用-apache-streampark-管理作业的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon#%E4%BD%BF%E7%94%A8-apache-streampark-%E7%AE%A1%E7%90%86%E4%BD%9C%E4%B8%9A">​</a></h3>
<p><strong>前提条件：</strong></p>
<ul>
<li>Kubernetes 客户端连接配置</li>
<li>Kubernetes RBAC 配置</li>
<li>容器镜像仓库配置 （案例中使用的是阿里云镜像免费版）</li>
<li>创建挂载 checkpoint/savepoint 的 pvc 资源</li>
</ul>
<p><strong>Kubernetes 客户端连接配置：</strong></p>
<p>将 k8s master节点~/.kube/config 配置直接拷贝到 StreamPark 服务器的目录，之后在 StreamPark 服务器执行以下命令显示 k8s 集群 running 代表权限和网络验证成功。</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">kubectl cluster-info</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Kubernetes RBAC 配置，创建 streampark 命名空间:</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">kubectl create ns streampark</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>使用 default 账户创建 clusterrolebinding 资源:</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">kubectl create secret docker-registry streamparksecret </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">--docker-server=registry-vpc.cn-zhangjiakou.aliyuncs.com </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">--docker-username=xxxxxx </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">--docker-password=xxxxxx -n streampark```</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>容器镜像仓库配置:</strong></p>
<p>案例中使用阿里云容器镜像服务ACR，也可以使用自建镜像服务harbor代替。</p>
<p>创建命名空间 StreamPark (安全设置需要设置为私有)</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/aliyun-43dec052b5792743675fb5a0e5980ebc.png" width="1080" height="316" class="img_iwx1"></p>
<p>在 StreamPark 配置镜像仓库，任务构建镜像会推送到镜像仓库</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/dockersystem_setting-60d5b7d9e930185cf1a9a404beab9dc0.png" width="1080" height="360" class="img_iwx1"></p>
<p>创建 k8s secret 密钥用来拉取 ACR 中的镜像 streamparksecret 为密钥名称 自定义</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">kubectl create secret docker-registry streamparksecret </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">--docker-server=registry-vpc.cn-zhangjiakou.aliyuncs.com </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">--docker-username=xxxxxx </span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">--docker-password=xxxxxx -n streampark</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>创建挂载 checkpoint/savepoint 的 pvc 资源，基于阿里云的对象存储OSS做K8S的持久化</p>
<p><strong>OSS CSI 插件：</strong></p>
<p>可以使用 OSS CSI 插件来帮助简化存储管理。您可以使用 csi 配置创建 pv，并且 pvc、pod 像往常一样定义，yaml 文件参考：
<a href="https://bondextest.oss-cn-zhangjiakou.aliyuncs.com/ossyaml.zip" target="_blank" rel="noopener noreferrer">https://bondextest.oss-cn-zhangjiakou.aliyuncs.com/ossyaml.zip</a></p>
<p><strong>配置要求：</strong></p>
<p>- 创建具有所需 RBAC 权限的服务帐户，参考：</p>
<p><a href="https://github.com/kubernetes-sigs/alibaba-cloud-csi-driver/blob/master/docs/oss.md" target="_blank" rel="noopener noreferrer">https://github.com/kubernetes-sigs/alibaba-cloud-csi-driver/blob/master/docs/oss.md</a></p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">kubectl -f rbac.yaml</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>- 部署OSS CSI 插件</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">kubectl -f oss-plugin.yaml</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>- 创建 CP&amp;SP 的 PV</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">kubectl -f checkpoints_pv.yaml kubectl -f savepoints_pv.yaml</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>- 创建 CP&amp;SP 的 PVC</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">kubectl -f checkpoints_pvc.yaml kubectl -f savepoints_pvc.yaml</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>配置好依赖环境，接下来我们就开始使用 Paimon 进行流式数仓的分层开发。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="案例"><strong>案例</strong><a class="hash-link" aria-label="案例的直接链接" title="案例的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon#%E6%A1%88%E4%BE%8B">​</a></h3>
<p>统计海运空运实时委托单量</p>
<p>任务提交：初始化 Paimon catalog 配置</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/paimon_catalog_setting-aa6a826f1cb1a7d9c90fc3fae71a0ef3.png" width="592" height="637" class="img_iwx1"></p>
<div class="language-sql codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-sql codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token keyword" style="color:rgb(86, 156, 214)">SET</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'execution.runtime-mode'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'streaming'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">set</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'table.exec.sink.upsert-materialize'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'none'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SET</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'sql-client.execution.result-mode'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'tableau'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- 创建并使用 FTS Catalog 底层存储方案采用阿里云oss</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> CATALOG </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">table_store</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'type'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'paimon'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'warehouse'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'oss://xxxxx/xxxxx'</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">#自定义oss存储路径</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">USE</span><span class="token plain"> CATALOG </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">table_store</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>一个任务同时抽取 postgres、mysql、sqlserver 三种数据库的表数据写入到 Paimon</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/application_setting-48542837b22debfeca15eddaf6ea93a0.png" width="1080" height="533" class="img_iwx1"></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/pom-949e43be1f8e611776858b7573047de2.jpg" width="1080" height="597" class="img_iwx1"></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/pod_template-4a36a24383f78f09d3090e5ddf7fe1fa.png" width="1080" height="623" class="img_iwx1"></p>
<p><strong>信息如下:</strong></p>
<div class="codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-text codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">Development Mode：Flink SQL</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">Execution Mode ：kubernetes application</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">Flink Version ：flink-1.16.0-scala-2.12</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">Kubernetes Namespace ：streampark</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">Kubernetes ClusterId ：（任务名自定义即可）</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#上传到阿里云镜像仓库的基础镜像</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">Flink Base Docker Image ：registry-vpc.cn-zhangjiakou.aliyuncs.com/xxxxx/flink-table-store:v1.16.0</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">Rest-Service Exposed Type：NodePort</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#paimon基础依赖包：</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">paimon-flink-1.16-0.4-20230424.001927-40.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">flink-shaded-hadoop-2-uber-2.8.3-10.0.jar</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">#flinkcdc依赖包下载地址：</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">https://github.com/ververica/flink-cdc-connectors/releases/tag/release-2.2.0</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>pod template:</strong></p>
<div class="language-yaml codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-yaml codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> v1</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> Pod</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> pod</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">template</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token key atrule">containers</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> flink</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">main</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">container</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token key atrule">volumeMounts</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> flink</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">checkpoints</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">csi</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">pvc</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        </span><span class="token key atrule">mountPath</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> /opt/flink/checkpoints</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> flink</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">savepoints</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">csi</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">pvc</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        </span><span class="token key atrule">mountPath</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> /opt/flink/savepoints</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token key atrule">volumes</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> flink</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">checkpoints</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">csi</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">pvc</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token key atrule">persistentVolumeClaim</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token key atrule">claimName</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> flink</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">checkpoints</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">csi</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">pvc</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> flink</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">savepoints</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">csi</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">pvc</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token key atrule">persistentVolumeClaim</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      </span><span class="token key atrule">claimName</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> flink</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">savepoints</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">csi</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">pvc</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token key atrule">imagePullSecrets</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> streamparksecret</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>Flink sql：</strong></p>
<ol>
<li>构建源表和paimon中ods表的关系，这里就是源表和目标表一对一映射</li>
</ol>
<div class="language-sql codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-sql codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token comment" style="color:rgb(106, 153, 85)">-- postgre数据库 示例</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TEMPORARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">shy_doc_hdworkdochd</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">doccode</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">not</span><span class="token plain"> </span><span class="token boolean">null</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'主键'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">businessmodel</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">450</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'业务模式'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">businesstype</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">450</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'业务性质'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">transporttype</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'运输类型'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">bookingguid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'操作编号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">KEY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">doccode</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> ENFORCED</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'postgres-cdc'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'hostname'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'数据库服务器IP地址'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'port'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'端口号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'username'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'用户名'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'password'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'密码'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'database-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'数据库名'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'schema-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'dev'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'decoding.plugin.name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'wal2json'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'table-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'doc_hdworkdochd'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'debezium.slot.name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'hdworkdochdslotname03'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TEMPORARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">shy_base_enterprise</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">entguid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">not</span><span class="token plain"> </span><span class="token boolean">null</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'主键'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">entorgcode</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">450</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'客户编号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">entnature</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">450</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'客户类型'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">entfullname</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'客户名称'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">KEY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">entguid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">entorgcode</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> ENFORCED</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'postgres-cdc'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'hostname'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'数据库服务器IP地址'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'port'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'端口号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'username'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'用户名'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'password'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'密码'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'database-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'数据库名'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'schema-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'dev'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'decoding.plugin.name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'wal2json'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'table-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'base_enterprise'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'debezium.snapshot.mode'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'never'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">-- 增量同步(全量+增量忽略该属性)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'debezium.slot.name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'base_enterprise_slotname03'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- 根据源表结构在paimon上ods层创建对应的目标表</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">IF</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">EXISTS</span><span class="token plain"> ods</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ods_shy_jh_doc_hdworkdochd</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">o_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'分区字段'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">create_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">timestamp</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'创建时间'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">KEY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">o_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">doccode</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> ENFORCED</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> PARTITIONED </span><span class="token keyword" style="color:rgb(86, 156, 214)">BY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">o_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'changelog-producer.compaction-interval'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2m'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">LIKE</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">shy_doc_hdworkdochd</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">EXCLUDING CONSTRAINTS EXCLUDING OPTIONS</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">IF</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">EXISTS</span><span class="token plain"> ods</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ods_shy_base_enterprise</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">create_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">timestamp</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'创建时间'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">KEY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">entguid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">entorgcode</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> ENFORCED</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'changelog-producer.compaction-interval'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2m'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">LIKE</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">shy_base_enterprise</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">EXCLUDING CONSTRAINTS EXCLUDING OPTIONS</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- 设置作业名，执行作业任务将源表数据实时写入到paimon对应表中</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SET</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'pipeline.name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ods_doc_hdworkdochd'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">INTO</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">ods</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ods_shy_jh_doc_hdworkdochd</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SELECT</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token keyword" style="color:rgb(86, 156, 214)">YEAR</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">docdate</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">o_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">TO_TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">CONVERT_TZ</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">CURRENT_TIMESTAMP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'UTC'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Asia/Shanghai'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">create_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">FROM</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">shy_doc_hdworkdochd</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">where</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">docdate</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">is</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">not</span><span class="token plain"> </span><span class="token boolean">null</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">and</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">docdate</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2023-01-01'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SET</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'pipeline.name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ods_shy_base_enterprise'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">INTO</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">ods</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ods_shy_base_enterprise</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SELECT</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">TO_TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">CONVERT_TZ</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">CURRENT_TIMESTAMP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'UTC'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Asia/Shanghai'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">create_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">FROM</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">shy_base_enterprise</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">where</span><span class="token plain"> entorgcode </span><span class="token operator" style="color:rgb(212, 212, 212)">is</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">not</span><span class="token plain"> </span><span class="token boolean">null</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">and</span><span class="token plain"> entorgcode </span><span class="token operator" style="color:rgb(212, 212, 212)">&lt;&gt;</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">''</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- mysql数据库 示例</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TEMPORARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">doc_order</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'主键'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">order_no</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'订单号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">business_no</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'OMS服务号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">is_deleted</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'是否作废'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">KEY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> ENFORCED</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'mysql-cdc'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'hostname'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'数据库服务器地址'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'port'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'端口号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'username'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'用户名'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'password'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'密码'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'database-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'库名'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'table-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'doc_order'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- 根据源表结构在paimon上ods层创建对应的目标表</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">IF</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">EXISTS</span><span class="token plain"> ods</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ods_bondexsea_doc_order</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">o_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'分区字段'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">create_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">timestamp</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'创建时间'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">KEY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">o_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> ENFORCED</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> PARTITIONED </span><span class="token keyword" style="color:rgb(86, 156, 214)">BY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">o_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'changelog-producer.compaction-interval'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2m'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">LIKE</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">doc_order</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">EXCLUDING CONSTRAINTS EXCLUDING OPTIONS</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- 设置作业名，执行作业任务将源表数据实时写入到paimon对应表中</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SET</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'pipeline.name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ods_bondexsea_doc_order'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">INTO</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">ods</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ods_bondexsea_doc_order</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SELECT</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token keyword" style="color:rgb(86, 156, 214)">YEAR</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">gmt_create</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">o_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">TO_TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">CONVERT_TZ</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">CURRENT_TIMESTAMP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'UTC'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Asia/Shanghai'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">create_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">FROM</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">doc_order</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">where</span><span class="token plain"> gmt_create </span><span class="token operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2023-01-01'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- sqlserver数据库 示例</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TEMPORARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">OrderHAWB</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">HBLIndex</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'主键'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">CustomerNo</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'客户编号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">CreateOPDate</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">timestamp</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'制单日期'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">KEY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">HBLIndex</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> ENFORCED</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'sqlserver-cdc'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'hostname'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'数据库服务器地址'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'port'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'端口号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'username'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'用户名'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'password'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'密码'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'database-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'数据库名'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'schema-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'dbo'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- 'debezium.snapshot.mode' = 'initial' -- 全量增量都抽取</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'scan.startup.mode'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'latest-offset'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token comment" style="color:rgb(106, 153, 85)">-- 只抽取增量数据</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'table-name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'OrderHAWB'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- 根据源表结构在paimon上ods层创建对应的目标表</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">IF</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">EXISTS</span><span class="token plain"> ods</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ods_airsea_airfreight_orderhawb</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">o_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'分区字段'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">create_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">timestamp</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'创建时间'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">KEY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">o_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">HBLIndex</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> ENFORCED</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> PARTITIONED </span><span class="token keyword" style="color:rgb(86, 156, 214)">BY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">o_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'changelog-producer.compaction-interval'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2m'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">LIKE</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">OrderHAWB</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">EXCLUDING CONSTRAINTS EXCLUDING OPTIONS</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- 设置作业名，执行作业任务将源表数据实时写入到paimon对应表中</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SET</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'pipeline.name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'ods_airsea_airfreight_orderhawb'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">INTO</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">ods</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ods_airsea_airfreight_orderhawb</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SELECT</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">RTRIM</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">HBLIndex</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">HBLIndex</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">CreateOPDate</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token keyword" style="color:rgb(86, 156, 214)">YEAR</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">CreateOPDate</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">o_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">TO_TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">CONVERT_TZ</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">CURRENT_TIMESTAMP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'UTC'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Asia/Shanghai'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">create_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">FROM</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">OrderHAWB</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">where</span><span class="token plain"> CreateOPDate </span><span class="token operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2023-01-01'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>业务表数据实时写入 Paimon ods 表效果如下：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/ods-bc0d5ecbef808b0ca349311569803f18.png" width="1080" height="422" class="img_iwx1"></p>
<ol start="2">
<li>将ods层表的数据打宽写入 dwd 层中，这里其实就是将 ods 层相关业务表合并写入dwd 中，这里主要是处理 count_order 字段的值，因为源表中的数据存在逻辑删除和物理删除所以通过 count 函数统计会有问题，所以我们这里采用 sum 聚合来计算单量，每个reference_no对应的count_order是1，如果逻辑作废通过sql将它处理成0，物理删除 Paimon 会自动处理。</li>
</ol>
<p>dim 维表我们这边直接拿的 doris 里面处理好的维表来使用，维表更新频率低，所以没有在 Paimon 里面进行二次开发。</p>
<div class="language-sql codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-sql codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token comment" style="color:rgb(106, 153, 85)">-- 在paimon-dwd层创建宽表</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">IF</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">EXISTS</span><span class="token plain"> dwd</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">dwd_business_order</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">reference_no</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'委托单号主键'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">bondex_shy_flag</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">8</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'区分'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">is_server_item</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'是否已经关联订单'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">order_type_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'业务分类'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">consignor_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">DATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'统计日期'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">consignor_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'客户编号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">consignor_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">160</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'客户名称'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">sales_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">32</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'销售编号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">sales_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">200</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'销售名称'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">delivery_center_op_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">32</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'交付编号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">delivery_center_op_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">200</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'交付名称'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">pol_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">100</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'起运港代码'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">pot_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">100</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'中转港代码'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">port_of_dest_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">100</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'目的港代码'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">is_delete</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">not</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'是否作废'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">order_status</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">8</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'订单状态'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">count_order</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">not</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'订单数'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">o_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'分区字段'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">create_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">timestamp</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'创建时间'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">KEY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">o_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">reference_no</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">bondex_shy_flag</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> ENFORCED</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> PARTITIONED </span><span class="token keyword" style="color:rgb(86, 156, 214)">BY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">o_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- 每个 partition 下设置 2 个 bucket</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'bucket'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'changelog-producer'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'full-compaction'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'snapshot.time-retained'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2h'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'changelog-producer.compaction-interval'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2m'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- 设置作业名，将ods层的相关业务表合并写入到dwd层</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SET</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'pipeline.name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'dwd_business_order'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">INTO</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">dwd</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">dwd_business_order</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SELECT</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">o</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">doccode</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">YEAR</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">o</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">docdate</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> o_year</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">TO_TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">CONVERT_TZ</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">CURRENT_TIMESTAMP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'UTC'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Asia/Shanghai'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">create_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">FROM</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">ods</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">ods_shy_jh_doc_hdworkdochd o</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">INNER</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">JOIN</span><span class="token plain"> ods</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">ods_shy_base_enterprise en </span><span class="token keyword" style="color:rgb(86, 156, 214)">ON</span><span class="token plain"> o</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">businessguid </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> en</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">entguid</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">LEFT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">JOIN</span><span class="token plain"> dim</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">dim_hhl_user_code sales </span><span class="token keyword" style="color:rgb(86, 156, 214)">ON</span><span class="token plain"> o</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">salesguid </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> sales</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">USER_GUID</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">LEFT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">JOIN</span><span class="token plain"> dim</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">dim_hhl_user_code op </span><span class="token keyword" style="color:rgb(86, 156, 214)">ON</span><span class="token plain"> o</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">bookingguid </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> op</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">USER_GUID</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">UNION</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">ALL</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SELECT</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">business_no</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">YEAR</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"> gmt_create </span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> o_year</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">TO_TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">CONVERT_TZ</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">CURRENT_TIMESTAMP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'UTC'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Asia/Shanghai'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">create_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">FROM</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">ods</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">ods_bondexsea_doc_order</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">UNION</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">ALL</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SELECT</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  HBLIndex</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">YEAR</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"> CreateOPDate </span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> o_year</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">TO_TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">CONVERT_TZ</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">CURRENT_TIMESTAMP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'UTC'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Asia/Shanghai'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">create_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">FROM</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  ods</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">ods_airsea_airfreight_orderhawb</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>flink ui 可以看到 ods 数据经过 paimon 实时 join 清洗到表 dwd_business_order</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/dwd_business_order-a017b7fa6dac855794cf9720a0421090.png" width="1080" height="646" class="img_iwx1"></p>
<p>2.将dwd层数据轻度聚合到dwm层中，将相关数据写入dwm.<code>dwm_business_order_count</code> 表中，该表数据会根据主键对聚合字段做 sum，sum_orderCount 字段就是聚合结果，物理删除的数据 sum 时 paimon 会自动处理。</p>
<div class="language-sql codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-sql codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token comment" style="color:rgb(106, 153, 85)">-- 创建dwm层轻度汇总表，根据日期、销售、操作、业务类别、客户、起运港、目的港汇总单量</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">IF</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">EXISTS</span><span class="token plain"> dwm</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">dwm_business_order_count</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'统计年'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_month</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'统计月'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">DATE</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'统计日期'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">bondex_shy_flag</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">8</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'区分'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">order_type_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'业务分类'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">is_server_item</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">int</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'是否已经关联订单'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">customer_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'客户编号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">sales_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'销售编号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">delivery_center_op_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'交付编号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">pol_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">100</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'起运港代码'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">pot_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">100</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'中转港代码'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">port_of_dest_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">100</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'目的港代码'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">customer_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">200</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'客户名称'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">sales_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">200</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'销售名称'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">delivery_center_op_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">200</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'交付名称'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">sum_orderCount</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'订单数'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">create_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">timestamp</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'创建时间'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">KEY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">             </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_month</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">             </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">             </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">order_type_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">             </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">bondex_shy_flag</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">             </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">is_server_item</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">             </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">customer_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">             </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">sales_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">             </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">delivery_center_op_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">             </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">pol_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">             </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">pot_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">             </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">port_of_dest_code</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> ENFORCED</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'changelog-producer'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'full-compaction'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'changelog-producer.compaction-interval'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2m'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'merge-engine'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'aggregation'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">-- 使用 aggregation 聚合计算 sum</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'fields.sum_orderCount.aggregate-function'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'sum'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'fields.create_date.ignore-retract'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'true'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'fields.sales_name.ignore-retract'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'true'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'fields.customer_name.ignore-retract'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'true'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'snapshot.time-retained'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2h'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'fields.delivery_center_op_name.ignore-retract'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'true'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- 设置作业名</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SET</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'pipeline.name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'dwm_business_order_count'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">INTO</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">dwm</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">dwm_business_order_count</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SELECT</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">YEAR</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">o</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">consignor_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token keyword" style="color:rgb(86, 156, 214)">MONTH</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">o</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">consignor_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_month</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">TO_TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">CONVERT_TZ</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">CURRENT_TIMESTAMP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'UTC'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Asia/Shanghai'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> create_date</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">FROM</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">dwd</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">dwd_business_order</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> o</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Flink UI 效果如下 dwd_business_orders 数据聚合写到 dwm_business_order_count：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/dwm_business_order_count-1abbcf7d6b31f15e49f2e035ecfdb8d7.png" width="194" height="649" class="img_iwx1"></p>
<p>4.将 dwm 层数据聚合到 dws 层中，dws 层是做了更小维度的汇总</p>
<div class="language-sql codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-sql codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token comment" style="color:rgb(106, 153, 85)">-- 创建根据操作人、业务类型聚合当天的单量</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">IF</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">EXISTS</span><span class="token plain"> dws</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">dws_business_order_count_op</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'统计年'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_month</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'统计月'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">DATE</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'统计日期'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">order_type_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'业务分类'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">delivery_center_op_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'交付编号'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">delivery_center_op_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:rgb(181, 206, 168)">200</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'交付名称'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">sum_orderCount</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">BIGINT</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'订单数'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">create_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">timestamp</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> </span><span class="token boolean">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">COMMENT</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'创建时间'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">KEY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_month</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">order_type_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">delivery_center_op_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">NOT</span><span class="token plain"> ENFORCED</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'merge-engine'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'aggregation'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">-- 使用 aggregation 聚合计算 sum</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'fields.sum_orderCount.aggregate-function'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'sum'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'fields.create_date.ignore-retract'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'true'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'snapshot.time-retained'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2h'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token string" style="color:rgb(206, 145, 120)">'fields.delivery_center_op_name.ignore-retract'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'true'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- 设置作业名</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SET</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'pipeline.name'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'dws_business_order_count_op'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">INTO</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  dws</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">dws_business_order_count_op</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SELECT</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  o</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_year</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">o</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_month</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">o</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">l_date</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">o</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">order_type_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">o</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">delivery_center_op_id</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">o</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">delivery_center_op_name</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">o</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">sum_orderCount</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">TO_TIMESTAMP</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">CONVERT_TZ</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">cast</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:rgb(86, 156, 214)">CURRENT_TIMESTAMP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">varchar</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'UTC'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Asia/Shanghai'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">AS</span><span class="token plain"> create_date</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">FROM</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  dwm</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">dwm_business_order_count</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> o</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Flink UI 效果如下 dws_business_order_count_op 数据写到 dws_business_order_count_op：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/dws_business_order_count_op-72bb62943dcef89451b47db142cfe689.png" width="191" height="630" class="img_iwx1"></p>
<p>总体数据流转示例</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/all_datastream-f095c45ce30fe21e178eac323c6a7a37.jpg" width="1080" height="515" class="img_iwx1"></p>
<p>源表：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/source-afa30e0d3ab0116582cc4bd7831ce2ca.png" width="1080" height="100" class="img_iwx1"></p>
<p>paimon-ods:</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/paimon-ods-876cf67ff375c0b5cb67d4a0e555b1a3.png" width="1080" height="94" class="img_iwx1"></p>
<p>paimon-dwd:</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/paimon-dwd-d3b020d2bd2b78c26944a6928be39e4e.png" width="1080" height="95" class="img_iwx1"></p>
<p>paimon-dwm:</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/paimon-dwm-778a748d6b64c9e61d73e6b6da1d625f.png" width="1080" height="39" class="img_iwx1"></p>
<p>paimon-dws:</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/paimon-dws-632e1291e21c4f628f7e87ca03ae5c6f.png" width="1080" height="56" class="img_iwx1"></p>
<p>特别提醒 sqlserver 数据库抽取时如果源表数据量过大全量抽取会锁表，建议在业务允许的情况下采用增量抽取。对于全量抽取 sqlserver 可以采用中转的方式 sqlserver 全量数据导入到 mysql，从 mysql 再到 paimon-ods ，后面再通过 sqlserever 做增量抽取。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="04-问题排查分析">04 问题排查分析<a class="hash-link" aria-label="04 问题排查分析的直接链接" title="04 问题排查分析的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon#04-%E9%97%AE%E9%A2%98%E6%8E%92%E6%9F%A5%E5%88%86%E6%9E%90">​</a></h2>
<p><strong>1. 聚合数据计算不准</strong></p>
<p>sqlserver cdc 采集数据到 paimon 表，说明：</p>
<p><strong>dwd 表：</strong></p>
<p>'changelog-producer' = 'input'</p>
<p><strong>ads 表：</strong></p>
<p>'merge-engine' = 'aggregation'，-- 使用 aggregation 聚合计算 sum</p>
<p>'fields.sum_amount.aggregate-function' = 'sum'</p>
<p>ADS 层聚合表采用 agg sum 会出现 dwd 数据流不产生 update_before，产生错误数据流 update_after  比如上游源表 update 10 到 30 dwd 层数据会变更为 30，ads 聚合层数据也会变更为 30，但是现在变为了 append 数据变成了 10+30=40 的错误数据。</p>
<p>解决办法：</p>
<p>By specifying 'changelog-producer' = 'full-compaction',
Table Store will compare the results between full compactions and produce the differences as changelog.
The latency of changelog is affected by the frequency of full compactions.</p>
<p>By specifying changelog-producer.compaction-interval table property (default value 30min),
users can define the maximum interval between two full compactions to ensure latency.
This table property does not affect normal compactions and they may still be performed once in a while by writers to reduce reader costs.</p>
<p>这样能解决上述问题。但是随之而来出现了新的问题。默认 changelog-producer.compaction-interval 是 30min，意味着 上游的改动到 ads 查询要间隔 30min，生产过程中发现将压缩间隔时间改成 1min 或者 2 分钟的情况下，又会出现上述 ADS 层聚合数据不准的情况。</p>
<div class="language-sql codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-sql codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token string" style="color:rgb(206, 145, 120)">'changelog-producer.compaction-interval'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2m'</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>需要在写入 Flink Table Store 时需要配置 table.exec.sink.upsert-materialize= none，避免产生 Upsert 流，以保证 Flink Table Store 中能够保存完整的 changelog，为后续的流读操作做准备。</p>
<div class="language-sql codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-sql codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token keyword" style="color:rgb(86, 156, 214)">set</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'table.exec.sink.upsert-materialize'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'none'</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>2. 相同 sequence.field 导致 dwd 明细宽表无法收到 update 数据更新</strong></p>
<p><strong>mysql cdc 采集数据到 paimon 表</strong></p>
<p>说明：</p>
<p>在 MySQL 源端执行 update 数据修改成功后，dwd_orders 表数据能同步成功</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/dwd_orders-8343ec8277c69354f8ee7cac0c4c9f91.png" width="1080" height="558" class="img_iwx1"></p>
<p>但是查看 dwd_enriched_orders 表数据无法同步，启动流模式查看数据，发现没有数据流向</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/log-42ef92b8036ed3698fb0fbb1abdaecab.png" width="1080" height="357" class="img_iwx1"></p>
<p><strong>解决：</strong></p>
<p>排查发现是由于配置了参数 'sequence.field' = 'o_orderdate'（使用 o_orderdate 生成 sequence id，相同主键合并时选择 sequence id 更大的记录）导致的，因为在修改价格的时候 o_orderdate 字段时间不变， 继而'sequence.field' 是相同的，导致顺序不确定，所以 ROW1 和 ROW2，它们的 o_orderdate 是一样的，所以在更新时会随机选择，所有将该参数去掉即可，去掉后正常按照输入的先后顺序，自动生成一个 sequence number，不会影响同步结果。</p>
<p><strong>3. Aggregate function 'last_non_null_value' does not support retraction</strong></p>
<p>报错：</p>
<div class="codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-text codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">Caused by: java.lang.UnsupportedOperationException: Aggregate function 'last_non_null_value' does not support retraction, If you allow this function to ignore retraction messages, you can configure 'fields.${field_name}.ignore-retract'='true'.</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>可以在官方文档找到解释：</p>
<div class="codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-text codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">Only sum supports retraction (UPDATE_BEFORE and DELETE), others aggregate functions do not support retraction.</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>可以理解为：除了 SUM 函数，其他的 Agg 函数都不支持 Retraction，为了避免接收到 DELETE 和 UPDATEBEFORE 消息报错，需要通过给指定字段配 <code>'fields.${field_name}.ignore-retract'='true'</code> 忽略，解决这个报错</p>
<div class="language-sql codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-sql codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'merge-engine'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'aggregation'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">-- 使用 aggregation 聚合计算 sum</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'fields.sum_orderCount.aggregate-function'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'sum'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'fields.create_date.ignore-retract'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'true'</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">#create_date 字段</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>4. paimon任务中断失败</strong></p>
<p>任务异常中断 导致pod挂掉，查看loki日志显示akka.pattern.AskTimeoutException: Ask timed out on</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/loki-372203296a8af19f7a32fcd2162fdc29.png" width="1080" height="288" class="img_iwx1"></p>
<p>java.util.concurrent.TimeoutException: Invocation of [RemoteRpcInvocation(JobMasterGateway.updateTaskExecutionState(TaskExecutionState))] at recipient [akka.tcp://flink@fts-business-order-count.streampark:6123/user/rpc/jobmanager_2] timed out. This is usually caused by: 1) Akka failed sending the message silently, due to problems like oversized payload or serialization failures. In that case, you should find detailed error information in the logs. 2) The recipient needs more time for responding, due to problems like slow machines or network jitters. In that case, you can try to increase akka.ask.timeout.\n"</p>
<p>初步判断应该是由于以上2个原因导致触发了 akka 的超时机制，那就调整集群的akka超时间配置和进行单个任务拆分或者调大资源配置。</p>
<p>我们这边先看如何进行参数修改:</p>
<table><thead><tr><th>key</th><th>default</th><th>describe</th></tr></thead><tbody><tr><td>akka.ask.timeout</td><td>10s</td><td>Timeout used for all futures and blocking Akka calls. If Flink fails due to timeouts then you should try to increase this value. Timeouts can be caused by slow machines or a congested network. The timeout value requires a time-unit specifier (ms/s/min/h/d).</td></tr><tr><td>web.timeout</td><td>600000</td><td>Timeout for asynchronous operations by the web monitor in milliseconds.</td></tr></tbody></table>
<p>在 conf/flink-conf.yaml 最后增加下面参数:</p>
<p><strong>akka.ask.timeout: 100s</strong></p>
<p><strong>web.timeout:1000000</strong></p>
<p>然后在 streampark 手动刷新下 flink-conf.yaml 验证参数是否同步成功。</p>
<p><strong>5. snapshot no such file or director</strong></p>
<p>发现 cp 出现失败情况</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/cp_fail-a5b4c7c1cd38f2563b651b23daab8140.jpg" width="903" height="502" class="img_iwx1"></p>
<p>对应时间点日志显示 Snapshot 丢失，任务显示为 running 状态，但是源表 mysql 数据无法写入 paimon ods 表</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/status_log-eed735d5dc4c6954042376d7b6f12388.png" width="1080" height="360" class="img_iwx1"></p>
<p>定位cp失败原因为：计算量大，CPU密集性，导致TM内线程一直在processElement，而没有时间做CP</p>
<p>无法读取 Snapshot 原因为：flink 集群资源不够，Writer 和 Committer 产生竞争，Full-Compaction 时读到了已过期部分的不完整的 Snapshot，目前官方针对这个问题已经修复:</p>
<p><a href="https://github.com/apache/incubator-paimon/pull/1308" target="_blank" rel="noopener noreferrer">https://github.com/apache/incubator-paimon/pull/1308</a></p>
<p>而解决 cp 失败的解决办法增加并行度，增加 deploymenttaskmanager slot 和 jobmanager cpu</p>
<div class="codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-text codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">-D kubernetes.jobmanager.cpu=0.8</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-D kubernetes.jobmanager.cpu.limit-factor=1</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-D taskmanager.numberOfTaskSlots=8</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-D jobmanager.adaptive-batch-scheduler.default-source-parallelism=2</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/dynamic_properties-33cd67364d80285f0e480974a60d52ff.jpg" width="1080" height="244" class="img_iwx1"></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_dashboard-4bcca1ae4f103249bd7c6c48625a4959.png" width="1080" height="487" class="img_iwx1"></p>
<p>在复杂的实时任务中，可以通过修改动态参数的方式，增加资源。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="05-未-来-规-划">05 未 来 规 划<a class="hash-link" aria-label="05 未 来 规 划的直接链接" title="05 未 来 规 划的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-bondex-with-paimon#05-%E6%9C%AA-%E6%9D%A5-%E8%A7%84-%E5%88%92">​</a></h2>
<ul>
<li>自建的数据平台 bondata 正在集成 paimon 的元数据信息、数据指标体系、血缘、一键 pipline 等功能，形成海程邦达的数据资产，并将在此基础上展开一站式数据治理</li>
<li>后面将基于 trino Catalog接入Doris，实现真正的离线数据和实时数据的one service</li>
<li>采用 doris + paimon 的架构方案继续推进集团内部流批一体数仓建设的步伐</li>
</ul>
<p>在这里要感谢之信老师和 StreamPark 社区在使用 StreamPark + Paimon 过程中的大力支持，在学习使用过程中遇到的问题，都能在第一时间给到解惑并得到解决，我们后面也会积极参与社区的交流和建设，让 paimon 能为更多开发者和企业提供流批一体的数据湖解决方案。</p>]]></content:encoded>
            <category>StreamPark</category>
            <category>生产实践</category>
            <category>paimon</category>
            <category>streaming-warehouse</category>
        </item>
        <item>
            <title><![CDATA[Apache StreamPark™ 在顺网科技的大规模生产实践]]></title>
            <link>https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang</link>
            <guid>https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang</guid>
            <pubDate>Mon, 09 Feb 2026 02:32:43 GMT</pubDate>
            <description><![CDATA[导读：本文主要介绍顺网科技在使用 Flink 计算引擎中遇到的一些挑战，基于 StreamPark 作为实时数据平台如何来解决这些问题，从而大规模支持公司的业务。]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/autor-4fee09aa3abf8842dcdbb7ada1aa9409.png" width="1080" height="460" class="img_iwx1"></p>
<p>**导读：**本文主要介绍顺网科技在使用 Flink 计算引擎中遇到的一些挑战，基于 StreamPark 作为实时数据平台如何来解决这些问题，从而大规模支持公司的业务。</p>
<ul>
<li>公司业务介绍</li>
<li>遇到的挑战</li>
<li>为什么用 StreamPark</li>
<li>落地实践</li>
<li>带来的收益</li>
<li>未来规划</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="公司业务介绍"><strong>公司业务介绍</strong><a class="hash-link" aria-label="公司业务介绍的直接链接" title="公司业务介绍的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#%E5%85%AC%E5%8F%B8%E4%B8%9A%E5%8A%A1%E4%BB%8B%E7%BB%8D">​</a></h2>
<p>杭州顺网科技股份有限公司成立于 2005 年，秉承科技连接快乐的企业使命，是国内具有影响力的泛娱乐技术服务平台之一。多年来公司始终以产品和技术为驱动，致力于以数字化平台服务为人们创造沉浸式的全场景娱乐体验。</p>
<p>自顺网科技成立以来，随着业务快速发展，顺网科技服务了 8 万家线下实体店，拥有超过 5000 万互联网用户，年触达超 1.4 亿网民，每 10 家公共上网服务场所有 7 家使用顺网科技产品。</p>
<p>在拥有庞大的用户群体的情况下，顺网科技为了给用户提供更加优质的产品体验，实现企业的数字化转型，从 2015 年开始大力发展大数据， Flink 在顺网科技的实时计算中一直扮演着重要的角色。在顺网科技，实时计算大概分为 4 个应用场景：</p>
<ul>
<li>用户画像实时更新：包括网吧画像和网民画像。</li>
<li>实时风控：包括活动防刷、异地登录监测等。</li>
<li>数据同步：包括 Kafka 数据同步到 Hive / Iceberg / ClickHouse 等。</li>
<li>实时数据分析：包括游戏、语音、广告、直播等业务实时大屏。</li>
</ul>
<p>到目前为止，顺网科技每日需要处理 TB 级别的数据，总共拥有 700+ 个实时任务，其中 FlinkSQL 任务占比为 95% 以上。随着公司业务快速发展和数据时效性要求变高，预计在今年年底 Flink 任务会达到 900+。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="遇到的挑战"><strong>遇到的挑战</strong><a class="hash-link" aria-label="遇到的挑战的直接链接" title="遇到的挑战的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#%E9%81%87%E5%88%B0%E7%9A%84%E6%8C%91%E6%88%98">​</a></h2>
<p>Flink 作为当下实时计算领域中最流行的技术框架之一，拥有高吞吐、低延迟、有状态计算等强大的特性。在探索中我们发现 Flink 虽然拥有强大的计算能力，但是对于作业开发管理和运维问题，社区并没有提供有效的解决方案。我们对 Flink 作业开发管理上遇到的一些痛点大概总结为 4 个方面，如下：</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/pain-4d2aee42ea7aae80eaeac17a6d51c090.png" width="1080" height="744" class="img_iwx1"></p>
<p>在面对 Flink 作业管理和运维上的的一系列痛点后，我们一直在寻找合适的解决方案来降低开发同学使用 Flink 门槛，提高工作效率。</p>
<p>在没有遇到 StreamPark 之前，我们调研了部分公司的 Flink 管理解决方案，发现都是通过自研实时作业平台的方式来开发和管理 Flink 作业。于是，我们也决定自研一套实时计算管理平台，来满足了开发同学对于 Flink 作业管理和运维的基础需求，我们这套平台叫 Streaming-Launcher，大体功能如下：</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/launcher-766611cb0dddb99d8437ead44d0665d4.png" width="1080" height="670" class="img_iwx1"></p>
<p>但是后续开发同学在使用过程中，发现 Streaming-Launcher 存在比较多的缺陷：Flink 开发成本依然过高、工作效率低下、问题排查困难。我们总结了 Streaming-Launcher 存在的缺陷，大致如下：</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="sql开发流程繁琐"><strong>SQL开发流程繁琐</strong><a class="hash-link" aria-label="sql开发流程繁琐的直接链接" title="sql开发流程繁琐的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#sql%E5%BC%80%E5%8F%91%E6%B5%81%E7%A8%8B%E7%B9%81%E7%90%90">​</a></h3>
<p>作业务开发需要多个工具完成一个 SQL 作业开发，提高了开发同学的使用门槛。</p>
<p><img decoding="async" loading="lazy" alt="cc0b1414ed43942e0ef5e9129c2bf817" src="https://streampark.apache.org/zh-CN/assets/images/sql_develop-ef85f6a001fb814d494c9b39eb2dfba9.png" width="1080" height="229" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="sql-client-存在弊端"><strong>SQL-Client 存在弊端</strong><a class="hash-link" aria-label="sql-client-存在弊端的直接链接" title="sql-client-存在弊端的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#sql-client-%E5%AD%98%E5%9C%A8%E5%BC%8A%E7%AB%AF">​</a></h3>
<p>Flink 提供的 SQL-Client 目前对作业运行模式支持上，存在一定的弊端。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/sql_client-32fd9eb063198e6f35349187eed61546.png" width="1080" height="721" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="作业缺少统一管理"><strong>作业缺少统一管理</strong><a class="hash-link" aria-label="作业缺少统一管理的直接链接" title="作业缺少统一管理的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#%E4%BD%9C%E4%B8%9A%E7%BC%BA%E5%B0%91%E7%BB%9F%E4%B8%80%E7%AE%A1%E7%90%86">​</a></h3>
<p>Streaming-Launcher 中，没有提供统一的作业管理界面。开发同学无法直观的看到作业运行情况，只能通过告警信息来判断作业运行情况，这对开发同学来说非常不友好。如果因为 Yarn 集群稳定性问题或者网络波动等不确定因素，一下子失败大批量任务，在开发同学手动恢复作业的过程中，很容易漏恢复某个任务而造成生产事故。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="问题诊断流程繁琐"><strong>问题诊断流程繁琐</strong><a class="hash-link" aria-label="问题诊断流程繁琐的直接链接" title="问题诊断流程繁琐的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#%E9%97%AE%E9%A2%98%E8%AF%8A%E6%96%AD%E6%B5%81%E7%A8%8B%E7%B9%81%E7%90%90">​</a></h3>
<p>一个作业查看日志需要通过多个步骤，一定程度上降低了开发同学工作效率。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/step-d945592bbe32c0e093289c6265472f1c.png" width="1080" height="122" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="为什么用-apache-streampark"><strong>为什么用</strong> <strong>Apache StreamPark™</strong><a class="hash-link" aria-label="为什么用-apache-streampark的直接链接" title="为什么用-apache-streampark的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#%E4%B8%BA%E4%BB%80%E4%B9%88%E7%94%A8-apache-streampark">​</a></h2>
<p>面对自研平台 Streaming-Launcher 存在的缺陷，我们一直在思考如何将 Flink 的使用门槛降到更低，进一步提高工作效率。考虑到人员投入成本和时间成本，我们决定向开源社区求助寻找合适的开源项目来对我们的 Flink 任务进行管理和运维。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="01--apache-streampark-解决-flink-问题的利器">01  <strong>Apache StreamPark™ 解决 Flink 问题的利器</strong><a class="hash-link" aria-label="01--apache-streampark-解决-flink-问题的利器的直接链接" title="01--apache-streampark-解决-flink-问题的利器的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#01--apache-streampark-%E8%A7%A3%E5%86%B3-flink-%E9%97%AE%E9%A2%98%E7%9A%84%E5%88%A9%E5%99%A8">​</a></h3>
<p>很幸运在 2022 年 6 月初，我们在 GitHub 机缘巧合之间认识到了 StreamPark，我们满怀希望地对 StreamPark 进行了初步的探索。发现 StreamPark 具备的能力大概分为三大块：用户权限管理、作业运维管理和开发脚手架。</p>
<p><strong>用户权限管理</strong></p>
<p>在 StreamPark 平台中为了避免用户权限过大，发生一些不必要的误操作，影响作业运行稳定性和环境配置的准确性，提供了相应的一些用户权限管理功能，这对企业级用户来说，非常有必要。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/permission-affd274acd10773ad4531da9102f3f91.png" width="1080" height="721" class="img_iwx1"></p>
<p><strong>作业运维管理</strong></p>
<p>**我们在对 StreamPark 做调研的时候，最关注的是 StreamPark 对于作业的管理的能力。**StreamPark 是否有能力管理作业一个完整的生命周期：作业开发、作业部署、作业管理、问题诊断等。**很幸运，StreamPark 在这一方面非常优秀，对于开发同学来说只需要关注业务本身，不再需要特别关心 Flink 作业管理和运维上遇到的一系列痛点。**在 StreamPark 作业开发管理管理中，大致分为三个模块：作业管理基础功能，Jar 作业管理，FlinkSQL 作业管理。如下：</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/homework_manager-96dc37860dd87f12ed55311b38116931.png" width="1080" height="542" class="img_iwx1"></p>
<p><strong>开发脚手架</strong></p>
<p>通过进一步的研究发现，StreamPark 不仅仅是一个平台，还包含 Flink 作业开发脚手架，在 StreamPark 中，针对编写代码的 Flink 作业，提供一种更好的解决方案，将程序配置标准化，提供了更为简单的编程模型，同时还提供了一些列 Connectors，降低了 DataStream 开发的门槛。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/connectors-d405c391d0cfdd753e7b329433275117.png" width="1080" height="720" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="02--apache-streampark-解决自研平台的问题">02  <strong>Apache StreamPark™ 解决自研平台的问题</strong><a class="hash-link" aria-label="02--apache-streampark-解决自研平台的问题的直接链接" title="02--apache-streampark-解决自研平台的问题的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#02--apache-streampark-%E8%A7%A3%E5%86%B3%E8%87%AA%E7%A0%94%E5%B9%B3%E5%8F%B0%E7%9A%84%E9%97%AE%E9%A2%98">​</a></h3>
<p>上面我们简单介绍了 StreamPark 的核心能力。在顺网科技的技术选型过程中，我们发现 StreamPark 所具备强大的功能不仅包含了现有 Streaming-Launcher 的基础功能，还提供了更完整的对应方案解决了 Streaming-Launcher 的诸多不足。在这部分，着重介绍下 StreamPark 针对我们自研平台 Streaming-Launcher 的不足所提供的解决方案。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/function-c2d3ad419e1676a0253d933935921a71.png" width="1080" height="720" class="img_iwx1"></p>
<p><strong>Flink 作业一站式的开发能力</strong></p>
<p>StreamPark 为了降低 Flink 作业开发门槛，提高开发同学工作效率，<strong>提供了 FlinkSQL IDE、参数管理、任务管理、代码管理、一键编译、一键作业上下线等使用的功能</strong>。在调研中，我们发现 StreamPark 集成的这些功能可以进一步提升开发同学的工作效率。在某种程度上来说，开发同学不需要去关心 Flink 作业管理和运维的难题，只要专注于业务的开发。同时，这些功能也解决了 Streaming-Launcher 中 SQL 开发流程繁琐的痛点。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/application-c99d4b0512fdb7d214e5429769629930.png" width="1080" height="959" class="img_iwx1"></p>
<p><strong>支持多种部署模式</strong></p>
<p>在 Streaming-Launcher 中，由于只支持 Yarn Session 模式，对于开发同学来说，其实非常不灵活。StreamPark 对于这一方面也提供了完善的解决方案。<strong>StreamPark 完整的支持了Flink 的所有部署模式：Remote、Yarn Per-Job、Yarn Application、Yarn Session、K8s Session、K8s Application</strong>**，<strong>可以让开发同学针对不同的业务场景自由选择合适的运行模式。</strong></p>
<p><strong>作业统一管理中心</strong></p>
<p>对于开发同学来说，作业运行状态是他们最关心的内容之一。在 Streaming-Launcher 中由于缺乏作业统一管理界面，开发同学只能通过告警信息和 Yarn 中Application 的状态信息来判断任务状态，这对开发同学来说非常不友好。StreamPark 针对这一点，提供了作业统一管理界面，可以一目了然查看到每个任务的运行情况。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/management-9eb1dec5b2fa480e897cf1c12d1425d8.png" width="1080" height="572" class="img_iwx1"></p>
<p>在 Streaming-Launcher 中，开发同学在作业问题诊断的时候，需要通过多个步骤才能定位作业运行日志。StreamPark 提供了一键跳转功能，能快速定位到作业运行日志。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/logs-e4e9f2084f1fbcf0a4afe079433cef0a.png" width="1080" height="575" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="落-地-实-践">落 地 实 践<a class="hash-link" aria-label="落 地 实 践的直接链接" title="落 地 实 践的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#%E8%90%BD-%E5%9C%B0-%E5%AE%9E-%E8%B7%B5">​</a></h2>
<p>在 StreamPark 引入顺网科技时，由于公司业务的特点和开发同学的一些定制化需求，我们对 StreamPark 的功能做了一些增加和优化，同时也总结了一些在使用过程中遇到的问题和对应的解决方案。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="01--结合-flink-sql-gateway-的能力">01  <strong>结合 Flink-SQL-Gateway 的能力</strong><a class="hash-link" aria-label="01--�结合-flink-sql-gateway-的能力的直接链接" title="01--结合-flink-sql-gateway-的能力的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#01--%E7%BB%93%E5%90%88-flink-sql-gateway-%E7%9A%84%E8%83%BD%E5%8A%9B">​</a></h3>
<p>在顺网科技，我们基于 Flink-SQL-Gateway 自研了 ODPS 平台来方便业务开发同学管理 Flink 表的元数据。业务开发同学在 ODPS 上对 Flink 表进行 DDL 操作，然后在 StreamPark 上对创建的 Flink 表进行分析查询操作。在整个业务开发流程上，我们对 Flink 表的创建和分析实现了解耦，让开发流程显得比较清晰。</p>
<p>开发同学如果想在 ODPS 上查询实时数据，我们需要提供一个 Flink SQL 的运行环境。我们使用 StreamPark 运行了一个 Yarn Session 的 Flink 环境提供给 ODPS 做实时查询。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/homework-96030dec4ea9db88b42668873f5a176d.png" width="1080" height="541" class="img_iwx1"></p>
<p>目前 StreamPark 社区为了进一步降低实时作业开发门槛，正在对接 Flink-SQL-Gateway。</p>
<p><a href="https://github.com/apache/streampark/issues/2274" target="_blank" rel="noopener noreferrer">https://github.com/apache/streampark/issues/2274</a></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="02--增强-flink-集群管理能力">02  <strong>增强 Flink 集群管理能力</strong><a class="hash-link" aria-label="02--增强-flink-集群管理能力的直接链接" title="02--增强-flink-集群管理能力的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#02--%E5%A2%9E%E5%BC%BA-flink-%E9%9B%86%E7%BE%A4%E7%AE%A1%E7%90%86%E8%83%BD%E5%8A%9B">​</a></h3>
<p>在顺网科技，存在大量从 Kafka 数据同步到 Iceberg / PG / Clickhouse / Hive 的作业。这些作业需要的 Yarn 对于资源要求和时效性要求不高，但是如果全部使用 Yarn Application 和 per-job 模式，每个任务都会启动 JobManager，那么会造成 Yarn 资源的浪费。对此，我们决定使用 Yarn Session 模式运行这些大量的数据同步作业。</p>
<p>在实践中我们发现业务开发同学很难直观的知道在每个 Yarn Session 中运行了多少个作业，其中包括作业总数和正在运行中的作业数量。基于这个原因，我们为了方便开发同学可以直观地观察到 Yarn Session 中的作业数量，在 Flink Cluster 界面增加了 All Jobs 和 Running Jobs 来表示在一个 Yarn Session 中总的作业数和正在运行的作业数。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/cluster-96bd791c1c4f3d6144fbd1d134d89cd6.png" width="1080" height="543" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="03--增强告警能力">03  <strong>增强告警能力</strong><a class="hash-link" aria-label="03--增强告警能力的直接链接" title="03--增强告警能力的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#03--%E5%A2%9E%E5%BC%BA%E5%91%8A%E8%AD%A6%E8%83%BD%E5%8A%9B">​</a></h3>
<p>因为每个公司的短信告警平台实现都各不相同，所以 StreamPark 社区并没有抽象出统一的短信告警功能。在此，我们通过 Webhook 的方式，自己实现了短信告警功能。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/alarm-8fa330c6a2d27cfd62878dcd20cd524c.png" width="1080" height="601" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="04--增加阻塞队列解决限流问题">04  <strong>增加阻塞队列解决限流问题</strong><a class="hash-link" aria-label="04--增加阻塞队列解决限流问题的直接链接" title="04--增加阻塞队列解决限流问题的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#04--%E5%A2%9E%E5%8A%A0%E9%98%BB%E5%A1%9E%E9%98%9F%E5%88%97%E8%A7%A3%E5%86%B3%E9%99%90%E6%B5%81%E9%97%AE%E9%A2%98">​</a></h3>
<p>在生产实践中，我们发现在大批量任务同时失败的时候，比如 Yarn Session 集群挂了，飞书 / 微信等平台在多线程同时调用告警接口时会存在限流的问题，那么大量的告警信息因为飞书 / 微信等平台限流问题，StreamPark 只会发送一部分的告警信息，这样非常容易误导开发同学排查问题。在顺网科技，我们增加了一个阻塞队列和一个告警线程，来解决限流问题。</p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/queue-83552f1862acff8811b74488e8fe7c05.png" width="1080" height="320" class="img_iwx1"></p>
<p>当作业监控调度器检测到作业异常时，会产生一条作业异常的消息发送的阻塞队列中，在告警线程中会一直消费阻塞队列中的消息，在得到作业异常消息后则会根据用户配置的告警信息单线程发送到不同的平台中。虽然这样做可能会让用户延迟收到告警，但是我们在实践中发现同时有 100+ 个 Flink 作业失败，用户接受到告警的延迟时间小于 3s。对于这种延迟时间，我们业务开发同学完全是可以接受的。该改进目前已经记录 ISSUE，正在考虑贡献到社区中。</p>
<p><a href="https://github.com/apache/streampark/issues/2142" target="_blank" rel="noopener noreferrer">https://github.com/apache/streampark/issues/2142</a></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="带来的收益">带来的收益<a class="hash-link" aria-label="带来的收益的直接链接" title="带来的收益的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#%E5%B8%A6%E6%9D%A5%E7%9A%84%E6%94%B6%E7%9B%8A">​</a></h2>
<p>我们从 StreamX 1.2.3（StreamPark 前身）开始探索和使用，经过一年多时间的磨合，我们发现 StreamPark 真实解决了 Flink 作业在开发管理和运维上的诸多痛点。</p>
<p>StreamPark 给顺网科技带来的最大的收益就是降低了 Flink 的使用门槛，提升了开发效率。我们业务开发同学在原先的 Streaming-Launcher 中需要使用 vscode、GitLab 和调度平台等多个工具完成一个 FlinkSQL 作业开发，从开发到编译到发布的流程中经过多个工具使用，流程繁琐。StreamPark 提供一站式服务，可以在 StreamPark 上完成作业开发编译发布，简化了整个开发流程。</p>
<p><strong>目前 StreamPark 在顺网科技已经大规模在生产环境投入使用，StreamPark 从最开始管理的 500+ 个 FlinkSQL 作业增加到了近 700 个 FlinkSQL作业，同时管理了 10+ 个 Yarn Sesssion Cluster。</strong></p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/achievements1-9eb1dec5b2fa480e897cf1c12d1425d8.png" width="1080" height="572" class="img_iwx1"></p>
<p><img decoding="async" loading="lazy" alt="图片" src="https://streampark.apache.org/zh-CN/assets/images/achievements2-5aa9b3c14892f9b1d8b054e82f3b4ad3.png" width="1080" height="545" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="未-来-规-划">未 来 规 划<a class="hash-link" aria-label="未 来 规 划的直接链接" title="未 来 规 划的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-shunwang#%E6%9C%AA-%E6%9D%A5-%E8%A7%84-%E5%88%92">​</a></h2>
<p>顺网科技作为 StreamPark 早期的用户之一，在 1 年期间内一直和社区同学保持交流，参与 StreamPark 的稳定性打磨，我们将生产运维中遇到的 Bug 和新的 Feature 提交给了社区。在未来，我们希望可以在 StreamPark 上管理 Flink 表的元数据信息，基于 Flink 引擎通过多 Catalog 实现跨数据源查询分析功能。目前 StreamPark 正在对接 Flink-SQL-Gateway 能力，这一块在未来对于表元数据的管理和跨数据源查询功能会提供了很大的帮助。</p>
<p>由于在顺网科技多是已 Yarn Session 模式运行的作业，我们希望 StreamPark 可以提供更多对于 Remote集群、Yarn Session 集群和 K8s Session 集群功能支持，比如监控告警，优化操作流程等方面。</p>
<p>考虑到未来，随着业务发展可能会使用 StreamPark 管理更多的 Flink 实时作业，单节点模式下的 StreamPark 可能并不安全。所以我们对于 StreamPark 的 HA 也是非常期待。</p>
<p>对于 StreamPark 对接 Flink-SQL-Gateway 能力、丰富 Flink Cluster 功能和 StreamPark HA，我们后续也会参与建设中。</p>]]></content:encoded>
            <category>StreamPark</category>
            <category>生产实践</category>
            <category>FlinkSQL</category>
        </item>
        <item>
            <title><![CDATA[Apache StreamPark™ 在尘锋信息的最佳实践，化繁为简极致体验]]></title>
            <link>https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess</link>
            <guid>https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess</guid>
            <pubDate>Mon, 09 Feb 2026 02:32:43 GMT</pubDate>
            <description><![CDATA[摘要：本文源自 StreamPark 在尘锋信息的生产实践，作者是资深数据开发工程师Gump。主要内容为：]]></description>
            <content:encoded><![CDATA[<p>**摘要：**本文源自 StreamPark 在尘锋信息的生产实践，作者是资深数据开发工程师Gump。主要内容为：</p>
<ol>
<li>技术选型</li>
<li>落地实践</li>
<li>业务支撑 &amp; 能力开放</li>
<li>未来规划</li>
<li>结束语</li>
</ol>
<p>尘锋信息是基于企业微信生态的一站式私域运营管理解决方案供应商，致力于成为全行业首席私域运营与管理专家，帮助企业构建数字时代私域运营管理新模式，助力企业实现高质量发展。</p>
<p>目前，尘锋已在全国拥有13个城市中心，覆盖华北、华中、华东、华南、西南五大区域，为超30个行业的10,000+家企业提供数字营销服务。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="01-技术选型"><strong>01 技术选型</strong><a class="hash-link" aria-label="01-技术选型的直接链接" title="01-技术选型的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#01-%E6%8A%80%E6%9C%AF%E9%80%89%E5%9E%8B">​</a></h2>
<p>尘锋信息在2021年进入了快速发展时期，随着服务行业和企业客户的增加，实时需求越来越多，落地实时计算平台迫在眉睫。</p>
<p>由于公司处于高速发展期，需求紧迫且变化快，所以团队的技术选型遵循以下原则:</p>
<ul>
<li>快：由于业务紧迫，我们需要快速落地规划的技术选型并运用生产</li>
<li>稳：满足快的基础上，所选择技术一定要稳定服务业务</li>
<li>新：在以上基础，所选择的技术也尽量的新</li>
<li>全：所选择技术能够满足公司快速发展和变化的业务，能够符合团队长期发展目标，能够支持且快速支持二次开发</li>
</ul>
<p>首先在计算引擎方面：我们选择 Flink，原因如下:</p>
<ul>
<li>团队成员对 Flink 有深入了解，熟读源码</li>
<li>Flink 支持批流一体，虽然目前公司的批处理架构还是基于 Hive、Spark 等。使用 Flink 进行流计算，便于后期建设批流一体和湖仓一体</li>
<li>目前国内 Flink 生态已经越来越成熟，Flink 也开始着手踏破边界向流式数仓发展</li>
</ul>
<p>在平台层面，我们综合对比了 StreamPark 、 Apache Zeppelin 和 flink-streaming-platform-web，也深入阅读了源码和并做了优缺点分析，关于后两个项目本文就不展开赘述，感兴趣的朋友可以去 GitHub 搜索，我们最终选择 StreamPark，理由如下：</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="完成度高"><strong>完成度高</strong><a class="hash-link" aria-label="完成度高的直接链接" title="完成度高的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#%E5%AE%8C%E6%88%90%E5%BA%A6%E9%AB%98">​</a></h3>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="1-支持flink-多版本"><strong>1. 支持Flink 多版本</strong><a class="hash-link" aria-label="1-支持flink-多版本的直接链接" title="1-支持flink-多版本的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#1-%E6%94%AF%E6%8C%81flink-%E5%A4%9A%E7%89%88%E6%9C%AC">​</a></h4>
<p>//视频链接（ Flink 多版本支持 Demo ）</p>
<p>新建任务时可以<strong>自由选择Flink版本</strong>，Flink 二进制版本包会自动上传至 HDFS（如果使用 Yarn 提交），且一个版本的二进制包只会在 HDFS 保存一份。任务启动时会自动根据上下文加载 HDFS 中的 Flink 二进制包，非常优雅。能够满足多版本共存，及升级Flink 新版本试用测试的场景。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_home-0a6f4f2014cc87b074ef259088af2b98.png" width="1080" height="223" class="img_iwx1"></p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="2-支持多种部署模式"><strong>2. 支持多种部署模式</strong><a class="hash-link" aria-label="2-支持多种部署模式的直接链接" title="2-支持多种部署模式的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#2-%E6%94%AF%E6%8C%81%E5%A4%9A%E7%A7%8D%E9%83%A8%E7%BD%B2%E6%A8%A1%E5%BC%8F">​</a></h4>
<p>StreamPark 支持 Flink <strong>所有主流的提交模式</strong>，如 standalone、yarn-session 、yarn application、yarn-perjob、kubernetes-session、kubernetes-application 而且StreamPark 不是简单的拼接 Flink run 命令来进行的任务提交，而是引入了 Flink Client 源码包，直接调用 Flink Client API 来进行的任务提交。这样的好处是代码模块化、易读、便于扩展，稳定，且能在后期根据 Flink 版本升级进行很快的适配。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/execution_mode-1182aeb8efe9572ec98c2a2b95293dc1.png" width="1080" height="324" class="img_iwx1"></p>
<p>Flink SQL 可以极大提升开发效率和提高 Flink 的普及。StreamPark 对于 <strong>Flink SQL 的支持非常到位</strong>，优秀的 SQL 编辑器，依赖管理，任务多版本管理等等。StreamPark 官网介绍后期会加入 Flink SQL 的元数据管理整合，大家拭目以待。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_sql-13f6952f92585140c5fc640b490918b0.png" width="1080" height="779" class="img_iwx1"></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_sql_version-a02b0f0eac9c5d6c0281b7471e438b78.png" width="1080" height="736" class="img_iwx1"></p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="4-java任务在线构建"><strong>4. JAVA任务在线构建</strong><a class="hash-link" aria-label="4-java任务在线构建的直接链接" title="4-java任务在线构建的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#4-java%E4%BB%BB%E5%8A%A1%E5%9C%A8%E7%BA%BF%E6%9E%84%E5%BB%BA">​</a></h4>
<p>//视频链接（ JAVA 任务构建 Demo）</p>
<p>Flink SQL 现在虽然足够强大，但使用 Java 和 Scala 等 JVM 语言开发 Flink 任务会更加灵活、定制化更强、便于调优和提升资源利用率。与 SQL 相比 Jar 包提交任务最大的问题是Jar包的上传管理等，没有优秀的工具产品会严重降低开发效率和加大维护成本。</p>
<p>StreamPark 除了支持 Jar 上传，更提供了<strong>在线更新构建</strong>的功能，优雅解决了以上问题：</p>
<p>1、新建 Project ：填写 GitHub/Gitlab（支持企业私服）地址及用户名密码，StreamPark 就能 Pull 和 Build 项目。</p>
<p>2、创建 StreamPark Custom-Code 任务时引用 Project，指定主类，启动任务时可选自动 Pull、Build 和绑定生成的 Jar，非常优雅！</p>
<p>同时 StreamPark 社区最近也在完善整个任务编译、上线的流程，以后的 StreamPark 会在此基础上更加完善和专业。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/system_list-6e9c13318d5aa2cfa4cdc11ac42c5844.png" width="1080" height="362" class="img_iwx1"></p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="5-完善的任务参数配置"><strong>5. 完善的任务参数配置</strong><a class="hash-link" aria-label="5-完善的任务参数配置的直接链接" title="5-完善的任务参数配置的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#5-%E5%AE%8C%E5%96%84%E7%9A%84%E4%BB%BB%E5%8A%A1%E5%8F%82%E6%95%B0%E9%85%8D%E7%BD%AE">​</a></h4>
<p>对于使用 Flink 做数据开发而言，Flink run 提交的参数几乎是难以维护的。StreamPark 也非常<strong>优雅的解决</strong>了此类问题，原因是上面提到的 StreamPark 直接调用 Flink Client API，并且从 StreamPark 产品前端打通了整个流程。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/parameter_configuration-94fb5d7ee0c9c04ed6d79ddb1cd3c1c7.png" width="1080" height="1001" class="img_iwx1"></p>
<p>大家可以看到，StreamPark 的任务参数设置涵盖了主流的所有参数，并且非常细心的对每个参数都做了介绍和最佳实践的最优推荐。这对于刚使用 Flink 的同学来说也是非常好的事情，避免踩坑！</p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="6-优秀的配置文件设计"><strong>6. 优秀的配置文件设计</strong><a class="hash-link" aria-label="6-优秀的配置文件设计的直接链接" title="6-优秀的配置文件设计的直接��链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#6-%E4%BC%98%E7%A7%80%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%AE%BE%E8%AE%A1">​</a></h4>
<p>对于 Flink 任务的原生参数，上面的任务参数已经涵盖了很大一部分。StreamPark 还提供了强大的<strong>Yaml 配置文件</strong> 模式和 <strong>编程模型</strong>。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/extended_parameters-75c3f87809d0675c2fc82bc8d2ec096e.jpg" width="1080" height="2245" class="img_iwx1"></p>
<p>1、对于 Flink SQL 任务，直接使用任务的 Yaml 配置文件可以配置 StreamPark 已经内置的参数，如常见的 <strong>CheckPoint、重试机制、State Backend、table planer 、mode</strong> 等等。</p>
<p>2、对于 Jar 任务，StreamPark 提供了通用的编程模型，该模型封装了 Flink 原生 API ，结合 StreamPark 提供的封装包可以非常优雅的获取配置文件中的自定义参数，这块文档详见：</p>
<p>编程模型：</p>
<div class="codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-text codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">https://streampark.apache.org/docs/development/Programming-paradigm</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>内置配置文件参数：</p>
<div class="codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-text codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">https://streampark.apache.org/docs/development/config</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>除此之外：</p>
<p>StreamPark 也<strong>支持Apache Flink® 原生任务</strong>，参数配置可以由 Java 任务内部代码静态维护，可以覆盖非常多的场景，比如存量 Flink 任务无缝迁移等等</p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="7-checkpoint-管理"><strong>7. Checkpoint 管理</strong><a class="hash-link" aria-label="7-checkpoint-管理的直接链接" title="7-checkpoint-管理的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#7-checkpoint-%E7%AE%A1%E7%90%86">​</a></h4>
<p>关于 Flink 的 Checkpoint（Savepoint）机制，最大的困难是维护 ，StreamPark 也非常优雅的解决此问题:</p>
<ul>
<li>StreamPark 会<strong>自动维护</strong>任务 Checkpoint 的目录及版本至系统中方便检索</li>
<li>当用户需要更新重启应用时，可以选择是否保存 Savepoint</li>
<li>重新启动任务时可选择 Checkpoint/Savepoint 从指定版本的恢复</li>
</ul>
<p>如下，开发同学能够非常直观方便的升级或处理异常任务，非常强大</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/checkpoint-e9edd22da076247770a0b40595626fb7.png" width="1080" height="483" class="img_iwx1"></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/recover-f1de53fdbe66c50b465d58d0a66050de.jpg" width="1053" height="391" class="img_iwx1"></p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="8-完善的报警功能"><strong>8. 完善的报警功能</strong><a class="hash-link" aria-label="8-完善的报警功能的直接链接" title="8-完善的报警功能的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#8-%E5%AE%8C%E5%96%84%E7%9A%84%E6%8A%A5%E8%AD%A6%E5%8A%9F%E8%83%BD">​</a></h4>
<p>对于流式计算此类7*24H常驻任务来说，监控报警是非常重要的 ，StreamPark 对于此类问题也有<strong>完善的解决方案</strong>:</p>
<ul>
<li>自带基于邮件的报警方式，0开发成本，配置即可使用</li>
<li>得益于 StreamPark 源码优秀的模块化，可以在 Task Track 处进行代码增强，引入公司内部的 SDK 进行电话、群组等报警方式，开发成本也非常低</li>
</ul>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/alarm_email-fd4c9ba1995ec69b7557bd1378dce737.png" width="1009" height="1340" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="源码优秀"><strong>源码优秀</strong><a class="hash-link" aria-label="源码优秀的直接链接" title="源码优秀的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#%E6%BA%90%E7%A0%81%E4%BC%98%E7%A7%80">​</a></h3>
<p>遵循技术选型原则，一个新的技术必须足够了解底层原理和架构思想后，才会考虑应用生产。在选择 StreamPark 之前，对其架构和源码进入过深入研究和阅读。发现 StreamPark 所选用的底层技术是国人非常熟悉的：MySQL、Spring Boot、Mybatis Plus、Vue 等，代码风格统一，实现优雅，注释完善，各模块独立抽象合理，使用了较多的设计模式，且代码质量很高，非常适合后期的排错及二次开发。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/code_notebook-542046feb8a312b5f6c057af551421c6.png" width="1080" height="527" class="img_iwx1"></p>
<p>StreamPark 于 2021年11月成功被开源中国评选为GVP - Gitee「最有价值开源项目」，足以见得其质量和潜力。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/certificate-2f5b95ebb0816ead327ec169c12996b6.png" width="1080" height="684" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="03-社区活跃"><strong>03 社区活跃</strong><a class="hash-link" aria-label="03-社区活跃的直接链接" title="03-社区活跃的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#03-%E7%A4%BE%E5%8C%BA%E6%B4%BB%E8%B7%83">​</a></h3>
<p>目前社区非常活跃，从2021年11月底落地 StreamPark (基于1.2.0-release），当时StreamPark 刚刚才被大家认识，还有一些体验上的小 Bug（不影响核心功能）。当时为了快速上线，屏蔽掉了一些功能和修复了一些小 Bug，正当准备贡献给社区时发现早已修复，这也可以看出目前社区的迭代周期非常快。以后我们公司团队也会努力和社区保持一致，将新特性快速落地，提升数据开发效率和降低维护成本。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="02-落地实践"><strong>02 落地实践</strong><a class="hash-link" aria-label="02-落地实践的直接链接" title="02-落地实践的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#02-%E8%90%BD%E5%9C%B0%E5%AE%9E%E8%B7%B5">​</a></h2>
<p>StreamPark 的环境搭建非常简单，跟随官网的搭建教程可以在小时内完成搭建。目前已经支持了前后端分离打包部署的模式，可以满足更多公司的需求，而且已经有 Docker Build 相关的 PR，相信以后 StreamPark 的编译部署会更加方便快捷。相关文档如下:</p>
<div class="codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-text codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">https://streampark.apache.org/docs/user-guide/deployment</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>为了快速落地和生产使用，我们选择了稳妥的 On Yarn 资源管理模式（虽然 StreamPark 已经很完善的支持 K8S），且已经有较多公司通过 StreamPark 落地了 K8S 部署方式，大家可以参考:</p>
<div class="codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-text codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">https://streampark.apache.org/blog/flink-development-framework-streampark</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>StreamPark 整合 Hadoop 生态可以说是0成本的（前提是按照 Flink 官网将 Flink 与 Hadoop 生态整合，能够通过 Flink 脚本启动任务即可）</p>
<p>目前我们也正在进行 K8S 的测试及方案设计，在未来一段时间会整体迁移至 K8S</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="01-落地-flinksql-任务"><strong>01 落地 FlinkSQL 任务</strong><a class="hash-link" aria-label="01-落地-flinksql-任务的直接链接" title="01-落地-flinksql-任务的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#01-%E8%90%BD%E5%9C%B0-flinksql-%E4%BB%BB%E5%8A%A1">​</a></h3>
<p>目前我们公司基于 Flink SQL 的任务主要为业务比较简单的实时 ETL 和计算场景，数量在10个左右，上线至今都十分稳定。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/online_flinksql-ca82a6f42e04e54e9f6da2b1e391b073.png" width="1080" height="118" class="img_iwx1"></p>
<p>StreamPark 非常贴心的准备了 Demo SQL 任务，可以直接在刚搭建的平台上运行，从这些细节可以看出社区对用户体验非常重视。前期我们的简单任务都是通过 Flink SQL 来编写及运行，StreamPark 对于 Flink SQL 的支持得非常好，优秀的 SQL 编辑器，创新型的 POM 及 Jar 包依赖管理，可以满足非常多的 SQL 场景下的问题。</p>
<p>目前我们正在进行元数据层面、权限、UDF等相关的方案调研、设计等</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="02-落地-jar-任务"><strong>02 落地 Jar 任务</strong><a class="hash-link" aria-label="02-落地-jar-任务的直接链接" title="02-落地-jar-任务的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#02-%E8%90%BD%E5%9C%B0-jar-%E4%BB%BB%E5%8A%A1">​</a></h3>
<p>由于目前团队的数据开发同学大多有 Java 和 Scala 语言基础，为了更加灵活的开发、更加透明的调优 Flink 任务及覆盖更多场景，我们也快速的落地了基于 Jar 包的构建方式。我们落地分为了两个阶段</p>
<p>第一阶段：<strong>StreamPark 提供了原生 Apache Flink® 项目的支持</strong>，我们将存量的任务Git地址配置至 StreamPark，底层使用 Maven 打包为 Jar 包，创建 StreamPark 的 Apache Flink任务，无缝的进行了迁移。在这个过程中，StreamPark 只是作为了任务提交和状态维护的一个平台工具，远远没有使用到上面提到的其他功能。</p>
<p>第二阶段：第一阶段将任务都迁移至 StreamPark 上之后，任务已经在平台上运行，但是任务的配置，如 checkpoint，容错以及 Flink 任务内部的业务参数的调整都需要修改源码 push 及 build，效率十分低下且不透明。</p>
<p>于是，根据 StreamPark 的 QuickStart 我们快速整合了StreamPark 的编程模型，也就是StreamPark Flink 任务（对于 Apache Flink）的封装。</p>
<p>如：</p>
<div class="codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-text codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">StreamingContext = ParameterTool + StreamExecutionEnvironment</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li>StreamingContext 为 StreamPark 的封装对象</li>
<li>ParameterTool 为解析配置文件后的参数对象</li>
</ul>
<div class="codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-text codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain"> String value = ParameterTool.get("${user.custom.key}")</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<ul>
<li>StreamExecutionEnvironment 为 Apache Flink® 原生任务上下文</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="03-业务支撑--能力开放"><strong>03 业务支撑 &amp; 能力开放</strong><a class="hash-link" aria-label="03-业务支撑--能力开放的直接链接" title="03-业务支撑--能力开放的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#03-%E4%B8%9A%E5%8A%A1%E6%94%AF%E6%92%91--%E8%83%BD%E5%8A%9B%E5%BC%80%E6%94%BE">​</a></h2>
<p>目前尘锋基于 StreamPark 的实时计算平台从去年11月底上线至今，已经上线 50+ Flink 任务，其中 10+为 Flink SQL 任务，40+ 为 Jar 任务。目前主要还是数据团队内部使用，近期会将实时计算平台开放全公司业务团队使用，任务量会大量增加。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/online_jar-48549248f657388c7aebc0c8491660fa.png" width="1080" height="445" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="01-实时数仓"><strong>01 实时数仓</strong><a class="hash-link" aria-label="01-实时��数仓的直接链接" title="01-实时数仓的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#01-%E5%AE%9E%E6%97%B6%E6%95%B0%E4%BB%93">​</a></h3>
<p>时数仓主要是用 Jar 任务，因为模式比较通用，使用 Jar 任务可以通用化的处理大量的数据表同步和计算，甚至做到配置化同步等，我们的实时数仓主要基 Apache Doris 来存储，使用 Flink 来进行清洗计算（目标是存算分离）</p>
<p>使用 StreamPark 整合其他组件也是非常简单，同时我们也将 Apache Doris 和 Kafka 相关的配置也抽象到了配置文件中，大大提升了我们的开发效率和灵活度。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="02-能力开放"><strong>02 能力开放</strong><a class="hash-link" aria-label="02-能力开放的直接链接" title="02-能力开放的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#02-%E8%83%BD%E5%8A%9B%E5%BC%80%E6%94%BE">​</a></h3>
<p>数据团队外的其他业务团队也有很多的流处理场景，于是我们将基于 StreamPark 的实时计算平台二次开发后，将以下能力开放全公司业务团队</p>
<ul>
<li>业务能力开放：实时数仓上游将所有业务表通过日志采集写入 Kafka，业务团队可基于 Kafka 进行业务相关开发，也可通过实时数仓（Apache Doris）进行 OLAP分析</li>
<li>计算能力开放：将大数据平台的服务器资源开放业务团队使用</li>
<li>解决方案开放：Flink 生态的成熟 Connector、Exactly Once 语义支持，可减少业务团队流处理相关的开发成本及维护成本</li>
</ul>
<p>目前 StreamPark 还不支持多业务组功能，多业务组功能会抽象后贡献社区。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/manager-07ba2a4bc979cd2dd86fc9e07384ec61.png" width="1080" height="235" class="img_iwx1"></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/task_retrieval-eee86f9c0af117cbf15d2af5d528b2cc.png" width="1080" height="382" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="04-未来规划"><strong>04 未来规划</strong><a class="hash-link" aria-label="04-未来规划的直接链接" title="04-未来规划的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#04-%E6%9C%AA%E6%9D%A5%E8%A7%84%E5%88%92">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="01-flink-on-k8s"><strong>01 Flink on K8S</strong><a class="hash-link" aria-label="01-flink-on-k8s的直接链接" title="01-flink-on-k8s的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#01-flink-on-k8s">​</a></h3>
<p>目前我司 Flink 任务都运行在 Yarn 上，满足当下需求，但 Flink on kubernetes 有以下优点:</p>
<ul>
<li><strong>统一运维</strong>。公司统一化运维，有专门的部门运维 K8S</li>
<li><strong>CPU 隔离</strong>。K8S Pod 之间 CPU 隔离，实时任务不相互影响，更加稳定</li>
<li><strong>存储计算分离</strong>。Flink 计算资源和状态存储分离，计算资源能够和其他组件资源进行混部，提升机器使用率</li>
<li><strong>弹性扩缩容</strong>。能够弹性扩缩容，更好的节省人力和物力成本</li>
</ul>
<p>目前本人也在整理和落地相关的技术架构及方案，并已在实验环境使用 StreamPark 完成了 Flink on kubernetes 的技术验证，生产落地这一目标由于有 StreamPark 的平台支持，以及社区同学的热心帮心，相信在未来不久就能达成。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="02-流批一体建设"><strong>02 流批一体建设</strong><a class="hash-link" aria-label="02-流批一体建设的直接链接" title="02-流批一体建设的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#02-%E6%B5%81%E6%89%B9%E4%B8%80%E4%BD%93%E5%BB%BA%E8%AE%BE">​</a></h3>
<p>个人认为批/流最大的区别在于算子 Task 的调度策略 和 数据在算子间的流转策略：</p>
<ul>
<li><strong>批处理</strong>上下游算子 Task 存在先后调度（上游Task结束释放资源），数据存在 Shuffle 策略（落地磁盘），缺点是时效性较低且计算无中间状态，但优点是吞吐量大，适合离线超大数据量计算。</li>
<li><strong>流处理</strong>上下游算子 Task 同时拉起（同时占用资源），数据通过网络在节点间流式计算，缺点是吞吐量不足，优点是时效性高及计算有中间状态，适合实时及增量计算场景。</li>
</ul>
<p>如上，个人认为选择<strong>批处理</strong>还是<strong>流处理</strong>，<strong>是数据开发针对不同数据量和不同业务场景的一种调优方式</strong>。但目前由于计算引擎和计算平台会将离线、实时区分，会造成开发及维护的撕裂，成本巨高不下。如果要实现批流一体，要实现以下几个方面：</p>
<ul>
<li>存储的统一（元数据的统一）：支持批及流的写入/读取</li>
<li>计算引擎的统一 ：能够使用一套 API 或 SQL 开发离线和实时任务</li>
<li>数据平台的统一 ：能够支持实时任务常驻，也能支持离线调度策略</li>
</ul>
<p>关于批流统一这一块，目前也正在调研、整理、感兴趣的小伙伴欢迎一块探讨项目学习。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="05-结束语"><strong>05 结束语</strong><a class="hash-link" aria-label="05-结束语的直接链接" title="05-结束语的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-dustess#05-%E7%BB%93%E6%9D%9F%E8%AF%AD">​</a></h2>
<p>以上就是 StreamPark 在尘锋信息生产实践的全部分享内容，感谢大家看到这里。写这篇文章的初心是为大家带来一点 StreamPark 的生产实践的经验和参考，并且和 StreamPark 社区的小伙伴们一道，共同建设 StreamPark ，未来也准备会有更多的参与和建设。非常感谢 StreamPark 的开发者们，能够提供这样优秀的产品，足够多的细节都感受到了大家的用心。虽然目前公司生产使用的（1.2.0-release）版本，在任务分组检索，编辑返回跳页等交互体验上还有些许不足，但瑕不掩瑜，相信 StreamPark 会越来越好，<strong>也相信 StreamPark 会推动 Apache Flink® 的普及</strong>。最后用 Apache Flink® 社区的一句话来作为结束吧：实时即未来！</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/author-487ad3c1ad9a397cd4c2614f54976368.png" width="844" height="439" class="img_iwx1"></p>]]></content:encoded>
            <category>StreamPark</category>
            <category>生产实践</category>
            <category>FlinkSQL</category>
        </item>
        <item>
            <title><![CDATA[Apache StreamPark™ 在 Joyme 的生产实践]]></title>
            <link>https://streampark.apache.org/zh-CN/blog/streampark-usercase-joyme</link>
            <guid>https://streampark.apache.org/zh-CN/blog/streampark-usercase-joyme</guid>
            <pubDate>Mon, 09 Feb 2026 02:32:43 GMT</pubDate>
            <description><![CDATA[摘要： 本文带来 StreamPark 在 Joyme 中的生产实践，作者是 Joyme 的大数据工程师秦基勇，主要内容为:]]></description>
            <content:encoded><![CDATA[<p><strong>摘要：</strong> 本文带来 StreamPark 在 Joyme 中的生产实践，作者是 Joyme 的大数据工程师秦基勇，主要内容为:</p>
<ul>
<li>遇见StreamPark</li>
<li>Flink Sql 作业开发</li>
<li>Custom code 作业开发</li>
<li>监控告警</li>
<li>常见问题</li>
<li>社区印象</li>
<li>总结</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="1-遇见-apache-streampark">1 遇见 Apache StreamPark™<a class="hash-link" aria-label="1 遇见 Apache StreamPark™的直接链接" title="1 遇见 Apache StreamPark™的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joyme#1-%E9%81%87%E8%A7%81-apache-streampark">​</a></h2>
<p>遇见 StreamPark 是必然的，基于我们现有的实时作业开发模式，不得不寻找一个开源的平台来支撑我司的实时业务。我们的现状如下:</p>
<ul>
<li>编写作业打包到服务器，然后执行 Flink run 命令进行提交，过程繁琐，效率低下</li>
<li>Flink Sql 通过自研的老平台提交，老平台开发人员已离职，后续的代码无人维护，即便有人维护也不得不面对维护成本高的问题</li>
<li>其中一部分作者是 SparkStreaming 作业，两套流引擎，框架不统一，开发成本大</li>
<li>实时作业有 Scala 和 Java 开发，语言和技术栈不统一</li>
</ul>
<p>基于以上种种原因，我们需要一个开源平台来管理我们的实时作业，同时我们也需要进行重构，统一开发模式，统一开发语言，将项目集中管理。</p>
<p>第一次遇见 StreamPark 就基本确定了，我们根据官网的文档快速进行了部署安装，搭建以后进行了一些操作，界面友好，Flink 多版本支持，权限管理，作业监控等一系列功能已能较好的满足我们的需求，进一步了解到其社区也很活跃，从 1.1.0 版本开始见证了 StreamPark 功能完善的过程，开发团队是非常有追求的，相信会不断的完善。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="2-flink-sql-作业开发">2 Flink SQL 作业开发<a class="hash-link" aria-label="2 Flink SQL 作业开发的直接链接" title="2 Flink SQL 作业开发的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joyme#2-flink-sql-%E4%BD%9C%E4%B8%9A%E5%BC%80%E5%8F%91">​</a></h2>
<p>Flink Sql 开发模式带来了很大的便利，对于一些简单的指标开发，只需要简单的 Sql 就可以完成，不需要写一行代码。Flink Sql 方便了很多同学的开发工作，毕竟一些做仓库的同学在编写代码方面还是有些难度。</p>
<p>打开 StreamPark 的任务新增界面进行添加新任务，默认 Development Mode 就是 Flink Sql 模式。直接在 Flink Sql 部分编写Sql 逻辑。</p>
<p>Flink Sql 部分，按照 Flink 官网的文档逐步编写逻辑 Sql 即可，对于我司来说，一般就三部分: 接入 Source ，中间逻辑处理，最后 Sink。基本上 Source 都是消费 kafka 的数据，逻辑处理层会有关联 MySQL 去做维表查询，最后 Sink 部分大多是 Es，Redis，MySQL。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="1-编写sql"><strong>1. 编写SQL</strong><a class="hash-link" aria-label="1-编写sql的直接链接" title="1-编写sql的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joyme#1-%E7%BC%96%E5%86%99sql">​</a></h3>
<div class="language-sql codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-sql codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token comment" style="color:rgb(106, 153, 85)">-- 连接kafka</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> source_table </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"> </span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">Data</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">ROW</span><span class="token operator" style="color:rgb(212, 212, 212)">&lt;</span><span class="token plain">uid STRING</span><span class="token operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector.type'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'kafka'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector.version'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'universal'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector.topic'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'主题'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector.properties.bootstrap.servers'</span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token string" style="color:rgb(206, 145, 120)">'broker地址'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector.startup-mode'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'latest-offset'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'update-mode'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'append'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'format.type'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'json'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector.properties.group.id'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'消费组id'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'format.derive-schema'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'true'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- 落地表sink</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">TABLE</span><span class="token plain"> sink_table </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token identifier">uid</span><span class="token identifier punctuation" style="color:rgb(212, 212, 212)">`</span><span class="token plain"> STRING</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">WITH</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector.type'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'jdbc'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector.url'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'jdbc:mysql://xxx/xxx?useSSL=false'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector.username'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'username'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector.password'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'password'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector.table'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'tablename'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector.write.flush.max-rows'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'50'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector.write.flush.interval'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'2s'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token string" style="color:rgb(206, 145, 120)">'connector.write.max-retries'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'3'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">-- 代码逻辑过</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(86, 156, 214)">INTO</span><span class="token plain"> sink_table</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token keyword" style="color:rgb(86, 156, 214)">SELECT</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(86, 156, 214)">Data</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">uid  </span><span class="token keyword" style="color:rgb(86, 156, 214)">FROM</span><span class="token plain"> source_table</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="2-添加依赖"><strong>2. 添加依赖</strong><a class="hash-link" aria-label="2-添加依赖的直接链接" title="2-添加依赖的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joyme#2-%E6%B7%BB%E5%8A%A0%E4%BE%9D%E8%B5%96">​</a></h3>
<p>关于依赖这块是 StreamPark 里特有的，在 StreamPark 中创新型的将一个完整的 Flink Sql 任务拆分成两部分组成: Sql 和 依赖，Sql 很好理解不多啰嗦，依赖是 Sql 里需要用到的一些 Connector 的 Jar，如 Sql 里用到了 Kafka 和 MySQL 的 Connector，那就需要引入这两个 Connector 的依赖，在 StreamPark 中添加依赖两种方式，一种是基于标准的 Maven pom 坐标方式，另一种是从本地上传需要的 Jar 。这两种也可以混着用，按需添加，点击应用即可， 在提交作业的时候就会自动加载这些依赖。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/add_dependency-281888d96a8f3ce6e9af01efef9de643.png" width="1080" height="469" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="3-参数配置"><strong>3. 参数配置</strong><a class="hash-link" aria-label="3-参数配置的直接链接" title="3-参数配置的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joyme#3-%E5%8F%82%E6%95%B0%E9%85%8D%E7%BD%AE">​</a></h3>
<p>在任务的添加和修改页面中已经罗列了一些常用的参数设置，更多的参数设置则提供了一个 yaml 配置文件，我们这里只是设置了 checkpoint 和 savepoint 这两个配置。一是 checkpoint 的位置，二是 执行 checkpoint 的频率。其他的配置基本没有动，这部分用户可以根据自己的需要按需配置。</p>
<p>剩下的一些参数设置就要根据作业的具体情况去对症下药的配置了，处理的数据量大了，逻辑复杂了，可能就需要更多的内存，并行度给多一些。有时候需要根据作业的运行情况进行多次调整。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/checkpoint_configuration-861a4f0439b1a0f8aade35e10e6b60c5.png" width="1080" height="610" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="4-动态参数设置"><strong>4. 动态参数设置</strong><a class="hash-link" aria-label="4-动态参数设置的直接链接" title="4-动态参数设置的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joyme#4-%E5%8A%A8%E6%80%81%E5%8F%82%E6%95%B0%E8%AE%BE%E7%BD%AE">​</a></h3>
<p>由于我们的模式部署是 on Yarn，在动态选项配置里配置了 Yarn 的队列名称。也有一些配置了开启增量的 Checkpoint 选项和状态过期时间，基本的这些参数都可以从 Flink 的官网去查询到。之前有一些作业确实经常出现内存溢出的问题，加上增量参数和过期参数以后，作业的运行情况好多了。还有就是 Flink Sql 作业设计到状态这种比较大和逻辑复杂的情况下，我个人感觉还是用 Streaming 代码来实现比较好控制一些。</p>
<ul>
<li>-Dyarn.application.queue= yarn队列名称</li>
<li>-Dstate.backend.incremental=true</li>
<li>-Dtable.exec.state.ttl=过期时间</li>
</ul>
<p>完成配置以后提交，然后在 application 界面进行部署。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/application_job-5518b58af2b481d7bdb36a7bae252c41.png" width="1080" height="422" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="3-custom-code-作业开发">3 Custom Code 作业开发<a class="hash-link" aria-label="3 Custom Code 作业开发的直接链接" title="3 Custom Code 作业开发的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joyme#3-custom-code-%E4%BD%9C%E4%B8%9A%E5%BC%80%E5%8F%91">​</a></h2>
<p>Streaming 作业我们是使用 Flink java 进行开发，将之前 Spark scala，Flink scala，Flink java 的作业进行了重构，然后工程整合到了一起，目的就是为了维护起来方便。Custom code 作业需要提交代码到 Git，然后配置项目:</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/project_configuration-add3d079bba91ac4977b830d3c3fe8f7.png" width="1080" height="365" class="img_iwx1"></p>
<p>配置完成以后，根据对应的项目进行编译，也就完成项目的打包环节。这样后面的 Constom code 作业也可以引用。每次需要上线都需要进行编译才可以，否则只能是上次编译的代码。这里有个问题，为了安全，我司的 gitlab 账号密码都是定期更新的。这样就会导致，StreamPark 已经配置好的项目还是之前的密码，结果导致编译时从 git 里拉取项目失败，导致整个编译环节失败，针对这个问题，我们联系到社区，了解到这部分已经在后续的 1.2.1 版本中支持了项目的修改操作。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_system-02dee8b704254087aae900731ae47076.png" width="1080" height="214" class="img_iwx1"></p>
<p>新建任务，选择 Custom code ，选择 Flink 版本，选择项目以及模块 Jar 包，选择开发的应用模式为 Apache Flink® (标准的 Flink 程序)，程序主函数入口类，任务的名称。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/add_projectconfiguration-26b97212de577a0cbc46b59f1eceea0b.png" width="1080" height="536" class="img_iwx1"></p>
<p>以及任务的并行度，监控的方式等，内存大小根据任务需要进行配置。Program Args 程序的参数则根据程序需要自行定义入口参数，比如：我们统一启动类是 StartJobApp，那么启动作业就需要传入作业的 Full name 告诉启动类要去找哪个类来启动此次任务，也就是一个反射机制，作业配置完成以后同样也是 Submit 提交，然后在 application 界面部署任务。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/application_interface-51c8f96e343842f32b56c3c889064cba.png" width="1080" height="500" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="4-监控告警">4 监控告警<a class="hash-link" aria-label="4 监控告警的直接链接" title="4 监控告警的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joyme#4-%E7%9B%91%E6%8E%A7%E5%91%8A%E8%AD%A6">​</a></h2>
<p>StreamPark 的监控需要在 setting 模块去配置发送邮件的基本信息。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/system_setting-6b5b21f22fc4a32b973ede0a5f21ebc2.png" width="1080" height="380" class="img_iwx1"></p>
<p>然后在任务里配置重启策略：监控在多久内几次异常，然后是报警还是重启的策略，同时发送报警要发到哪个邮箱。目前我司使用版本是 1.2.1 只支持邮件发送。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/email_setting-7b8ddba6688c75cfad32f5d16e93354f.png" width="1080" height="243" class="img_iwx1"></p>
<p>当我们的作业出现失败的情况下，就可以接收到报警邮箱。这报警还是很好看的有木有，可以清楚看到我们的哪个作业，什么状态。也可以点击下面的具体地址进行查看。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/alarm_eamil-29b2875dbfcbeb071fef815ab751786a.png" width="1080" height="1517" class="img_iwx1"></p>
<p>关于报警这一块目前我们基于 StreamPark 的 t_flink_app 表进行了一个定时任务的开发。为什么要这么做？因为发送邮件这种通知，大部分人可能不会去及时去看。所以我们选择监控每个任务的状态去把对应的监控信息发送我们的飞书报警群，这样可以及时发现问题去解决任务。一个简单的 python 脚本，然后配置了 crontab 去定时执行。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="5-常见问题">5 常见问题<a class="hash-link" aria-label="5 常见问题的直接链接" title="5 常见问题的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joyme#5-%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98">​</a></h2>
<p>关于作业的异常问题，我们归纳分析了基本分为这么几种情况:</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="1-作业启动失败"><strong>1. 作业启动失败</strong><a class="hash-link" aria-label="1-作业启动失败的直接链接" title="1-作业启动失败的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joyme#1-%E4%BD%9C%E4%B8%9A%E5%90%AF%E5%8A%A8%E5%A4%B1%E8%B4%A5">​</a></h3>
<p>作业启动失败的问题，就是点击启动运行部署。发现起不来，这时候需要看界面的详情信息的日志。在我们的任务列表中有一个眼睛的按钮，点进去。在start logs 中会找到提交的作业日志信息，点进去查看，如果有明显的提示信息，直接解决就可以了。如果没有，就需要去查看后台部署任务的目录 logs/下面的 streamx.out，打开以后会找到启动失败的日志信息。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/start_log-6ce6b3125c8693db96197193241d6807.png" width="1080" height="83" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="2-作业运行失败"><strong>2. 作业运行失败</strong><a class="hash-link" aria-label="2-作业运行失败的直接链接" title="2-作业运行失败的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joyme#2-%E4%BD%9C%E4%B8%9A%E8%BF%90%E8%A1%8C%E5%A4%B1%E8%B4%A5">​</a></h3>
<p>如果是任务已经起来了，但是在运行阶段失败了。这种情况表面看上去和上面的情况一样，实则完全不同，这种情况是已经将任务提交给集群了，但是任务运行不起来，那就是我们的任务自身有问题了。同样可以用上面第一种情况的排查方式打开作业的具体日志，找到任务在 yarn 上运行的信息，根据日志里记录的 yarn 的 tackurl 去 yarn 的日志里查看具体的原因，是 Sql 的 Connector 不存在，还是代码的哪行代码空指针了，都可以看到具体的堆栈信息。有了具体信息，就可以对症下药了。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/yarn_log-100e18b484ec81cf3165736de8259365.png" width="1080" height="82" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="6-社区印象">6 社区印象<a class="hash-link" aria-label="6 社区印象的直接链接" title="6 社区印象的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joyme#6-%E7%A4%BE%E5%8C%BA%E5%8D%B0%E8%B1%A1">​</a></h2>
<p>很多时候我们在 StreamPark 用户群里讨论问题，都会得到社区小伙伴的即时响应。提交的一些 issue 在当下不能解决的，基本也会在下一个版本或者最新的代码分支中进行修复。在群里，我们也看到很多不是社区的小伙伴，也在积极互相帮助去解决问题。群里也有很多其他社区的大佬，很多小伙伴也积极加入了社区的开发工作。整个社区给我的感觉还是很活跃！</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="7-总结">7 总结<a class="hash-link" aria-label="7 总结的直接链接" title="7 总结的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-joyme#7-%E6%80%BB%E7%BB%93">​</a></h2>
<p>目前我司线上运行 60 个实时作业，Flink sql 与 Custom-code 差不多各一半。后续也会有更多的实时任务进行上线。很多同学都会担心 StreamPark 稳不稳定的问题，就我司根据几个月的生产实践而言，StreamPark 只是一个帮助你开发作业，部署，监控和管理的一个平台。到底稳不稳，还是要看自家的 Hadoop yarn 集群稳不稳定（我们用的onyan模式），其实已经跟 StreamPark关系不大了。还有就是你写的 Flink Sql 或者是代码健不健壮。更多的是这两方面应该是大家要考虑的，这两方面没问题再充分利用 StreamPark 的灵活性才能让作业更好的运行，单从一方面说 StreamPark 稳不稳定，实属偏激。</p>
<p>以上就是 StreamPark 在乐我无限的全部分享内容，感谢大家看到这里。非常感谢 StreamPark 提供给我们这么优秀的产品，这就是做的利他人之事。从1.0 到 1.2.1 平时遇到那些bug都会被即时的修复，每一个issue都被认真对待。目前我们还是 onyarn的部署模式，重启yarn还是会导致作业的lost状态，重启yarn也不是天天都干的事，关于这个社区也会尽早的会去修复这个问题。相信 StreamPark 会越来越好，未来可期。</p>]]></content:encoded>
            <category>StreamPark</category>
            <category>生产实践</category>
            <category>FlinkSQL</category>
        </item>
        <item>
            <title><![CDATA[Apache StreamPark™ 一站式计算利器在海博科技的生产实践，助力智慧城市建设]]></title>
            <link>https://streampark.apache.org/zh-CN/blog/streampark-usercase-haibo</link>
            <guid>https://streampark.apache.org/zh-CN/blog/streampark-usercase-haibo</guid>
            <pubDate>Mon, 09 Feb 2026 02:32:43 GMT</pubDate>
            <description><![CDATA[摘要：本文「 StreamPark 一站式计算利器在海博科技的生产实践，助力智慧城市建设 」作者是海博科技大数据架构师王庆焕，主要内容为：]]></description>
            <content:encoded><![CDATA[<p>**摘要：**本文「 StreamPark 一站式计算利器在海博科技的生产实践，助力智慧城市建设 」作者是海博科技大数据架构师王庆焕，主要内容为：</p>
<ol>
<li>选择 StreamPark</li>
<li>快速上手</li>
<li>应用场景</li>
<li>功能扩展</li>
<li>未来期待</li>
</ol>
<p>海博科技是一家行业领先的人工智能物联网产品和解决方案公司。目前在公共安全、智慧城市、智慧制造领域，为全国客户提供包括算法、软件和硬件产品在内的全栈式整体解决方案。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="01-选择-apache-streampark"><strong>01. 选择 Apache StreamPark™</strong><a class="hash-link" aria-label="01-选择-apache-streampark的直接链接" title="01-选择-apache-streampark的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-haibo#01-%E9%80%89%E6%8B%A9-apache-streampark">​</a></h2>
<p>海博科技自 2020 年开始使用 Flink SQL 汇聚、处理各类实时物联数据。随着各地市智慧城市建设步伐的加快，需要汇聚的各类物联数据的数据种类、数据量也不断增加，导致线上维护的 Flink SQL 任务越来越多，一个专门的能够管理众多 Flink SQL 任务的计算平台成为了迫切的需求。</p>
<p>在体验对比了 Apache Zeppelin 和 StreamPark 之后，我们选择了 StreamPark 作为公司的实时计算平台。相比 Apache Zeppelin， StreamPark 并不出名。‍‍‍‍‍‍‍‍‍‍‍‍但是在体验了 StreamPark 发行的初版，阅读其设计文档后，我们发现其基于 <strong>一站式</strong> 设计的思想，能够覆盖 Flink 任务开发的全生命周期，使得配置、开发、部署、运维全部在一个平台即可完成。我们的开发、运维、测试的同学可以使用 StreamPark 协同工作，<strong>低代码</strong> + <strong>一站式</strong> 的设计思想坚定了我们使用 StreamPark 的信心。</p>
<p>//视频链接（ StreamX 官方视频）</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="02-落地实践"><strong>02. 落地实践</strong><a class="hash-link" aria-label="02-落地实践的直接链接" title="02-落地实践的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-haibo#02-%E8%90%BD%E5%9C%B0%E5%AE%9E%E8%B7%B5">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="1-快速上手"><strong>1. 快速上手</strong><a class="hash-link" aria-label="1-快速上手的直接链接" title="1-快速上手的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-haibo#1-%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B">​</a></h3>
<p>使用 StreamPark 完成一个实时汇聚任务就像把大象放进冰箱一样简单，仅需三步即可完成:</p>
<ul>
<li>编辑 SQL</li>
</ul>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_sql-a8811954a9f765640bb08ad9cd139a15.png" width="1080" height="578" class="img_iwx1"></p>
<ul>
<li>上传依赖包</li>
</ul>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/dependency-172169d43c50f455fb7e2c7e08de32a2.png" width="1080" height="449" class="img_iwx1"></p>
<ul>
<li>部署运行</li>
</ul>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/deploy-d486a5c0eb238a9f2a6ce5f2b3013500.png" width="1080" height="538" class="img_iwx1"></p>
<p>仅需上述三步，即可完成 Mysql 到 Elasticsearch 的汇聚任务，大大提升数据接入效率。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="2-生产实践"><strong>2. 生产实践</strong><a class="hash-link" aria-label="2-生产实践的直接链接" title="2-生产实践的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-haibo#2-%E7%94%9F%E4%BA%A7%E5%AE%9E%E8%B7%B5">​</a></h3>
<p>StreamPark 在海博主要用于运行实时 Flink SQL任务: 读取 Kafka 上的数据，进行处理输出至 Clickhouse 或者 Elasticsearch 中。</p>
<p>从2021年10月开始，公司逐渐将 Flink SQL 任务迁移至 StreamPark 平台来集中管理，承载我司实时物联数据的汇聚、计算、预警。</p>
<p>截至目前，StreamPark 已在多个政府、公安生产环境进行部署，汇聚处理城市实时物联数据、人车抓拍数据。以下是在某市专网部署的 StreamPark 平台截图 :</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/application-b12eb5d36d548a02e52ec12a28ddcec0.png" width="1080" height="613" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="03-应用场景"><strong>03. 应用场景</strong><a class="hash-link" aria-label="03-应用场景的直接链接" title="03-应用场景的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-haibo#03-%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF">​</a></h2>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="1-实时物联感知数据汇聚"><strong>1. 实时物联感知数据汇聚</strong><a class="hash-link" aria-label="1-实时物联感知数据汇聚的直接链接" title="1-实时物联感知数据汇聚的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-haibo#1-%E5%AE%9E%E6%97%B6%E7%89%A9%E8%81%94%E6%84%9F%E7%9F%A5%E6%95%B0%E6%8D%AE%E6%B1%87%E8%81%9A">​</a></h4>
<p>汇聚实时的物联感知数据，我们直接使用 StreamPark 开发 Flink SQL 任务，针对 Flink SQL 未提供的方法，StreamPark 也支持 Udf 相关功能，用户通过 StreamPark 上传 Udf 包，即可在 SQL 中调用相关 Udf，实现更多复杂的逻辑操作。</p>
<p>“SQL+UDF” 的方式，能够满足我们绝大部分的数据汇聚场景，如果后期业务变动，也只需要在 StreamPark 中修改 SQL 语句，即可完成业务变更与上线。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/data_aggregation-e5caba8eee38a8444df6cb3382a1d978.png" width="1080" height="607" class="img_iwx1"></p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="2-flink-cdc数据库同步"><strong>2. Flink CDC数据库同步</strong><a class="hash-link" aria-label="2-flink-cdc数据库同步的直接链接" title="2-flink-cdc数据库同步的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-haibo#2-flink-cdc%E6%95%B0%E6%8D%AE%E5%BA%93%EF%BF%BD%EF%BF%BD%E5%90%8C%E6%AD%A5">​</a></h4>
<p>为了实现各类数据库与数据仓库之前的同步，我们使用 StreamPark 开发 Flink CDC SQL 任务。借助于 Flink CDC 的能力，实现了 Oracle 与 Oracle 之间的数据同步， Mysql/Postgresql 与 Clickhouse 之间的数据同步。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_cdc-318444c917eb66f591a5c75db9662e78.png" width="794" height="232" class="img_iwx1"></p>
<p><strong>3. 数据分析模型管理</strong></p>
<p>针对无法使用 Flink SQL 需要开发 Flink 代码的任务，例如: 实时布控模型、离线数据分析模型，StreamPark 提供了 Custom code 的方式，允许用户上传可执行的 Flink Jar 包并运行。</p>
<p>目前，我们已经将人员，车辆等 20 余类分析模型上传至 StreamPark，交由 StreamPark 管理运行。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/data_aggregation-e5caba8eee38a8444df6cb3382a1d978.png" width="1080" height="607" class="img_iwx1"></p>
<p><strong>综上:</strong> 无论是 Flink SQL 任务还是 Custome code 任务，StreamPark 均提供了很好的支持，满足各种不同的业务场景。 但是 StreamPark 缺少任务调度的能力，如果你需要定期调度任务， StreamPark 目前无法满足。社区成员正在努力开发调度相关的模块，在即将发布的 1.2.3 中 会支持任务调度功能，敬请期待。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="04-功能扩展"><strong>04. 功能扩展</strong><a class="hash-link" aria-label="04-功能扩展的直接链接" title="04-功能扩展的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-haibo#04-%E5%8A%9F%E8%83%BD%E6%89%A9%E5%B1%95">​</a></h2>
<p>Datahub 是 Linkedin 开发的一个元数据管理平台，提供了数据源管理、数据血缘、数据质量检查等功能。海博科技基于 StreamPark 和 Datahub 进行了二次开发，实现了数据表级/字段级的血缘功能。通过数据血缘功能，帮助用户检查 Flink SQL 的字段血缘关系。并将血缘关系保存至Linkedin/Datahub 元数据管理平台。</p>
<p>//两个视频链接（基于 StreamX 开发的数据血缘功能）</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="05-未来期待"><strong>05. 未来期待</strong><a class="hash-link" aria-label="05-未来期待的直接链接" title="05-未来期待的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-haibo#05-%E6%9C%AA%E6%9D%A5%E6%9C%9F%E5%BE%85">​</a></h2>
<p>目前，StreamPark 社区的 Roadmap 显示 StreamPark 1.3.0 将迎来全新的 Workbench 体验、统一的资源管理中心 (JAR/UDF/Connectors 统一管理)、批量任务调度等功能。这也是我们非常期待的几个全新功能。</p>
<p>Workbench 将使用全新的工作台式的 SQL 开发风格，选择数据源即可生成 SQL，进一步提升 Flink 任务开发效率。统一的 UDF 资源中心将解决当前每个任务都要上传依赖包的问题。批量任务调度功能将解决当前 StreamPark 无法调度任务的遗憾。</p>
<p>下图是 StreamPark 开发者设计的原型图，敬请期待。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/data_source-5f9b710b4186a08571192ae81ab350d1.png" width="830" height="518" class="img_iwx1"></p>]]></content:encoded>
            <category>StreamPark</category>
            <category>生产实践</category>
            <category>FlinkSQL</category>
        </item>
        <item>
            <title><![CDATA[自如基于Apache StreamPark™ 的实时计算平台实践]]></title>
            <link>https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru</link>
            <guid>https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru</guid>
            <pubDate>Mon, 09 Feb 2026 02:32:43 GMT</pubDate>
            <description><![CDATA[导读：自如作为一家专注于提供租房产品和服务的 O2O 互联网公司，构建了一个涵盖城市居住生活领域全链条的在线化、数据化、智能化平台，实时计算在自如一直扮演着重要的角色。到目前为止，自如每日需要处理 TB 级别的数据，本文由来自自如的实时计算小伙伴带来，介绍了自如基于 StreamPark 的实时计算平台深度实践。]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/cover-87ff8832da8f5d9398ed5a1e2f283d0d.png" width="1080" height="460" class="img_iwx1"></p>
<p>**导读：**自如作为一家专注于提供租房产品和服务的 O2O 互联网公司，构建了一个涵盖城市居住生活领域全链条的在线化、数据化、智能化平台，实时计算在自如一直扮演着重要的角色。到目前为止，自如每日需要处理 TB 级别的数据，本文由来自自如的实时计算小伙伴带来，介绍了自如基于 StreamPark 的实时计算平台深度实践。</p>
<ul>
<li>实时计算遇到的挑战</li>
<li>需求解决方案之路</li>
<li>基于 StreamPark 的深度实践</li>
<li>实践经验总结和示例</li>
<li>带来的收益</li>
<li>未来规划</li>
</ul>
<p>自如作为提供租房产品及服务的 O2O 互联网品牌，成立于 2011 年 10 月，自如已为近 50 万业主、500 万自如客提供服务，管理房源超过 100 万间。截至 2021 年 3 月，自如已开通北京、上海、深圳、杭州、南京、广州、成都、天津、武汉、苏州 10 大城市。
自如通过打造涵盖 To C 和 To B 的品质居住产品、逐步实现城市居住生活领域全链条的线上化、数据化、智能化的平台能力。自如 APP 装机量累计达 1.4 亿次，日均线上服务调用达 4 亿次，拥有智能化房源万余间。自如现已在 PC、APP、微信全渠道实现租房、服务、社区的 O2O 闭环，省去传统租房模式所有中间冗余环节，通过 O2O 模式重构居住市场格局，并建立了中国最大的 O2O 青年居住社区。</p>
<p>在拥有庞大用户群体情况下，自如为了给用户提供更加优质的产品体验，实现企业的数字化转型，从 2021 年开始大力发展实时计算，Flink 在自如的实时计算中一直扮演着重要的角色。到目前为止，自如每日需要处理 TB 级别的数据，总共拥有 500+ 个实时作业，并支撑每日超过 1000 万次的数据调用请求。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="实时计算遇到的挑战"><strong>实时计算遇到的挑战</strong><a class="hash-link" aria-label="实时计算遇到的挑战的直接链接" title="实时计算遇到的挑战的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#%E5%AE%9E%E6%97%B6%E8%AE%A1%E7%AE%97%E9%81%87%E5%88%B0%E7%9A%84%E6%8C%91%E6%88%98">​</a></h2>
<p>在自如，实时计算大概分为 2 个应用场景：</p>
<ul>
<li>
<p>数据同步：包括 Kafka、Mysql、Mongo 数据同步到 Hive / Paimon / ClickHouse 等。</p>
</li>
<li>
<p>实时数仓：包括出租、收房、家服等业务实时指标。</p>
</li>
</ul>
<p>在实时计算实践过程中遇到了一些挑战，大致如下：</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="01-作业上线效率低"><strong>01 作业上线效率低</strong><a class="hash-link" aria-label="01-作业上线效率低的直接链接" title="01-作业上线效率低的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#01-%E4%BD%9C%E4%B8%9A%E4%B8%8A%E7%BA%BF%E6%95%88%E7%8E%87%E4%BD%8E">​</a></h3>
<p>在自如实时作业的开发上线流程是：数据仓库开发人员将 Flink SQL 代码嵌入到程序中，在本地进行代码调试，然后编译成 FatJar，最后再将作业以工单和 JAR 包形式提交给运维，运维负责作业上线的小伙伴再通过命令行的方式将作业部署到线上 Kubernetes session 环境。可以看到这一过程涉及到诸多环节，每一步都是需要人为介入，效率极其低下，而且非常容易出错，影响工作效率和稳定性。因此，我们亟需构建一套高效、自动化的实时计算平台，以满足日益增涨的实时计算需求。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/job_goes_online-ae38a4f939687b0e80e8e5677885fe0d.png" width="1080" height="356" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="02-作业归属信息不明确"><strong>02 作业归属信息不明确</strong><a class="hash-link" aria-label="02-作业归属信息不明确的直接链接" title="02-作业归属信息不明确的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#02-%E4%BD%9C%E4%B8%9A%E5%BD%92%E5%B1%9E%E4%BF%A1%E6%81%AF%E4%B8%8D%E6%98%8E%E7%A1%AE">​</a></h3>
<p>由于实时计算平台没有对作业进行统一管理，业务代码都是由 GitLab 管理，虽然解决了部分问题，但是我们发现仓库代码与线上部署的 Flink 作业管理之间仍然存在缺陷：缺乏明确归属、缺少分组和有效权限控制，导致作业管理混乱且责任链路难以追溯。为确保代码和上线作业的一致和可控性，亟需建立严格且清晰的作业管理体系，其中包括实行严格的代码版本控制、明确作业归属和负责人、以及建立有效的权限控制。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="03-作业维护困难"><strong>03 作业维护困难</strong><a class="hash-link" aria-label="03-作业维护困难的直接链接" title="03-作业维护困难的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#03-%E4%BD%9C%E4%B8%9A%E7%BB%B4%E6%8A%A4%E5%9B%B0%E9%9A%BE">​</a></h3>
<p>在自如有多个不同版本的 Flink 作业在运行，由于 Apache Flink® 的 API 在大版本升级中经常会发生变动，且不保证向下兼容性，这直接导致流作业项目代码的升级成本变得很高。因此如何管理这些不同版本的作业成了头痛的问题。</p>
<p>由于没有统一的作业平台，这些作业在提交时，只能通过执行脚本的形式进行提交。不同的作业有不同重要程度和数据量级，作业所需资源和运行参数也都各不相同，都需要相应的修改。我们可以通过修改提交脚本或直接在代码中设置参数来进行修改，但这使得配置信息的获取变得困难，尤其是当作业出现重启或失败时，FlinkUI 无法打开，配置信息变成一个黑盒。因此，亟需建立一个更加高效、支持配置实时计算平台。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="04-作业开发调试困难"><strong>04 作业开发调试困难</strong><a class="hash-link" aria-label="04-作业开发调试困难的直接链接" title="04-作业开发调试困难的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#04-%E4%BD%9C%E4%B8%9A%E5%BC%80%E5%8F%91%E8%B0%83%E8%AF%95%E5%9B%B0%E9%9A%BE">​</a></h3>
<p>在以往的开发流程中，我们通常在本地的 IDEA 环境中，通过将 SQL 代码嵌入程序代码的方式进行作业的开发和调试，以验证程序的正确性。然而，这种方式存在如下弊端：</p>
<p>1.多数据源调试困难。通常，一个需求可能涉及多个不同的数据源。为了在本地环境调试，开发人员需要申请开通数据访问需要的白名单，这一过程既耗时又繁琐。</p>
<p>2.SQL 代码难以阅读和修改。由于 SQL 代码是嵌入在程序代码中的，这使得代码难以阅读，修改起来也相当不便。更为困难的是，当需要通过 SQL 片段的方式进行调试时，由于缺少 SQL 版本管理和语法校验的支持，开发人员很难通过客户端日志定位到具体的 SQL 行号，从而找出执行失败的原因。</p>
<p>因此，急需提高开发、调试的效率</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="寻求解决方案之路"><strong>寻求解决方案之路</strong><a class="hash-link" aria-label="寻求解决方案之路的直接链接" title="寻求解决方案之路的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#%E5%AF%BB%E6%B1%82%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88%E4%B9%8B%E8%B7%AF">​</a></h2>
<p>在平台构建的初期阶段，2022 年初开始我们就全面调查了行业内的几乎所有相关项目，涵盖了商业付费版和开源版。经过调查和对比发现，这些项目都或多或少地存在一定的局限性，可用性和稳定性也无法有效地保障。</p>
<p>综合下来 StreamPark 在我们的评估中表现最优，是唯一一个没有硬伤且扩展性很强的项目：同时支持 SQL 和 JAR 作业，在 Flink 作业的部署模式上也是最为完善和稳定的，特有的架构设计使得不仅不会锁定 Flink 版本，还支持便捷的版本切换和并行处理，有效解决了作业依赖隔离和冲突的问题。我们重点关注的作业管理 &amp; 运维能力也非常完善，包括监控、告警、SQL 校验、SQL 版本对比、CI 等功能，StreamPark 对 Flink on K8s 的支持也是我们调研的所有开源项目中最为完善的。但 StreamPark 的 K8s 模式提交需在本地构建镜像导致存储资源消耗。</p>
<p>目前在最新的 2.2 版本中社区已经重构了这部分实现</p>
<p>在深入分析了众多开源项目的优缺点后，我们认为可以先去参与了解那些拥有优秀的架构、充满发展潜力，并且核心团队积极努力的项目，投身其中。基于这样的认识，我们做出了如下决策：</p>
<p>1.在作业部署模式上，我们决定采用 On Kubernetes 的模式。实时作业的资源消耗具有动态性，对 Kubernetes 提供的弹性扩缩容有强烈的需求，这有助于我们更好地应对数据产出的波动，确保作业的稳定运行。</p>
<p>2.在开源组件的选择上，我们经过各项指标综合对比评估，最终选择了当时的 StreamX。后续和社区保持密切的沟通，在此过程中深刻感受到创始人认真负责的态度和社区的团结友善的氛围，也见证了项目 2022 年 09 月加入 Apache 孵化器的过程，这让我们对该项目的未来充满希望。</p>
<p>3.在 StreamPark 基础上，我们要推动与公司已有生态的整合，以便更好地满足我们的业务需求。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="基于-apache-streampark-的深度实践"><strong>基于 Apache StreamPark™ 的深度实践</strong><a class="hash-link" aria-label="基于-apache-streampark-的深��度实践的直接链接" title="基于-apache-streampark-的深度实践的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#%E5%9F%BA%E4%BA%8E-apache-streampark-%E7%9A%84%E6%B7%B1%E5%BA%A6%E5%AE%9E%E8%B7%B5">​</a></h2>
<p>基于上述决策，我们启动了以 “痛点需求” 为导向的实时计算平台演进工作，基于StremaPark 打造一个稳定、高效、易维护的实时计算平台。从 2022 年初开始我们便参与社区的建设，同时我们内部平台建设也正式提上日程。</p>
<p>首先我们在 StreamPark 的基础上进一步完善相关的功能：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/platform_construction-b73e12b57a4a9f558ada77038496bf50.png" width="1080" height="522" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="01-ldap-登录支持"><strong>01 LDAP 登录支持</strong><a class="hash-link" aria-label="01-ldap-登录支持的直接链接" title="01-ldap-登录支持的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#01-ldap-%E7%99%BB%E5%BD%95%E6%94%AF%E6%8C%81">​</a></h3>
<p>在 StreamPark 的基础上，我们进一步完善了相关的功能，其中包括对 LDAP 的支持，以便我们未来可以完全开放实时能力，让公司的四个业务线所属的分析师能够使用该平台，预计届时人数将达到 170 人左右。随着人数的增加，账号的管理变得越发重要，特别是在人员变动时，账号的注销和申请将成为一项频繁且耗时的操作。所以，接入 LDAP 变得尤为重要。因此我们及时和社区沟通，并且发起讨论，最终我们贡献了该 Feature。现在在 StreamPark 开启 LDAP 已经变得非常简单，只需要简单两步即可：</p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step1-填写对应的-ldap-配置">step1: 填写对应的 LDAP 配置:<a class="hash-link" aria-label="step1: 填写对应的 LDAP 配置:的直接链接" title="step1: 填写对应的 LDAP 配置:的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step1-%E5%A1%AB%E5%86%99%E5%AF%B9%E5%BA%94%E7%9A%84-ldap-%E9%85%8D%E7%BD%AE">​</a></h4>
<p>编辑 application.yml 文件，设置 LDAP 基础信息，如下：</p>
<div class="language-yaml codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-yaml codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token key atrule">ldap</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token comment" style="color:rgb(106, 153, 85)"># Is ldap enabled?</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">enable</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> </span><span class="token boolean important">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token comment" style="color:rgb(106, 153, 85)">## AD server IP, default port 389</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">urls</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> ldap</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain">//99.99.99.99</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token number" style="color:rgb(181, 206, 168)">389</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token comment" style="color:rgb(106, 153, 85)">## Login Account</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">base-dn</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> dc=streampark</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">dc=com</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">username</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> cn=Manager</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">dc=streampark</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain">dc=com</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">password</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> streampark</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">user</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token key atrule">identity-attribute</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> uid</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token key atrule">email-attribute</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> mail</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step2--ldap-登陆">step2:  LDAP 登陆<a class="hash-link" aria-label="step2:  LDAP 登陆的直接链接" title="step2:  LDAP 登陆的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step2--ldap-%E7%99%BB%E9%99%86">​</a></h4>
<p>登录界面点击 LDAP 方式登录，然后输入对应的账号密码，点击登录即可</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/ldap-39a8f66b7bba105117ecbfc54551dc95.png" width="1080" height="581" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="02-提交作业自动生成-ingress"><strong>02 提交作业自动生成 Ingress</strong><a class="hash-link" aria-label="02-提交作业自动生成-ingress的直接链接" title="02-提交作业自动生成-ingress的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#02-%E6%8F%90%E4%BA%A4%E4%BD%9C%E4%B8%9A%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90-ingress">​</a></h3>
<p>由于公司的网络安全政策，运维人员在 Kubernetes 的宿主机上仅开放了 80 端口，这导致我们无法直接通过 “域名+随机端口” 的方式访问在 Kubernetes 上的作业 WebUI。为了解决这个问题，我们需要使用Ingress在访问路径上增加一层代理，从而启到访问路由的效果。在 StreamPark 2.0 版本我们贡献了 Ingress 相关的功能[3]。采用了策略模式的实现方式，在初始构建阶段，获取 Kubernetes 的元数据信息来识别其版本，针对不同版本来进行相应的对象构建，确保了在各种 Kubernetes 环境中都能够顺利地使用 Ingress 功能。</p>
<p>具体的配置步骤如下：</p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step1-点击进入-setting--选择-ingress-setting填写域名">step1: 点击进入 Setting-&gt; 选择 Ingress Setting，填写域名<a class="hash-link" aria-label="step1: 点击进入 Setting-> 选择 Ingress Setting，填写域名的直接链接" title="step1: 点击进入 Setting-> 选择 Ingress Setting，填写域名的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step1-%E7%82%B9%E5%87%BB%E8%BF%9B%E5%85%A5-setting--%E9%80%89%E6%8B%A9-ingress-setting%E5%A1%AB%E5%86%99%E5%9F%9F%E5%90%8D">​</a></h4>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/ingress_setting-2b8e1403aae4ff708a05f61f87d34733.png" width="1080" height="384" class="img_iwx1"></p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step2-提交作业">step2: 提交作业<a class="hash-link" aria-label="step2: 提交作业的直接链接" title="step2: 提交作业的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step2-%E6%8F%90%E4%BA%A4%E4%BD%9C%E4%B8%9A">​</a></h4>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/k8s_job-1759da059df126162f2b7e0c7b9b121a.png" width="1080" height="367" class="img_iwx1"></p>
<p>点击进入 K8s 管理平台，可以观察到在提交 Flink 作业的同时会对应提交一个名称相同的 Ingress</p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step3-点击进入-flink-的-webui">step3: 点击进入 Flink 的 WebUI<a class="hash-link" aria-label="step3: 点击进入 Flink 的 WebUI的直接链接" title="step3: 点击进入 Flink 的 WebUI的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step3-%E7%82%B9%E5%87%BB%E8%BF%9B%E5%85%A5-flink-%E7%9A%84-webui">​</a></h4>
<p>可以观察到生成的地址将由三部分组成：域名 + 作业提交的命名空间 + 作业名称</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_webui-ca719f066a60a19004af7d6761eae27d.png" width="1080" height="451" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="03-支持查看作业部署日志"><strong>03 支持查看作业部署日志</strong><a class="hash-link" aria-label="03-支持查看作业部署日志的直接链接" title="03-支持查看作业部署日志的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#03-%E6%94%AF%E6%8C%81%E6%9F%A5%E7%9C%8B%E4%BD%9C%E4%B8%9A%E9%83%A8%E7%BD%B2%E6%97%A5%E5%BF%97">​</a></h3>
<p>在持续部署作业的过程中，我们逐渐意识到，没有日志就无法进行有效的运维操作，日志的留存归档和查看成为了我们在后期排查问题时非常重要的一环。因此在 StreamPark 2.0 版本我们贡献了 On Kubernetes 模式下启动日志存档、页面查看的能力[4]，现在点击作业列表里的日志查看按钮，可以很方便的查看作业的实时日志。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/k8s_log-aafb7f2dff97d584b187ab4a22de9eaf.png" width="1080" height="473" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="04-集成-grafana-监控图表链接"><strong>04 集成 Grafana 监控图表链接</strong><a class="hash-link" aria-label="04-集成-grafana-监控图表链接的直接链接" title="04-集成-grafana-监控图表链接的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#04-%E9%9B%86%E6%88%90-grafana-%E7%9B%91%E6%8E%A7%E5%9B%BE%E8%A1%A8%E9%93%BE%E6%8E%A5">​</a></h3>
<p>在实际的使用过程中，我们发现随着作业数量的增加，使用人数的上升，以及涉及的部门的增多，面临故障自排查困难的问题。我们团队的运维能力实际上是非常有限的。由于专业领域的不同，当我们告诉用户去 Grafana、ELK 上查看图表和日志时，用户通常会感到无从下手，不知道如何去找到与自己作业相关的信息。</p>
<p>为了解决这个问题，我们在社区提出一个需求：希望每个作业都能够通过超链接直接跳转到对应的监控图表和日志归档页面，这样使用者就可以直接查看与自己作业相关的监控信息和日志。无需在复杂的系统界面中进行繁琐的搜索，从而提高故障排查的效率。</p>
<p>我们在社区展开了讨论、并很快得到响应、大家都认为这是一个普遍存在的需求、因此很快有开发小伙伴提交了设计和相关PR，该问题也很快被解决，现在在 StreamPark 中要开启该功能已经变得非常简单:</p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step1-创建徽章标签">step1: 创建徽章标签<a class="hash-link" aria-label="step1: 创建徽章标签的直接链接" title="step1: 创建徽章标签的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step1-%E5%88%9B%E5%BB%BA%E5%BE%BD%E7%AB%A0%E6%A0%87%E7%AD%BE">​</a></h4>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/create_badge_label-a6542822bd5a1e9274ca0017d25a9ccd.png" width="1080" height="649" class="img_iwx1"></p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step2-将徽章标签和跳转链接进行关联">step2: 将徽章标签和跳转链接进行关联<a class="hash-link" aria-label="step2: 将徽章标签和跳转链接进行关联的直接链接" title="step2: 将徽章标签和跳转链接进行关联的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step2-%E5%B0%86%E5%BE%BD%E7%AB%A0%E6%A0%87%E7%AD%BE%E5%92%8C%E8%B7%B3%E8%BD%AC%E9%93%BE%E6%8E%A5%E8%BF%9B%E8%A1%8C%E5%85%B3%E8%81%94">​</a></h4>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/relevancy-a1914717d6479d16e07f7f1e6193f409.png" width="1062" height="400" class="img_iwx1"></p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step3-点击徽章标签进行链接跳转">step3: 点击徽章标签进行链接跳转<a class="hash-link" aria-label="step3: 点击徽章标签进行链接跳转的直接链接" title="step3: 点击徽章标签进行链接跳转的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step3-%E7%82%B9%E5%87%BB%E5%BE%BD%E7%AB%A0%E6%A0%87%E7%AD%BE%E8%BF%9B%E8%A1%8C%E9%93%BE%E6%8E%A5%E8%B7%B3%E8%BD%AC">​</a></h4>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/link_jump-f353a479fac3e5576056edcaab705dda.png" width="1080" height="381" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="05-集成-flink-sql-security-权限控制"><strong>05 集成 Flink sql security 权限控制</strong><a class="hash-link" aria-label="05-集成-flink-sql-security-权限控制的直接链接" title="05-集成-flink-sql-security-权限控制的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#05-%E9%9B%86%E6%88%90-flink-sql-security-%E6%9D%83%E9%99%90%E6%8E%A7%E5%88%B6">​</a></h3>
<p>在我们的系统中，血缘关系管理采用 Apache Atlas，权限管理基于开源项目 Flink-sql-security，这是一个FlinkSQL数据脱敏和行级权限解决方案的开源项目，支持面向用户级别的数据脱敏和行级数据访问控制，即特定用户只能访问到脱敏后的数据或授权过的行。</p>
<p>这种设计是为了处理一些复杂的继承逻辑。例如，当将加密字段 age 的A 表与 B 表进行 join 操作，得到 C 表时，C 表中的 age 字段应继承 A 表的加密逻辑，以确保数据的加密状态不会因数据处理过程中的转换而失效。这样，我们可以更好地保护数据的安全性，确保数据在整个处理过程中都符合安全标准。</p>
<p>在权限控制方面，我们基于 Flink-sql-security 做了二次开发，实现了 flink-sql-security-streampark 插件。基本的实现思路如下：</p>
<p>1.在检查提交时系统会解析传入的 SQL，获取 InputTable 和 OutputTable 两个数据集。</p>
<p>2.系统通过对远端权限服务的查询，获取到用户所绑定的 RBAC（基于角色的访问控制）权限。</p>
<p>3.根据获取到的 RBAC 权限，系统会得到对应的表的加密规则。</p>
<p>4.系统将通过重写 SQL，将原本 SQL 查询字段包上一层预设的加密算法，进而实现逻辑的重组。</p>
<p>5.最后，系统会根据重组后的逻辑，进行相应的提交。</p>
<p>通过这样的整合和插件的开发，我们实现了对用户查询请求的权限控制，从而确保了数据的安全性。</p>
<p><strong>01行级权限条件</strong></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/row_level_permissions-cd7665f926dd3c92e8479be34f9084d5.png" width="1080" height="348" class="img_iwx1"></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/row_level_permissions_table-780239498d6b6d09c8a5c1ffe4ad44ef.png" width="1080" height="151" class="img_iwx1"></p>
<p>输入 SQL</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">SELECT * FROM orders;执行SQL</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>用户 A 的真实执行 SQL:</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">SELECT * FROM orders WHERE region = 'beijing';</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>用户 B 的真实执行 SQL:</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">SELECT * FROM orders WHERE region = 'hangzhou';</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>02字段脱敏条件</strong></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/field_desensitization-3005c6f1d9c2f7ad0530d09a5a9aecea.png" width="1080" height="269" class="img_iwx1"></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/field_desensitization_table-e200cbbf0081e2d416411659a188bb90.png" width="1080" height="160" class="img_iwx1"></p>
<p>输入 SQL</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">SELECT name, age, price, phone FROM user;</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>执行 SQL:</p>
<p>用户 A 的真实执行 SQL:</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">SELECT Encryption_function(name), age, price, Sensitive_field_functions(phone) FROM user;</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>用户 B 的真实执行 SQL:</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">SELECT name, Encryption_function(age), price, Sensitive_field_functions(phone) FROM user;</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="06-基于-apache-streampark-的数据同步平台"><strong>06 基于 Apache StreamPark™ 的数据同步平台</strong><a class="hash-link" aria-label="06-基于-apache-streampark-的数据同步平台的直接链接" title="06-基于-apache-streampark-的数据同步平台的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#06-%E5%9F%BA%E4%BA%8E-apache-streampark-%E7%9A%84%E6%95%B0%E6%8D%AE%E5%90%8C%E6%AD%A5%E5%B9%B3%E5%8F%B0">​</a></h3>
<p>随着 StreamPark 的技术解决方案在公司的成功落地，我们实现了对 Flink 作业的深度支持，从而为数据处理带来质的飞跃。这促使我们对过往的数据同步逻辑进行彻底的革新，目标是通过技术的优化和整合，最大限度地降低运维成本。因此，我们逐步替换了历史上的 Sqoop 作业、Canal 作业和 Hive JDBC Handler 作业，转而采用 Flink CDC 作业、Flink 流和批作业。在这个过程中，我们也不断优化和强化 StreamPark 的接口能力，新增了状态回调机制，同时实现了与 DolphinScheduler[7] 调度系统的完美集成，进一步提升了我们的数据处理能力。</p>
<p>外部系统集成 StreamPark 步骤如下，只需要简单几个步骤即可：</p>
<p>1.首先创建 API 访问的 Token：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/token-94cb364497fe129fc62be3bbb7193390.png" width="1080" height="288" class="img_iwx1"></p>
<p>2.查看 Application 外部调用链接：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/call_link-da9d24e3a1993590cf25da174d5fb676.png" width="1080" height="390" class="img_iwx1"></p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">curl -X POST '/flink/app/start' \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-H 'Authorization: $token' \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">-H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">--data-urlencode 'savePoint=' \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">--data-urlencode 'allowNonRestored=false' \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">--data-urlencode 'savePointed=false' \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">--data-urlencode 'id=100501'</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>3.DolphinScheduler 中配置 Http 调度</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/http_scheduling-267e8ae0aa04d5901cd98bea50370d69.png" width="1080" height="576" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="实践经验总结"><strong>实践经验总结</strong><a class="hash-link" aria-label="实践经验总结的直接链接" title="实践经验总结的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#%E5%AE%9E%E8%B7%B5%E7%BB%8F%E9%AA%8C%E6%80%BB%E7%BB%93">​</a></h2>
<p>在深度使用 StreamPark 实践过程中，我们总结了一些常见问题和实践过程中所探索出解决方案，我们把这些汇总成示例，仅供大家参考。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="01-构建-base-镜像"><strong>01 构建 Base 镜像</strong><a class="hash-link" aria-label="01-构建-base-镜像的直接链接" title="01-构建-base-镜像的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#01-%E6%9E%84%E5%BB%BA-base-%E9%95%9C%E5%83%8F">​</a></h3>
<p>要使用 StreamPark 在 Kubernetes 上部署一个 Flink 作业，首先要准备一个基于 Flink 构建的 Base 镜像。然后，在 Kubernetes 平台上，会使用用户所提供的镜像来启动 Flink 作业。如果是沿用官方所提供的 “裸镜像”，在实际开发中是远远不够的，用户开发的业务逻辑往往会涉及到上下游多个数据源，这就需要相关数据源的 Connector，以及 Hadoop 等关联依赖。因此需要将这部分依赖项打入镜像中，下面我将介绍具体操作步骤。</p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step1-首先创建一个文件夹内部包含两个文件夹和一个-dockerfile-文件">step1: 首先创建一个文件夹，内部包含两个文件夹和一个 Dockerfile 文件<a class="hash-link" aria-label="step1: 首先创建一个文件夹，内部包含两个文件夹和一个 Dockerfile 文件的直接链接" title="step1: 首先创建一个文件夹，内部包含两个文件夹和一个 Dockerfile 文件的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step1-%E9%A6%96%E5%85%88%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E5%A4%B9%E5%86%85%E9%83%A8%E5%8C%85%E5%90%AB%E4%B8%A4%E4%B8%AA%E6%96%87%E4%BB%B6%E5%A4%B9%E5%92%8C%E4%B8%80%E4%B8%AA-dockerfile-%E6%96%87%E4%BB%B6">​</a></h4>
<p><img decoding="async" loading="lazy" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAxwAAACmCAIAAADf3B7RAAAbi0lEQVR4Xu3d6VcUZ77A8fl/7tzLzJu598w5PYlRSVwQJYqoIIsLakwEWdwSQEGR3Q0RFMG4g0rTTQLIZJmcyWYmM4lJjNmMW2KMMUbjvt6n+2kfi3qaprCrGqS/dT5nDlT9ajFv5nu6iuo/xMw5AgAAgDD9QV8FAACAgSKqAAAAbEBUAQAA2ICoAgAAsAFRBQAAYAOiCgAAwAZEFQAAgA2GeVStbni9JJjlG7vmlr4xIus9fRcAAIDHMMyjSs+pXupfn/LKP/S9AAAABiq6o8pvakGEuqq+44eej3/t/PAXfZPtuo5cFOeq85zVN0VG/MtHY/M/0dcDADBcEVWR66r/fPf7gwcPbt25r2+y3d1798W5/vX1FX2To6pbzxw5fvnHX26JC7h95/6Zn2++98WVrE1f65MhLK775pNvfz926trRE1f1rdZnAACIJKJqwPSzWDTso6q5+9ydu77zmpZLV+8UNp/Q54Paefjc9ZuBg4h/hT5gcQYAgAgbnKhaVP5WcuE7+nqdGBPD+nqL9CQKn34Wi4Z3VO04fE6eVHTV0RNXPe9deOvTSz/9ekumj2igjIov9b2Mpqz8XFywnJeLHkxWZgAAGBSDEFWLyt9sa/cecHv77SoxIMbEsNhF32qFnkTh089i0fCOqu9+vPHAX1TbO39UK+NfPirXi2Xfm+f1vZSSXScv/HZbTl65flf+bAomKzMAAAyWQYgqlUqhu8riWGh6EoVPP0tQKaXHKvafqjlwetrqL+Sa0FEVm//J8sbvat1nS/ecFPvqA0GHF9d9o2+NeayoEscsbDqxuf1sYfOJccs/1QdMxAXUec5mrvtK/Czmxb9LnPGLk+YnnMr3nZIZFPrhp3c/vyzHvj57PbP6+Jenr+nBZGUGAIDBMghRFWMhmPodsEhPovDpZzHJ2vT1sVPX/FXjW+7ff/DtD9eLdnzfV1TFv3z0/WOX1UNCYrnn32XN7pP6wUW+iLYwDl+7ce+rM9dMdRU0qtYfOnPj1j1xPeJ/i3d+r9aLC3jvi9/ESnXMm7fvffjlZbFezYjjix2F7o8udh25+NvVO3Ly9Q98f8xYtvfUlat3Ll+7e/Ad88dRT2d/LC/m9Pmbpk1G4h915+79194P/Glk0GCyMgMAwGAZnKiKCZlNITYNlJ5E4dPPYiRC5Idfbqo6UYvIINFJD4JF1Rcnr5qn/cvV63eXbfvONPz598GHRVqtO3hGjelRtf7AWZFKYqWIJ1FXxmN+diL4McW51Exew7dy5Xc/3rhveBhdRlUIyxu/k5OhPzZr6vrRGJFBg8nKDAAAg2XQoiqmj3gKuvKx6UkUPv0sRvLjKLFc+O1215GLa/eeOvjO+RPnHmWWKao+OBa4paXm97zxk8qsi5dvZ1YfV8Pq/tfFK7e7P7pY5j/4V2d8bSGWS7/fUZOmqKpu9X1G9cDfdpUtp40X8Nanl+TuP/16q/3dC+IC2v55QT1g/vbRS3JMRdUDf8ccOX5l75vnGzp+EOuNR9MdffgfZG/IZ6pMrASTlRkAACJmMKMqRksoe4sqJuJRVbzzexkQ127cy9r86H5cbP4nJ88Hntc2RtWSrYFSuXr9rullTurTo3c+C2SNGhZhlFffK2VkXoilqSvwkLgxqqpaTsuiEldVuqfXLUVxHPmpk6i02VWP6i1z3Vci0R74b0ROLf7cN/kwqu7cvb/1tR+MBwmhufucPP7ZC6Hu/emsBJOVGQAAImaQoyqmd1fZW1QxEY+qg++cl+Wx542fTJsWbvhGho4xqva9GZjf1WOen7Lyc/ng1Lc/XA8MvxUYFj+Yhhes//r9Y5c/OHZ522vmqKrYf0oWlei2la8+eo5KEtcpj6l3kjpdrdv3WnYVVSfOWc2jypbT8ul10WFle0/pAyFYCSYrMwAARMzgR1WMoavsLaqYiEfVkeOBVyiJhNK3XrzsewWAMarUvT9RRfr89z/5Pty6cv2u/PXDLwPDL24MMmwio0ocQT1+XrD9hD723heBC255+/yunnNGXUcuyk3dH12MMUTV258GPjkLbXnjd9du+E59/36QZOyXlWCyMgMAQMQMiaiKedhV9hZVTMSjSt7ju34z+P/Ny4efjFEVev6jrwLFIyvq9Hnfg1miVPRJnYwqtYjfgr58QXZb6OUz/+PqKqp6/vWrfhyTrE1fy7uHYlF/rDcgVoLJygwAABEzVKIqxt9V9hZVzCBFVV/dc9wfAXpU9TVviioZQH0VmIkpqsTy4y+3jK9IkGSoieXn327r5Pp3P78cM5Coyqj48udLgVd0qgfCBspKMFmZAQAgYoZQVDlBT6Lw6WdRQt/++yW823/qVl3OliAHN1FRlbX5m1M/B8rpk29/N43JW4r37z9Qbyjti8WomrLy87MXAqd7/5ivxh6PlWCyMgMAQMQQVQOmn0VRD6rv/rv5KaLgD6o/fBhcf+pIf1BdPVR+4B8/m4ZT1x77+79/ffM/v9YcCLwuQZ7r3/6KenHj179fuyv3Nd2Ma3k7cAFbPOYH1U2sRFVs/icnfgj8HeJHX4V6K1W/rASTlRkAACKGqBow/SyPTrfrpEwK0ysSns7+OOgrFZZtC7wYU8ybHj/XX6mQs+UbuebGrXuml4Kq91rtOHxOrpFRpd5TJWLrzl3fGrFe/jWftGJ74AJML8QSRBdeunpHEOEVYy2q1ItJZcyFJkJQFN6unnPiP46+1UowWZkBACBiiKoB089ipN51+fNvt1//4Jc1u0+KKFFfKvxAe/mn+ps+Md/5oW9e1Iyqk4tXerWOCKyH6+90f3RRNJwYVmcUYaQmTVEltP3zghy7duOe8QaiumV5/tItUTnFO7+vbj0jvxBGrLx95778dr9+o0odRyye9y60vxuE8SsF5fvlH/TxTnYrwWRlBgCAiCGqBkw/i5H/a2oCryM3LiJl+vqammMnA7fMTIvYRf+amqN9fKXM9Zu9PoLSo0oQv8rhHy8+emj96eyP1TvZTYs4iProK3RUqReThl6M7xeVL1x40PvLcBQrwWRlBgCAiCGqBkw/i0nW5m+On370hcoP/N+X5/tC5W98HyndvG3+Wz/RNx8cu2z8PuP79327mN5+LulfqCx2FMOmr4uRnzOZHmwS+6qnyD/88tFT5AmFnx05fsV0ASIBjV9os7gucPNRvrbKxPglNiGW9PIv1S49H/8qesjUgooMTfGv0DcNaAYAgIgZ5lE1iERAVLeeqWo5nbr2mL5VJ4qnsOnEpraz5ftOGeMjKDW8vNH8UdZj8x2z2XfM4p3f6y9fcMK01V+IntPXAwDwJCKqAAAAbEBUAQAA2ICoAgAAsAFRBQAAYAOiCgAAwAZEFQAAgA2IKgAAABsQVQAAADYgqgAAAGzwB9dTIwAAABAmogoAAMAGRBUAAIANiCoAAAAbEFUAAAA2IKoAAABsQFQBAADYgKgCAACwAVFlm9IN9aUbG3QFa2sW5q0YP3GyvgsAABg2iCrb6DlltGZ9fcrsBfpeAABgeIiiqMpbsmxO5nx9vV30kNLNzHxB33F4iJ+UkL04Z21ZeVVNzcJFWfoAAADDW7RElSiqtnbvIbfHua7SEyqoYdlV05NT3G53z8Nl/YaN+gwAAMNbtESVaClRVI52ld5P4dPPMjTt3rNH5pS3o6O+vmHJsuX6DAAAw1u0RJXL+a7Skyh8+lmGoFGxz3Z1dYmi2rV79zOjYvUBAACiQRRFlcvhrtKTKHz6WYaglLQM+TFV8eo1+lYAAKJEdEWVy8mu0pMofPpZghoxcnRi0vS58+YnTE7UtwadTE5NHzMuTh8IamxcvPhv1dfB02fPkVGVv3SZvhUAgCgRdVHlcqyr9CQKn34Wk2dGxZaVV3i8Xpk1YnG3t9c3NOgBNCr22fKKSuNkd3f31m2Nyalppkmx72H/Uli0Misnd9++feJnuUu7x2N8Xqq4ZLXaJBe5Y1FxsemYAAAMe9EYVS5nukpPovDpZzGprd1sbBq1iLSaNWeucXJzXZ15yL+43e7EpGnGycmJSXLTlvqGTv/DUqaloLBITpasKTVv8y8itvRLBQBgeIvSqHI50FV6EoVPP4tRWXmFjJiW1tbCopUpaRn5S5fV1zfIlQcOHFCTFZVVcuW+fftFEqWkpS/Oya3dHMislpbWuPhJalhFlVg6Ol6TRxYqq6rl51Lejo4x4323DsdPmJg8My03L18Oi5YSvwpivX61AAAMb0TVkxpVU6ZOkynj8XgmJ041bqrbUi83vfDSIuOk2+2e+Hyvb8vZuKlWblpTulatVFHV1dU1d16vt8DXbg58MDYnc55ayTNVAAC4ojaqbC8qV8SjKufh50PiB9Om+EkJ5RWV5ZWVCxa+KH7Nzs2Tk1nZi02Tsc+NFU0mNm3d1qhWqqhq3rHDNL9wUZbcZHyyiqgCAMAVnVHlRFG5Ih5V6o7exIR+vqpZ1JWcFLGlb21qbhab2trcao2KKlFmpuHk1DS5ST1W5SKqAADwi7qocqioXBGPquYdO3r8f46nbzJPNvsmPX1MVtXUyCRScaaiqmiV+Y/4kqYny01EFQAAJtEVVc4VlSviUSU/YfJ4vfomExlVfeUXUQUAgC2iKKocLSpXxKOqvCJwUy9hSq+n1HXqRuFAb/8RVQAAWBctUeV0UbkiHlVZObmBlFmy1LRpzPi4VcUlxSWrRe64DI+0D/RBdaIKAADroiWq8pYsc7SoXBGPqoQpU2XKeL1e09s71QuoXsrKFr+KrfJX3ysVej/VHvqVCkQVAADWRUtUufxd5VxRuSIeVYIoIVkzrf6XfybPTMtanLNh4ya5sqWlVU0aXv6575WCwuRU36R6G3tLa/CXfxJVAABYF0VR5TQ9icKnn8VEfdRkWjwe82dym+u2mIf8i7u9va+vqSGqAACwjqiyjZ5E4dPPYqJ/obLX621s3C7CyDQ5KvbZisoqr2Hy8OHD2xobk1PTTZMJkxPlQGHRStOmxKTpctPLBYVqZVrGbLkyN3+JaR4AgOhBVA0HIq2SpifPyZwnokffGnQyNT1jbNwEfQAAADweogoAAMAGRBUAAIANiCoAAAAbEFUAAAA2IKoAAABsQFQBAADYgKgCAACwAVEFAABgA6IKAADABkQVAACADYgqAAAAGxBVAAAANiCqAAAAbEBUAQAA2ICoAgAAsAFRBQAAYAOiCgAAwAZElW1KN9SXbmzQFaytWZi3YvzEyfouAABg2CCqbKPnlNGa9fUpsxfoewEAgOEhiqIqb8myOZnz9fV20UNKNzPzBX3Hx1ZQVLRyVXHm/ECrjRg5urhk9aba2pS0jBBjAADACdESVaKo2tq9h9we57pKT6igbOyqrq6unp6emnXr5K/ZuXk9/mXXrt0hxgAAgBOiJapES4micrSr9H4Kn34Wo76jaleIMQAA4IRoiSqX812lJ1H49LMYmWppxMjRq4pLNmzclJKWHmIMAAA4IYqiyuVwV+lJFD79LEYWa8niGAAACEd0RZXLya7Skyh8+lmMLNaSaWzMuLhZc+ampmc8N3a8PgwAAB5P1EWVy7Gu0pMofPpZjPRaOuxfStaUBh1LnpnauH27GJCPXnV3d9durouflKAfGQAADFQ0RpXLma7Skyh8+lmMTFE1Nm6CrKU1pWv1sYatW71erxwwLjt2vPrMqFj94AAAYECiNKpcDnSVnkTh089iNKCoksu2xsbc/CUpaRmFRStbWlrkyn5vIAIAgH4RVVEUVdubmp4aMVKtn5w41ePxyE1Tp83Qjw8AAKyL0qiyvahcQz6qOjs74+InmY6Qm79E7pKdm2faBAAABiQao8qJonIN+ajau3effoTJiUlyl7LyCn0rAACwLuqiyqGicg35qKrdXKcfQejoeE1sbdy+Xd8EAACsi66ocq6oXE98VDXpmwAAgHVRFFWOFpVryEdV6Nt/5RWV+lYAAGBdtESV00XlGvJRFfpB9Zy8fNMmAAAwINESVXlLljlaVK4hH1U92oNTCVOmtvNKBQAAbBItUeXyd5VzReV6EqJKLFu3bsvJy09OTXulsGj/fvXyz/X6wQEAwIBEUVQ5TU+i8OlnMRpQVNU3bFWv+jQur766k6+pAQAgfESVbfQkCp9+FqPOzk5RRVU1NfLXMePiZCet7v2FymoseWbq9qYmlVPd3d11dVviJz2vHxkAAAwUURV1xsZNSJ81J33W7DHj4/StAADg8RBVAAAANiCqAAAAbEBUAQAA2ICoAgAAsAFRBQAAYAOiCgAAwAZEFQAAgA2IKgAAABsQVQAAADYgqgAAAGxAVAEAANiAqAIAALABUQUAAGADogoAAMAGRBUAAIANiKrISZv/ovyhdGNDCPqOAABg6COqIkQUlQomPaSIKgAAnnREVSTIoiKqAAAYxogqx6miIqoAABjGiCpnGYtq2EdVQVHRylXFmfMX6JscFT8pIXtxztqy8qqamoWLssSaESNHF5es3lRbm5KWYZwcrCsEAEQDospBpqKyParKyivq6raYVNesEz0h2kKEhb6Lo7q6unp6emrWrdM3OWd6corb7e55uKzfsFGszM7Nk7/u2rXbODwoVwgAiBJElVP0orI9qlpaWlVM6Iu7vV3U1VMjRuo7OmRQkmX3nj3y3+vt6Kivb1iybLmrV1TtMg4PyhUCAKIEUeWIoEWlgklfr89YIaOqs7Pz1Z07JVEYbW3uw4cPB8Kqp6epqXlsXLy+rxMinyyjYp+VJ921e/czo2LV+hEjR68qLtmwcVNKWrpxPvJXCACIHkTVINBDKpyo2rNnr2l9wpSppWVlKq3qttTr+zoh8smSkpYh/43Fq9foW3WRv0IAQPQgqgaBHlL2RpW0/JUCGRxiWZyTqw+4/J/oJCZNnztvfnJq+phxcfpA0OGEyYn6VtdjJYs4ZtL05LnzFkybkWL8qKkv4gIy5y+YMHGS/DV99hz5D8xfukwf1oW4woFeCQAAJkSVI/RUsk4/Wl9CR5WwpnStbI6mpmbTplGxz5ZXVHq83kB29fR0d3dv3daYnJqmH0dERll5hXHY3d5e39BgqqugyTJ7bmZHR8fhw4fF/85ImanWiwsQx/R2dKhjdnS8VllVLdarGXH8w/6lsGhlQVHRwUOH5OTLBYXFJauNdznFIieLiovFjiIQ5a8la0r7vUIrVwIAQL+IKkfoqWSdfrS+9BtVQrvH0+MPpvhJCcb1m+vqVEMYF7fbnZg0zXSQ2trN5jn/ItJq1py5akxPFrFVBEqPL1M6RF0Zj7mpttZ8OP8izqVmJicmyZWN27cbE0pElagl9atxEbEldhwbN0H+KrLSeFL9Ci1eCQAA/SKqHKGnknX60fpiJaq2NzXJRJi34AW1sqKySq7ct29/QWFRSlr64pzc2s2BzBKHjYsP3F9z+V/cEFjf2lpYtDIlLSN/6bL6+ga58sCBA2rSlCzps+Z0+D/+8Xi9aRmzjVdVsnqN3F1c/LLlK8QFLF2+QvwsV65++PGSiiqxiINXVddk5+bNf2GhWD9+wsTkmWm5eflyq2gp8asg1rsGElUWrwQAgH4RVY7QU8k6/Wh9sRJVKoly85fINVOmTpNr3G73xOcnG4c3bgp8ZqNaRA17PJ7JiVONw3Vb6uWmF15aJNcYkyV91mx5Q629vT05Nd24oziO/NhJVJpsIGnCxEki0Xr8n6s9O2acfzIQVZ1dXQsWBr6O2qivZ6osRpX1KwEAoF9E1RPMSlSJlpJ5UVi0Uq5R73DKyl5sGo59bqzHf7tw67ZGuSbn4UdB4gfTcPykhPKKyvLKSpU7KlnSMmZ5/Q9giW6bnvzoOSppcU6uPKbeSep0c+fNd/W6/ddkmpTCjCrrVwIAQL+IqieYlagqXLlKxsGy5SvkGpFBco3pKSupqblZbGprc8tf1Y3CiQm9PtMKSiaLOIIsKrEkTZ+hj4kUk1tF8C3KXmxUUFgkN4nLdhmiyvS8uRJmVFm/EgAA+kVU2eapjW6H6OeSrESVelJK3aRrbt7R47+dpw8LVTU1cl5WVPMO33B7H8MmMlnU0t3dHfTlC01Nvm4LvWzyPySuoqpole9v+nRhRpX1KwEAoF9ElW30GLKLfi7JSlTtb2mRcaBeZyCjqq9OMkWV/ODK4/XqkzpTVPX4v3pPfzGBDLUe32PyQRa5vqy8wuV8VFm/EgAA+kVU2caYQf/1zDjpjyPH/2liyl+ySp7e0KbXkkX6uaR+oyotY1Z3d7eYaW199Dd66o6eldt/6gZZwpReT6kHpaIqYfKUHTtelT/Lbzg2qqyq7vG/Vuq5seP1gxg5HVXWrwQAgH4RVbYxZpCKKuXPMxY8dlfp55JCR1XS9Bnt7e2yLUrXlqn16hFsKw+qZz18lDt/yVLT8JjxcauKS4pLVouykWtksqzfsEH8PDFhcltbm9x3+SsFxh3Vs/PGtzwE5XRUWb8SAAD6RVTZxphBMqTED3+rOfjXwrqYuGni17/krNWDyQr9XFKIqEpMmn7g4EFZDAcPHRIBZNhkeKVC78fP9VcqJEyZKtd4vV7TS0HV01ovZWXLNaZkEcXT6V8j1s/JfPQ3dFOnzZA7ml6IJWQtzjnoX+QLIJyOKutXAgBAv4gq2xgzSEWV9H8vbxK//un5dD2YrNDPJcmoamtrW7biZemVgsKy8orG7U3q/eOvv/66MWgkw8s/94ldklPTREOo16a3tPYqDPVdN63+l38mz/QNb9i4KTDc0qomTckiLF2+Qo61t7cbbyBWVfvuu4ll7969y18pmJEyM33WnLVl5Z2dnT3+a5bf7ud0VLksXwkAAP0iqmxjzCBTVP2tqkX8+t+j4/VgskI/lySjKsQiBkQD6Tu6fF9Ts8U87V/c7e3619SoT7BMi8fjMRabniyC+FUO79r96KH1p0aMVO9kNy3iIOqjrwhElcUrAQCgX0SVbYwZFJmo2r8/8Jd9xqWj4zXRUiIURBCMGDla30sSfVNRWaVeKNXjf157W2Oj6e3nkv6FymLHxsbtInqMY/LTnaqaGtO+r+7cKfeqrKpW60c/O6aqulp+j41cxAVs3dZo/EKbhMmJcpN6c6mJGJYDppt0Y8bFyfWm75kJeoVWrgQAgH4RVbYxZpApqv66otaJ23/hE8WTND15Tua81PSMsXET9IGgw4lJ0/Wtj0ccc9qMFHHM5Jmp+ssXImnoXAkA4AlFVNnGmEGPHlRfd+ivhXX/439Q/X8Xl+rBZIV+LgAAMNQQVbYxZpCMKqM/T59v+ysVAADA0EFU2caYQaql/jhynHz551PrD+m1ZJF+LgAAMNQQVbbRY8gu+rkAAMBQQ1TZRo8hu+jnAgAAQw1RBQAAYAOiCgAAwAZEFQAAgA2IKgAAABsQVQAAADYgqgAAAGxAVAEAANiAqAIAALABUQUAAGADogoAAMAG/w9NaarD8D1KSwAAAABJRU5ErkJggg==" width="796" height="166" class="img_iwx1"></p>
<p>conf 文件夹：存放 HDFS 配置文件，主要用于配置 Flink 的 Checkpoint 写入和FlinkSQL 中使用 Hive 的元数据</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/hdfs_conf-8af6d1660d09b58fc28a6fec1bff604b.png" width="824" height="284" class="img_iwx1"></p>
<p>lib 文件夹：存放涉及到的 Jar 依赖包，如下：</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/lib-faa76eddded5bdcb4228bf65c2d3122d.png" width="842" height="722" class="img_iwx1"></p>
<p>Dockerfile 文件用于定义镜像的构建</p>
<div class="language-dockerfile codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-dockerfile codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">FROM apache/flink:1.14.5-scala_2.11-java8</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">ENV TIME_ZONE=Asia/Shanghai</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">COPY ./conf /opt/hadoop/conf</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">COPY lib $FLINK_HOME/lib/</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step2-镜像构建命令使用多架构构建模式如下">step2: 镜像构建命令使用多架构构建模式，如下：<a class="hash-link" aria-label="step2: 镜像构建命令使用多架构构建模式，如下：的直接链接" title="step2: 镜像构建命令使用多架构构建模式，如下：的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step2-%E9%95%9C%E5%83%8F%E6%9E%84%E5%BB%BA%E5%91%BD%E4%BB%A4%E4%BD%BF%E7%94%A8%E5%A4%9A%E6%9E%B6%E6%9E%84%E6%9E%84%E5%BB%BA%E6%A8%A1%E5%BC%8F%E5%A6%82%E4%B8%8B">​</a></h4>
<div class="language-dockerfile codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-dockerfile codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">docker buildx build --push --platform linux/amd64 -t ${私有镜像仓库地址}</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="02-base-镜像集成-arthas-示例"><strong>02 Base 镜像集成 Arthas 示例</strong><a class="hash-link" aria-label="02-base-镜像集成-arthas-示例的直接链接" title="02-base-镜像集成-arthas-示例的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#02-base-%E9%95%9C%E5%83%8F%E9%9B%86%E6%88%90-arthas-%E7%A4%BA%E4%BE%8B">​</a></h3>
<p>随着公司内新发布上线的运行作业越来越多，团队内常常会遇到作业在长时间运行后性能下降的这种问题，如 Kafka 消费能力减弱、内存使用增加和 GC 时间延长等，我们是比较推荐使用Arthas，一款阿里巴巴开源的 Java 诊断工具。可以通过全局视角实时查看java应用 load、内存、gc、线程的状态信息，并能在不修改应用代码的情况下，完成查看方法调用的出入参、异常，监测方法执行耗时，类加载信息等，可以大大提升我们线上问题排查效率。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/arthas-31f8df2a167d53420d2b4a828003a449.png" width="1080" height="526" class="img_iwx1"></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/advanced-e5c462ae9a888deddb5939a7c8065732.png" width="1080" height="416" class="img_iwx1"></p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/arthas_log-fbc7dc0891690e569c6ad63359fc52fd.png" width="1080" height="390" class="img_iwx1"></p>
<p>因此做了 base 镜像集成 arthas，来方便运行时问题的排查。</p>
<div class="language-dockerfile codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-dockerfile codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">FROM apache/flink:1.14.5-scala_2.11-java8</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">ENV TIME_ZONE=Asia/Shanghai</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">COPY ./conf /opt/hadoop/conf</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">COPY lib $FLINK_HOME/lib/</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">RUN apt-get update --fix-missing &amp;&amp; apt-get install -y fontconfig --fix-missing &amp;&amp; \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    apt-get install -y openjdk-8-jdk &amp;&amp; \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    apt-get install -y ant &amp;&amp; \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    apt-get clean;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">RUN apt-get install sudo -y</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"># Fix certificate issues</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">RUN apt-get update &amp;&amp; \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    apt-get install ca-certificates-java &amp;&amp; \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    apt-get clean &amp;&amp; \</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    update-ca-certificates -f;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"># Setup JAVA_HOME -- useful for docker commandline</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">RUN export JAVA_HOME</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">RUN apt-get install -y unzip</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">RUN curl -Lo arthas-packaging-latest-bin.zip  'https://arthas.aliyun.com/download/latest_version?mirror=aliyun'</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">RUN unzip -d arthas-latest-bin arthas-packaging-latest-bin.zip</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="03-镜像中依赖冲突的解决方式"><strong>03 镜像中依赖冲突的解决方式</strong><a class="hash-link" aria-label="03-镜像中依赖冲突的解决方式的直接链接" title="03-镜像中依赖冲突的解决方式的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#03-%E9%95%9C%E5%83%8F%E4%B8%AD%E4%BE%9D%E8%B5%96%E5%86%B2%E7%AA%81%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E5%BC%8F">​</a></h3>
<p>在使用 StreamPark 的过程中，我们常遇到基于 Base 镜像运行的 Flink 作业中出现 NoClassDefFoundError、ClassNotFoundException 和 NoSuchMethodError 这三种依赖冲突异常。排查思路就是，找到报错中所示的冲突类，所在的包路径。例如这个报错的类在 org.apache.orc<!-- -->:orc-core<!-- -->， 就到相应模块的目录下跑 mvn dependency::tree 然后搜 orc-core，看一下是谁带进来的依赖，用 exclusion 去掉就可以了。下面我通过一个 base 镜像中的 flink-shaded-hadoop-3-uber JAR 包引起的依赖冲突示例，来详细介绍通过自定义打包的方法来解决依赖冲突。</p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step1-clone-flink-shaded-项目到本地">step1: Clone flink-shaded 项目到本地👇<a class="hash-link" aria-label="step1: Clone flink-shaded 项目到本地👇的直接链接" title="step1: Clone flink-shaded 项目到本地👇的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step1-clone-flink-shaded-%E9%A1%B9%E7%9B%AE%E5%88%B0%E6%9C%AC%E5%9C%B0">​</a></h4>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">git clone https://github.com/apache/flink-shaded.git</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_shaded-f21909c81059b2ea4ebd8307998cbc26.png" width="1080" height="529" class="img_iwx1"></p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step2-项目加载到-idea-中">step2: 项目加载到 IDEA 中<a class="hash-link" aria-label="step2: 项目加载到 IDEA 中的直接链接" title="step2: 项目加载到 IDEA 中的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step2-%E9%A1%B9%E7%9B%AE%E5%8A%A0%E8%BD%BD%E5%88%B0-idea-%E4%B8%AD">​</a></h4>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/idea-d654040d5fad6fefd756ede9a9ac8a4b.png" width="1080" height="586" class="img_iwx1"></p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step3-针对冲突的部分进行排除后再进行打包">step3: 针对冲突的部分进行排除后再进行打包。<a class="hash-link" aria-label="step3: 针对冲突的部分进行排除后再进行打包。的直接链接" title="step3: 针对冲突的部分进行排除后再进行打包。的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step3-%E9%92%88%E5%AF%B9%E5%86%B2%E7%AA%81%E7%9A%84%E9%83%A8%E5%88%86%E8%BF%9B%E8%A1%8C%E6%8E%92%E9%99%A4%E5%90%8E%E5%86%8D%E8%BF%9B%E8%A1%8C%E6%89%93%E5%8C%85">​</a></h4>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="04-集中作业配置示例"><strong>04 集中作业配置示例</strong><a class="hash-link" aria-label="04-集中作业配置示例的直接链接" title="04-集中作业配置示例的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#04-%E9%9B%86%E4%B8%AD%E4%BD%9C%E4%B8%9A%E9%85%8D%E7%BD%AE%E7%A4%BA%E4%BE%8B">​</a></h3>
<p>使用 StreamPark 有个非常大的便利就是可以进行配置的集中管理，可以将所有的配置项，配置到平台所绑定的 Flink 目录下的 conf 文件中。</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">cd /flink-1.14.5/conf</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">vim flink-conf.yaml</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/conf-ff77bc47a1f6af137a3326cc05cfdfee.png" width="1080" height="562" class="img_iwx1"></p>
<p>配置完成后保存。然后进入到平台的 Setting 下，点击 Flink Conf 这个图标。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_conf-db4fdbcbac08f9e19eaf550c1332de25.png" width="1080" height="351" class="img_iwx1"></p>
<p>点击 Sync Conf 全局配置文件就会进行相应的同步，新提交的作业就会按照新的配置进行提交。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/sync_conf-9d2b45b6f42376859fda062127e33d82.png" width="1080" height="485" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="05-apache-streampark-配置-dns-解析"><strong>05 Apache StreamPark™ 配置 DNS 解析</strong><a class="hash-link" aria-label="05-apache-streampark-配置-dns-解析的直接链接" title="05-apache-streampark-配置-dns-解析的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#05-apache-streampark-%E9%85%8D%E7%BD%AE-dns-%E8%A7%A3%E6%9E%90">​</a></h3>
<p>在使用 StreamPark 平台提交 FlinkSQL 的过程中，一个正确合理的 DNS 解析配置非常重要。主要涉及到以下几点：</p>
<p>1.Flink 作业的 Checkpoint 写入 HDFS 需要通过 ResourceManager 获取的一个 HDFS 节点进行快照写入，如果企业中同时有发生Hadoop集群的扩容，并且这些这些新扩容出来的节点，没有被DNS解析服务所覆盖，就直接会导致Checkpoint失败，从而影响线上稳定。</p>
<p>2.Flink 作业的通常需要配置公司内部不同数据源的连接串。如果配置数据库的真实 IP 地址，往往这个地址会随着迁库时常发生变化，而导致线上作业异常退出。因此在实际生产中连接串往往是由域名加属性参数构成，请求时由DNS服务将其解析为真实 IP 地址，在进行访问。</p>
<p>起初，我们是通过 Pod Template 来维护 DNS 配置的。</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">apiVersion: v1</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">kind: Pod</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">metadata:</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  name: pod-template</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">spec:</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  hostAliases:</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    - ip: 10.216.xxx.79</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      hostnames:</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        - handoop1</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    - hostnames:</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        - handoop2</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      ip: 10.16.xx.48</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    - hostnames:</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        - handoop3</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      ip: 10.16.xx.49</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    - hostnames:</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        - handoop4</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">      ip: 10.16.xx.50</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">   .......</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>虽然该方法理论上可行，但在实际操作过程中，我们遭遇到了一系列问题。当进行 HDFS 扩容时，我们发现 Flink 的 Checkpoint 功能出现了写入失败的情况，而数据库迁移也出现了链接失败的问题，这导致我们的线上服务突然宕机。经过深入的排查，我们发现这些问题的根源在于 DNS 解析。</p>
<p>过去，我们曾使用 hostAliases 来维护域名和 IP 地址之间的映射关系。但这种方法在实际操作中代价较大，因为每当更新 hostAliases 时，我们都需要停掉所有的 Flink 作业，这无疑增加了我们的运维成本。为了寻求一种更为灵活和可靠的方法来管理 DNS 解析配置，保障 Flink 作业的正常运行，我们决定搭建 dnsmasq 来进行双向的 DNS 解析。</p>
<p>在完成 dnsmasq 的配置和安装后，我们首先需要对 Flink 镜像中 /etc 目录下的resolv.conf 配置文件进行覆盖。然而，由于 resolv.conf 是一个只读文件，如果我们想要覆盖它，就需要使用挂载的方式。因此，我们首先将 resolv.conf 配置成 ConfigMap，以便在覆盖过程中使用。这样，我们就能够更为灵活和可靠地管理DNS 解析配置，从而确保 Flink 作业的稳定运行。</p>
<div class="language-yaml codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-yaml codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> v1</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token key atrule">data</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">resolv.conf</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> "nameserver  10.216.138.226" //DNS服务</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> ConfigMap</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">creationTimestamp</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">"2022-07-13T10:16:18Z"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">managedFields</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> dns</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">configmap</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">  </span><span class="token key atrule">namespace</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> native</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">flink</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>在通过 Pod Template 进行挂载。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/pod_template-d8a9864bc8486d493025cc5e8b0e6dd1.png" width="1080" height="476" class="img_iwx1"></p>
<p>这样大数据平台相关的 DNS 就可以维护在 dnsmasq 上，而 Flink 作业所运行的宿主机就可以按照 DNS 解析流程。</p>
<p>1.先检查自己本地的 hosts 文件，是否存在对应关系，读取到记录进行解析，没有则进行下一步</p>
<p>2.操作系统会去查看本地的 DNS 缓存，没有则进行下一步</p>
<p>3.操作系统会去我们在网络配置中定义的 DNS 服务器地址上进行查找</p>
<p>以此来实现动态的实现 DNS 的变更识别。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="06-多实例部署实践"><strong>06 多实例部署实践</strong><a class="hash-link" aria-label="06-多实例部署实践的直接链接" title="06-多实例部署实践的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#06-%E5%A4%9A%E5%AE%9E%E4%BE%8B%E9%83%A8%E7%BD%B2%E5%AE%9E%E8%B7%B5">​</a></h3>
<p>在实际生产环境中，我们常常需要操作多个集群，包括一套用于测试的集群和一套线上正式集群。任务首先在测试集群中进行结果验证和性能压测，确保无误后再发布到线上正式集群。</p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step1-修改端口号避免多个服务端口冲突">step1: 修改端口号，避免多个服务端口冲突<a class="hash-link" aria-label="step1: 修改端口号，避免多个服务端口冲突的直接链接" title="step1: 修改端口号，避免多个服务端口冲突的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step1-%E4%BF%AE%E6%94%B9%E7%AB%AF%E5%8F%A3%E5%8F%B7%E9%81%BF%E5%85%8D%E5%A4%9A%E4%B8%AA%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%8F%A3%E5%86%B2%E7%AA%81">​</a></h4>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/port_number-e421801c946def0b0e2df3747239fec6.png" width="1080" height="622" class="img_iwx1"></p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step2-修改-workspace">step2: 修改 workspace<a class="hash-link" aria-label="step2: 修改 workspace的直接链接" title="step2: 修改 workspace的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step2-%E4%BF%AE%E6%94%B9-workspace">​</a></h4>
<p>多个不同的实例服务需要配置多个不同的 workspace，这样避免资源干扰导致出现一些奇怪 bug。</p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="step3-启动多实例服务">step3: 启动多实例服务<a class="hash-link" aria-label="step3: 启动多实例服务的直接链接" title="step3: 启动多实例服务的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#step3-%E5%90%AF%E5%8A%A8%E5%A4%9A%E5%AE%9E%E4%BE%8B%E6%9C%8D%E5%8A%A1">​</a></h4>
<p>为了实现生产环境与测试环境的隔离，我们在启动流程的初始阶段引入了一个关键步骤。我们通过输入命令(针对Hadoop B 集群):</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">export HADOOP_CONF_DIR=/home/streamx/conf</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>有效地切断了 Flink on K8s 加载 HDFS 配置的默认逻辑。这样的操作确保了 A StreamPark 仅连接至 A Hadoop 环境，而 B StreamPark 则对应连接至 B Hadoop 环境，从而达到了将测试和生产环境进行完整隔离的目的。</p>
<p>具体来说，在这一操作指令生效后，我们就可以确保在 10002 端口提交的 Flink 作业所连接的 Hadoop 环境为 B Hadoop 环境。这样一来，B Hadoop 环境与过去在 10000 端口提交的 Flink 作业所使用的Hadoop环境就成功实现了隔离，有效防止了不同环境之间的相互干扰，确保了系统的稳定性和可靠性。</p>
<p>下述内容为 Flink 加载 Hadoop 环境逻辑代码分析：</p>
<div class="language-yaml codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-yaml codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">// 寻找hadoop配置文件的流程</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">//1、先去寻找是否添加了参数</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain">kubernetes.hadoop.conf.config</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">map.name</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">@Override</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">public Optional&lt;String</span><span class="token punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> getExistingHadoopConfigurationConfigMap() </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    final String existingHadoopConfigMap =</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">            flinkConfig.getString(KubernetesConfigOptions.HADOOP_CONF_CONFIG_MAP);</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    if (StringUtils.isBlank(existingHadoopConfigMap)) </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        return Optional.empty();</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"> else </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        return Optional.of(existingHadoopConfigMap.trim());</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">@Override</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">public Optional&lt;String</span><span class="token punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> getLocalHadoopConfigurationDirectory() </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    // 2、如果没有 1 中指定的参数，查找提交 native 命令的本地环境是否有环境变量</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain">HADOOP_CONF_DIR</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    final String hadoopConfDirEnv = System.getenv(Constants.ENV_HADOOP_CONF_DIR);</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    if (StringUtils.isNotBlank(hadoopConfDirEnv)) </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        return Optional.of(hadoopConfDirEnv);</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    // 3、如果没有 2 中环境变量，再继续看否有环境变量</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain">HADOOP_HOME</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    final String hadoopHomeEnv = System.getenv(Constants.ENV_HADOOP_HOME);</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    if (StringUtils.isNotBlank(hadoopHomeEnv)) </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        // Hadoop 2.2+</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        final File hadoop2ConfDir = new File(hadoopHomeEnv</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> "/etc/hadoop");</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        if (hadoop2ConfDir.exists()) </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">            return Optional.of(hadoop2ConfDir.getAbsolutePath());</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        // Hadoop 1.x</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        final File hadoop1ConfDir = new File(hadoopHomeEnv</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> "/conf");</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        if (hadoop1ConfDir.exists()) </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">            return Optional.of(hadoop1ConfDir.getAbsolutePath());</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    return Optional.empty();</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">final List&lt;File</span><span class="token punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> hadoopConfigurationFileItems = getHadoopConfigurationFileItems(localHadoopConfigurationDirectory.get());</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">// 如果没有找到 1、2、3 说明没有 hadoop 环境</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">if (hadoopConfigurationFileItems.isEmpty()) </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    LOG.warn(</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">            "Found 0 files in directory </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> skip to mount the Hadoop Configuration ConfigMap."</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">            localHadoopConfigurationDirectory.get());</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    return flinkPod;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">// 如果 2 或者 3 存在，会在路径下查找 core</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">site.xml 和 hdfs</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">site.xml 文件</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">private List&lt;File</span><span class="token punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> getHadoopConfigurationFileItems(String localHadoopConfigurationDirectory) </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    final List&lt;String</span><span class="token punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> expectedFileNames = new ArrayList&lt;</span><span class="token punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain">();</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    expectedFileNames.add("core</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">site.xml");</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    expectedFileNames.add("hdfs</span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token plain">site.xml");</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    final File directory = new File(localHadoopConfigurationDirectory);</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    if (directory.exists() </span><span class="token important">&amp;&amp;</span><span class="token plain"> directory.isDirectory()) </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        return Arrays.stream(directory.listFiles())</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">                .filter(</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">                        file </span><span class="token punctuation" style="color:rgb(212, 212, 212)">-</span><span class="token punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token scalar string" style="color:rgb(206, 145, 120)"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token scalar string" style="color:rgb(206, 145, 120)">                                file.isFile()</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token scalar string" style="color:rgb(206, 145, 120)">                                        &amp;&amp; expectedFileNames.stream()</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token scalar string" style="color:rgb(206, 145, 120)">                                                .anyMatch(name -&gt; file.getName().equals(name)))</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">                .collect(Collectors.toList());</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"> else </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">        return Collections.emptyList();</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">//如果有 hadoop 的环境，将会把上述两个文件解析为 kv 对，然后构建成一个 ConfigMap，名字命名规则如下</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">public static String getHadoopConfConfigMapName(String clusterId) </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">    return Constants.HADOOP_CONF_CONFIG_MAP_PREFIX + clusterId;</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>然后进行进程端口占用查询：</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">netstat -tlnp | grep 10000</span><br></span><span class="token-line" style="color:#9CDCFE"><span class="token plain">netstat -tlnp | grep 10002</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="带来的收益"><strong>带来的收益</strong><a class="hash-link" aria-label="带来的收益的直接链接" title="带来的收益的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#%E5%B8%A6%E6%9D%A5%E7%9A%84%E6%94%B6%E7%9B%8A">​</a></h2>
<p>我们的团队从 StreamX（即 StreamPark 的前身）开始使用，经过一年多的实践和磨合，StreamPark 显著改善了我们在 Apache Flink® 作业的开发管理和运维上的诸多挑战。StreamPark 作为一站式服务平台，极大地简化了整个开发流程。现在，我们可以直接在 StreamPark 平台上完成作业的开发、编译和发布，这不仅降低了 Flink 的管理和部署门槛，还显著提高了开发效率。</p>
<p>自从部署 StreamPark 以来，我们已经在生产环境中大规模使用该平台。从最初管理的 50 多个 FlinkSQL 作业，增长到目前近 500 个作业，如图在 StreamPark 上划分为 7 个 team，每个 team 中有几十个作业。这一转变不仅展示了 StreamPark 的可扩展性和高效性，也充分证明了它在实际业务中的强大应用价值。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/production_environment-4f155f3b14a4e95c5367ba99a6c5a6f8.png" width="1080" height="522" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="未-来-期-待"><strong>未 来 期 待</strong><a class="hash-link" aria-label="未-来-期-待的直接链接" title="未-来-期-待的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-ziru#%E6%9C%AA-%E6%9D%A5-%E6%9C%9F-%E5%BE%85">​</a></h2>
<p>自如作为 StreamPark 早期的用户之一，我们一直和社区同学保持密切交流，参与 StreamPark 的稳定性打磨，我们将生产运维中遇到的 Bug 和新的 Feature 提交给了社区。在未来，我们希望可以在 StreamPark 上管理 Apache Paimon 湖表的元数据信息和 Paimon 的 Action 辅助作业的能力，基于 Flink 引擎通过对接湖表的 Catalog 和 Action 作业，来实现湖表作业的管理、优化于一体的能力。目前 StreamPark 正在对接 Paimon 数据集成的能力，这一块在未来对于实时一键入湖会提供很大的帮助。</p>
<p>在此也非常感谢 StreamPark 团队一直以来对我们的技术支持，祝 Apache StreamPark 越来越好，越来越多用户去使用，早日毕业成为顶级 Apache 项目。</p>]]></content:encoded>
            <category>StreamPark</category>
            <category>生产实践</category>
        </item>
        <item>
            <title><![CDATA[长安汽车从自研平台到Apache StreamPark™ 的升级实践]]></title>
            <link>https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan</link>
            <guid>https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan</guid>
            <pubDate>Mon, 09 Feb 2026 02:32:43 GMT</pubDate>
            <description><![CDATA[导读：长安汽车是中国汽车四大集群阵营企业之一，随着业务发展和数智化的推进，对数据的实效性要求越来越高，Flink 作业越来越多，长安汽车原本开发了一套流应用平台，用来满足开发人员对于 Flink 作业管理和运维工作的基础需求，但是在实际使用中面临诸多挑战和困境，最终使用 Apache StreamPark 来作为一站式实时计算平台，有效解决了之前面临的诸多困境，StreamPark 提供的解决方案简化了整个开发流程，在 Flink 作业开发部署上节省了很多时间，走出了作业运维管理的泥沼，显著地提升了效率。]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/cover-cfb54d18805b5d425d6bbd2659db2533.png" width="1080" height="460" class="img_iwx1"></p>
<p><strong>导读</strong>：长安汽车是中国汽车四大集群阵营企业之一，随着业务发展和数智化的推进，对数据的实效性要求越来越高，Flink 作业越来越多，长安汽车原本开发了一套流应用平台，用来满足开发人员对于 Flink 作业管理和运维工作的基础需求，但是在实际使用中面临诸多挑战和困境，最终使用 Apache StreamPark 来作为一站式实时计算平台，有效解决了之前面临的诸多困境，StreamPark 提供的解决方案简化了整个开发流程，在 Flink 作业开发部署上节省了很多时间，走出了作业运维管理的泥沼，显著地提升了效率。</p>
<p>供稿单位｜长安智能化研究院云平台开发所</p>
<p>编辑校对｜潘月鹏</p>
<p>重庆长安汽车股份有限公司（简称“长安汽车”）成立于 1996 年 10 月 31 日，是中国汽车四大集团阵营企业，拥有 161 年历史底蕴，现在旗下包括长安启源、深蓝汽车、阿维塔、长安引力、长安凯程等自主品牌以及长安福特、长安马自达等合资品牌。</p>
<p>近些年随着汽车销量的不断增加与智能化程度的不断提升，车辆每天将产生千亿级别的 CAN 数据，清洗处理后的数据也在 50 亿级别，面对如此庞大且持续膨胀的数据规模，如何从海量数据中快速提取挖掘有价值的信息，为研发、生产、销售等部门提供数据支持，成为当前亟需解决的问题。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="1实时计算面临的挑战"><strong>1.实时计算面临的挑战</strong><a class="hash-link" aria-label="1实时计算面临的挑战的直接链接" title="1实时计算面临的挑战的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan#1%E5%AE%9E%E6%97%B6%E8%AE%A1%E7%AE%97%E9%9D%A2%E4%B8%B4%E7%9A%84%E6%8C%91%E6%88%98">​</a></h2>
<p>长安汽车数据的存储与分析处理主要由云上和云下两部分构成，云上指的是我们部署在腾讯云服务器上的大数据集群，CDH 搭建，用于存储热数据；云下是部署在本地机房的 CDP 集群，从云上拉取同步数据，进行存储和分析。<strong>Flink 在长安汽车实时计算中一直扮演着重要的角色，长安汽车开发了一套流应用平台，来满足开发人员对于 Flink 作业管理和运维工作的基础需求</strong>。但是在实际使用中，流应用平台存在以下四各方面问题：</p>
<p>①<strong>功能单一</strong>: 只提供部署功能，无用户权限管理、团队管理、角色管理、项目管理，无法满足项目、团队管理需求。</p>
<p>②<strong>易用性不足</strong>: SQL 编写无提示、日志浏览不便、不支持调试、无错误检测、无版本管理、无配置中心等。</p>
<p>③<strong>可扩展性较差</strong>: 不支持在线扩容 Flink 集群、新增或更换 Flink 版本，新增 Flink Connectors、CDC 等。</p>
<p>④<strong>可维护性较差</strong>: 无日志查看、无版本管理、无配置中心等。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="2为什么用-streampark"><strong>2.为什么用 StreamPark</strong><a class="hash-link" aria-label="2为什么用-streampark的直接链接" title="2为什么用-streampark的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan#2%E4%B8%BA%E4%BB%80%E4%B9%88%E7%94%A8-streampark">​</a></h2>
<p>我们针对Flink 作业面临的困境，决定先从开源领域寻求解决方案，因此我们全面调研了Apache StreamPark、Dxxky、strxxing-xx-web等开源项目，<strong>从核心能力、稳定性、易用性、可扩展性、可维护性、操作体验等多个维度进行了全方位的评估对比，并结合当前我们的流作业开发需求以及我司的大数据平台后续规划，发现 Apache StreamPark 是最符合我们当前需求的产品。因此采用 StreamPark 作为我们的流计算平台</strong>，StreamPark 有以下优势：</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="完善的基础管理能力"><strong>完善的基础管理能力</strong><a class="hash-link" aria-label="完善的基础管理能力的直接链接" title="完善的基础管理能力的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan#%E5%AE%8C%E5%96%84%E7%9A%84%E5%9F%BA%E7%A1%80%E7%AE%A1%E7%90%86%E8%83%BD%E5%8A%9B">​</a></h3>
<p>StreamPark 解决了我们已有的流应用平台无用户权限管理、团队管理、角色管理、项目管理、团队管理等问题。</p>
<p>① StreamPark 平台提供了用户权限管理功能。这些功能可以确保用户只能访问其所需的数据和资源，并限制其对系统或作业的修改权限。对于企业级用户而言，这种管理功能非常必要，因为它有助于保护企业的数据安全、维护系统稳定性，并确保作业的顺利运行。通过合理地设置和管理用户权限，企业可以更好地控制数据访问和操作，从而降低风险并提高工作效率。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/capability-2f9e6fd6a844689944e87e108221d5d9.png" width="554" height="370" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="一站式流处理平台"><strong>一站式流处理平台</strong><a class="hash-link" aria-label="一站式流处理平台的直接链接" title="一站式流处理平台的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan#%E4%B8%80%E7%AB%99%E5%BC%8F%E6%B5%81%E5%A4%84%E7%90%86%E5%B9%B3%E5%8F%B0">​</a></h3>
<p>StreamPark 解决了流应用平台易用性不足，SQL 编写无提示、日志浏览不方便、无错误检测、无版本管理、无配置中心等问题。</p>
<p>① StreamPark 具备完善的 SQL 校验功能，实现了自动 build/push 镜像，使用自定义类加载器，<strong>通过 Child-first 加载方式解决了 YARN 和 K8s 两种运行模式、支持了自由切换 Flink 版本等特性。</strong></p>
<p>② StreamPark 提供了作业监控和日志管理的功能，<strong>可以帮助用户实时监控作业的运行状态，查看作业的日志信息，以及进行故障排除</strong>。使得用户可以快速发现和解决作业运行中的问题。</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="可扩展性强"><strong>可扩展性强</strong><a class="hash-link" aria-label="可扩展性强的直接链接" title="可扩展性强的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan#%E5%8F%AF%E6%89%A9%E5%B1%95%E6%80%A7%E5%BC%BA">​</a></h3>
<p>StreamPark 解决了流应用平台可扩展性差，不支持在线扩容 Flink集群、新增或更换 Flink 版本、Flink Connectors 不足等问题。</p>
<p>① StreamPark 设计具有良好的可扩展性和灵活性，<strong>可以支持大规模的 Flink on Yarn 作业运行，它能够与现有的 Yarn 集群无缝集成</strong>，并可以根据需要进行定制和扩展。此外，StreamPark 还提供了多种配置选项和功能扩展点，以满足用户多样化的需求。</p>
<p>② <strong>StreamPark 具备 Flink 作业开发所需的整套工具</strong>。在 StreamPark 中，对于编写代码的 Flink 作业，它提供了一种更优秀的解决方案，将程序配置进行了标准化，简化了编程模型，同时还提供了一系列连接器，显著降低了 DataStream 开发的难度。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/connectors-399832ebea5ac259c19088bb4290efc2.png" width="554" height="369" class="img_iwx1"></p>
<p>除了上述优点外，<strong>StreamPark 还能妥善管理作业的整个生命周期，包括作业的开发、部署、运营以及问题诊断等环节，使开发人员能够专注于业务本身，无需过多关注 Flink 作业的管理和运维问题</strong>。StreamPark 的作业开发管理模块大致可以分为三个部分：作业管理基础功能、Jar 作业管理和 FlinkSQL 作业管理。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/job_management-ccb5b6adb51dd3dc263c4511360a4291.png" width="1080" height="542" class="img_iwx1"></p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="3streampark落地实践"><strong>3.StreamPark落地实践</strong><a class="hash-link" aria-label="3streampark落地实践的直接链接" title="3streampark落地实践的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan#3streampark%E8%90%BD%E5%9C%B0%E5%AE%9E%E8%B7%B5">​</a></h2>
<p>为了使 StreamPark 在日常生产实践中与我们的需求更加契合，我们对其进行了一定的适应性改造：</p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="适应性改造"><strong>适应性改造</strong><a class="hash-link" aria-label="适应性改造的直接链接" title="适应性改造的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan#%E9%80%82%E5%BA%94%E6%80%A7%E6%94%B9%E9%80%A0">​</a></h3>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="告警信息改造"><strong>告警信息改造</strong><a class="hash-link" aria-label="告警信息改造的直接链接" title="告警信息改造的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan#%E5%91%8A%E8%AD%A6%E4%BF%A1%E6%81%AF%E6%94%B9%E9%80%A0">​</a></h4>
<p>长安汽车针对 StreamPark 的一些特性进行了适应性改造，比如针对 StreamPark 的告警不仅支持邮件、飞书、钉钉和企业微信推送，还支持将告警信息按照重要程度进行分类，推送到不同的告警群与相关个人，方便相关运维人员及时捕捉重要告警信息，快速响应。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/alarm_information-b67199a66276ada93c1dba47a7581dc9.png" width="497" height="385" class="img_iwx1"></p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="nocos-配置管理支持"><strong>Nocos 配置管理支持</strong><a class="hash-link" aria-label="nocos-配置管理支持的直接链接" title="nocos-配置管理支持的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan#nocos-%E9%85%8D%E7%BD%AE%E7%AE%A1%E7%90%86%E6%94%AF%E6%8C%81">​</a></h4>
<p>为解决 Flink 应用的配置信息写死在 Jar 包中，给开发、测试、运维带来的不便，我们将 Nacos 与 StreamPark 平台进行集成，带来了如下优势：</p>
<p>① 配置集中管理，通过 StreamPark，开发人员可以集中管理所有 Flink 应用配置信息，实现配置的集中管理和更新，避免了在多个平台间进行切换和重复操作。同时加强了配置管理的安全性，对访问和修改配置的操作进行权限控制，防止未经授权的访问和修改。</p>
<p>② 配置动态更新，StreamPark 与 Nacos 的集成使得 Flink 应用能够及时获取最新的配置信息，实现配置的动态更新，避免了修改 Flink 配置信息后需要重新编译、发布、重启等繁琐流程，提高了系统的灵活性和响应速度。同时，StreamPark 可以利用 Nacos 的配置推送功能，实现配置信息的自动化更新。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/nocos-382ee7fe44f0199ec2209b703381d6cf.png" width="682" height="264" class="img_iwx1"></p>
<h3 class="anchor anchorWithStickyNavbar_xQxx" id="遇到的问题及解决方案"><strong>遇到的问题及解决方案</strong><a class="hash-link" aria-label="遇到的问题及解决方案的直接链接" title="遇到的问题及解决方案的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan#%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98%E5%8F%8A%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88">​</a></h3>
<p>我们当前私有云分析集群使用的是 Cloudera CDP，Flink 版本为 Cloudera Version 1.14，整体 Flink 安装目录以及配置文件结构与社区版本有较大出入。直接根据 StreamPark 官方文档进行部署，将无法配置 Flink Home，以及后续整体 Flink 任务提交到集群中，因此需要进行针对化适配集成，在满足使用需求上，尽量提供完整的 StreamPark 使用体验。</p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="1-flink集群无法访问"><strong>1. Flink集群无法访问</strong><a class="hash-link" aria-label="1-flink集群无法访问的直接链接" title="1-flink集群无法访问的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan#1-flink%E9%9B%86%E7%BE%A4%E6%97%A0%E6%B3%95%E8%AE%BF%E9%97%AE">​</a></h4>
<p>① 问题描述：Cloudera Flink 的安装路径与实际提交路径不一致，实际提交路径下缺少 conf 目录。</p>
<p>② 解决办法：实际的 flink 提交路径在</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">/opt/cloudera/parcels/Flink-$ {version}/lib/flink/bin/flink</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>因此路径</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">/opt/cloudera/parcels/Flink-$ {version}/1ib/flink</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>可以理解为真正的 Flink Home，具体查看该目录下内容。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/flink_home-effa79b6d882bdee8a3963543b193a0b.png" width="413" height="140" class="img_iwx1"></p>
<p>发现缺少 conf 目录，倘若配置该目录在 StreamPark 为 Flink Home 将无法访问到集群，因此可软连接 Flink 配置或者在该路径下编辑集群中的 Flink 配置文件。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/conf-42f135b00a0b3048efb6aa939efd30ac.png" width="484" height="167" class="img_iwx1"></p>
<p>综上，前置配置和打包好代码（代码中可能会涉及到自己使用上的优化修改）之后，可以进行部署。</p>
<p>注意 2.0 的版本打包的话直接执行源码中的 build.sh 即可，选择混合部署，生成的包在 dist 目录下。</p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="2-hadoop-环境检查失败"><strong>2. Hadoop 环境检查失败</strong><a class="hash-link" aria-label="2-hadoop-环境检查失败的直接链接" title="2-hadoop-环境检查失败的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan#2-hadoop-%E7%8E%AF%E5%A2%83%E6%A3%80%E6%9F%A5%E5%A4%B1%E8%B4%A5">​</a></h4>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/hadoop-1c0b84f088853fdc601244e8fad4abdf.png" width="554" height="183" class="img_iwx1"></p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">vi /etc/profile</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>解决办法：在部署 StreamPark 的节点上添加一下 hadoop 环境即可添加</p>
<div class="language-shell codeBlockContainer_APcc theme-code-block"><div class="codeBlockContent_ihow"><pre tabindex="0" class="prism-code language-shell codeBlock_iz1S thin-scrollbar" style="color:#9CDCFE;background-color:#1E1E1E"><code class="codeBlockLines_GbGI"><span class="token-line" style="color:#9CDCFE"><span class="token plain">export HADOOP_CONF_DIR=/etc/hadoop/conf</span><br></span></code></pre><div class="buttonGroup_lm1i"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_JoRx" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_ZTbR"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_r18r"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>source 使其生效，重启 StreamPark 即可。</p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="3-hdfs-的-flink路径下缺少-lib-目录"><strong>3. HDFS 的 Flink路径下缺少 lib 目录</strong><a class="hash-link" aria-label="3-hdfs-的-flink路径下缺少-lib-目录的直接链接" title="3-hdfs-的-flink路径下缺少-lib-目录的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan#3-hdfs-%E7%9A%84-flink%E8%B7%AF%E5%BE%84%E4%B8%8B%E7%BC%BA%E5%B0%91-lib-%E7%9B%AE%E5%BD%95">​</a></h4>
<p>解决办法：在于部署后的 StreamPark 在 HDFS 上的工作目录上 lib 目录没有正常上传，找到 HDFS 上初始化的 StremPark work 路径，观察一下 hdfs:///streampark/flink/.../下的 lib 目录是否完整，不完整的话手动将本地 Flink Home 目录下的 lib put 上去即可。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/lib-681f949f839a87303f598e2e7b907e24.png" width="554" height="214" class="img_iwx1"></p>
<h4 class="anchor anchorWithStickyNavbar_xQxx" id="4-作业失败后自动拉起导致作业重复"><strong>4. 作业失败后自动拉起导致作业重复</strong><a class="hash-link" aria-label="4-作业失败后自动拉起导致作业重复的直接链接" title="4-作业失败后自动拉起导致作业重复的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan#4-%E4%BD%9C%E4%B8%9A%E5%A4%B1%E8%B4%A5%E5%90%8E%E8%87%AA%E5%8A%A8%E6%8B%89%E8%B5%B7%E5%AF%BC%E8%87%B4%E4%BD%9C%E4%B8%9A%E9%87%8D%E5%A4%8D">​</a></h4>
<p>StreamPark 自身具备作业使用后重启拉取的能力，当检测到作业失败后会重新拉起，但在实践中发现会出现同一个失败的作业在 YARN上启动多个的情况，经过和社区沟通，已确定是个 Bug，最终在 2.1.3 中解决了该 Bug。</p>
<h2 class="anchor anchorWithStickyNavbar_xQxx" id="4带来的收益"><strong>4.带来的收益</strong><a class="hash-link" aria-label="4带来的收益的直接链接" title="4带来的收益的直接链接" href="https://streampark.apache.org/zh-CN/blog/streampark-usercase-changan#4%E5%B8%A6%E6%9D%A5%E7%9A%84%E6%94%B6%E7%9B%8A">​</a></h2>
<p>目前长安汽车已经在云上生产/预生产环境、云下生产/预生产环境中部署了 StreamPark，截至发稿前 StreamPark 共管理了 150+ 的 Flink 作业，包括 JAR 和与 SQL 作业。涉及利用 Flink、FlinkCDC 等技术，从 MySQL 或 kafka 同步数据到 MySQL、Doris、HBase、Hive 等数据库。后续所有环境总计 3000+ 的 Flink 作业也会分批迁至 StreamPark 来集中管理。</p>
<p><strong>Apache StreamPark 带来的收益最明显的就是其提供了一站式服务，业务开发同学可以在 StreamPark 上完成作业开发编译发布，无需再使用多个工具完成一个 FlinkSQL 作业开发，简化了整个开发流程</strong>，StreamPark 给我们在 Flink 作业开发部署上节省了很多时间，显著地提升了 Flink 应用开发效率。</p>
<p><img decoding="async" loading="lazy" src="https://streampark.apache.org/zh-CN/assets/images/job-767d96706631b95dadf7638c142a0adc.png" width="1080" height="542" class="img_iwx1"></p>]]></content:encoded>
            <category>StreamPark</category>
            <category>生产实践</category>
        </item>
    </channel>
</rss>