子午线
Kubernetes的开源Trino控制平面和MCP服务器。
getmeridian.dev · v1.1
Trino集群的配置需要30-90秒。Meridian消除了这种等待——热备用池使预配置的集群保持空闲和就绪状态,并在零秒内保留。CI/CD作业、批处理工作负载或多租户平台没有冷启动。
子午线是二合一的: Kubernetes操作员 管理整个集群生命周期(Empty → Pending → Idle → Reserved)和a MCP服务器 借助19个工具,Claude、Cursor或任何MCP客户端都可以通过自然语言配置集群、添加目录、轮换凭据和运行查询。
内部构建的平台大数据团队。现在开源。
______________________________________________________________________
MCP服务器--从这里开始
这 meridian binary是一个独立的MCP服务器,用于 Kubernetes上的任何Trino部署.安装操作员以获得完整的热备用池体验;如果没有它,MCP服务器在第一天就很有用。
安装
二进制(所有平台):
# macOS arm64
curl -Lo meridian.tar.gz https://github.com/meridian-io/meridian/releases/download/v1.1/trino-mcp-server_v1.1_darwin_arm64.tar.gz
tar xzf meridian.tar.gz && sudo mv meridian /usr/local/bin/Docker:
docker pull ghcr.io/meridian-io/trino-mcp-server:v1.1跑
# stdio — for Claude Desktop / local MCP clients
meridian --transport stdio --namespace meridian
# SSE — for remote / team use (Cursor, Claude API)
meridian --transport sse --addr :8080 --namespace meridian
# In-cluster (reads service account token automatically)
meridian --transport sse --addr :8080连接到克劳德桌面
添加 ~/.config/claude/claude_desktop_config.json:
{
"mcpServers": {
"meridian": {
"command": "meridian",
"args": ["--transport", "stdio", "--namespace", "meridian"]
}
}
}可用的MCP工具
| 工具 | 描述 | 缓存TTL |
|---|---|---|
list_clusters | 列出所有具有阶段、运行状况、协调器URL | --的集群 |
get_cluster | 获取特定集群的完整详细信息 | -- |
create_cluster | 从配置文件中配置新的Trino集群 | -- |
delete_cluster | 拆除一个集群 | -- |
reserve_cluster | 将空闲集群分配给客户端(幂等) | -- |
release_cluster | 将集群返回到空闲池 | -- |
scale_pool | 在ClusterPool上设置所需的副本计数 | -- |
list_pools | 列出所有当前状态的ClusterPools | -- |
add_catalog | 将新目录推送到集群--不重新启动 | 缓存无效 |
remove_catalog | 删除目录--不重新启动 | 缓存无效 |
list_catalogs | 列出群集中注册的所有目录 | 5分钟 |
list_schemas | 列出目录中的架构 | 5分钟 |
list_tables | 列出目录架构中的表 | 5分钟 |
get_table_schema | 获取表的列名和数据类型 | 5分钟 |
execute_query | 执行SQL并将结果作为表返回。标记为 mcp_query_id 用于审计相关性。使用 output_file 以CSV格式写入大结果。 | 无(通过选择加入 ttl 参数) |
explain_query | 返回SQL语句的Trino执行计划,不执行 | 5分钟 |
rotate_credentials | 触发保险库/ASM凭据刷新 | -- |
get_audit_log | 获取集群生命周期和管理事件 | -- |
promote_environment | 从dev升级配置→ 暂存→ prod | -- |
查询结果缓存
Meridian将Trino查询结果缓存在内存中,以避免在同一会话中重复调用的冗余往返。
| 工具 | 默认TTL | 基本原理 |
|---|---|---|
execute_query | 无 | 数据更改必须立即可见——选择加入 ttl=N 对于静态数据 |
list_catalogs | 5分钟 | 目录列表很少更改 |
list_schemas | 5分钟 | 架构列表很少更改 |
list_tables | 5分钟 | 表列表很少更改 |
get_table_schema | 5分钟 | 列元数据很少更改 |
它是如何工作的:
- 第一个电话→ 缓存未命中→ 查询点击Trino→ 结果与到期时间戳一起存储
- TTL内的同一呼叫→ 缓存命中→ 结果立即返回,标记
[cache hit] - TTL到期后→ 下一个调用再次命中Trino并刷新缓存
add_catalog/remove_catalog立即使目录缓存无效,因此list_catalogs始终反映当前状态
单程: 如果两个相同的查询同时到达(例如,Claude在一个回合中调用同一个工具两次),只有一个查询会命中Trino。第二个等待,一旦第一个完成,就会从缓存中提供服务。
选择缓存 execute_query: 通过 ttl=N 查询静态或参考数据时:
Run SELECT * FROM mysql_testdb.testdb.orders on trino-local with ttl=60缓存密钥: SHA-256哈希 (coordinatorURL + sql)不同的SQL或不同的集群=不同的缓存条目,没有冲突。
边缘案例-- add_catalog: 当您通过MCP添加或删除目录时,该协调器的缓存将立即失效。 list_catalogs 稍后调用将始终命中Trino并返回当前状态——没有过时的数据。
查询标记
发送到Trino的每个SQL语句都会自动标记一个唯一的 mcp_query_id:
SELECT * FROM mysql_testdb.testdb.orders
-- mcp_query_id=3f2a1b4c-e8d7-4a9b-b1c2-0f5e6d7a8b9c标记显示为SQL注释,因此Trino正常执行它。这 query_id 显示在每个结果的顶部:
query_id: 3f2a1b4c-e8d7-4a9b-b1c2-0f5e6d7a8b9c
| name |
|-------------|
| 55555577 |
| 76y56 |
(2 rows)使用它在Trino UI中查找确切的执行情况(http://:8080/ui)或查询历史记录——在调试慢速查询或意外结果时非常有用。
注意:标签仅适用于新的Trino调用。缓存点击数([cache hit])跳过标记,因为查询再也不会到达Trino。
CSV文件导出
对于会溢出上下文窗口的大型结果集,请使用 output_file 将结果以CSV格式写入,而不是内联返回:
Run SELECT * FROM mysql_testdb.testdb.orders on trino-local with output_file=/tmp/orders.csv退货:
Results written to /tmp/orders.csv (1042 rows, 8 columns)
query_id: 3f2a1b4c-...该文件包含一个标题行,后面是所有数据行。完整的表永远不会发送到LLM,只有摘要。
______________________________________________________________________
建筑
┌──────────────────────────────────────────────────────┐
│ Project Meridian │
│ │
│ ┌────────────┐ ┌─────────────┐ ┌───────────────┐ │
│ │ Web UI │ │ REST API │ │ MCP Server │ │
│ │ Next.js │ │ Go/mTLS │ │ Go · 19 tools│ │
│ └────────────┘ └──────┬──────┘ └──────┬────────┘ │
│ │ │ │
│ ┌────────▼────────────────▼──────┐ │
│ │ Kubernetes API Server │ │
│ └────────┬────────────────────────┘ │
│ ┌─────────────────┼──────────────┐ │
│ ▼ ▼ ▼ │
│ ClusterController ClusterPool ClusterPool │
│ Controller Autoscaler │
└──────────────────────────────────────────────────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
Cluster(Idle) Cluster(Reserved) Cluster(Pending)集群生命周期
Empty → Pending → Idle → Reserved
↓
Failed组件
| 目录 | 语言 | 描述 |
|---|---|---|
mcp/ | 转到 | MCP服务器-- 船舶优先,独立二进制 |
operator/ | Go | Kubernetes操作员-控制器、CRD、REST API |
ui/ | Next.js | Web管理仪表板 |
charts/ | Helm | 一个命令安装 |
config/ | YAML | CRD清单 |
docs/ | HTML | 体系结构和API文档 |
Kubernetes操作员
操作员在Kubernetes上管理整个Trino集群生命周期。三个控制器在一个二进制文件中运行:
| 控制员 | 职责 |
|---|---|
ClusterController | 每个集群的生命周期: Empty → Pending → Idle → Reserved → Failed。创建协调器部署、工作器部署和协调器服务。健康门转换为空闲。处理协调员驱逐恢复。 |
ClusterPoolController | 维护热备用池:创建要访问的集群 spec.replicas,在过度配置时删除最旧的空闲群集(每个周期一个),立即清除故障群集。 |
ClusterPoolAutoscalerController | 调整 ClusterPool.spec.replicas 基于利用率(reserved / total).在≥阈值时放大(默认70%),在\ 添加一个名为的目录 mysql_testdb 到名为的集群 trino-local 具有以下特性: |
`` connector.name=mysql connection-url=jdbc:mysql://mysql:3306 connection-user=root connection-password=trino_test ``步骤2--浏览目录:
列出中的架构mysql_testdb目录上trino-local
步骤3——查询数据:
跑SHOW TABLES FROM mysql_testdb.testdb上trino-local
直接在Trino中验证:
docker exec meridian-trino trino --execute "SHOW CATALOGS"
docker exec meridian-trino trino --execute "SHOW SCHEMAS FROM mysql_testdb"注: 添加MySQL目录时,请使用mysql:3306作为连接URL(不是localhost:3306).Trino在Docker内部运行,并通过内部Docker网络主机名访问MySQLmysql.
______________________________________________________________________
# MCP server
cd mcp && go build -o ../bin/meridian ./cmd/meridian-mcp
# Kubernetes operator
cd operator && go build -o ../bin/meridian-operator .
# Or use Make
make build # operator
make build-mcp # MCP server
make test # all tests手动测试用例
以下测试用例涵盖了所有端到端的工作工具。在运行本地开发环境的Claude Desktop中运行它们(docker compose up -d + ./hack/setup-local.sh).
测试中使用的参考表:
| 数据库 | 表 | 行 | 列 |
|---|---|---|---|
MySQL testdb | test | 2 | name (第11章) |
______________________________________________________________________
| # | 对克劳德说什么 | 预期结果 |
|---|---|---|
| 1 | List all clusters in the meridian namespace | 表演 trino-local, trino-idle-01, trino-idle-02, trino-pending-01, trino-reserved-01 与相位和健康 |
| 2 | Get details for the cluster named trino-local in the meridian namespace | 显示协调器URL http://localhost:8080,阶段,健康状况 |
| 3 | Add a catalog called mysql_testdb to trino-local with connector.name=mysql, connection-url=jdbc:mysql://mysql:3306, connection-user=root, connection-password=trino_test | 退货 Catalog "mysql_testdb" added to cluster "trino-local" |
| 4 | List all catalogs on trino-local | 表演 mysql_testdb, system, tpch --结果是新鲜的(缓存被addcatalog破坏) |
| 5 | List all catalogs on trino-local again (同一对话) | 与相同的结果 [cache hit] --从5分钟缓存中提供 |
| 6 | List schemas in the mysql_testdb catalog on trino-local | 表演 information_schema, testdb |
| 7 | List tables in mysql_testdb.testdb on trino-local | 表演 orders, test (或任何存在的表格) |
| 8 | Show me the schema for the test table in mysql_testdb.testdb on trino-local | 显示列 name 与类型 char(11) |
| 9 | Run SELECT * FROM mysql_testdb.testdb.test on trino-local | 返回2行: 55555577, 76y56 --没有 [cache hit] (默认情况下execute_query没有缓存) |
| 10 | Run that same query again (同一对话) | 再次返回2行--仍然没有 [cache hit] (正确-数据可能已更改) |
| 11 | Run SELECT * FROM mysql_testdb.testdb.test on trino-local with ttl=60 | 返回2行,否 [cache hit] 第一次通话 |
| 12 | Run that same query again (同一对话,60秒内) | 返回2行 [cache hit] --选择加入缓存正在工作 |
| 13 | Run SELECT * FROM mysql_testdb.testdb.test on trino-local | 结果包括 query_id: 在第一行,查询标记正在工作 |
| 14 | 打开 http://localhost:8080/ui 在浏览器中,按以下方式查找查询 mcp_query_id 在查询文本中 | 查询出现在Trino UI中,标记注释可见 |
| 15 | Run SELECT * FROM mysql_testdb.testdb.test on trino-local and save the results to /tmp/test.csv | 退货 Results written to /tmp/test.csv (2 rows, 1 columns) --没有内联表 |
| 16 | cat /tmp/test.csv (在终端中) | CSV文件包含标题 name 2个数据行 |
| 17(清理) | Remove the mysql_testdb catalog from trino-local | 退货 Catalog "mysql_testdb" removed from cluster "trino-local" |
注: 测试5、12需要在 相同的克劳德桌面会话 --缓存在内存中,并在MCP进程重新启动时重置。
______________________________________________________________________
第2阶段——操作员手册测试
先决条件:集群正在运行,CRD已应用,操作员正在本地运行。
kubectl apply -f operator/config/crd/bases/
./bin/meridian-operator --namespace meridian --kubeconfig ~/.kube/config群集生命周期(空→ 待定→ Idle → 预留→ Idle)
| # | 行动 | 预期结果 |
|---|---|---|
| 18 | kubectl apply -f operator/config/samples/test-cluster.yaml | 集群 test-cluster 创建阶段 "" (空) |
| 19 | kubectl get cluster test-cluster -n meridian -w | 阶段转换: "" → Pending 操作员在几秒钟内创建部署和服务 |
| 20 | kubectl get deployments -n meridian | test-cluster-coordinator (1个复制品)和 test-cluster-worker (2个副本)存在 |
| 21 | kubectl get svc -n meridian | test-cluster-coordinator 端口8080上存在服务 |
| 22 | 等待协调器吊舱就绪,然后观察集群 | 阶段转换 Pending → Idle, ready: true, idleAt 时间戳设置 |
| 23 | kubectl patch cluster test-cluster -n meridian --type=merge -p '{"spec":{"clientId":"client-abc","reservationId":"res-001"}}' | 集群转换 Idle → Reserved, reservedAt 时间戳设置 |
| 24 | kubectl get cluster test-cluster -n meridian -o jsonpath='{.status.phase}' | 退货 Reserved |
| 25 | kubectl patch cluster test-cluster -n meridian --type=merge -p '{"spec":{"clientId":"","reservationId":""}}' | 集群转换 Reserved → Idle, idleAt 刷新 |
热备用池(ClusterPool)
| # | 行动 | 预期结果 |
|---|---|---|
| 26 | kubectl apply -f operator/config/samples/test-clusterpool.yaml | 集群泳池 test-pool 创建于 spec.replicas: 2 |
| 27 | kubectl get clusters -n meridian -l meridian.io/cluster-pool=test-pool -w | 自动创建2个集群(test-pool-),每次转换为空→ 待定→ 闲置 |
| 28 | kubectl patch clusterpool test-pool -n meridian --type=merge -p '{"spec":{"replicas":1}}' | 下一次对账(≤30s)后,删除最旧的空闲集群——剩余1个集群 |
| 29 | kubectl patch clusterpool test-pool -n meridian --type=merge -p '{"spec":{"replicas":3}}' | 创建2个新集群,以达到所需的3个数量 |
| 30 | kubectl get clusterpool test-pool -n meridian -o jsonpath='{.status}' | 表演 readyReplicas, pendingReplicas, reservedReplicas 计数 |
清理
| # | 行动 | 预期结果 |
|---|---|---|
| 31 | kubectl delete clusterpool test-pool -n meridian | 所有者引用级联--自动删除所有池群集 |
| 32 | kubectl delete cluster test-cluster -n meridian | 通过所有者引用删除协调员部署、工作人员部署和服务 |
______________________________________________________________________
CRD
# meridian.io/v1alpha1
Cluster — single Trino cluster lifecycle
ClusterPool — hot standby pool of N clusters
ClusterPoolAutoscaler — scale pool by reservation utilization超越AI代理
MCP服务器是一个标准的RPC接口,任何自动化Trino集群生命周期的系统都可以使用它,而不仅仅是LLM。
CI/CD管道
为集成测试保留一个新的集群,运行它们,完成后发布:
# GitHub Actions
- name: Reserve test cluster
run: |
RESULT=$(mcp-client call reserve_cluster \
--profile ci --reservation-id ${{ github.run_id }})
echo "COORDINATOR_URL=$(echo $RESULT | jq -r .coordinatorUrl)" >> $GITHUB_ENV
- name: Run integration tests
run: ./test.sh $COORDINATOR_URL
- name: Release cluster
if: always()
run: mcp-client call release_cluster --cluster-name ${{ env.CLUSTER_NAME }}工作流编排器
将集群生命周期作为气流/Dagster/Prefect DAG的一部分进行管理:
@task
def reserve_trino_cluster(dag_run):
return mcp.call("reserve_cluster", profile="batch", reservation_id=dag_run.run_id)
@task
def run_transformation(cluster):
run_dbt(target=cluster["coordinatorUrl"])
@task
def release_trino_cluster(cluster):
mcp.call("release_cluster", cluster_name=cluster["clusterName"])其他MCP客户端
| 客户端 | 用例 |
|---|---|
| Slack/PagerDuty bot | 随叫随到的工程师通过点击按钮扩展池 |
| Backstage插件 | 应用程序开发人员通过表单提供集群,无需kubectl访问 |
| Terraform/Plumi提供者 | 将集群池声明为代码基础设施 |
为什么选择Meridian
- 不存在开源Trino控制平面 — 特立尼达和多巴哥#396 自2019年开放;子午线就是答案
- 不存在官方Trino MCP服务器 — 特立尼达和多巴哥#26239 开放;Meridian提供19种管理工具,而不仅仅是查询执行
- 作为通用操作接口工作 --CI/CD、编排器、内部工具和AI代理都使用相同的二进制文件
路线图
| 阶段 | 状态 | 描述 |
|---|---|---|
| 第一阶段——MCP服务器 | ✅ 完成 | 19个MCP工具、Go二进制、stdio+SSE传输、本地开发设置、TTL查询结果缓存(模式元数据5分钟、查询选择加入、单次重复数据删除、目录更改自动失效)、查询标记(mcp_query_id 用于审计相关性),CSV文件导出用于大型结果集,通过查询执行计划 explain_query |
| 第二阶段——Kubernetes操作员 | ✅ 完成 | 群集控制器(空→待定→Idle→预留→Idle→降级),ClusterPoolController(热备用池,逐步缩减,最旧的优先选择,通过 maxClusterAge,滚动映像升级),ClusterPoolAutoscalerController(基于利用率的滞后),Trino网关集成,工作负载标记池 |
| 第3阶段-REST API | ✅ 完整 | 完整的REST界面:保留、释放、列出集群(阶段/配置文件/工作负载过滤器)、获取集群、列出池、扩展池——所有这些都有mTLS和跨客户端所有权验证 |
| 第4阶段——目录和凭证层 | ✅ 完成 | 注释驱动的凭据轮换,无需重新启动群集。支持Kubernetes Secrets、HashiCorp Vault(K8s-auth,KV v2)和AWS Secrets Manager(IRSA)。TTL缓存,具有主动刷新、指数回退和 CredentialRotation Cluster对象上的条件。 |
| 第5阶段——轮廓系统 | 🔨 进行中 | ClusterPool配置文件模板--注入Trino config.properties, jvm.config,并在配置时将定义编目到协调器和工作Pod中 |
| 第6阶段——Web用户界面 | 📋 计划 | Next.js仪表板——集群池可视化、目录管理UI、审计跟踪查看器 |
| 第7阶段——Helm图表和文档 | 📋 计划 | 一个命令安装、快速入门指南、完整的架构文档 |
______________________________________________________________________
许可证
Apache 2.0——请参阅 许可证
