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

太长不看:

  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 报错。

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

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

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

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

  • 思源笔记

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

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

    22337 引用 • 89380 回帖

相关帖子

优质回帖
  • tianzhongs 1 赞同

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

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

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

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

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

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

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

    image.png

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • suhe98 1 评论

    image.png

    我的 assets 文件夹。不过话说回来,是 s3 同步快点还是 webdav 快呢。有没有测试过的,个人一直用 s3

    不用想,铁定 s3,webdav 的响应更慢,并行更少,对于思源是相当不友好的
    zxhd86
  • 其他回帖
  • 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 回复
  • zxhd86

    数据库和索引是不经过同步的,它们放在 temp 目录下。

    调用一堆内核 api 跟很多数据发生变化无关,我指的是打开 siyuan.log,看这一堆东西的上下文:

    I 2024/08/17 00:06:34 s3.go:94: uploaded object [repo/objects/c4/0294c4d4c1c85d1d3c85d9ad8527c8988d4121]
    I 2024/08/17 00:06:34 sync.go:1265: uploaded chunk [objects/c4/0294c4d4c1c85d1d3c85d9ad8527c8988d4121, 561/6604]
    I 2024/08/17 00:06:34 s3.go:94: uploaded object [repo/objects/cf/5e4f6bad5e4a80d2e2e596b5bb084eb1447915]
    I 2024/08/17 00:06:34 sync.go:1265: uploaded chunk [objects/cf/5e4f6bad5e4a80d2e2e596b5bb084eb1447915, 562/6604]
    I 2024/08/17 00:06:34 s3.go:94: uploaded object [repo/objects/89/24958a3954bd9c8bad705e0f6a03a8d33f6273]
    I 2024/08/17 00:06:34 sync.go:1265: uploaded chunk [objects/89/24958a3954bd9c8bad705e0f6a03a8d33f6273, 563/6604]
    I 2024/08/17 00:06:34 s3.go:94: uploaded object [repo/objects/d9/2c22093eaa028952d2a912f5af45c8a24d0328]
    I 2024/08/17 00:06:34 sync.go:1265: uploaded chunk [objects/d9/2c22093eaa028952d2a912f5af45c8a24d0328, 564/6604]
    I 2024/08/17 00:06:34 s3.go:94: uploaded object [repo/objects/60/3ddb05be9c7b26b7b962eb6bd4948c50a78915]
    I 2024/08/17 00:06:34 sync.go:1265: uploaded chunk [objects/60/3ddb05be9c7b26b7b962eb6bd4948c50a78915, 565/6604]

    它们就是实际上传下载的数据分块,如果数量小,时间短,那就说明并不是在这一步阻塞的。

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

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

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

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

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

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

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

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

    1 回复
  • 查看全部回帖

推荐标签 标签

  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    55 引用 • 85 回帖
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1434 引用 • 10054 回帖 • 490 关注
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    25 引用 • 191 回帖 • 16 关注
  • 钉钉

    钉钉,专为中国企业打造的免费沟通协同多端平台, 阿里巴巴出品。

    15 引用 • 67 回帖 • 339 关注
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    75 引用 • 1737 回帖 • 5 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    17 引用 • 53 回帖 • 136 关注
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖 • 1 关注
  • 招聘

    哪里都缺人,哪里都不缺人。

    190 引用 • 1057 回帖
  • iOS

    iOS 是由苹果公司开发的移动操作系统,最早于 2007 年 1 月 9 日的 Macworld 大会上公布这个系统,最初是设计给 iPhone 使用的,后来陆续套用到 iPod touch、iPad 以及 Apple TV 等产品上。iOS 与苹果的 Mac OS X 操作系统一样,属于类 Unix 的商业操作系统。

    85 引用 • 139 回帖 • 1 关注
  • 博客

    记录并分享人生的经历。

    273 引用 • 2388 回帖
  • 安装

    你若安好,便是晴天。

    132 引用 • 1184 回帖
  • FlowUs

    FlowUs.息流 个人及团队的新一代生产力工具。

    让复杂的信息管理更轻松、自由、充满创意。

    1 引用 • 1 关注
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    75 引用 • 258 回帖 • 617 关注
  • 互联网

    互联网(Internet),又称网际网络,或音译因特网、英特网。互联网始于 1969 年美国的阿帕网,是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。

    98 引用 • 344 回帖
  • 开源中国

    开源中国是目前中国最大的开源技术社区。传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现、使用、并交流开源技术的平台。目前开源中国社区已收录超过两万款开源软件。

    7 引用 • 86 回帖
  • 创业

    你比 99% 的人都优秀么?

    84 引用 • 1399 回帖
  • SVN

    SVN 是 Subversion 的简称,是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用了分支管理系统,它的设计目标就是取代 CVS。

    29 引用 • 98 回帖 • 680 关注
  • Latke

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

    71 引用 • 535 回帖 • 787 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖
  • 新人

    让我们欢迎这对新人。哦,不好意思说错了,让我们欢迎这位新人!
    新手上路,请谨慎驾驶!

    52 引用 • 228 回帖
  • IPFS

    IPFS(InterPlanetary File System,星际文件系统)是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。请浏览 IPFS 入门笔记了解更多细节。

    21 引用 • 245 回帖 • 241 关注
  • jQuery

    jQuery 是一套跨浏览器的 JavaScript 库,强化 HTML 与 JavaScript 之间的操作。由 John Resig 在 2006 年 1 月的 BarCamp NYC 上释出第一个版本。全球约有 28% 的网站使用 jQuery,是非常受欢迎的 JavaScript 库。

    63 引用 • 134 回帖 • 724 关注
  • wolai

    我来 wolai:不仅仅是未来的云端笔记!

    2 引用 • 14 回帖
  • TGIF

    Thank God It's Friday! 感谢老天,总算到星期五啦!

    287 引用 • 4484 回帖 • 669 关注
  • SEO

    发布对别人有帮助的原创内容是最好的 SEO 方式。

    35 引用 • 200 回帖 • 22 关注
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    8 引用 • 26 回帖
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 595 关注