2026/9/17 7:12:30

datart 开源 BI 数据可视化平台 MySQL 部署与故障排查

datart 开源 BI 数据可视化平台 MySQL 部署与故障排查 数据可视化这件事很多团队都经历过同一个阶段业务方要报表Excel 手工统计撑不了多久买商业 BI预算和采购流程又卡着自研一套图表平台前端图表库加上后端查询调度没两三个月下不来。datart 就是在这个夹缝里被越来越多人翻出来的开源项目——一套可以自己部署的数据可视化与 BI 平台数据源接进来、数据集配好、拖几张图、拼成仪表板或者数据大屏整套链路是完整的。这篇不讲空概念讲的是 datart 部署使用这条路上我实际走过的顺序先在单机上十分钟跑通看到登录页再换成 MySQL 元数据库搭生产形态然后是起得来但用不了的那几类故障怎么排查最后是数据源接入、源码编译和上线之后要盯的几件事。不管你只是想在测试机上试一把还是准备把它放进内网给整个业务线用下面这些步骤和坑都能直接对得上。1. 先把 datart 的定位和内部概念捋顺再动手部署1.1 datart 处理的是数据到画面这条完整链路很多人第一次打开 datart 会有点懵因为它的左侧菜单层级比想象中深。其实它的模型非常线性数据源Source→ 数据集Dataset→ 图表Chart→ 仪表板 / 数据大屏Dashboard / Screen。数据源就是你已有的业务库MySQL、PostgreSQL、ClickHouse、Doris、Hive 这些都能接数据集是一层逻辑视图你可以在里面写 SQL、定义字段类型、配置变量和权限图表是绑定了数据集的具体可视化单元仪表板和大屏则是图表的容器和布局层。理解这条链路的顺序很关键因为它直接决定了你部署完之后该按什么顺序去验证。正确做法是先配一个数据源、连一下测试库再建一个最简单的数据集然后拖一张柱状图出来。如果这三步走通了说明你的部署是健康的如果连数据源都保存失败那就别去折腾大屏渲染的问题先回来查后端和数据库连接。另外要清楚 datart 自己也需要一个数据库这个库不存你的业务数据只存元数据——用户、组织、权限、数据源配置、数据集定义、仪表板布局全在这里。这个库叫元数据库它选什么是部署方案里第一个需要拍板的决定。1.2 部署前必须先定下来的三个变量我在帮别人看部署问题时发现绝大多数的返工都不是技术难度问题而是这三个变量一开始没说清楚。第一个是元数据库。datart 默认用 H2 内嵌数据库好处是开箱即用坏处是数据跟着容器走。测试环境随便用生产环境必须换 MySQL这一点后面单独展开讲。第二个是对外访问方式。是直接暴露8080端口用 IP 访问还是走 Nginx 反向代理挂个域名还是挂在内网某个子路径下比如/bi/。这个决定会影响你的代理配置、会话 Cookie、大屏里的资源路径越早定越好。临时用 IP 撑着后面换域名时经常会出现登录后跳回登录页的情况。第三个是内存。datart 是个 Java 应用默认堆内存对小型使用没什么问题但你要跑大屏、跑大数据量的 SQL 查询默认配置很容易 OOM。提前规划好容器内存上限和 JVM 参数比事后重启救火省事得多。1.3 四种部署形态按场景选而不是按先进程度选部署形态适合场景优点主要代价单机 Docker H2本地试用、功能验证、POC十分钟跑通零依赖数据不持久化不能多人用Docker Compose MySQL中小团队生产环境编排清晰升级简单可备份需要自己维护 MySQL源码编译部署需要改代码、定制功能可深度定制前后端环境、构建时间长容器编排平台部署已有集群、要统一运维扩缩容与运维统一学习与配置成本高我的建议是先用第一种把功能摸熟再直接跳到第二种上线。很多人一上来就想用源码编译显得正规结果卡在 Node 版本和 Maven 依赖上下不来反而对项目本身失去了信心。先把能跑起来的那一版跑起来比什么都重要。2. 十分钟跑通单机 Docker 版先见到登录页再说2.1 拉镜像与启动命令的每个参数都有理由单机版的核心就是一条docker run。但我不建议你复制一条命令就完事里面每个参数都是为了让后面的迁移少踩坑docker pull datart/datart:latest mkdir -p /opt/datart/config /opt/datart/data docker run -d --name datart \ -p 8080:8080 \ -v /opt/datart/config:/datart/config \ -v /opt/datart/data:/datart/data \ -e TZAsia/Shanghai \ --restart unless-stopped \ datart/datart:latest-v /opt/datart/config:/datart/config是把外置配置文件目录挂出来容器启动时会读这个目录下的application-config.yml这是后面换 MySQL 的关键入口。-v /opt/datart/data:/datart/data是挂内嵌数据库和运行时数据目录不挂的话容器一删数据全没。-e TZAsia/Shanghai是为了让容器内的时间和你本地一致时区问题在 BI 工具里会直接表现为图表上的数据差了八小时。--restart unless-stopped保证宿主机重启后服务能自己起来。注意镜像的仓库名和标签在不同版本间可能调整动手前建议去项目的官方仓库或镜像仓库确认一下当前推荐的镜像名与版本标签尽量不要在生产环境直接用latest。启动之后用docker logs -f datart盯日志等到出现类似应用启动完成、Web 服务监听 8080 端口的输出就说明容器内的进程起来了。这一步的日志非常重要后面排查问题时你会发现九成的问题在日志里都有痕迹只是当时没看。2.2 第一次登录必须做的三件事浏览器打开http://服务器IP:8080会出现登录页。默认内置账号是admin初始密码通常是123456具体以官方文档为准不同版本可能有差异。登录进去之后我建议按顺序做完三件事。第一件立刻改掉初始密码。这不是形式主义很多团队把平台跑在内网就放松了结果初始密码一直没改谁扫到了都能进。改完之后把新密码存到团队的密钥管理里。第二件创建一个组织并把自己和同事加进去。datart 的资源数据源、数据集、仪表板都是挂在组织下做权限隔离的如果你在默认组织外面到处建资源后期整理权限会很痛苦。先把组织结构和成员理清楚再开始建资源。第三件验证一下元数据是不是真的能持久化。具体做法很简单建一个测试用的目录或资源然后docker restart datart重启后看看它还在不在。这一步能提前暴露卷没挂对的问题比等到生产上丢配置要好得多。2.3 容器里的 H2 数据到底存在哪值不值得依赖H2 是文件型数据库数据落在容器内的某个数据目录下。你可以进去看一眼实际路径docker exec -it datart sh -c ls -lh /datart/data看到那些.mv.db之类的文件就是你的全部元数据。这里有两个很现实的判断一是单文件数据库在高并发写入下是有风险的多人同时配数据集、保存仪表板的时候可能出现锁等待二是它没有成熟的在线备份方案你只能停服务复制文件。所以 H2 的定位非常明确——试用可以长期用不行。真要跑起来给业务用直接进下一节的方案。3. 换成 MySQL 元数据库把生产形态用 compose 编排起来3.1 为什么这一步不是可选优化而是必须做H2 的问题不在于性能不够而在于它和容器生命周期绑在一起并且缺少你熟悉的那套运维手段。你没法用mysqldump定时备份没法做主从出问题时没有慢查询日志可看迁移服务器的时候还得停服务拷文件。换成 MySQL 之后备份、监控、迁移、升级全都回到了你熟悉的轨道上。还有个容易被忽略的点元数据库是 datart 升级时自动执行表结构变更的地方。版本升级时应用会根据内置的迁移脚本去改元数据库的表结构如果这个库是 H2 且文件在容器里一旦升级过程中出错回滚几乎没有余地。用独立的 MySQL升级前先备份一份出问题直接还原这才叫有退路。3.2 compose 编排文件MySQL 参数里的三个坑下面这份是可直接改用的 compose 骨架我把它写得比较完整是因为几个参数如果不设后面一定会遇到问题services: mysql: image: mysql:8.0 container_name: datart-mysql restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: 请替换成强密码 MYSQL_DATABASE: datart MYSQL_USER: datart MYSQL_PASSWORD: 请替换成强密码 TZ: Asia/Shanghai command: - --character-set-serverutf8mb4 - --collation-serverutf8mb4_general_ci - --default-authentication-pluginmysql_native_password - --max_connections500 - --default-time-zone08:00 volumes: - /opt/datart/mysql:/var/lib/mysql healthcheck: test: [CMD, mysqladmin, ping, -h, 127.0.0.1] interval: 10s timeout: 5s retries: 12 datart: image: datart/datart:latest container_name: datart restart: unless-stopped depends_on: mysql: condition: service_healthy ports: - 8080:8080 environment: TZ: Asia/Shanghai volumes: - /opt/datart/config:/datart/config - /opt/datart/data:/datart/data三个必须说的参数utf8mb4不设中文和特殊字符迟早出乱码mysql_native_password是为了兼容部分 JDBC 驱动在老版本下的认证方式MySQL 8 默认的认证插件有时候会让连接直接失败报一个看起来和密码无关的错max_connections要配合 datart 自己的连接池来调太小会出现连接池耗尽的报错太大又可能把数据库压垮。healthcheck加depends_on: condition: service_healthy这组配置是防止一种很典型的失败MySQL 容器启动了但还没初始化完datart 就急着去连连不上直接启动失败然后你就看到一个服务起来又退出了的诡异现象。加上健康检查datart 会等 MySQL 真正可用了再启动。3.3 application-config.yml 的字段含义与连接串细节配置文件放在挂载出来的/opt/datart/config/application-config.yml内容大致是这样spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://mysql:3306/datart?useUnicodetruecharacterEncodingutf8useSSLfalsezeroDateTimeBehaviorconvertToNullserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue username: datart password: 请替换成强密码连接串里那几个参数不是装饰serverTimezoneAsia/Shanghai决定 JDBC 怎么解释时间不写容易出现时间偏移allowPublicKeyRetrievaltrue是在useSSLfalse的情况下让驱动能完成认证握手少了它可能直接连不上zeroDateTimeBehaviorconvertToNull是应对历史数据里那些0000-00-00的脏时间值BI 平台上查这种字段报错是很常见的。characterEncodingutf8配合数据库的utf8mb4中文才不会变成问号。配置文件名和字段名在不同版本之间可能微调如果你改完配置没生效第一件事是去容器日志里确认应用到底读到了哪个配置文件很多时候是路径挂错了或者文件权限不对导致读不进去。3.4 建库、建表、首次启动的正确顺序顺序不能乱先让 MySQL 跑起来并且建好datart库再启动 datart。库的表结构一般有两种处理方式一种是应用首次启动时自动执行内置的建表脚本另一种是手动把项目提供的初始化 SQL 引入。日志里如果出现建表相关输出基本可以确认自动初始化成功了。如果启动报出表不存在这类错误多半是初始化脚本没跑成功——常见原因是数据库账号没有建表权限或者字符集不对导致脚本执行中断。这时候别急着删库重来先看日志里具体是哪条语句失败了。4. 起得来不代表能用几类典型故障的完整排查路径4.1 容器起来了但登录 500 或者页面一片空白这是我被问得最多的一类。排查顺序我固定成四步走你可以照着复现。第一步看后端日志。直接docker logs --tail 200 datart重点找异常堆栈里第一个出现的类名和错误信息。如果是数据库连接类异常回到上一节检查连接串和账号权限如果是建表或字段相关的异常那就是元数据库初始化没完成。第二步确认元数据表数量对不对。进 MySQL 执行SHOW TABLES;如果只有零散几张表说明初始化脚本只跑了一半这种情况下页面能打开但一操作就报错是必然的。第三步查静态资源。如果登录页本身是空白按浏览器 F12 看 Network 面板前端资源是不是 404。如果走的是 Nginx 反向代理那基本上是代理路径没配全导致的。第四步查浏览器控制台。前端报的跨域、Cookie 无法写入、请求被重定向这些信息只在控制台里看得到。尤其是走域名访问的场景登录成功后跳回登录页十有八九是会话 Cookie 的域或安全属性跟你的代理协议不匹配。4.2 图表上的时间差八小时三层时区要一起对齐时区问题在 BI 工具里特别扎眼因为业务方第一眼就会看到昨天的数据怎么跑到今天来了。要解决它得同时对齐三层容器时区、数据库时区、JDBC 连接串时区。容器用TZAsia/ShanghaiMySQL 用--default-time-zone08:00连接串用serverTimezoneAsia/Shanghai三者一致才稳。注意如果只改了应用侧而不改数据库侧的时区那么写入和读取的偏移方向相反问题会变得更隐蔽——数据看起来正常但按天聚合的时候边界会错。改完配置记得重启容器并且用一条明确带时间条件的查询验证一下别靠肉眼看图表判断。4.3 中文乱码和导出图片里的方块字中文问题分两种。一种是数据乱码根因在字符集数据库、表、连接串三处都必须是 UTF-8 系列缺一处就可能在某个环节被转错。另一种是界面或导出图片里出现方块这不是编码问题而是容器里没装中文字体。如果你用到大屏导出图片、报表截图这类功能就在镜像基础上装一套中文字体或者在构建镜像时把字体文件打进去。排查手法很直接图表里中文正常、只有导出的图片是方块那就是字体连图表里的中文都不正常那就是字符集。4.4 反向代理配置和长连接超时挂域名访问是标准做法Nginx 的配置重点是这几个头不能少server { listen 80; server_name bi.example.com; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_http_version 1.1; proxy_read_timeout 300s; proxy_send_timeout 300s; } }X-Forwarded-Proto不加应用可能以为是 HTTP导致生成的链接和 Cookie 属性出问题。proxy_read_timeout默认值偏短大屏加载、大数据量查询很容易超过默认超时表现就是页面转圈然后报错把超时调大通常就解决了。如果你还要挂子路径访问务必确认应用侧支持该路径配置否则前端资源会全部 404这种情况我建议宁可单独给一个二级域名也不要去改子路径。5. 把业务库接进来数据源配置的实操要点5.1 连接账号的权限与连接池调优配数据源的时候第一原则是给只读账号。BI 平台的职责是查询和展示不是写业务数据用业务主库的读写账号去连是给自己埋雷。只读账号配合视图或者专门的查询库能挡掉绝大部分误操作风险。连接池方面要注意 datart 只是众多客户端之一你的业务库本身可能还承受着线上服务的压力。所以连接数不要开太大同时把查询超时设上一个合理值。实践里最难受的场景不是查询慢而是某个同事写了一条全表扫描的 SQL把数据库连接占满导致所有人的报表一起打不开。给查询加超时和限制返回行数比事后追责有用。5.2 驱动缺失Doris、ClickHouse 这类数据源怎么补驱动MySQL、PostgreSQL 这类常见数据库驱动一般镜像里就带了。但如果你要接 Doris、ClickHouse、达梦、Kylin 这类常常会遇到驱动类找不到的报错。解决思路是把对应的 JDBC 驱动包放进应用的驱动加载目录然后重启容器。# 先确认容器内的驱动目录位置路径以实际镜像为准 docker exec -it datart sh -c ls -l /datart/lib # 拷进去之后重启 docker cp ./clickhouse-jdbc.jar datart:/datart/lib/ docker restart datart这里有个经验驱动包的版本要和目标数据库的版本匹配。用太新的驱动连老版本数据库或者反过来都可能出现奇怪的认证失败或协议不兼容。补完驱动后先在数据源页面点测试连接通过了再去建数据集别跳过这一步。5.3 数据集里的 SQL 变量和视图模式的取舍数据集有两种典型用法一种是用可视化界面选表和字段视图模式另一种是直接写 SQLSQL 模式。视图模式上手快、可维护性好适合标准化报表SQL 模式灵活可以写复杂关联和聚合适合做宽表。如果要在 SQL 里做参数化datart 支持在 SQL 中嵌入变量配合仪表板上的筛选器一起用。这里有个容易踩的点变量替换的写法写错了不会报错只会返回空结果。所以写完 SQL 后一定要先在数据集编辑页里实际执行一次看着结果对上了再拿去配图表。另外SQL 模式下的数据集是每次查询实时执行的如果 SQL 本身很重仪表板每刷新一次数据库就要扛一次这种情况建议在数据库侧先建好物化视图或汇总表。6. 源码编译部署什么情况下值得折腾怎么少走弯路6.1 先判断你到底需不需要源码部署源码部署的唯一理由是你要改代码改前端界面、加一个新的数据源适配、调整某个业务逻辑。如果你只是想部署使用容器方案已经完全够用而且升级维护都更简单。我见过不少人为了可控去编译源码结果时间全花在环境上最后部署出来的版本还不如官方镜像稳定。如果你确实需要定制先把环境对齐JDK 版本、Maven 版本、Node 版本这三样必须严格匹配官方要求尤其是 Node版本高了或低了前端构建都可能失败。6.2 前后端构建的流程与产物落点大致的流程是先构建前端再打包后端前端的构建产物需要被后端打包进最终的运行包# 前端 cd frontend npm install --registryhttps://registry.npmmirror.com npm run build # 后端 cd .. mvn clean package -DskipTests具体的模块名和产物路径各版本会有差异打包完成后你会拿到一个可执行的 jar。启动的时候通过外置配置文件指定配置位置java -jar target/datart-server.jar \ --spring.config.additional-locationfile:./config/ \ --server.port8080--spring.config.additional-location这个参数很有用它让你在不重新打包的前提下改数据库配置和容器方案里挂载配置目录是一个思路。6.3 编译期最常见的几类报错按我遇到过的频率排一下。前端依赖安装失败多数是网络问题换镜像源或者配好代理缓存Node 版本导致的构建报错报错信息往往很模糊看到语义不明的构建错误先怀疑版本打包时内存不足Maven 打大项目默认堆内存不够会直接中断调大内存参数即可前端产物没被正确打进 jar表现是后端起来了但页面 404这时候要检查前端构建是否真的执行成功、产物目录是否被后端打包插件包含进去。7. 上线之后要盯的三件事备份、升级、权限7.1 元数据库的备份策略和迁移姿势元数据库备份用最朴素的方式就够定时mysqldump导出datart库保留最近若干天的文件。但要注意一个细节——元数据里保存的是数据源连接信息密码可能是加密存储的所以在跨环境迁移时把元数据库直接搬到另一套环境可能会因为加密密钥或环境差异导致连接失效。稳妥的做法是迁移后逐个数据源点一次测试连接确认。迁移服务器时顺序是新环境部署好、元数据库导入、配置文件对齐、启动验证、最后改域名解析。不要在业务高峰期操作也不要在没验证的情况下就切流量。7.2 版本升级备份、替换、观察迁移日志升级的流程其实很短但每一步都不能省。先备份元数据库这是唯一的兜底。然后拉取新版本镜像停旧容器、起新容器重点观察启动日志里有没有表结构迁移的输出和报错。如果迁移失败回滚方式就是还原数据库备份加回退旧镜像版本。注意升级前最好先在测试环境用同一份元数据库副本演练一次尤其是跨大版本升级。生产环境直接升级赌的是运气。7.3 组织权限模型的最小可用配置最后说权限因为这是上线之后最容易出乱子的一块。datart 的权限链路是组织 → 成员 → 资源授权。我的建议是不要一开始就设计复杂的分层先做三档管理员能配数据源和数据集的、分析者能建图表和仪表板但不能改数据源的、查看者只能看被分享的内容。绝大多数团队用这三档就够了。资源授权的时候注意数据源和数据集是分开授权的。有同事反馈我能看到仪表板但打开报没权限通常就是仪表板给了权限、但它依赖的数据集没给。这种问题不用改代码去资源授权里补一下就行。我在实际使用中最深的一个体会是datart 这类平台的价值不在于能画多炫的图而在于它把业务自助这件事的边界划清了——数据源和数据集的维护权留在技术人员手里图表和仪表板的搭建权交给业务方。部署只是把地基打好真正省时间的是上线之前就想清楚谁能碰哪一层。这套规矩定下来平台就不需要你天天救火了。