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

本贴最后更新于 243 天前,其中的信息可能已经时异事殊

太长不看:

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

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

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

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

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

  • 思源笔记

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

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

    25092 引用 • 103447 回帖

相关帖子

优质回帖
  • tianzhongs 1 赞同

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

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

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

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

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

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

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

    image.png

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • 另外说一句,同步慢就是会发生冲突这么多的元凶,只要你同步的足够快,用户根本来不及做自己的骚操作,慢就是同步出冲突的最终元凶,你不能指望本身是一个轻型文档编辑器,用户还要等你个五六秒才开始下一步的操作,PC 端尚要等这么久,移动端这种退出往往不由客户端本身决定的情况,冲突只会更严重

    1 回复
  • 其他回帖
  • zxhd86

    我再说的通俗一点,如果你家里宽带有 10000 兆的带宽,那么你下载腾讯 s3 的速度就是一万兆,你个人就算是硬盘提供得了这么大的速度吗?详情见这里,https://doc.fincloud.tencent.cn/tcloud/Storage/COS/845813/uploaddownloadfaq
    对象存储的性能和带宽不上限,只按量,远超你自己局域网运行一个 docker 的性能

    对象储存对于少量大文件的带宽确实能跑满,但是大量小文件就不太行了。这个我已经在腾讯云上尝试过了,参照上面的记录,golang 并发上传数设为 640,但是每秒上传文件数他就是有上限的,腾讯云也只能达到每秒 20 个,目前看来,对于小文件,还是 minio 在本地是比较快。

    如果你测试出更好的数据,可以跟我说一下怎么写,我也可以改进下 siyuan 这方面的代码。

    我说了没有那么好的事情,即自由又稳定,况且,又不是没有解决方案,只需要把附件这种不会频繁变动的内容单独走另一个单独的上传信息通道就好了,而不是放到高频索引里面再扫一遍

    可是实际上外部变动主要就是改附件啊,单纯思源本身的笔记文件反而不太会被改,因为其他软件读不懂……

    至少 ob 可以直接知道该同步哪一个 md 文件,思源可以在操作后马上知道该同步哪一个 sy 文件吗?倘若能,为什么要去扫盘?难道是因为我改了一个 sy 文件,每一次都要扫库看看我有没有改其他文件吗?那为什么不一直扫,万一我改了其他的文件但是没该文档,岂不是没有办法了,只能等我改文档的时候再帮我检测一下?这个思路倒是可以理解了。我是真的觉得,和用户的操作一块进行,监听哪些文件发生更改,然后没有中间服务商直接同步哪些文件,都比现在快。

    我倒是没有否认 ob livesync 建立快照速度更快,更有优越性,只不过 golang 上没有太好可用的包。

    我知道你不停的强调建立一个快照或者索引有多快,但是,在我用的过程中,建立快照并不是卡我的原因,原因是这个快照索引本身就是没有时效性的,不可靠的,所以它不是建立完就没事了,他需要下载下来,然后解析,然后一个个核对,我的同步大部分时间就是花在这个核对索引上,一直在校验索引,少则校验 5-6s,多则半分钟,3.10 版本有时候校验索引都会卡死,扫盘建立的索引,终究还是要扫盘去核对

    此索引非彼索引啊,这里有两个概念的索引,siyuan sqlite 里的索引和快照 dejavu 使用的文档索引。思源懒得判断文档变化情况选择全部校验一遍来重建 sqlite 确实是懒政情况了,但是这跟同步的索引和快照完全是两回事啊。解决问题终究还是要一个个来的。

    局域网内客户端是可以互相沟通同步的,每个客户端都具有与储存器之间的完整的中间件

    我觉得对等点本身就是一个服务端了吧……硬要这么说,思源也可以内部塞一个 webdav 或 s3 实现,然后直接通过局域网发现协议互相找到端口,进行同步。但是这种情况下思源自己就成为服务端了,这跟思源作为伺服的区别有多大呢?

    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]

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

  • 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
  • 查看全部回帖

推荐标签 标签

  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

    1 引用 • 1 回帖
  • 游戏

    沉迷游戏伤身,强撸灰飞烟灭。

    181 引用 • 821 回帖
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 442 关注
  • 京东

    京东是中国最大的自营式电商企业,2015 年第一季度在中国自营式 B2C 电商市场的占有率为 56.3%。2014 年 5 月,京东在美国纳斯达克证券交易所正式挂牌上市(股票代码:JD),是中国第一个成功赴美上市的大型综合型电商平台,与腾讯、百度等中国互联网巨头共同跻身全球前十大互联网公司排行榜。

    14 引用 • 102 回帖 • 316 关注
  • Telegram

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

    5 引用 • 35 回帖
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖 • 1 关注
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    187 引用 • 318 回帖 • 255 关注
  • QQ

    1999 年 2 月腾讯正式推出“腾讯 QQ”,在线用户由 1999 年的 2 人(马化腾和张志东)到现在已经发展到上亿用户了,在线人数超过一亿,是目前使用最广泛的聊天软件之一。

    45 引用 • 557 回帖
  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    181 引用 • 400 回帖 • 1 关注
  • JSON

    JSON (JavaScript Object Notation)是一种轻量级的数据交换格式。易于人类阅读和编写。同时也易于机器解析和生成。

    52 引用 • 190 回帖
  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    22 引用 • 212 回帖
  • Bug

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

    76 引用 • 1742 回帖
  • 知乎

    知乎是网络问答社区,连接各行各业的用户。用户分享着彼此的知识、经验和见解,为中文互联网源源不断地提供多种多样的信息。

    10 引用 • 66 回帖
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 158 关注
  • WebSocket

    WebSocket 是 HTML5 中定义的一种新协议,它实现了浏览器与服务器之间的全双工通信(full-duplex)。

    48 引用 • 206 回帖 • 294 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    948 引用 • 1460 回帖
  • CentOS

    CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise Linux 依照开放源代码规定释出的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定的服务器以 CentOS 替代商业版的 Red Hat Enterprise Linux 使用。两者的不同在于 CentOS 并不包含封闭源代码软件。

    239 引用 • 224 回帖 • 1 关注
  • 创造

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

    184 引用 • 1015 回帖
  • Anytype
    3 引用 • 31 回帖 • 13 关注
  • App

    App(应用程序,Application 的缩写)一般指手机软件。

    91 引用 • 384 回帖
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    34 引用 • 467 回帖 • 760 关注
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 78 关注
  • 创业

    你比 99% 的人都优秀么?

    82 引用 • 1395 回帖
  • ZeroNet

    ZeroNet 是一个基于比特币加密技术和 BT 网络技术的去中心化的、开放开源的网络和交流系统。

    1 引用 • 21 回帖 • 647 关注
  • PWL

    组织简介

    用爱发电 (Programming With Love) 是一个以开源精神为核心的民间开源爱好者技术组织,“用爱发电”象征开源与贡献精神,加入组织,代表你将遵守组织的“个人开源爱好者”的各项条款。申请加入:用爱发电组织邀请帖
    用爱发电组织官网:https://programmingwithlove.stackoverflow.wiki/

    用爱发电组织的核心驱动力:

    • 遵守开源守则,体现开源&贡献精神:以分享为目的,拒绝非法牟利。
    • 自我保护:使用适当的 License 保护自己的原创作品。
    • 尊重他人:不以各种理由、各种漏洞进行未经允许的抄袭、散播、洩露;以礼相待,尊重所有对社区做出贡献的开发者;通过他人的分享习得知识,要留下足迹,表示感谢。
    • 热爱编程、热爱学习:加入组织,热爱编程是首当其要的。我们欢迎热爱讨论、分享、提问的朋友,也同样欢迎默默成就的朋友。
    • 倾听:正确并恳切对待、处理问题与建议,及时修复开源项目的 Bug ,及时与反馈者沟通。不抬杠、不无视、不辱骂。
    • 平视:不诋毁、轻视、嘲讽其他开发者,主动提出建议、施以帮助,以和谐为本。只要他人肯努力,你也可能会被昔日小看的人所超越,所以请保持谦虚。
    • 乐观且活跃:你的努力决定了你的高度。不要放弃,多年后回头俯瞰,才会发现自己已经成就往日所仰望的水平。积极地将项目开源,帮助他人学习、改进,自己也会获得相应的提升、成就与成就感。
    1 引用 • 487 回帖
  • Office

    Office 现已更名为 Microsoft 365. Microsoft 365 将高级 Office 应用(如 Word、Excel 和 PowerPoint)与 1 TB 的 OneDrive 云存储空间、高级安全性等结合在一起,可帮助你在任何设备上完成操作。

    5 引用 • 34 回帖
  • abitmean

    有点意思就行了

    38 关注