Redash数据查询与可视化功能深度解析
本文深入解析了Redash平台的核心功能,包括SQL查询编辑器的智能特性、丰富的可视化图表类型与配置选项、灵活的仪表板创建与布局管理系统,以及可靠的数据刷新与自动更新机制。文章通过详细的技术架构图、配置示例和最佳实践,全面展示了Redash如何帮助数据分析师和开发人员高效地进行数据查询和可视化分析。
SQL查询编辑器功能详解
Redash的SQL查询编辑器是其核心功能之一,为数据分析师和开发人员提供了一个强大而直观的SQL编写环境。该编辑器不仅支持基本的SQL语法高亮和自动完成,还集成了丰富的辅助功能,让数据查询变得更加高效和便捷。
编辑器核心功能架构
Redash的SQL查询编辑器采用模块化设计,主要包含以下几个核心组件:
classDiagram
class QueryEditor {
+String content
+DataSource dataSource
+executeQuery()
+saveQuery()
+formatQuery()
}
class AutoComplete {
+List~String~ suggestions
+getTableSuggestions()
+getColumnSuggestions()
+getFunctionSuggestions()
}
class SyntaxHighlighter {
+highlightSQL()
+detectErrors()
}
class ParameterManager {
+List~Parameter~ parameters
+parseParameters()
+validateParameters()
}
class SchemaBrowser {
+List~Table~ tables
+browseSchema()
+previewTable()
}
QueryEditor --> AutoComplete
QueryEditor --> SyntaxHighlighter
QueryEditor --> ParameterManager
QueryEditor --> SchemaBrowser
智能自动完成功能
Redash的自动完成功能基于数据库schema信息,能够智能推荐表名、列名、函数和关键字。系统会实时分析当前光标位置和上下文,提供最相关的建议。
自动完成类型示例:
| 完成类型 | 触发字符 | 示例建议 |
|---|---|---|
| 表名完成 | 空格后 | users, orders, products |
| 列名完成 | . 后 |
id, name, created_at |
| 函数完成 | ( 前 |
COUNT(), SUM(), DATE() |
| 关键字完成 | 语句开始 | SELECT, FROM, WHERE |
参数化查询支持
Redash支持强大的参数化查询功能,允许用户在SQL查询中定义动态参数,这些参数可以通过UI界面进行配置和输入。
参数语法示例:
SELECT
user_id,
name,
email
FROM users
WHERE
created_at >= {{ start_date }}
AND created_at <= {{ end_date }}
AND status = {{ status_filter }}
支持的参数类型包括:
- 文本参数:自由输入的文本值
- 数字参数:数值类型输入
- 日期参数:日期选择器
- 枚举参数:预定义选项列表
- 查询驱动参数:基于其他查询结果的动态选项
实时语法检查和错误提示
编辑器内置了SQL语法检查器,能够实时检测语法错误并提供详细的错误信息。错误提示包括:
- 语法错误位置标记
- 错误类型描述
- 建议修复方案
- 上下文相关的帮助信息
Schema浏览器集成
Schema浏览器允许用户在不离开编辑器的情况下浏览数据库结构:
flowchart TD
A[连接数据源] --> B[加载Schema信息]
B --> C[显示数据库对象树]
C --> D[选择表或视图]
D --> E[查看列信息]
E --> F[插入到查询编辑器]
Schema浏览器功能:
- 树形结构展示数据库、表、视图
- 列信息预览(名称、类型、注释)
- 快速插入表名和列名到编辑器
- 表数据预览功能
查询执行与管理
查询编辑器提供了完整的查询生命周期管理:
执行流程:
sequenceDiagram
participant User
participant Editor
participant Server
participant Database
User->>Editor: 编写SQL查询
Editor->>Server: 发送查询请求
Server->>Database: 执行SQL语句
Database->>Server: 返回结果集
Server->>Editor: 格式化结果
Editor->>User: 显示可视化结果
查询管理功能:
- 异步执行:长时间查询不会阻塞界面
- 查询取消:支持中途取消执行中的查询
- 结果缓存:相同查询结果缓存优化
- 执行历史:保存最近的查询执行记录
高级编辑功能
键盘快捷键支持:
-- 常用快捷键示例
Ctrl/Cmd + Enter -- 执行查询
Ctrl/Cmd + / -- 注释/取消注释
Ctrl/Cmd + D -- 复制当前行
Ctrl/Cmd + F -- 查找
Ctrl/Cmd + H -- 替换
代码格式化功能: 编辑器支持自动SQL格式化,遵循标准的SQL代码风格指南,包括:
- 关键字大写化
- 适当的缩进和对齐
- 子查询嵌套格式化
- 连接语句优化布局
多数据源适配
Redash的查询编辑器支持多种数据库类型,针对不同数据源提供特定的功能优化:
| 数据源类型 | 特殊功能支持 | 语法特性 |
|---|---|---|
| PostgreSQL | 窗口函数、CTE、JSON操作 | 完整的PG语法支持 |
| MySQL | 存储过程、变量、引擎特性 | MySQL特有函数 |
| BigQuery | 标准SQL、嵌套字段、分区表 | BigQuery特有语法 |
| Redshift | 列压缩、排序键、分布键 | Redshift优化提示 |
协作与版本控制
查询编辑器集成了团队协作功能:
- 查询共享:生成可分享的查询链接
- 版本历史:保存查询修改历史记录
- 协作编辑:多人同时编辑查询(企业版)
- 评论系统:在查询上添加注释和反馈
性能优化特性
编辑器包含多项性能优化功能:
- 查询优化提示:基于执行计划的性能建议
- 结果分页:大数据集的分页显示
- 增量加载:大型结果的渐进式加载
- 本地缓存:查询草稿的自动保存
Redash的SQL查询编辑器通过结合现代IDE的优秀特性和数据库专业工具的专业功能,为用户提供了一个既强大又易用的SQL编写环境。无论是简单的数据检索还是复杂的分析查询,都能在这个编辑器中高效完成。
可视化图表类型与配置选项
Redash提供了丰富多样的可视化图表类型,每种图表都配备了精细的配置选项,让用户能够根据不同的数据特性和分析需求,创建出专业级别的数据可视化效果。本文将深入解析Redash支持的图表类型及其详细的配置选项。
核心图表类型概览
Redash内置了13种主要的可视化图表类型,涵盖了从基础统计图表到高级分析图表的完整谱系:
| 图表类型 | 图标 | 主要用途 | 适用场景 |
|---|---|---|---|
| 折线图 (Line) | 📈 | 趋势分析 | 时间序列数据、连续变化 |
| 柱状图 (Column) | 📊 | 比较分析 | 分类数据对比、数量比较 |
| 面积图 (Area) | 📉 | 累积趋势 | 部分与整体关系、累积效果 |
| 饼图 (Pie) | 🥧 | 占比分析 | 比例分布、组成结构 |
| 散点图 (Scatter) | 🔵 | 相关性分析 | 变量关系、分布模式 |
| 气泡图 (Bubble) | 🫧 | 多维度分析 | 三个变量的关系展示 |
| 热力图 (Heatmap) | 🔥 | 密度分析 | 数据密度、二维分布 |
| 箱线图 (Box) | 📦 | 统计分布 | 数据分布、异常值检测 |
| 表格 (Table) | 📋 | 明细数据 | 原始数据展示、详细查看 |
| 计数器 (Counter) | 🔢 | 关键指标 | 单一数值展示、KPI监控 |
| 地图 (Map) | 🗺️ | 地理数据 | 地理位置分布、区域分析 |
| 漏斗图 (Funnel) | 🪣 | 转化分析 | 业务流程、转化率分析 |
| 桑基图 (Sankey) | ➰ | 流向分析 | 资源流动、能量转移 |
图表配置架构解析
Redash的图表配置采用分层架构设计,每个图表类型都有统一的配置接口:
classDiagram
class VisualizationConfig {
+string type
+string name
+function getOptions()
+function Renderer()
+function Editor()
+boolean isDefault
+boolean isDeprecated
+number defaultRows
+number defaultColumns
}
class ChartOptions {
+string globalSeriesType
+object legend
+object xAxis
+array yAxis
+object series
+object seriesOptions
+string numberFormat
+string dateTimeFormat
}
class SeriesOptions {
+string type
+string name
+string color
+boolean showInLegend
+object marker
}
VisualizationConfig --> ChartOptions : contains
ChartOptions --> SeriesOptions : contains
详细配置选项解析
1. 基础图表配置
每个图表都支持以下基础配置选项:
// 默认配置选项
const DEFAULT_OPTIONS = {
globalSeriesType: "column", // 全局系列类型
sortX: true, // X轴排序
legend: { // 图例配置
enabled: true, // 是否显示图例
placement: "auto", // 图例位置
traceorder: "normal" // 图例顺序
},
xAxis: { // X轴配置
type: "-", // 轴类型
labels: { enabled: true } // 标签显示
},
yAxis: [ // Y轴配置(支持多轴)
{ type: "linear" }, // 主Y轴
{ type: "linear", opposite: true } // 次Y轴
],
alignYAxesAtZero: false, // Y轴零点对齐
series: { // 系列配置
stacking: null, // 堆叠方式
error_y: { // 误差线
type: "data",
visible: true
}
}
};
2. 格式化选项
Redash提供了强大的数据格式化功能:
{
numberFormat: "0,0[.]00000", // 数字格式
percentFormat: "0[.]00%", // 百分比格式
dateTimeFormat: "DD/MM/YYYY HH:mm", // 日期时间格式
textFormat: "{{ @@yPercent }} ({{ @@y }} ± {{ @@yError }})", // 文本模板
enableLink: false, // 启用链接
linkOpenNewTab: true, // 新标签页打开
linkFormat: "" // 链接格式模板
}
3. 高级图表特定配置
折线图特定配置:
{
line: {
shape: "linear", // 线条形状:linear/spline
dash: "solid", // 虚线样式
width: 2 // 线条宽度
},
marker: {
symbol: "circle", // 标记符号
size: 6, // 标记大小
line: { width: 1 } // 标记边框
}
}
柱状图特定配置:
{
column: {
grouping: true, // 分组显示
groupPadding: 0.2, // 组内间距
pointPadding: 0.1, // 点间距
borderWidth: 0, // 边框宽度
borderRadius: 0 // 边框圆角
}
}
饼图特定配置:
{
pie: {
innerSize: "0%", // 内径大小(环形图)
startAngle: 0, // 起始角度
endAngle: 360, // 结束角度
depth: 0, // 3D深度
sorting: true // 排序
},
direction: {
type: "counterclockwise" // 方向:顺时针/逆时针
}
}
配置选项的最佳实践
1. 数据映射配置
Redash支持灵活的数据列映射,可以将查询结果的列映射到图表的各个维度:
// 列映射配置示例
const columnMapping = {
"sales_amount": "y", // 销售额映射到Y轴
"date": "x", // 日期映射到X轴
"product_category": "series", // 产品类别映射到系列
"region": "size" // 区域映射到大小(气泡图)
};
2. 多Y轴配置
对于需要对比不同量级的数据系列,可以配置多个Y轴:
yAxis: [
{
type: "linear", // 主Y轴:线性
title: { text: "销售额" }, // 轴标题
opposite: false // 左侧显示
},
{
type: "linear", // 次Y轴:线性
title: { text: "增长率" }, // 轴标题
opposite: true // 右侧显示
}
]
3. 堆叠与分组配置
根据分析需求选择合适的堆叠或分组方式:
series: {
stacking: "normal", // 堆叠方式:normal/percent/null
// 或者
grouping: true // 分组显示
}
高级可视化类型详解
地理空间可视化
Redash的地图可视化支持多种地理数据格式:
// 地图配置选项
{
map: {
center: [0, 0], // 地图中心点
zoom: 2, // 缩放级别
style: "light", // 地图样式
clusters: true, // 启用聚类
heatmap: false // 热力图模式
},
markers: {
size: 10, // 标记大小
color: "#ff0000", // 标记颜色
opacity: 0.8 // 透明度
}
}
桑基图配置
桑基图用于展示流量和转移关系:
{
sankey: {
node: {
width: 20, // 节点宽度
padding: 10, // 节点间距
color: "category" // 节点着色方式
},
link: {
color: "source", // 链接着色方式
opacity: 0.6 // 链接透明度
}
}
}
响应式与交互配置
Redash图表支持丰富的交互功能:
{
interactivity: {
tooltip: true, // 启用提示框
hover: true, // 悬停效果
click: true, // 点击交互
zoom: true, // 缩放功能
pan: true // 平移功能
},
responsive: {
enabled: true, // 响应式设计
maintainAspectRatio: false, // 保持宽高比
rules: [ // 响应式规则
{
condition: { maxWidth: 500 },
chartOptions: { legend: { enabled: false } }
}
]
}
}
通过深入了解Redash的可视化图表类型和配置选项,用户可以充分发挥其强大的数据可视化能力,创建出既美观又富有洞察力的数据仪表板。
仪表板创建与布局管理
Redash的仪表板功能是其核心特性之一,它允许用户将多个可视化组件组合到一个统一的界面中,实现数据的综合展示和分析。仪表板的创建与布局管理涉及到数据结构设计、前端交互、后端API等多个层面的技术实现。
仪表板数据结构设计
Redash使用SQLAlchemy ORM来管理仪表板相关的数据模型。仪表板的核心数据结构包括Dashboard和Widget两个主要模型:
class Dashboard(BelongsToOrgMixin, TimestampMixin, ChangeTrackingMixin, db.Model):
__tablename__ = 'dashboards'
id = Column(db.Integer, primary_key=True)
name = Column(db.String(255))
slug = Column(db.String(255))
version = Column(db.Integer)
is_draft = Column(db.Boolean, default=False)
is_archived = Column(db.Boolean, default=False)
tags = Column(MutableList.as_mutable(ARRAY(db.String)))
layout = Column(JSONB) # 存储布局配置的JSON字段
options = Column(JSONB) # 存储仪表板选项
# 关系定义
widgets = db.relationship('Widget', backref='dashboard', cascade='all, delete-orphan')
user = db.relationship('User', backref='dashboards')
Widget模型负责管理仪表板中的各个可视化组件:
class Widget(BelongsToOrgMixin, db.Model):
__tablename__ = 'widgets'
id = Column(db.Integer, primary_key=True)
dashboard_id = Column(db.Integer, db.ForeignKey('dashboards.id'))
visualization_id = Column(db.Integer, db.ForeignKey('visualizations.id'))
text = Column(db.Text)
width = Column(db.Integer)
options = Column(JSONB)
created_at = Column(db.DateTime, default=db.func.now())
# 布局相关字段
position_x = Column(db.Integer)
position_y = Column(db.Integer)
position_auto = Column(db.Boolean, default=True)
网格布局系统
Redash采用基于网格的响应式布局系统,支持灵活的组件排列和自适应显示。布局系统的主要特性包括:
| 布局特性 | 描述 | 配置参数 |
|---|---|---|
| 网格列数 | 定义仪表板的水平网格列数 | gridWidth: 24 |
| 组件宽度 | 每个组件占据的网格列数 | width: 6 (1-24) |
| 组件高度 | 组件的高度(基于内容自适应) | height: auto |
| 位置锁定 | 是否允许自动调整组件位置 | position_auto: false |
布局配置使用JSON格式存储,示例结构如下:
{
"gridWidth": 24,
"autoPosition": true,
"widgets": [
{
"id": 1,
"col": 0,
"row": 0,
"sizeX": 6,
"sizeY": 4,
"minSizeX": 2,
"minSizeY": 2
},
{
"id": 2,
"col": 6,
"row": 0,
"sizeX": 6,
"sizeY": 3,
"fixed": true
}
]
}
拖拽排序实现机制
Redash的拖拽排序功能基于React-Grid-Layout库实现,提供了流畅的用户体验:
// 前端拖拽排序实现
const DashboardGrid = ({ widgets, onLayoutChange }) => {
const handleLayoutChange = (newLayout) => {
// 更新组件位置信息
const updatedWidgets = widgets.map(widget => {
const layoutItem = newLayout.find(item => item.i === widget.id.toString());
return {
...widget,
position_x: layoutItem.x,
position_y: layoutItem.y,
width: layoutItem.w
};
});
onLayoutChange(updatedWidgets);
};
return (
<ReactGridLayout
className="layout"
cols={24}
rowHeight={30}
onLayoutChange={handleLayoutChange}
draggableHandle=".widget-drag-handle"
>
{widgets.map(widget => (
<div key={widget.id} data-grid={{
x: widget.position_x,
y: widget.position_y,
w: widget.width,
h: widget.height || 4,
minW: 2,
minH: 2
}}>
<WidgetComponent widget={widget} />
</div>
))}
</ReactGridLayout>
);
};
布局管理API
后端提供完整的RESTful API来管理仪表板布局:
class DashboardsResource(BaseResource):
@require_permission('edit_dashboard')
def post(self, dashboard_id):
"""更新仪表板布局"""
dashboard = models.Dashboard.get_by_id_and_org(dashboard_id, self.current_org)
# 解析布局数据
layout_data = request.get_json()
# 验证布局数据
self._validate_layout(layout_data)
# 更新组件位置
for widget_data in layout_data.get('widgets', []):
widget = models.Widget.get_by_id_and_org(widget_data['id'], self.current_org)
if widget and widget.dashboard_id == dashboard_id:
widget.position_x = widget_data['col']
widget.position_y = widget_data['row']
widget.width = widget_data['sizeX']
db.session.add(widget)
# 更新仪表板布局配置
dashboard.layout = layout_data
db.session.add(dashboard)
db.session.commit()
return {'layout': dashboard.layout}
def _validate_layout(self, layout_data):
"""验证布局数据的有效性"""
if not isinstance(layout_data, dict):
raise ValidationError('Layout data must be a JSON object')
if 'gridWidth' not in layout_data:
raise ValidationError('Missing gridWidth in layout data')
if not 12 <= layout_data['gridWidth'] <= 36:
raise ValidationError('Grid width must be between 12 and 36')
响应式布局适配
Redash的布局系统支持多种屏幕尺寸的响应式适配:
flowchart TD
A[用户访问仪表板] --> B{检测屏幕尺寸}
B -->|大屏幕| C[应用完整布局]
B -->|中等屏幕| D[调整组件宽度]
B -->|小屏幕| E[启用移动端布局]
C --> F[显示所有组件]
D --> G[合并相邻组件]
E --> H[垂直堆叠组件]
F --> I[渲染完成]
G --> I
H --> I
响应式布局的配置示例:
const responsiveConfig = {
breakpoints: {
lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0
},
cols: {
lg: 24, md: 18, sm: 12, xs: 8, xxs: 4
},
margin: [10, 10],
containerPadding: [10, 10]
};
布局版本控制
Redash支持仪表板布局的版本控制,确保布局变更的可追溯性:
class DashboardVersioning:
"""仪表板版本管理"""
def create_version(self, dashboard, user):
"""创建布局版本快照"""
version_data = {
'layout': dashboard.layout.copy(),
'widgets': [
{
'id': w.id,
'position_x': w.position_x,
'position_y': w.position_y,
'width': w.width,
'options': w.options
}
for w in dashboard.widgets
],
'timestamp': datetime.utcnow(),
'user_id': user.id
}
# 存储版本历史
if not hasattr(dashboard, 'version_history'):
dashboard.version_history = []
dashboard.version_history.append(version_data)
dashboard.version = len(dashboard.version_history)
return dashboard.version
def restore_version(self, dashboard, version_number):
"""恢复特定版本的布局"""
if version_number < 1 or version_number > len(dashboard.version_history):
raise ValueError('Invalid version number')
version_data = dashboard.version_history[version_number - 1]
# 恢复布局配置
dashboard.layout = version_data['layout']
# 恢复组件位置
for widget_data in version_data['widgets']:
widget = next((w for w in dashboard.widgets if w.id == widget_data['id']), None)
if widget:
widget.position_x = widget_data['position_x']
widget.position_y = widget_data['position_y']
widget.width = widget_data['width']
widget.options = widget_data['options']
return dashboard
性能优化策略
为了确保大型仪表板的流畅运行,Redash实现了多项性能优化措施:
- 懒加载机制:组件在进入视口时才加载数据
- 布局缓存:频繁访问的布局配置进行缓存
- 批量更新:多个布局变更合并为单次数据库操作
- 增量渲染:只重新渲染发生变化的组件
class LayoutOptimizer:
"""布局性能优化器"""
def optimize_layout_update(self, dashboard_id, changes):
"""优化布局更新操作"""
# 批量处理组件位置更新
widget_updates = []
for change in changes:
if change['type'] == 'widget_move':
widget_updates.append((
change['widget_id'],
change['position_x'],
change['position_y'],
change['width']
))
# 执行批量更新
if widget_updates:
self._batch_update_widget_positions(widget_updates)
# 更新布局配置
self._update_dashboard_layout(dashboard_id, changes)
def _batch_update_widget_positions(self, updates):
"""批量更新组件位置"""
# 使用SQLAlchemy的bulk_update_mappings提高性能
update_data = [
{
'id': widget_id,
'position_x': pos_x,
'position_y': pos_y,
'width': width
}
for widget_id, pos_x, pos_y, width in updates
]
db.session.bulk_update_mappings(Widget, update_data)
通过这样的架构设计,Redash提供了强大而灵活的仪表板布局管理系统,既满足了用户对可视化界面定制化的需求,又保证了系统的性能和稳定性。
数据刷新与自动更新机制
Redash的数据刷新与自动更新机制是其核心功能之一,它确保了仪表板和可视化图表能够实时反映最新的数据状态。这一机制通过精心设计的任务调度系统、智能的查询执行策略和健壮的错误处理机制,为用户提供了可靠的数据自动更新体验。
任务调度架构
Redash使用RQ Scheduler作为核心调度引擎,通过周期性的任务执行来实现数据的自动刷新。整个调度系统的架构如下:
flowchart TD
A[RQ Scheduler] --> B[周期性任务定义]
B --> C[refresh_queries<br/>查询刷新]
B --> D[refresh_schemas<br/>模式刷新]
B --> E[cleanup_query_results<br/>结果清理]
B --> F[remove_ghost_locks<br/>锁清理]
C --> G[获取过期查询列表]
G --> H[检查刷新条件]
H --> I[应用参数和限制]
I --> J[入队执行]
D --> K[遍历数据源]
K --> L[检查跳过条件]
L --> M[异步刷新模式]
核心刷新机制
查询刷新流程
Redash的查询刷新机制通过refresh_queries()函数实现,该函数定期执行以检查并刷新所有过期的查询:
def refresh_queries():
started_at = time.time()
logger.info("Refreshing queries...")
enqueued = []
for query in models.Query.outdated_queries():
if not _should_refresh_query(query):
continue
try:
query_text = _apply_default_parameters(query)
query_text = _apply_auto_limit(query_text, query)
enqueue_query(
query_text,
query.data_source,
query.user_id,
scheduled_query=query,
metadata={"query_id": query.id, "Username": query.user.get_actual_user()},
)
enqueued.append(query)
except Exception as e:
message = "Could not enqueue query %d due to %s" % (query.id, repr(e))
logging.info(message)
error = RefreshQueriesError(message).with_traceback(e.__traceback__)
sentry.capture_exception(error)
刷新条件检查
在刷新查询之前,系统会进行多重条件检查以确保刷新的合理性:
def _should_refresh_query(query):
if settings.FEATURE_DISABLE_REFRESH_QUERIES:
logger.info("Disabled refresh queries.")
return False
elif query.org.is_disabled:
logger.debug("Skipping refresh of %s because org is disabled.", query.id)
return False
elif query.data_source is None:
logger.debug("Skipping refresh of %s because the datasource is none.", query.id)
return False
elif query.data_source.paused:
logger.debug(
"Skipping refresh of %s because datasource - %s is paused (%s).",
query.id,
query.data_source.name,
query.data_source.pause_reason,
)
return False
else:
return True
模式刷新机制
除了查询数据的刷新,Redash还提供了数据源模式的自动刷新功能:
@job("schemas", timeout=settings.SCHEMAS_REFRESH_TIMEOUT)
def refresh_schema(data_source_id):
ds = models.DataSource.get_by_id(data_source_id)
logger.info("task=refresh_schema state=start ds_id=%s", ds.id)
start_time = time.time()
try:
ds.get_schema(refresh=True)
logger.info(
"task=refresh_schema state=finished ds_id=%s runtime=%.2f",
ds.id,
time.time() - start_time,
)
statsd_client.incr("refresh_schema.success")
except JobTimeoutException:
logger.info(
"task=refresh_schema state=timeout ds_id=%s runtime=%.2f",
ds.id,
time.time() - start_time,
)
statsd_client.incr("refresh_schema.timeout")
except Exception:
logger.warning("Failed refreshing schema for the data source: %s", ds.name, exc_info=1)
statsd_client.incr("refresh_schema.error")
logger.info(
"task=refresh_schema state=failed ds_id=%s runtime=%.2f",
ds.id,
time.time() - start_time,
)
周期性任务配置
Redash的周期性任务通过periodic_job_definitions()函数进行配置,支持灵活的调度间隔设置:
| 任务功能 | 默认间隔 | 超时时间 | 结果TTL |
|---|---|---|---|
| 查询刷新 | 30秒 | 600秒 | 600秒 |
| 幽灵锁清理 | 1分钟 | - | 600秒 |
| 空计划清理 | 60分钟 | - | - |
| 模式刷新 | 可配置 | 可配置 | - |
| 用户详情同步 | 1分钟 | 60秒 | 600秒 |
jobs = [
{"func": refresh_queries, "timeout": 600, "interval": 30, "result_ttl": 600},
{
"func": remove_ghost_locks,
"interval": timedelta(minutes=1),
"result_ttl": 600,
},
{"func": empty_schedules, "interval": timedelta(minutes=60)},
{
"func": refresh_schemas,
"interval": timedelta(minutes=settings.SCHEMAS_REFRESH_SCHEDULE),
},
]
智能参数处理
在查询刷新过程中,Redash会智能处理查询参数和自动限制:
def _apply_default_parameters(query):
parameters = {p["name"]: p.get("value") for p in query.parameters}
if any(parameters):
try:
return query.parameterized.apply(parameters).query
except InvalidParameterError as e:
error = f"Skipping refresh of {query.id} because of invalid parameters: {str(e)}"
track_failure(query, error)
raise
except QueryDetachedFromDataSourceError as e:
error = (
f"Skipping refresh of {query.id} because a related dropdown "
f"query ({e.query_id}) is unattached to any datasource."
)
track_failure(query, error)
raise
else:
return query.query_text
def _apply_auto_limit(query_text, query):
should_apply_auto_limit = query.options.get("apply_auto_limit", False)
return query.data_source.query_runner.apply_auto_limit(query_text, should_apply_auto_limit)
资源清理机制
为了保持系统的高效运行,Redash实现了完善的资源清理机制:
def cleanup_query_results():
"""
Job to cleanup unused query results -- such that no query links to them anymore, and older than
settings.QUERY_RESULTS_CLEANUP_MAX_AGE (a week by default, so it's less likely to be open in someone's browser and be used).
"""
logger.info(
"Running query results clean up (removing maximum of %d unused results, that are %d days old or more)",
settings.QUERY_RESULTS_CLEANUP_COUNT,
settings.QUERY_RESULTS_CLEANUP_MAX_AGE,
)
unused_query_results = models.QueryResult.unused(settings.QUERY_RESULTS_CLEANUP_MAX_AGE)
deleted_count = models.QueryResult.query.filter(
models.QueryResult.id.in_(unused_query_results.limit(settings.QUERY_RESULTS_CLEANUP_COUNT).subquery())
).delete(synchronize_session=False)
models.db.session.commit()
logger.info("Deleted %d unused query results.", deleted_count)
错误处理与监控
Redash的刷新机制包含了完善的错误处理和监控功能:
sequenceDiagram
participant Scheduler
participant RefreshJob
participant QueryRunner
participant ErrorTracker
participant Monitoring
Scheduler->>RefreshJob: 触发刷新任务
RefreshJob->>QueryRunner: 执行查询
QueryRunner-->>RefreshJob: 返回结果或错误
alt 执行成功
RefreshJob->>Monitoring: 记录成功指标
else 执行超时
RefreshJob->>ErrorTracker: 记录超时错误
RefreshJob->>Monitoring: 记录超时指标
else 执行失败
RefreshJob->>ErrorTracker: 记录失败详情
RefreshJob->>Monitoring: 记录错误指标
end
系统通过StatsD进行性能指标监控,记录成功、超时和错误等关键指标,确保运维人员能够及时了解系统状态。
黑名单机制
为了防止问题数据源影响整个系统的稳定性,Redash实现了数据源黑名单机制:
def refresh_schemas():
blacklist = [int(ds_id) for ds_id in redis_connection.smembers("data_sources:schema:blacklist") if ds_id]
global_start_time = time.time()
logger.info("task=refresh_schemas state=start")
for ds in models.DataSource.query:
if ds.paused:
logger.info("task=refresh_schema state=skip ds_id=%s reason=paused(%s)", ds.id, ds.pause_reason)
elif ds.id in blacklist:
logger.info("task=refresh_schema state=skip ds_id=%s reason=blacklist", ds.id)
elif ds.org.is_disabled:
logger.info("task=refresh_schema state=skip ds_id=%s reason=org_disabled", ds.id)
else:
refresh_schema.delay(ds.id)
这种机制确保了即使某个数据源出现问题,也不会影响其他数据源的正常刷新操作。
Redash的数据刷新与自动更新机制通过多层次的设计,实现了高效、可靠的数据同步,为用户提供了实时的数据可视化体验。其灵活的配置选项和健壮的错误处理机制,使其能够适应各种复杂的生产环境需求。
Redash作为一个功能强大的数据分析和可视化平台,通过其智能的SQL查询编辑器、多样化的图表类型、灵活的仪表板布局管理和可靠的数据刷新机制,为用户提供了完整的数据分析解决方案。其模块化的架构设计、响应式的界面适配和完善的错误处理机制,确保了系统在不同场景下的稳定性和高效性。无论是简单的数据检索还是复杂的分析需求,Redash都能提供专业级别的支持,帮助用户从数据中获得有价值的洞察。
Kimi-K2.5Kimi K2.5 是一款开源的原生多模态智能体模型,它在 Kimi-K2-Base 的基础上,通过对约 15 万亿混合视觉和文本 tokens 进行持续预训练构建而成。该模型将视觉与语言理解、高级智能体能力、即时模式与思考模式,以及对话式与智能体范式无缝融合。Python00
GLM-4.7-FlashGLM-4.7-Flash 是一款 30B-A3B MoE 模型。作为 30B 级别中的佼佼者,GLM-4.7-Flash 为追求性能与效率平衡的轻量化部署提供了全新选择。Jinja00
VLOOKVLOOK™ 是优雅好用的 Typora/Markdown 主题包和增强插件。 VLOOK™ is an elegant and practical THEME PACKAGE × ENHANCEMENT PLUGIN for Typora/Markdown.Less00
PaddleOCR-VL-1.5PaddleOCR-VL-1.5 是 PaddleOCR-VL 的新一代进阶模型,在 OmniDocBench v1.5 上实现了 94.5% 的全新 state-of-the-art 准确率。 为了严格评估模型在真实物理畸变下的鲁棒性——包括扫描伪影、倾斜、扭曲、屏幕拍摄和光照变化——我们提出了 Real5-OmniDocBench 基准测试集。实验结果表明,该增强模型在新构建的基准测试集上达到了 SOTA 性能。此外,我们通过整合印章识别和文本检测识别(text spotting)任务扩展了模型的能力,同时保持 0.9B 的超紧凑 VLM 规模,具备高效率特性。Python00
KuiklyUI基于KMP技术的高性能、全平台开发框架,具备统一代码库、极致易用性和动态灵活性。 Provide a high-performance, full-platform development framework with unified codebase, ultimate ease of use, and dynamic flexibility. 注意:本仓库为Github仓库镜像,PR或Issue请移步至Github发起,感谢支持!Kotlin07
compass-metrics-modelMetrics model project for the OSS CompassPython00