Graft主要解决这些问题:
1. 离线优先的APP:把同步存储的活甩给Graft,开发更简单
2. 跨设备同步:手机/电脑/网页随时同步数据,不受平台限制
3. 随处部署:能在服务器、小程序甚至U盘里运行
4. 啥数据都能同步:数据库/文件/自定义格式都行,且数据绝对一致
做SQLSync项目时我发现需要这个工具。SQLSync是把SQLite数据库搬到浏览器里的技术(原理类似Git),但它像物理复制那样把所有改动都同步给每个客户端——这在服务器还行,但在浏览器里就太笨重了。
于是我开始寻找更适合边缘计算(比如手机APP)的同步方案,需要满足:
✓ 让客户端自己决定同步时间
✓ 只同步需要的数据
✓ 随时随地能同步(包括离线状态)
✓ 能同步任意类型数据
✓ 还要保证强一致性
结果发现根本没有现成方案,那就自己造一个吧!
#与众不同的同步方案
现有方案基本分两类:
① 全量同步:把整个数据库拷给每个客户端——太占内存
② 逻辑同步(比如CDC/CRDT):只同步字段级改动,但必须深度改造APP
Graft走了第三条路:
• 像全量同步那样不挑数据类型(只管传输二进制)
• 像逻辑同步那样只传变更摘要
核心概念叫"Volume"——由固定大小的"Page"组成的存储单元。客户端通过"快照"来读写数据,Graft则智能地只同步必要的部分。
#懒人同步:想什么时候同步都行
现实中的手机APP经常断网、内存有限。Graft允许客户端随时"快进"到最新状态,同步时只需问服务器:"上次同步后改了啥?"
服务器返回的"graft"(名字来源于植物嫁接)就像变更清单,告诉客户端哪些页面需要更新。关键是——这时只传变更清单,不传实际数据!要不要下载新数据完全由客户端决定。
#精准同步:只下载需要的部分
在浏览器/小程序里不可能下载整个数据库。客户端拿到变更清单后,可以像拼拼图那样只下载缺失的部分。
Graft提供三种预加载策略:
1. 智能预测:用Leap算法猜你可能需要哪些数据
2. 人工指导:比如你知道用户总要查看个人资料页,就提前加载
3. 全量回退:必要时也能退化成全量同步(适合服务器端)
#边缘友好:数据就在你身边
Graft通过两种方式优化:
① 数据缓存在全球边缘节点,访问速度飞快
② 客户端极其轻量,能塞进任何环境(甚至冰箱上的显示屏)
#强一致性:冲突也不怕
采用"可序列化快照隔离"技术:
• 读操作互不干扰
• 写操作严格按顺序执行
当离线修改和服务器冲突时,Graft会拒绝提交,客户端可以选择:
- 重试:拉取最新数据重新提交
- 合并:类似Git的冲突处理
- 分叉:直接另存为新版本
#Graft能用来做什么?
• 离线应用:便签/待办清单,断网也能用
• 全平台同步:手机/电脑数据自动同步
• 快速启动:新设备秒获最新数据
• 万物皆可同步:AI模型/地理数据/猫照片...
#Graft SQLite扩展(libgraft)
今天,libgraft这是开始使用 Graft 的最简单方法。它是原生 SQLite 扩展,可以在任何 SQLite 上运行。它使用 Graft 复制客户端实际使用的数据库部分,从而可以在资源受限的环境中运行 SQLite。
libgraft实现SQLite 虚拟文件系统 (VFS),允许它拦截对数据库的所有读写操作。它提供与 SQLite 在WAL 模式下运行时相同的事务和并发语义。使用libgraft可为您的应用程序带来以下好处:
- 与对象存储进行异步复制
- 实现懒人式部分复制:边缘和设备中的惰性部分副本
- 保证强一致性:可序列化快照隔离
- 支持数据回滚:时间点恢复