菜单

同步引擎

相关源文件

同步引擎是 Joplin 中管理设备与远程存储服务(同步目标)之间数据同步的核心组件。它负责处理本地更改的上传、远程更改的下载、冲突解决以及同步过程中的端到端加密。此页面记录了同步引擎的架构和工作流程、它如何与其他组件交互以及它为确保可靠同步而采用的各种机制。

有关实现特定同步目标的信息,请参阅同步目标

架构概述

同步引擎由多个组件组成,这些组件协同工作,为跨设备和同步目标提供可靠的同步体验。

来源

关键组件

  1. 同步器:协调整个同步过程的主要类。它负责处理更改的上传、下载和冲突解决。

  2. FileApi:一个用于与同步目标交互的抽象接口。它提供了在同步目标上创建、读取、更新和删除文件的方法。

  3. LockHandler:管理锁以防止多个客户端同时同步,这可能导致冲突。

  4. MigrationHandler:当新版本需要更改同步结构时,负责升级同步目标。

  5. EncryptionService:管理在数据上传到同步目标之前对其进行端到端加密。

  6. ResourceService:管理资源(附件),这些资源由于其大小而需要特殊处理。

  7. JoplinServerApi:当用作同步目标时,用于与 Joplin Server 通信的客户端。

同步工作流程

同步过程分为 UPDATE_REMOTE、DELETE_REMOTE 和 DELTA 三个主要阶段。这些阶段可以单独执行,也可以在完整同步中一起执行。

来源

初始化阶段

在实际同步开始之前,同步器会

  1. 检查同步目标是否有效且兼容
  2. 从远程获取并验证同步信息
  3. 如果启用了加密,则设置加密
  4. 获取同步锁以防止并发同步操作

来源

UPDATE_REMOTE 阶段

在此阶段,本地更改将被推送到同步目标。

  1. 查找自上次同步以来在本地创建或修改的所有项目(笔记、文件夹等)。
  2. 对于每个项目,检查它是否存在于远程,以及是否存在冲突。
  3. 如果没有冲突,则将项目上传到同步目标。
  4. 对于资源(附件),同时上传元数据和文件内容。

来源

DELETE_REMOTE 阶段

在此阶段,本地删除的项目将从同步目标中删除。

  1. 查找所有在本地被删除的项目。
  2. 从同步目标中删除每个项目。

来源

DELTA 阶段

在此阶段,同步目标中的更改将被应用于本地。

  1. 获取自上次同步以来在远程创建或修改的所有项目。
  2. 对于每个项目,检查它是否存在于本地,以及是否存在冲突。
  3. 如果没有冲突,则将更改应用于本地。
  4. 对于资源,如果需要,则下载文件内容。

锁定系统

同步引擎使用锁定系统来防止多个设备同时同步,这可能导致冲突和数据损坏。

来源

锁类型

  1. 排他锁 (LockType.Exclusive):用于需要对同步目标进行排他访问的操作,例如迁移。一次只有一个客户端可以持有排他锁。

  2. 同步锁 (LockType.Sync):用于正常同步。多个客户端可以同时持有同步锁,但前提是没有排他锁存在。

来源

锁操作

LockHandler 处理锁操作。

  1. 获取锁:在同步之前,客户端会尝试获取适当类型的锁。
  2. 检查锁:客户端在尝试同步之前会检查是否存在任何排他锁。
  3. 刷新锁:锁具有 TTL(生存时间),在长时间操作期间必须定期刷新。
  4. 释放锁:同步完成后,释放锁。

来源

冲突解决

当同一项目在同步之间被多个设备修改时,就会发生冲突。同步引擎有机制来检测和处理这些冲突。

来源

冲突检测

在以下情况下会检测到冲突:

  1. 自上次同步以来,项目已被远程删除但在本地被修改。
  2. 自上次同步以来,项目在本地和远程都被修改。

来源

冲突处理

检测到冲突时:

  1. 对于笔记,冲突版本将标记有 is_conflict 标志。
  2. 冲突的笔记将被移到一个特殊的“冲突”文件夹。
  3. 用户可以通过比较版本并决定保留哪个来手动解决冲突。

来源

端到端加密

同步引擎支持端到端加密(E2EE),以确保数据在离开客户端之前被加密。

来源

加密过程

  1. 检查同步信息中是否启用了加密。
  2. 对于每个要同步的项目,使用活动的主密钥对其进行加密。
  3. 对于资源,加密元数据和资源 blob。
  4. 将加密后的数据发送到同步目标。

来源

解密过程

  1. 从同步目标下载项目时,检查它们是否被加密。
  2. 如果已加密,则使用适当的主密钥进行解密。
  3. 对于资源,加密元数据和资源 blob。

来源

同步目标

Joplin 通过 FileApi 接口支持多种同步目标。

来源

FileApi 接口

FileApi 接口为所有同步目标提供了一组通用操作。

  1. 文件操作:get、put、delete、list、mkdir
  2. 增量同步:获取自上次同步以来的更改。
  3. 锁定:创建、检查和删除锁。
  4. 批处理:为了效率而进行批处理操作。

来源

Joplin 服务器

Joplin Server 是官方同步目标,具有增强功能。

  1. 用户认证:安全的用户认证。
  2. 文件存储:笔记、附件等的存储。
  3. 共享:支持共享笔记和笔记本。
  4. 增量同步:仅同步更改,效率高。

来源

资源处理

由于附件的体积可能很大,因此在同步过程中需要特殊处理资源(附件)。

来源

资源上传

上传资源时:

  1. 上传资源元数据(标题、MIME 类型等)。
  2. 上传资源 blob(文件内容)。
  3. 对于大型资源,处理潜在的超时问题。
  4. 如果 blob 自上次同步以来未更改,则跳过上传。

来源

资源下载

资源是懒加载的。

  1. 最初,同步过程中仅下载资源元数据。
  2. 资源被标记为 FETCH_STATUS_IDLE
  3. 当应用程序请求资源时,它会被下载并标记为 FETCH_STATUS_DONE
  4. 下载错误会被跟踪,并可以重试。

来源

共享同步

在使用 Joplin Server 或 Joplin Cloud 作为同步目标时,Joplin 支持共享笔记本和与其他用户协作。

来源

共享过程

当一个文件夹被共享时:

  1. 将在 Joplin Server 上创建一个共享。
  2. 文件夹会获得一个 share_id 属性。
  3. 文件夹中的所有笔记和资源都将继承此 share_id
  4. 在同步期间,share_id 会传播到所有子项

来源

共享同步

同步期间

  1. 检查并更新文件夹、笔记和资源的共享 ID
  2. 处理资源在多篇笔记中使用的特殊情况
  3. 确保共享项使用适当的主密钥进行加密

来源

性能优化

同步引擎包含多项优化以提高性能

  1. 增量同步:仅获取自上次同步以来的更改,而不是所有项
  2. 批量处理:将操作分组以减少 API 调用
  3. 资源优化:仅在需要时下载资源
  4. 并发同步预防:使用锁来防止浪费性的并发同步
  5. 错误处理:专门处理网络超时和瞬时错误

来源

数据库迁移

当 Joplin 新版本引入结构性更改时,同步目标可能需要数据库迁移。

来源

迁移过程

  1. 检查同步目标版本
  2. 如果需要升级,则获取独占锁
  3. 执行迁移
  4. 更新同步目标版本
  5. 释放锁

来源

结论

Joplin 同步引擎是一个复杂的系统,它处理跨设备和各种同步目标的数据同步。它管理端到端加密、冲突解决、资源处理和共享的复杂性,同时提供无缝的用户体验。模块化设计和清晰定义的接口允许通过新的同步目标和功能扩展该系统。