Serverless 数据层选型:D1、Turso、Neon、Supabase 与 Upstash

系统讲解 Serverless/边缘计算的数据层选型:云数据库托管(Neon/Supabase)、边缘 SQLite(D1/Turso)、KV/Redis(Upstash/Cloudflare KV)、边缘向量库与对象存储,覆盖读写模式、冷启动影响、连接管理与延迟、SQLite vs PostgreSQL vs NoSQL 选型矩阵,以及生产数据层架构设计。

一、引言

Serverless 函数的无状态特性,把数据层推到了「函数之外」——数据库成为唯一有状态的部分。而边缘计算又把问题加剧:你的函数在东京跑,数据库却在弗吉尼亚,一次查询就是 200ms 光速往返。Serverless 数据层选型的本质是:延迟、一致性、成本与「边缘近度」的权衡。

本文系统讲 Serverless 数据层:先对比边缘 SQLite(D1/Turso)与托管 PostgreSQL(Neon/Supabase)两条主线,再讲 KV/Redis(Upstash/Cloudflare KV)、向量库与对象存储;接着覆盖连接管理与冷启动影响、延迟优化与数据架构设计,最后给出完整的选型矩阵。

关联:https://plumephp.com/tools-serverless-cold-start/(函数形态)、https://plumephp.com/tools-edge-cache-cdn-strategy/(缓存)、https://plumephp.com/cloudflare-d1-fullstack-guide/(D1 实战)、https://plumephp.com/vercel-nextjs-postgres-saas/(Vercel Postgres)。


二、两大主线:边缘 SQLite vs 托管 PostgreSQL

2.1 边缘 SQLite(D1 / Turso)

D1   :Cloudflare 的分布式 SQLite,绑定 Workers,edge 就近
Turso:libSQL(SQLite 分支),多地域副本,HTTP API

共同点:
  1. SQLite 内核 → 轻量、零配置
  2. 数据副本部署到边缘 → 就近读
  3. 写需要协调(单主或多主)→ 写延迟高于读
维度D1Turso
运行时绑定Cloudflare Workers任意(HTTP/SDK)
地域Cloudflare 网络多地域副本
写模型单主 + 备份多主/单主可选
生态wrangler、Drizzle/PrismalibSQL、Turso CLI
适用Cloudflare 全家桶多平台边缘

2.2 托管 PostgreSQL(Neon / Supabase)

Neon    :Serverless Postgres,按需冷启动、分支管理、存储计算分离
Supabase:Postgres + Auth + Storage + Realtime 一体

共同点:
  1. 完整 Postgres 功能(事务/复杂查询/扩展)
  2. 自动休眠/唤醒(serverless 计费)
  3. 连接是「有状态」的 → 需要连接池/HTTP 接口
维度NeonSupabase
核心存储计算分离、分支Postgres + BaaS 全家桶
连接连接池 + 自动缩放连接池 + HTTP API
额外服务纯数据库Auth/Storage/Realtime
适用纯数据层快速全栈 MVP

2.3 怎么选

需要低延迟边缘读 + 简单数据模型  → D1 / Turso
需要完整 SQL/事务/复杂查询      → Neon / Supabase
边缘读为主、写少                → 边缘 SQLite
写多、强一致、跨区域            → 托管 Postgres

一句话总结:边缘 SQLite 主打「数据到边缘、就近读」,托管 Postgres 主打「完整能力、云上中心化」——延迟敏感且模型简单选前者,能力需求高选后者。


三、KV 与 Redis:快速键值层

3.1 Cloudflare KV vs Upstash Redis

Cloudflare KV:
  全局复制的键值存储,最终一致
  适合:配置、会话元数据、静态映射、缓存

Upstash Redis:
  云 Redis,通过 HTTP/REST 访问(无 TCP 连接占用)
  适合:计数器、排行榜、实时数据、Pub/Sub、TTL 缓存
// Cloudflare KV
await env.KV.put('config:feature-x', 'true', { expirationTtl: 3600 })
const v = await env.KV.get('config:feature-x')

// Upstash Redis(HTTP)
import { Redis } from '@upstash/redis'
const redis = new Redis(env.UPSTASH_REDIS_REST_URL, env.UPSTASH_REDIS_REST_TOKEN)
await redis.incr('counter:orders')         // 原子自增
await redis.zadd('leaderboard', { score: 95, member: 'user1' })

3.2 KV vs Redis 选型

维度KVRedis
一致性最终一致强一致
写入吞吐高(异步复制)高(同步)
数据结构字符串字符串/哈希/列表/集合/有序集合
原子操作部分丰富(INCR/PEXPIRE/Lua)
适用配置/缓存/会话计数器/队列/实时数据

3.3 Durable Objects(Cloudflare)

KV 最终一致无法保证「强一致状态」
DO:边缘上的有状态单实例 → 强一致、可做状态机
适合:WebSocket 状态、协调器、强一致计数器

一句话总结:KV 快但最终一致,Redis 有丰富数据结构与原子操作——配置/会话用 KV,计数器/排行榜/实时用 Redis,强一致状态用 Durable Objects。


四、连接管理与冷启动影响

4.1 连接是 Serverless 的「稀缺资源」

问题:每个函数实例都想连数据库,但 Postgres 连接数有限
      函数冷启动 + 建连 = 双重延迟
方案:
  1. 连接池(Neon/Supabase pooler / PgBouncer)
  2. 函数级复用:模块级全局连接(不每次请求新建)
  3. HTTP 接口(Supabase REST / Turso HTTP)免连接池
// 模块级连接复用(Serverless 最佳实践)
// lib/db.ts
const pool = new Pool({ connectionString: DATABASE_URL })  // 模块级 → 实例内复用

export async function query(sql: string, params?: any[]) {
  return pool.query(sql, params)
}
// 注意:每次冷启动会重新建池 → 用连接池 + 预热减轻

4.2 冷启动中的数据延迟

三层延迟:
  ① 函数冷启动(运行时拉起)
  ② 数据库建连(TCP+TLS 握手)
  ③ 跨区域网络往返(边缘到数据库所在地)

优化:
  ① 预热 + 轻运行时
  ② 连接池/HTTP 免握手
  ③ 数据放边缘(D1/Turso)或 CDN 缓存

4.3 连接数上限的治理

1. 应用层限流:并发控制(并发池)
2. 数据库层:连接池 / max_connections 配置
3. 架构层:读走副本、写走主库

一句话总结:Serverless 数据库延迟 = 冷启动 + 建连 + 跨区往返——连接池/HTTP 免握手、模块级复用、数据放边缘,三管齐下压延迟。


五、SQLite vs PostgreSQL vs NoSQL 选型矩阵

维度SQLite(D1/Turso)PostgreSQL(Neon/Supabase)Redis/KV
延迟(边缘)低(数据在边缘)中(需网络往返)极低
一致性单写强一致强一致KV 最终/Redis 强
事务支持完备有限
复杂查询基础完备无
写吞吐单主受限高(可扩展)极高
数据量中大内存受限
适合边缘读多、简单模型复杂业务核心缓存/实时/计数器

组合架构(推荐):

核心业务数据  → Neon/Supabase(Postgres,事务与复杂查询)
边缘高频读    → D1/Turso(就近)或 CDN 缓存
实时/计数器   → Upstash Redis
会话/配置     → Cloudflare KV
文件/图片     → R2/S3 对象存储
向量检索      → 向量库(Pinecone/Weaviate 或 Postgres pgvector)

一句话总结:选型不是「选一个」,而是分层组合——Postgres 管核心、边缘 SQLite 管就近读、Redis 管实时、KV 管会话、R2 管对象、向量库管语义检索。


六、边缘向量库与对象存储

6.1 向量检索(AI 应用数据层)

方案:
  pgvector(Postgres 扩展)→ 与业务数据同库,简化架构
  独立向量库(Pinecone/Weaviate/Cloudflare Vectorize)→ 规模大
  Turso/D1 暂不适合大规模向量
-- pgvector 示例
CREATE EXTENSION vector;
ALTER TABLE products ADD COLUMN embedding vector(384);
SELECT id FROM products ORDER BY embedding <-> $1 LIMIT 10;  -- 余弦距离

6.2 对象存储(文件/图片)

R2/S3:静态资源、图片、上传文件
配合 CDN:边缘缓存、免出口流量(R2 特色)
图片处理:Cloudflare Images / Vercel Image 服务

6.3 AI 数据层的分层

结构化业务数据 → Postgres
向量/语义       → pgvector / 向量库
文件/模型权重   → R2/S3
Prompt/会话     → KV/Redis

一句话总结:AI 数据层 = Postgres 管业务、pgvector/向量库管语义、R2 管文件、KV 管会话——向量检索与业务数据同库能显著简化架构。


七、数据架构设计要点

7.1 读写模式决定部署

读多写少(内容站/推荐)    → 边缘副本 + CDN 缓存
写多读少(订单/日志)      → 中心主库 + 队列削峰
实时数据(排行榜/计数)    → Redis
时序数据(监控/事件)      → 时序库 / Redis 聚合

7.2 一致性需求分级

强一致(金额/库存)   → Postgres 事务
弱一致(阅读数/热度)  → KV/Redis + 异步回写
最终一致(社交时间线) → 边缘 SQLite 副本 + 同步

7.3 数据分层示例

请求 → 边缘 KV/缓存(命中即回)→ 边缘 SQLite 副本(就近读)
     → 中心 Postgres(权威写)→ Redis(实时/计数)→ 对象存储(文件)

一句话总结:架构设计先定读写模式与一致性分级——强一致进 Postgres 事务、弱一致进缓存异步回写,再用边缘副本与 CDN 把高频读压到最近处。


八、成本与配额

8.1 计费模式对比

服务计费维度免费额度注意
D1读/写请求5M 读/天写请求贵
Turso副本数+请求每库 250M 读多副本加钱
Neon计算时间+存储按需休眠唤醒计费
Supabase存储+带宽500MB DB无服务器级
Upstash命令数+存储高频免费层命令计费
Cloudflare KV读写+存储免费层大写一致性弱

8.2 成本优化要点

1. 高频读用缓存(KV/CDN)→ 省数据库请求
2. 写密集用批处理/队列合并
3. 边缘 SQLite 减少跨区网络费
4. Postgres 用 Neon 休眠省计算时间
5. 监控请求量级,设预算告警

一句话总结:成本优化 = 读走缓存、写走批处理、就近部署省网络、按需休眠省计算——每个服务都有免费额度,关键是别让高频读打到贵路径。


九、生产架构落地示例

场景:SaaS 应用(用户/订单/内容/实时)

数据分层:
  ┌─ Cloudflare KV ── 会话/配置/特性开关(最终一致可接受)
  ├─ Upstash Redis ── 排行榜/计数器/PubSub(实时强一致)
  ├─ D1/Turso ────── 内容/帖子(读多写少,边缘就近)
  ├─ Neon/Supabase ─ 订单/用户/权限(强一致,事务核心)
  ├─ R2/S3 ───────── 图片/文件(对象存储 + CDN)
  └─ pgvector ────── 向量检索(AI 搜索/推荐)

写路径:函数 → Postgres(事务)/ 队列削峰
读路径:边缘缓存 → 边缘 SQLite → Postgres

一句话总结:生产 Serverless 数据层是「六层分工」——KV 会话、Redis 实时、SQLite 边缘内容、Postgres 核心事务、R2 对象、向量库语义,读写路径分层直达最合适的存储。


十、速查表

需求选型
边缘低延迟读D1 / Turso
完整 SQL/事务Neon / Supabase
实时/计数器/队列Upstash Redis
会话/配置/特性开关Cloudflare KV
强一致状态Durable Objects
文件/图片R2 / S3
向量检索pgvector / 向量库
复杂查询Postgres
连接治理连接池 / HTTP API
成本优化缓存 + 批处理 + 就近

一句话记忆:Serverless 数据层按「延迟、一致性、成本」分层——边缘 SQLite(D1/Turso)就近读、托管 Postgres(Neon/Supabase)管事务、KV 管会话、Redis 管实时、R2 管对象、pgvector 管向量;延迟瓶颈是冷启动+建连+跨区往返,用连接池/HTTP 免握手、模块级复用、数据放边缘解决;没有万能数据库,只有合适的分层。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「tools」更多文章

  1. 部署与回滚策略:蓝绿、金丝雀与不可变部署实战
  2. 边缘认证与会话管理:JWT、Cookie 与 Serverless 登录实战
  3. 可观测性与错误追踪:日志、Trace 与告警闭环