
自己折腾过几套实时计算平台之后我对Dinky这套东西的评价是它能帮你把Flink SQL的开发、提交、运维串起来省掉大量在命令行和代码之间来回切换的碎片时间。这篇文章就是把我最近在CentOS上完整部署Dinky的过程做个记录从系统初始化到数据库准备、配置文件修改、启动服务再到接入Flink集群跑通第一个SQL任务全部过一遍。核心环境是CentOS 7.9和Dinky 1.0.3如果你用的是CentOS 7、8或者Stream版本大部分步骤也能直接参考。部署Dinky并不是解压即用它依赖MySQL存元数据还要连一个真正干活的Flink集群。所以整个链路里任何一个环节出问题最终都会在Dinky页面上表现为“任务提交失败”或者“集群注册不成功”。这篇文章适合两类人看一类是刚接触Dinky、想在虚拟机里快速搭一套环境试试效果的数据开发另一类是已经在生产环境用Flink想引入Dinky做SQL平台化管理的平台工程师。我会把每一步背后的原因也写进去尽量做到你照着操作一遍下次出问题知道去哪排查。1. 部署前的整体规划与思路拆解1.1 Dinky是什么解决什么问题Dinky定位是“实时计算平台”底层基于Apache Flink但它不是Flink的替代品而是站在Flink上面做一层管理。你可以把它理解成一个针对Flink SQL的IDE加运维后台浏览器里写SQL做语法校验看执行计划一键提交到Flink集群然后在页面上管理作业、查日志、做定时调度。如果没有Dinky这套平台日常用Flink SQL开发是什么状态要么把SQL写死在代码里要么手敲flink run命令提交JAR包每个作业的个人风格还不一样时间一长脚本散落在各个服务器运维接手非常痛苦。Dinky把SQL变成了一种“资源”可以保存版本、多人协作提交记录和运行状态都在页面上有迹可循。对于需要对外提供数据开发能力的团队来说它解决的不只是开发效率还有流程规范化的问题。1.2 选型Dinky版本和配套组件Dinky的版本迭代不算慢不同版本对Flink版本、JDK版本、MySQL版本的支持都不一样。我这次选的是Dinky 1.0.3配套Flink 1.16.2数据库用MySQL 5.7JDK用1.8。这套组合在CentOS 7.9上跑下来比较稳网上踩坑帖子也相对多遇到问题容易搜到答案。版本选型上有个原则不要盲目追求最新。Dinky新版往往对应Flink的新版本而Flink版本升级会连带影响Hadoop、Hive等一堆依赖。如果你的下游组件还停留在旧版本强行上新版Dinky就是给自己挖坑。反过来太老的Dinky版本对Flink 1.16以上支持又不全面。建议先在测试环境装一套把日常任务跑一遍确认没问题再考虑生产。选型时可以画一个简单的兼容性匹配表把Dinky版本、Flink版本、JDK版本、MySQL版本对应起来避免部署到一半发现某个组件版本不兼容。1.3 我用的环境清单和拓扑规划我是在一台VMware虚拟机里做的部署生产环境通常会用云主机或物理机思路一致。给出一份我实际使用的环境清单组件版本/规格操作系统CentOS 7.9 Minimal硬件规格4核CPU / 8GB内存 / 100GB磁盘JDKOpenJDK 1.8.0_362MySQL5.7.44Dinky1.0.3Flink1.16.2 StandaloneWeb访问端口8888网络拓扑上Dinky和Flink可以装在同一台机器上生产环境建议分散部署。MySQL单独一台或使用云数据库都行关键是Dinky所在机器能通过网络访问到MySQL和Flink的JobManager地址。我在这套环境里所有组件都在一台虚拟机好处是调试方便坏处是不能暴露端口映射问题。后面章节里讲到网络排查的地方需要你根据自己机器的IP做替换。2. CentOS基础环境准备别在这一步省事2.1 系统初始化静态IP、主机名、时间同步CentOS装好之后第一件事不是急着装Dinky而是把系统基础环境整理干净。最小化安装默认没有图形界面系统资源分配紧凑这对跑Dinky反而是好事。首先要配置一个固定IP不然重启后IP变了Dinky页面上注册的Flink集群地址、你访问Web后台的地址全都要跟着改。配置方法不复杂编辑/etc/sysconfig/network-scripts/ifcfg-ens192这个文件把BOOTPROTOstaticONBOOTyes再手动指定IPADDR、NETMASK、GATEWAY和DNS。不同虚拟机的网卡名可能不同可以用ip addr命令先看一下实际名称。接着设置主机名我习惯把主机名改成dinky-server同时修改/etc/hosts把本机IP和主机名对应起来。Flink、Dinky、MySQL之间相互访问时很多报错都源于主机解析不到。时区同步也不能漏Dinky的调度任务依赖服务器时间如果时间差了太多定时任务执行时间会对不上。系统装了chrony的情况下启动并启用chronyd服务配置好NTP源后时间会逐渐校正。我见过不少部署案例最后作业调度时间不对排查半天发现是服务器时区还是UTC所以在初始化阶段就要统一为Asia/Shanghai。2.2 JDK与MySQL的安装要点JDK我直接用yum装的OpenJDK 1.8命令很简单yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel装完之后确认一下JAVA_HOME是否生效可以把下面这行追加到/etc/profile里让全局都能找到Java环境export JAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk export PATH$JAVA_HOME/bin:$PATHDinky本身是用Java写的它会以子进程方式提交Flink作业所以JDK版本尽量和Flink要求保持一致。JDK 11、17虽然也能跑但遇到反射、模块化相关问题排查起来麻烦建议稳妥用1.8。MySQL的安装方式不少我用的是MySQL官方提供yum仓库装的5.7。装好之后需要手动启动服务设置开机自启。这里有一个容易忽略的点Dinky初始化数据库时需要建库建用户如果你用的是云数据库可以跳过本地安装但一定要把白名单和账号权限配好。无论哪种方式字符集必须用utf8mb4因为Dinky的元数据里会存SQL文本如果SQL里有中文注释或者中文字符串字符集不对会直接报错或乱码。2.3 防火墙、SELinux和目录权限处理CentOS 7默认开了firewalld如果你不想在防火墙上做过多规则配置最直接的办法是关掉它。这个动作仅限测试环境生产环境要按公司安全规范开放端口。我这次在虚拟机里模拟直接执行了systemctl stop firewalld systemctl disable firewalldSELinux同样建议先关掉不然Dinky访问MySQL、写日志文件时都可能遇到权限被拒的问题报错信息还不直观。关闭SELinux需要修改/etc/selinux/config把SELINUXenforcing改成SELINUXdisabled然后重启系统才会完全生效。如果想不重启也可以用setenforce 0临时放宽但下次重启又会恢复所以两条命令建议都执行。再强调一下目录权限。Dinky解压后默认归root但实际运行不要用root跑。我会单独创建一个dinky系统用户把安装目录所有者改掉。很多新手在这里偷懒直接用root启动结果Dinky生成的日志、临时文件全是root权限后续维护时用普通用户清理非常麻烦也不安全。3. Dinky安装包下载与核心配置文件修改3.1 获取Dinky发行包并准备目录Dinky官方在GitHub有Release页面找到对应版本号的dinky-release-*.tar.gz包下载下来传到服务器。如果你那边的网络下载慢也可以传本地包上去。文件名里的版本号后面通常还会标明适配的Flink版本比如dinky-release-1.0.3-flink-1.16.tar.gz之类下载时要看清。解压之前我先规划好安装路径统一放到/opt下面tar -zxvf dinky-release-1.0.3.tar.gz -C /opt/ mv /opt/dinky-release-1.0.3 /opt/dinky useradd -r -s /sbin/nologin dinky chown -R dinky:dinky /opt/dinky为什么要把目录放到/opt而不是/root因为/root目录权限默认限制很多普通用户无法访问Dinky以普通用户运行时就容易出问题。另外要把安装目录下的bin目录加入PATH或者至少记录好路径后续启动、停止都要用。Dinky需要知道自己的家目录所以auto.sh脚本内部会读取目录信息尽量不要移动安装路径部署完再迁目录会引入很多环境变量问题。3.2 数据库账号准备与SQL脚本导入Dinky的元数据存储在MySQL里所以要先建一个独立的数据库。我习惯把数据库命名为dinky_metadata账号单独建一个不给root权限避免其他应用受到影响。在MySQL命令行里执行CREATE DATABASE IF NOT EXISTS dinky_metadata DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER dinky% IDENTIFIED BY Dinky123; GRANT ALL PRIVILEGES ON dinky_metadata.* TO dinky%; FLUSH PRIVILEGES;这里有个细节账号主机部分如果用%意味着任何来源都能连适合Dinky和MySQL不在同一台机器的情况如果都在同一台可以收紧成localhost。初始化Dinky表结构时需要执行安装包里自带的SQL脚本。脚本通常在/opt/dinky/sql目录下可能有一个主脚本和多个升级脚本首次部署只需要执行主脚本。比如mysql -h127.0.0.1 -udinky -pDinky123 dinky_metadata /opt/dinky/sql/dinky.sql执行完可以确认一下表数量如果表很少或者执行报错要立刻看脚本里的注释确认没有漏表。Dinky后续升级时还会用到sql/upgrade目录下的脚本所以这个路径要保留。3.3 application.yml配置避坑指南Dinky启动时读取的核心配置在/opt/dinky/config/application.yml这个文件里配置了服务端口、数据库连接、日志级别等。不同版本可能还会拆分出application-mysql.yml之类的文件但整体逻辑差不多。我修改了这几个关键项server: port: 8888 spring: datasource: url: jdbc:mysql://127.0.0.1:3306/dinky_metadata?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue username: dinky password: Dinky123如果你是MySQL 8.0建议在URL后面加allowPublicKeyRetrievaltrue不然连接时可能因为公钥检索限制报错。如果是MySQL 5.7加这个参数无伤大雅。serverTimezoneAsia/Shanghai一定要加上否则后端在处理时间类型时可能和本地时区差出8个小时。YAML文件的缩进非常严格不能用Tab缩进。我有一次修改配置把注释顶格了导致启动时解析失败日志里看不到明确行号后来逐行排查才发现是多了一个空格。建议修改配置前先备份原文件出问题时还能对比。4. 启动Dinky并完成首次Web访问4.1 用auto.sh启动服务和查看日志Dinky安装包提供了一键启动脚本bin/auto.sh。启动之前先确保MySQL和Flink集群已准备好尤其是MySQL如果连不上Dinky启动后进入流程会一直报错然后进程自动退出。启动命令cd /opt/dinky bin/auto.sh start脚本执行完不会有特别醒目的成功提示所以接下来最重要的一步是看日志。Dinky的日志在/opt/dinky/logs目录下核心日志是dinky.log。用tail -100f实时观察tail -100f /opt/dinky/logs/dinky.log如果日志尾部出现“Started DinkyApplication”之类的字样说明启动成功。如果进程一闪而过先别急着重新启动把日志往回翻找到异常堆栈。常见问题集中在数据库连接、端口被占用、配置文件解析失败这几类。4.2 首次登录Dinky控制台要注意什么浏览器访问http://你的IP:8888默认账号密码都是admin。第一次登录成功后会看到几个导航菜单包括数据开发、注册中心、运维中心、系统设置等。有一点容易忽略默认密码一定要尽快改掉因为Dinky后台可以提交、删除作业权限范围很大暴露在公网等于裸奔。登录进去后建议先花几分钟把“注册中心”里的几个菜单点一遍熟悉集群配置、数据源配置、告警配置的位置。Dinky很多功能是分角色权限的后续如果多人使用最好先规划好用户角色不要让所有人都用管理员账号。页面能正常打开只能说明Dinky自身进程没问题真正的功能验证要等到接入Flink集群之后。4.3 配置systemd守护Dinky进程如果直接用auto.sh start启动进程是挂在当前shell下的一旦终端退出或者服务器意外重启Dinky不会自动拉起。生产环境我建议用systemd管理。在/etc/systemd/system/dinky.service里写入[Unit] DescriptionDinky Service Afternetwork.target mysqld.service [Service] Userdinky Typeforking ExecStart/opt/dinky/bin/auto.sh start ExecStop/opt/dinky/bin/auto.sh stop Restarton-failure RestartSec10 [Install] WantedBymulti-user.target写完后执行systemctl daemon-reload再用systemctl start dinky启动。这里要注意auto.sh如果返回成功但实际进程没有起来systemd会误判启动成功。所以启动完还是要确认日志。有些版本的auto.sh没有为systemd设计PID文件如果发现systemd状态和实际进程不一致可以把ExecStart直接改成/usr/bin/java -jar /opt/dinky/lib/dinky-admin.jar配合Typesimple这样进程生命周期由systemd管理更可靠。5. 在Dinky里接入Flink集群和第一个SQL任务5.1 注册Flink集群Standalone和YARN两种模式Dinky本身不计算它要把SQL提交到Flink集群。Flink集群可以先启动一个Standalone模式的实例在Flink安装目录下执行bin/start-cluster.sh然后进入Dinky后台“注册中心”-“Flink集群”点击新增集群集群类型选择Standalone填上JobManager地址比如http://127.0.0.1:8081。保存后会做连通性检测如果地址能访问状态就会变成“正常”。如果生产环境用的是YARN注册方式又不一样。Dinky需要读取Hadoop配置所以要提前配置好HADOOP_HOME和HADOOP_CONF_DIR并且部署Dinky的机器得有权限向YARN提交任务。通常还要在Dinky安装目录下补充对应的Flink发行包或者依赖JAR。Standalone模式适合开发和测试YARN模式才是生产主流因为它能根据资源池隔离多个作业避免任务之间互相抢占。首次部署建议先用Standalone跑通全流程再切换到YARN。5.2 配置数据源并跑通第一个FlinkSQLFlink集群注册成功之后还需要配置数据源让Dinky知道你可以连接哪些库。在“注册中心”-“数据源”里新增MySQL数据源填上连接地址、数据库名、账号密码。这里填的账号要确保Dinky服务器能访问到目标MySQL而不是只在页面填了就能连上。Dinky会做一次连通性测试失败就直接红字提示。数据源配好后进入“数据开发”页新建一个SQL作业执行模式选Standalone集群选择刚才注册的Flink集群然后写一个最简单但能验证全链路的SQLselect hello dinky as msg;点击“执行”后Dinky会把这条SQL翻译成Flink作业提交到集群。如果能看到返回结果说明从Dinky到MySQL、从Dinky到Flink的链路全部通了。这一步是关键的分水岭跑通了后面复杂作业多半就是SQL写法或业务依赖的问题链路本身不用再操心。5.3 作业运维和调度的小技巧Dinky页面上提交的作业可以在“运维中心”看到运行状态、日志和停止操作。这里有几个我实际总结出的经验。第一FlinkSQL作业最好在语句里显式设置Checkpoint哪怕是开发环境也养成习惯例如set execution.checkpointing.interval30s; set state.checkpoints.dirfile:///opt/flink/checkpoints;这样作业突然重启时能从Checkpoint恢复不至于从头消费数据。第二Dinky支持定时调度可以把一个写好的SQL作业绑定为周期任务但配置调度前一定先手动执行一次确认作业能稳定跑完。第三如果作业一直处于“RUNNING”但没有数据输出先看任务是否真的提交到了Flink集群而不是卡在Dinky内部提交步骤。6. 部署中常见问题与排查经验6.1 启动就报数据库连接失败怎么办这是我在交流群里看到最多的部署问题一般分三种情况。第一种是MySQL服务没启动或者端口没开用ss -lntp查看3306端口有没有监听。第二种是Dinky配置的数据库账号密码错了直接看异常里的“Access denied”字眼。第三种比较隐蔽MySQL的bind-address默认绑定了127.0.0.1如果Dinky不在本机即使账号权限是%也连不上需要把/etc/my.cnf里的bind-address改成0.0.0.0再重启MySQL。还有一次遇到URL里时区参数没写启动不报错但登录后台后时间总是差8小时。排查方法很简单用客户端连一下数据库执行select now()再对比Dinky页面上显示的服务器时间很容易判断。6.2 Web页面打不开或502错误排除掉Dinky进程没启动的情况先看端口有没有监听ss -lntp | grep 8888如果有监听再确认防火墙是否拦截用curl -v http://127.0.0.1:8888在本机验证一次本机能通、外网不通问题就出在防火墙或安全组。生产环境在云上还要检查云安全组规则这是一个特别容易被忽略的坑。如果本机curl都没反应说明服务确实没有正常监听回头查日志。还有一种情况是Nginx做了反向代理然后报502。这是Nginx到Dinky后端连接不上通常因为Dinky启动太慢代理超时。可以适当调大proxy_read_timeout或者等Dinky日志出现启动完成字样后再访问。6.3 Flink任务提交失败的常见原因在Dinky里执行SQL时如果报错提到“Connection refused”多半是Flink JobManager地址填的不对或者Flink集群没启动。如果报错提到“ClassNotFound”一般是Flink版本和Dinky自带的依赖不匹配需要重新下载对应版本的Dinky发行包。如果报错是“No applicable buffer”大概率是TaskManager的内存或槽位不足到Flink页面看Slot信息把并行度调小或者增加TaskManager。还有一类问题是用户权限。Dinky以dinky用户运行如果/opt/dinky目录权限不足提交作业时Dinky没法写临时文件会出现奇怪的IO异常。看到日志里出现Permission denied时第一时间检查安装目录和/tmp目录的权限别急着怀疑代码。7. 部署后的日常维护与升级建议7.1 配置备份与数据库定时备份Dinky部署起来不难难的是数据维护。Dinky的所有作业定义、集群配置、数据源信息都存在MySQL的dinky_metadata库里这个库丢了整个平台就只剩一个空壳。我建议至少每天做一次逻辑备份用crontab简单实现0 2 * * * mysqldump -h127.0.0.1 -udinky -pDinky123 dinky_metadata /data/backup/dinky_metadata_$(date %F).sql 2/dev/null备份文件放/data/backup定期清理历史文件保留最近7天足够。另外/opt/dinky/config目录里的application.yml虽然不大但改动频繁也应该加入备份范围。我在升级Dinky或修改配置前都会先做一次全备相当于给整个平台上一个保险。7.2 Dinky升级时的注意事项Dinky升级和首次安装不同不是解压覆盖那么简单。首先要看官方发版说明找到从你当前版本到目标版本的升级SQL脚本一般放在sql/upgrade目录。升级前备份数据库然后按顺序执行升级脚本顺序不能跳否则字段对不上应用启动后就会各种报错。其次不要直接覆盖整个安装目录。我习惯先把新包解压到另一个目录然后对比配置文件确认新版本有哪些参数变化再把旧版本的application.yml里自定义的配置项复制过去。Dinky安装目录下的lib、plugins和config三个目录各有分工升级时尤其要谨慎。如果升级后作业跑不起来第一件事不是回滚版本而是把logs/dinky.log里的异常堆栈找出来看是升级脚本没执行完整还是某个插件和旧配置不兼容。我个人在实际操作中最大的体会是Dinky这类平台型组件部署本身并不是核心难点真正考验人的是对依赖关系的理解和对异常日志的耐心。每一次启动失败、任务提交报错其实都在提醒你对Flink集群状态、网络配置、权限设置的理解还差了一点。按照这篇文章从环境初始化开始一步步走基本能避开大多数新手会踩的坑剩下的问题多半也能通过看日志快速定位。