关于思源同步为啥这么慢的探究

太长不看:

  1. 扫盘建立快照不够高效,占比 10%
  2. 网络条件拉跨,占比 10-100%(假如你家网速正常就 10%,不正常直接断了,影响算 100% 是没问题吧trollface
  3. 同步有锁,必须交替进行,占比 30%
  4. web 上传对小文件极不友好,占比 50%

关于一些前置的讨论可以看看 Issue #12246 · siyuan-note/siyuan ,我在这里研究了下 obsidian 的 livesync 插件与思源同步机制的差异,试图搞清楚,为啥都能使用 S3 作为同步中介,livesync 可以做到实时同步,而思源则有明显的卡顿感。

一个反直觉的观点是,思源的快照机制并不慢,至少不是同步慢的最主要问题。以下是测试出来的快照建立时间于同步时间之间的差异:

  • 日记编辑 0.75s,未同步
  • 主题更新(22 个文件,2m 数据量)0.86s,同步时间 3s
  • 安装插件(650 个文件,20m 数据量)3.36s,同步时间 94s
  • 删除插件(删除 650 个文件,20mb 数据)0.86s,同步时间 14s

以上都是先建立快照,再进行同步的操作,换而言之,同步的时间已经是去除快照建立的时间了,但是还是可以看出相对于快照操作是很慢的。

因此同步慢的的最大根源就是同步加锁……而已吗?

直到今天之前,我都是这个观点,但我忽然想到,同步加锁只是会影响到另一端同步并下载云端内容的速度,理论上不会影响到我这一端上传的速度,或许还要严格评估一下 web io 对于同步速度的影响。因此我直接在本地搭建了一个 docker minio,新开了一个库作为测试。我同时把我主笔记库的数据复制过来了,总共是 800m 的大小,6500 个文件。

我阅读了 dejavu 的代码,发现它里面有对同时上传文件数的限制。我合理的怀疑这就是问题的根源。于是,我拉到本地,进行修改,将同时上传、下载文件数的限制,也是 NewPoolWithFunc 的 poolSize 全拉高了 10 倍,重新打包思源的 kernel,进行测试。以上所有操作都是基于思源是个开源软件,所有,哎,就是能改着玩!

在我进行修改之前,使用本地的 minio 进行全库上传的耗时是 440s,那么,你觉得我修改后的耗时是多少呢?

还是 436s!

这少掉的 4s,完全可以被认为就是一个误差而已,因此可以说,dejavu 里对同时上传文件大小的限制,根本就不是同步慢的原因。

我尝试绕过思源,直接通过 minio 的 webui 上传,时间相差无几。

接着,我做了另一种尝试,使用 restic 进行备份,然后直接通过 webui 上传。备份同样的内容,思源的同步机制总共生成了 13,062 个文件,259 个文件夹,而 restic 则是 48 个文件,261 个文件夹。

最后,restic 的上传时间为 10s。

在查看日志中发现,minio 的同时上传速度哪怕在本地也只能做到每秒 40 左右的文件。

作为测试,我尝试使用官方的上传机制,这次就更慢了,每秒只能上传 16 个文件。而且甚至因为同时上传等待时间过长,还给我返回了 time out 报错。

因此,问题的根源似乎很清楚了:思源扫盘建立快照当然可以进步,但进步空间不大。改善云端同步协作机制、实现无锁同步,以及改变思源的快照分片机制,才是根本解决方案。

那么,古尔丹,代价是什么呢?

代价就是,从此思源的增量下载能力可能大大减弱,可能你下载一个快照,就得把整个库下载回来,因为现在一个数据分块对应了多个实际的文件,你只能一起下载回来再拆分。

这里,我就不得不感慨,省空间换时间,还是省时间换空间,依然、并且永远,是一个值得考虑的问题啊。

  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    23020 引用 • 92597 回帖

相关帖子

优质回帖
  • tianzhongs 1 赞同

    目前的优化的话,我能想到的就是类似于 Duplicati(某备份工具),他也是增量备份,他的逻辑是

    1. 第一个文件:把元数据的一些映射关系做了信息映射;
    2. 别的文件就是加密后的元数据,同样也是进行了分片,但是他多了一个步骤,就是

    压缩,我觉得这个压缩很有搞头

    1. 每次增量备份,只多备份新的修改的元数据对照和压缩的元数据

    他这个备份工具也支持加密,也是一样的,我个人体验同步速度算快的,毕竟他压缩的大小能指定,比如说 650MB(CD 大小),元数据足够大的话,就会有很多的 650MB 的压缩包,上传起来比思源现在的上传小文件肯定会快很多;

    然后就是映射关系,他本地也有一个数据库,保存的是映射关系和日志,相当于是缓存,可以删因为云端也有,这种同步的话,除了第一次同步这个日志数据库慢点,其余时间都比思源快很多。

    加密上传后的的目录:能看到精简了很多

    image.png

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • 现在 ipv6 都开放了,如果只是 vps 同步,还要必要?还要什么服务器?我一般快照这些都是关闭的,写个批处理每天增量备份一下 data 目录就是.

  • 其他回帖
  • 我想向你描述的很清楚了,包括你现在又说伺服,我一开头表达的很清楚

    同步目前最简单粗暴的增本增效的方法就是,直接在服务器上给每个订阅用户运行自己的思源内核实例,在使用官方同步的情况下,客户端后端直接与云端内核通信,离线状态下客户端自己记录距离上一次同步的离线时间戳,每当与云端内核连接,就开始对比数据新鲜度,而冲突解调在云端内核进行

    代表我不是不知道伺服可以最快解决,但是你不能作为一个官方订阅,让用户自己伺服吧,所以我直接说了云内核,增本增效。

    但是说实话,就做一个最简单的同步,单纯从打开窗口或者后端 api 请求判断哪个 sy 文件发送了改变,上传了哪些文件,删除了哪些文件,禁止 fs,真正的按需同步,也比现在快,大家当然想要如果修改了 3 个字,就只做同步 3 个字的操作,但现在恐怕连修改了 3 个字就只同步这个文档的操作都没做到

    这个是想表达,储存器性能根本不是原因,是自己没做足够复杂的中间件处理,最为全世界广泛应用的技术,对象存储已经是最好的云端存储方案了,就好像是,能不能让博尔特再快 5s,这样我看他跑步时间就更短了,有没有可能是自己阈值太高?

    然后就是,我也没有把 live 看成是什么标杆,它也是早轮子而已

    说白了,你觉得很简单的东西,像 live 做的监听对象,思源加了没有?最后我说这么多,我觉得最核心的还是这个

    从去年讨论到现在,关于同步已经讨论了无数多个先进方案了。我的评价是,别自嗨,主要看 D 怎么说

    1 回复
  • sunk926 1 评论
    #!/bin/sh
    docker stop siyuan 
    
    echo -e "\n\n" >> /root/siyuan/rsync.log
    echo Sync started at $(date "+%Y-%m-%d %H:%M:%S")  >> /root/siyuan/rsync.log
    mount -t cifs -o username=sun,password=123456 //192.168.8.8/f/ /mnt/windows_share
    
    #rsync -avz --delete --exclude=rsync.log /root/siyuan/ /mnt/windows_share/siyuan >> /root/siyuan/rsync.log 2>&1 || /usr/bin/pwsh /root/siyuan/qqMail.ps siyuanSyncError_192.168.8.8
    
    rsync -avz --delete --exclude=rsync.log /root/siyuan/ /mnt/windows_share/siyuan || /usr/bin/pwsh /root/siyuan/qqMail.ps siyuanSyncError_192.168.8.6
    
    umount /mnt/windows_share
    docker start siyuan
    

    这是我之前的 linux 上的同步方案,你可以参考一下,每天晚上自动停止思源服务,自动挂载备份,然后同步,同步出错后发送邮件通知, 还有失败日志. 用了好几年了,几乎没出过问题,就算磁盘满 发过几次邮件.你可以修改一下在桌面端使用,原理一样的.

    其实现在用的少了,之前还自己搭建 s3,太折腾了,目前就用 cloudflare 了,省事,反正你只要不要往笔记里面塞太多大文件,同步还是能接受的.
    sunk926
  • zxhd86

    对象储存高并发支持得不好吗?

    可悲的是,确实不高,我自己手动修改了并发数后运行的效果确实如果。可能 minio 的性能有限,可能官方同步在控制台对于并发数做了限制,但是事实就是,大量小文件的并发上传和下载速度并不好。

    可能花尽心思搞一堆东西,也就优化个一两秒

    这倒不能这么说,只使用 s3 的 obsidian livesync 算是为我们揭示冷备份方案的上限了,他确实没有在云端运行一个实例的。就算算上思源跟 livesync 建立同步上的差异,对于 20mb、650 个文件的同步,那也能从 90s 砍到 4(建立快照) + 3s,这是极大的提升了。

    就做一个最简单的同步,单纯从打开窗口或者后端 api 请求判断哪个 sy 文件发送了改变,上传了哪些文件,删除了哪些文件,禁止 fs,真正的按需同步,也比现在快

    不太行,因为有外部修改的因素,不考虑这个就确实可以。

    obsidian 使用了 node 的 fs.watch 来递归监听文件夹变化,它也不是靠监听窗口和自身的修改动作实现文件修改事件的监听的。livesync 归根结底也是调用了 obsidian 的这个接口。可惜,golang 没有这么方便的东西,有归有,但是 windows、linux、mac 各有各的接口,头都大了。目前最有希望的还是使用轮询机制动态监听,而不是在同步时才扫描文档、建立快照。

    但现在恐怕连修改了 3 个字就只同步这个文档的操作都没做到

    这个据我所知应该是实现了?不过每次同步最少是要上传、下载一份索引,这个索引体积依照 data 而定,我的 data 大概需要 134kb 的索引,emmm……

    1 回复
  • 查看全部回帖

推荐标签 标签

  • 外包

    有空闲时间是接外包好呢还是学习好呢?

    26 引用 • 232 回帖
  • danl
    146 关注
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖
  • 安装

    你若安好,便是晴天。

    132 引用 • 1184 回帖 • 1 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    8449 引用 • 38490 回帖 • 155 关注
  • flomo

    flomo 是新一代 「卡片笔记」 ,专注在碎片化时代,促进你的记录,帮你积累更多知识资产。

    5 引用 • 107 回帖
  • 学习

    “梦想从学习开始,事业从实践起步” —— 习近平

    171 引用 • 512 回帖
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    21 引用 • 140 回帖 • 2 关注
  • 星云链

    星云链是一个开源公链,业内简单的将其称为区块链上的谷歌。其实它不仅仅是区块链搜索引擎,一个公链的所有功能,它基本都有,比如你可以用它来开发部署你的去中心化的 APP,你可以在上面编写智能合约,发送交易等等。3 分钟快速接入星云链 (NAS) 测试网

    3 引用 • 16 回帖 • 6 关注
  • Solidity

    Solidity 是一种智能合约高级语言,运行在 [以太坊] 虚拟机(EVM)之上。它的语法接近于 JavaScript,是一种面向对象的语言。

    3 引用 • 18 回帖 • 400 关注
  • GitBook

    GitBook 使您的团队可以轻松编写和维护高质量的文档。 分享知识,提高团队的工作效率,让用户满意。

    3 引用 • 8 回帖
  • Notion

    Notion - The all-in-one workspace for your notes, tasks, wikis, and databases.

    7 引用 • 40 回帖
  • GitHub

    GitHub 于 2008 年上线,目前,除了 Git 代码仓库托管及基本的 Web 管理界面以外,还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱(报表)、代码片段分享(Gist)等功能。正因为这些功能所提供的便利,又经过长期的积累,GitHub 的用户活跃度很高,在开源世界里享有深远的声望,并形成了社交化编程文化(Social Coding)。

    210 引用 • 2036 回帖
  • JVM

    JVM(Java Virtual Machine)Java 虚拟机是一个微型操作系统,有自己的硬件构架体系,还有相应的指令系统。能够识别 Java 独特的 .class 文件(字节码),能够将这些文件中的信息读取出来,使得 Java 程序只需要生成 Java 虚拟机上的字节码后就能在不同操作系统平台上进行运行。

    180 引用 • 120 回帖 • 3 关注
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 5 关注
  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 592 关注
  • 反馈

    Communication channel for makers and users.

    123 引用 • 913 回帖 • 250 关注
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    21 引用 • 31 回帖 • 4 关注
  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖 • 2 关注
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    407 引用 • 3578 回帖
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    71 引用 • 535 回帖 • 789 关注
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    178 引用 • 997 回帖
  • OpenShift

    红帽提供的 PaaS 云,支持多种编程语言,为开发人员提供了更为灵活的框架、存储选择。

    14 引用 • 20 回帖 • 632 关注
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    170 引用 • 414 回帖 • 387 关注
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 779 关注
  • 导航

    各种网址链接、内容导航。

    42 引用 • 175 回帖