十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

使用Superset构建多数据源(MySQL/Hive)自助OLAP看板:Python大数据分析实战指南

使用Superset构建多数据源(MySQL/Hive)自助OLAP看板:Python大数据分析实战指南 引言现代BI的挑战与Superset的定位在数据驱动决策的时代企业往往同时使用多种数据存储系统——MySQL存储业务交易数据Hive承载离线海量日志ClickHouse负责实时指标MongoDB存放文档型数据。如何将这些异构数据源统一到同一套可视化平台让业务人员能够自助探索、自由组合、秒级响应是数据工程团队面临的核心挑战。Apache Superset作为开源BI工具凭借其“轻量级、云原生、Python驱动”的特性在过去三年中迅速崛起成为取代Tableau/PowerBI的强力候选。它原生支持50数据源连接器内置SQL Lab交互式查询和丰富的可视化图表库且所有元数据均存储在PostgreSQL中便于版本管理与二次开发。本文将基于Superset 4.1.02026年3月最新稳定版从零搭建一套连接MySQL事实表和Hive维度表的混合数据看板涵盖环境部署、数据源配置、虚拟数据集创建、SQL Lab调优、行级权限控制、缓存策略及看板发布全流程。目录引言现代BI的挑战与Superset的定位第一章 环境准备Docker-Compose极速部署与源码定制1.1 为什么选择Docker部署1.2 docker-compose.yml配置详解1.3 自定义配置连接MySQL和Hive的必要驱动1.4 启动与验证第二章 数据源准备MySQL与Hive测试数据集2.1 MySQL数据初始化2.2 Hive数据初始化第三章 数据源连接MySQL与Hive的注册与测试3.1 通过UI添加MySQL数据库3.2 添加Hive数据库含Kerberos或LDAP配置3.3 处理Hive分区表若适用第四章 创建虚拟数据集多源联邦查询4.1 创建订单宽表视图跨MySQLHive JOIN4.2 性能优化物化视图 vs 实时查询4.3 中文列名与数据类型映射第五章 高级分析创建计算指标与参数化查询5.1 使用Python函数自定义计算列5.2 动态参数化查询URL过滤第六章 可视化图表构建从基础到高级6.1 时间序列趋势图每日GMV6.2 地理分布图城市销售额6.3 商品品类分析饼图 柱状图组合6.4 高级自定义ECharts图表第七章 看板设计与交互多数据源联动7.1 创建Dashboard7.2 全局过滤器跨图表联动7.3 层级下钻Drill Through第八章 行级权限与数据安全8.1 基于角色的行级过滤8.2 列级权限敏感字段脱敏第九章 性能调优缓存、异步查询与结果集压缩9.1 三级缓存策略9.2 异步查询Celery Redis9.3 结果集压缩与分页第十章 运维与监控日志、告警与备份10.1 日志收集10.2 重要告警配置10.3 元数据定期备份第十一章 扩展使用Python API自动化管理11.1 使用Superset Python Client第一章 环境准备Docker-Compose极速部署与源码定制1.1 为什么选择Docker部署Superset官方推荐生产环境使用Docker-Compose或Kubernetes。本地开发测试用Docker最为高效——镜像内置了所有Python依赖pandas、sqlalchemy、pyhive无需手动解决thrift/hive的兼容性问题。我们采用官方GitHub仓库提供的docker-compose.yml并做三处定制增加mysql-client和hive-jdbc驱动预设管理员账号挂载本地自定义Python配置文件1.2 docker-compose.yml配置详解yamlversion: 3.8 services: superset: image: apache/superset:4.1.0 container_name: superset_olap restart: always ports: - 8088:8088 environment: - SUPERSET_SECRET_KEY${SECRET_KEY} - SUPERSET_LOAD_EXAMPLESno # 不加载示例数据提升启动速度 - DATABASE_DBsuperset - DATABASE_HOSTpostgres - DATABASE_PASSWORDsuperset - DATABASE_USERsuperset depends_on: - postgres - redis volumes: - ./superset_home:/app/superset_home # 持久化配置文件 - ./custom_configs:/app/pythonpath # 挂载自定义配置 - ./data:/data # 挂载本地CSV测试数据 command: sh -c superset db upgrade superset init superset fab create-admin --username admin --firstname Admin --lastname User --email adminexample.com --password admin123 superset run -p 8088 --with-threads --reload --debugger healthcheck: test: [CMD, curl, -f, http://localhost:8088/health] interval: 30s timeout: 10s retries: 5 postgres: image: postgres:15 container_name: superset_postgres environment: - POSTGRES_DBsuperset - POSTGRES_USERsuperset - POSTGRES_PASSWORDsuperset volumes: - pg_data:/var/lib/postgresql/data ports: - 5432:5432 redis: image: redis:7.2 container_name: superset_redis ports: - 6379:6379 volumes: - redis_data:/data volumes: pg_data: redis_data:关键参数说明SUPERSET_LOAD_EXAMPLESno减少初始化时间约3分钟--with-threads开启多线程模式支持并发查询--reload开发模式下热加载Python代码1.3 自定义配置连接MySQL和Hive的必要驱动在custom_configs/superset_config.py中添加以下内容python# -*- coding: utf-8 -*- import os from datetime import timedelta # 安全密钥生产环境务必使用环境变量 SECRET_KEY os.environ.get(SUPERSET_SECRET_KEY) or dev-secret-change-me # 会话超时设置为24小时 SESSION_COOKIE_SAMESITE Lax SESSION_COOKIE_SECURE False # 本地HTTP测试设为False # 数据库连接池设置避免Hive连接数爆炸 SQLALCHEMY_POOL_SIZE 10 SQLALCHEMY_MAX_OVERFLOW 20 SQLALCHEMY_POOL_RECYCLE 3600 # 结果后端缓存使用Redis RESULT_BACKEND redis://redis:6379/0 CACHE_CONFIG { CACHE_TYPE: RedisCache, CACHE_DEFAULT_TIMEOUT: 300, CACHE_KEY_PREFIX: superset_, CACHE_REDIS_URL: redis://redis:6379/1 } # CSV导出最大行数 CSV_EXPORT_MAX_ROWS 1000000 # 允许跨域若需嵌入其他网页 ENABLE_CORS True CORS_OPTIONS {supports_credentials: True} # 增加Hive的thrift传输大小处理大结果集 HIVE_THRIFT_TRANSPORT SASL HIVE_AUTH NONE # 若使用Kerberos则改为KERBEROS1.4 启动与验证bash# 创建必要目录 mkdir -p superset_home custom_configs data # 启动所有容器 docker-compose up -d # 等待约2分钟后访问 http://localhost:8088 # 账号 admin / admin123验证驱动是否安装bashdocker exec -it superset_olap pip list | grep -E mysql|hive|impala预期输出应包含mysql-connector-python、pyhive、impyla等。第二章 数据源准备MySQL与Hive测试数据集为了演示多源联合分析我们构造一个典型的电商场景MySQL存储订单事实表orders包含订单ID、用户ID、商品ID、金额、下单时间Hive存储用户维度表dim_users用户ID、注册时间、城市、会员等级和商品维度表dim_products商品ID、类目、品牌、上架时间2.1 MySQL数据初始化在MySQL容器中执行以下SQLsqlCREATE DATABASE IF NOT EXISTS ecommerce; USE ecommerce; CREATE TABLE orders ( order_id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id INT NOT NULL, product_id INT NOT NULL, amount DECIMAL(12,2) NOT NULL, order_date DATE NOT NULL, order_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, status TINYINT DEFAULT 1 COMMENT 1:成功 2:退款 ); -- 插入100万条模拟数据使用存储过程 DELIMITER $$ CREATE PROCEDURE generate_orders(IN num_rows INT) BEGIN DECLARE i INT DEFAULT 1; WHILE i num_rows DO INSERT INTO orders (user_id, product_id, amount, order_date) VALUES ( FLOOR(1 RAND() * 100000), -- 10万用户 FLOOR(1 RAND() * 5000), -- 5000商品 ROUND(RAND() * 500 10, 2), -- 10~510元 DATE_ADD(2025-01-01, INTERVAL FLOOR(RAND() * 600) DAY) ); SET i i 1; END WHILE; END$$ DELIMITER ; CALL generate_orders(1000000); -- 生成100万订单 CREATE INDEX idx_user_date ON orders(user_id, order_date); CREATE INDEX idx_product_date ON orders(product_id, order_date);2.2 Hive数据初始化假设Hive已部署在hive-server:10000若未部署可用Docker的bigdata-hive镜像。执行以下DDLsqlCREATE DATABASE IF NOT EXISTS ecommerce_dw; USE ecommerce_dw; -- 用户维度表50万行 CREATE EXTERNAL TABLE IF NOT EXISTS dim_users ( user_id INT, register_date DATE, city STRING, membership_level TINYINT COMMENT 1:铜牌 2:银牌 3:金牌 4:钻石 ) ROW FORMAT DELIMITED FIELDS TERMINATED BY \t STORED AS TEXTFILE LOCATION /user/hive/warehouse/ecommerce_dw/dim_users; -- 商品维度表5000行 CREATE EXTERNAL TABLE IF NOT EXISTS dim_products ( product_id INT, category STRING, brand STRING, launch_date DATE, price DECIMAL(10,2) ) ROW FORMAT DELIMITED FIELDS TERMINATED BY \t STORED AS TEXTFILE LOCATION /user/hive/warehouse/ecommerce_dw/dim_products;生成测试数据并上传到HDFSpython# generate_hive_data.py import random from datetime import datetime, timedelta import pandas as pd # 用户数据 users [] start_date datetime(2024, 1, 1) for i in range(1, 500001): register start_date timedelta(daysrandom.randint(0, 730)) city random.choice([北京,上海,广州,深圳,杭州,成都,武汉]) level random.choices([1,2,3,4], weights[0.4,0.3,0.2,0.1])[0] users.append(f{i}\t{register.strftime(%Y-%m-%d)}\t{city}\t{level}) with open(/tmp/dim_users.tsv, w) as f: f.write(\n.join(users)) # 商品数据 products [] categories [电子产品,服装,食品,家居,图书] brands [品牌A,品牌B,品牌C,品牌D] for i in range(1, 5001): launch start_date timedelta(daysrandom.randint(0, 365)) price round(random.uniform(10, 2000), 2) cat random.choice(categories) brand random.choice(brands) products.append(f{i}\t{cat}\t{brand}\t{launch.strftime(%Y-%m-%d)}\t{price}) with open(/tmp/dim_products.tsv, w) as f: f.write(\n.join(products))上传至Hive表路径bashhdfs dfs -put /tmp/dim_users.tsv /user/hive/warehouse/ecommerce_dw/dim_users hdfs dfs -put /tmp/dim_products.tsv /user/hive/warehouse/ecommerce_dw/dim_products第三章 数据源连接MySQL与Hive的注册与测试3.1 通过UI添加MySQL数据库登录Superset点击右上角Settings → Database Connections → Database。Database选择MySQLSQLAlchemy URItextmysqlmysqlconnector://root:mysql123host.docker.internal:3306/ecommerce注意由于Superset在容器内需使用host.docker.internal指向宿主机MySQL若MySQL也在容器中使用服务名mysql:3306。Extra高级参数json{ engine_params: { pool_size: 5, max_overflow: 10, pool_recycle: 3600, connect_args: { connect_timeout: 10, charset: utf8mb4 } }, metadata_params: {}, schemas_allowed_for_csv_upload: [ecommerce] }点击Test Connection显示Connection looks good!后保存。3.2 添加Hive数据库含Kerberos或LDAP配置若Hive未开启认证texthive://hive-server:10000/ecommerce_dw?authNONE若开启Kerberostexthive://hive-server:10000/ecommerce_dw?authKERBEROSkerberos_service_namehive在Extra中增加Hive特有参数json{ engine_params: { connect_args: { configuration: { hive.exec.parallel: true, hive.exec.parallel.thread.number: 8, hive.auto.convert.join: true } } }, metadata_cache_timeout: 600 }保存后在SQL Lab中尝试查询SELECT * FROM dim_users LIMIT 10确保返回结果。3.3 处理Hive分区表若适用如果事实表按日期分区如orders_ds需在Superset中设置分区列。编辑Hive数据源在Advanced → Partition columns中添加ds并选择Partition type: Range。这样在SQL Lab中查询时会自动添加分区过滤避免全表扫描。第四章 创建虚拟数据集多源联邦查询Superset的核心优势在于Virtual Dataset——允许用户基于一个或多个物理表编写SQL生成一个逻辑视图后续图表均基于该视图构建。这完美解决了多数据源JOIN的问题但注意跨源JOIN实际是在Superset后端内存中完成的不适合大表JOIN需谨慎使用。4.1 创建订单宽表视图跨MySQLHive JOIN进入SQL Lab选择MySQL数据源ecommerce执行以下查询sql-- 该查询会从MySQL拉取orders再从Hive拉取dim_users和dim_products -- 注意Superset会将结果暂存为临时表但建议用视图固化 SELECT o.order_id, o.user_id, u.city, u.membership_level, o.product_id, p.category, p.brand, o.amount, o.order_date, DATE_FORMAT(o.order_date, %Y-%m) as month, YEAR(o.order_date) as year, MONTH(o.order_date) as month_num, QUARTER(o.order_date) as quarter, CASE WHEN u.membership_level 3 AND o.amount 100 THEN 高价值 WHEN o.amount 200 THEN 高金额 ELSE 普通 END AS order_segment FROM ecommerce.orders o LEFT JOIN ecommerce_dw.dim_users u ON o.user_id u.user_id LEFT JOIN ecommerce_dw.dim_products p ON o.product_id p.product_id WHERE o.order_date 2025-01-01 AND o.status 1 -- 仅成功订单点击Run确认结果无误后点击Save as → Save as Virtual Dataset命名为v_orders_wide并选择数据库为ecommerce默认存于MySQL。此时该视图将出现在数据集列表中。4.2 性能优化物化视图 vs 实时查询跨源查询每次加载都会触发两次网络IO延迟较高。生产环境建议两种方案物化到MySQL使用Airflow调度每日将Hive维度同步到MySQL通过INSERT INTO ... SELECT然后在Superset中只连接MySQL一个数据源。使用Trino/Presto作为统一SQL引擎Superset直接连接Trino由Trino负责跨源查询优化。本文采用方案1的简化版——使用Superset的Scheduled Reports功能每日凌晨将宽表结果写入MySQL物理表图表直接查询该物理表。sql-- 在MySQL中创建物化表 CREATE TABLE ecommerce.mv_orders_wide AS SELECT ...; -- 同上SQL -- 每日刷新使用 TRUNCATE INSERT在Superset中将数据集从虚拟视图切换为物理表mv_orders_wide。4.3 中文列名与数据类型映射在数据集编辑页面点击Edit Columns为每个列设置中文别名如order_id→订单ID并调整数据类型amount→Decimalorder_date→Dateuser_id→Numbercity→String同时标记Default指标COUNT(order_id)作为默认计数SUM(amount)作为总金额。第五章 高级分析创建计算指标与参数化查询5.1 使用Python函数自定义计算列Superset 4.1支持在数据集中添加Custom SQL计算字段也可通过Python函数实现复杂逻辑。在数据集详情页点击 Custom Columnsql-- 计算客单价 CASE WHEN COUNT(order_id) 0 THEN SUM(amount) / COUNT(order_id) ELSE 0 END对于更复杂的逻辑如同比、环比可利用Saved QueryPython Exporterpython# 在Superset的Jupyter Notebook插件中需安装superset-jupyter from superset import security_manager from superset.models.slice import Slice import pandas as pd # 获取当前数据集查询结果 df get_dataset_data(v_orders_wide, metrics[SUM(amount)], groupby[city, month], time_rangelast year) # 计算同比 df[prev_year] df[SUM(amount)].shift(12) df[yoy_growth] (df[SUM(amount)] - df[prev_year]) / df[prev_year]5.2 动态参数化查询URL过滤Superset支持在仪表板URL中传递参数例如texthttp://localhost:8088/superset/dashboard/1/?city上海membership_level4在数据集SQL中使用{{ filter_values(city) }}宏sqlSELECT * FROM mv_orders_wide WHERE 11 AND city {{ filter_values(city)[0] }} AND membership_level {{ filter_values(membership_level)[0] | int }}需在数据集设置中开启Allow ad-hoc queries和Template parameters。第六章 可视化图表构建从基础到高级6.1 时间序列趋势图每日GMV创建新Chart选择数据集mv_orders_wide可视化类型Time-series Line ChartMetricsSUM(amount)别名GMVTimeorder_date粒度dayGroup bycity多条线对比Filtersorder_date 2025-06-01在Advanced中开启Rolling avg (7 days)平滑曲线6.2 地理分布图城市销售额使用Deck.gl Scatterplot或Mapbox。需提前在Superset中添加地理编码Settings → Mapbox。操作维度city指标SUM(amount)在Geography中设置Longitude和Latitude列需提前在数据集中添加经纬度映射若无经纬度数据可改用TableHeatmap展示。6.3 商品品类分析饼图 柱状图组合Pie Chartcategory为维度COUNT(order_id)为指标展示销量占比Bar Chartbrand为维度SUM(amount)为指标并按category分组6.4 高级自定义ECharts图表Superset 4.1内置了ECharts插件支持水球图、雷达图等。若需完全自定义可在custom_configs中添加自定义前端插件需Node.js构建本文不展开。第七章 看板设计与交互多数据源联动7.1 创建Dashboard点击 Dashboard命名为电商大盘分析 - 多源融合将上述图表逐一添加至看板拖拽布局顶部放置全局过滤器日期范围、城市、会员等级7.2 全局过滤器跨图表联动点击Edit Dashboard → Add FilterFilter 1order_date→ 日期范围选择器默认最近30天Filter 2city→ 多选下拉框Filter 3membership_level→ 单选过滤器基于数据集字段自动作用于所有使用该数据集的图表实现多源统一过滤。7.3 层级下钻Drill Through在图表设置中开启Enable drill to detail。用户点击某个柱状图柱子时可跳转至明细数据表格需预先创建Detail图表。通过{{ url_param(order_id) }}传递参数。第八章 行级权限与数据安全8.1 基于角色的行级过滤业务场景区域经理只能看本城市数据。Superset通过Row Level Security (RLS)实现。在Settings → Dashboard Roles中创建角色Regional_Manager关联到数据集mv_orders_wide添加规则json{ clause: WHERE city IN (SELECT assigned_city FROM user_city_mapping WHERE username {{ current_username() }}) }在user_city_mapping表中维护用户名与城市的对应关系此表需提前创建在MySQL中8.2 列级权限敏感字段脱敏在数据集编辑中将user_id标记为Sensitive并设置Allowed Roles仅管理员可见。普通用户查询该列将返回***。第九章 性能调优缓存、异步查询与结果集压缩9.1 三级缓存策略一级缓存前端浏览器缓存静态资源通过Nginx配置二级缓存后端Redis缓存SQL查询结果TTL300秒三级缓存数据源MySQL和Hive自身的查询缓存如Hive的hive.cache.expr.evaluation在superset_config.py中调整pythonCACHE_DEFAULT_TIMEOUT 600 # 延长至10分钟 CACHE_QUERY_RESULTS True CACHE_CONFIG { CACHE_TYPE: RedisCache, CACHE_REDIS_URL: redis://redis:6379/2, CACHE_KEY_PREFIX: superset_result_, }9.2 异步查询Celery Redis对于Hive大查询如扫描数月数据可启用Celery异步任务避免浏览器超时。bash# 启动Celery worker celery -A superset.tasks.celery_app:app worker --loglevelinfo在配置中启用pythonENABLE_CELERY True CELERY_BROKER_URL redis://redis:6379/3 CELERY_RESULT_BACKEND redis://redis:6379/3超时设置pythonHIVE_QUERY_TIMEOUT 600 # 10分钟9.3 结果集压缩与分页在MySQL连接URI中添加textmysqlmysqlconnector://...?compresstrueHive则通过配置hive.exec.compress.outputtrue。对于大结果集在SQL Lab中设置Limit为100000并开启Server Side Pagination。第十章 运维与监控日志、告警与备份10.1 日志收集Superset日志输出到容器stdout可使用docker logs superset_olap -f --tail 100实时查看。生产环境建议集成ELKpython# superset_config.py LOGGING_LEVEL INFO LOGGING_FORMAT %(asctime)s - %(name)s - %(levelname)s - %(message)s SILENCE_FAB True10.2 重要告警配置查询超时告警监控Celery任务失败率数据源连接数告警通过Superset的/health端点检查database_connections缓存命中率Redisinfo stats中查看keyspace_hits10.3 元数据定期备份PostgreSQL元数据库每日备份脚本bash#!/bin/bash docker exec superset_postgres pg_dump -U superset superset /backup/superset_$(date %Y%m%d).sql第十一章 扩展使用Python API自动化管理Superset提供完整的REST APISwagger文档/api/v1/swagger可用Python批量创建数据集、图表和看板。11.1 使用Superset Python Clientbashpip install apache-superset-clientpythonfrom superset_client import SupersetClient client SupersetClient( hosthttp://localhost:8088, usernameadmin, passwordadmin123 ) # 创建数据集 dataset_payload { database: 1, # MySQL数据库ID schema: ecommerce, table_name: mv_orders_wide, owners: [1], is_sqllab_view: False, columns: [ {column_name: order_id, type: INT, is_dttm: False}, {column_name: amount, type: DECIMAL, is_dttm: False}, {column_name: order_date, type: DATE, is_dttm: True}, ] } response client.post(/api/v1/dataset/, jsondataset_payload) print(Dataset ID:, response.json()[id]) # 批量创建图表 chart_configs [ {slice_name: 日趋势, viz_type: line, datasource_id: 123}, {slice_name: 城市分布, viz_type: mapbox, datasource_id: 123}, ] for cfg in chart_configs: client.post(/api/v1/chart/, jsoncfg)
返回列表