思源的同步悖论

🙏

大家好,我是较长时间没有出现的 muhanstudio,今天来和大家唠唠一个老大难的问题:

  • 思源笔记的同步

思源同步的现状

思源的同步,无论是性能还是稳定性,已经被诟病了很久,尽管相比之前有了很大的进步,但是如果我们不区别对待,把它和市面上的云笔记软件相比,以下三大雷区基本上踩了一个遍。

  1. 冲突合并约等于没有
  2. 同步进行非常缓慢
  3. 会使当前编辑丢失

对同步速度的看法

我曾经持有一个粗暴的观点,认为只要同步的够快,用户根本来不及进行什么骚操作,也不会产生很多的冲突,反而是磨磨蹭蹭、畏手畏脚的走独木桥更容易摔下去。

插件开发尝试

同样,我也曾为之做过一点改变,连续开发了两款插件,一个是同步感知插件,一个是加速同步插件,他们的作用一个是尝试模拟官方的效果,在不同设备之间尝试寻找一个沟通点,在其中一个设备更改内容同步后,立即通知其他设备发起同步,一个是为了解除官方自动同步最快要等 30 秒的限制,只要你愿意,可以将同步操作的前置等待时间在保证正常顺序的同时加速到极限,但是,效果远远没有达到我的预期,主要是因为,整个机制依旧建立在思源的同步上,我只是加速了通知每个终端思源开始同步这个过程,而以上的问题,依旧没有得到很好的改善,这让我曾经郁闷过很长一段时间。

同步机制的妥协

但是随着后来深入分析思源的同步机制,会发现,其实思源因为纯本地化,在数据同步上做了很大的妥协。本地化存储(localstore)和自伺服(selfhosted)下的数据私有化完全不是一个概念,云笔记也可以是自己的云,但是本地化笔记就真的只是本地而已。

冲突合并与自伺服系统的差异

体现在什么地方?尤其在冲突合并上,对于自伺服系统,你可以完全和云笔记一样,拥有一个 24h 活跃的数据中心,这个数据中心可以作为唯一的参照基准,对于多个客户端在一个广播周期内发来的数据,数据中心可以自己处理好冲突取舍与合并,合并机制并不是最重要的,重要的是主动广播权和并发接受多版本数据的能力,数据中心拥有最高话语权,可以向所有设备在一个同步响应周期内广播相同的数据,哪怕合并机制做的简单粗暴,最终多端数据依旧是一致性的。数据中心还可以存储多个版本的数据,而不只是单线程的 IO 处理,如果想要回撤,由于数据中心存储了每个客户端的响应,同样可以在所有的版本之间做选择。

思源同步的工作方式

而思源的同步是怎么做的呢?或者说,只能怎么做?作为一个本质上完全本地化的软件,它目前是依赖于一个静态的储存设备,而这种情况下,目前最好的选择是对象存储,我下面会采用一些比喻来避免我的描述变成技术名词大集合,可能有一点不恰当,但是尽量贴切的来描述对象存储在思源同步中的角色。

并发性与一致性问题

每个客户端是一个独立的人,他们互相之间没有通道可以沟通(官方订阅也貌似做了设备显示,可设备之间的沟通也约等于没有),但是都可以走进一个静态的仓库里面,仓库里面本身没有人,只有数据,且没有主动广播消息的能力,仓库一次只能进一个人,进去后可以复制仓库的数据,或者修改仓库里的数据,在这种情况下,要保持所有人的数据都是一样的,光是逻辑上的问题就很多:

  1. 并发性与一致性问题
  2. 数据同步滞后
  3. 缺乏事务控制

并发性与一致性问题

由于每个客户端进入仓库后可以读取或修改数据,但其他客户端在它们进入仓库之前无法得知最新的修改结果,这导致数据的一致性无法得到保障。例如,客户端 A 进入仓库,读取并修改了数据,但此时客户端 B 仍然读取了旧数据,因为可能 A 同样可以在自己同步的过程中持续修改本地数据,或在 A 写入新数据之前,B 已经读取并打算写入自己的修改。这样就可能发生数据的不一致。 即使通过某种机制保证一次只能有一个人进入仓库,也无法确保在下一个人进入仓库前,其他人始终读取到最新的数据,特别是在修改数据的过程中会产生暂时不一致的状态。

数据同步滞后

假设在进入仓库时可以成功锁定资源并避免并发访问,虽然仓库中的数据在每次写入后是最新的,但客户端获取到数据和执行修改之间存在时间差。在这个时间差中,其他客户端可能会基于旧数据做出决策,而不是基于仓库里的最新数据。 如果不设计同步机制(例如读写操作中加入时间戳或版本控制),数据滞后将会导致多个客户端的数据版本不一致。没有全局同步机制,无法确保每次更新的数据能被所有客户端即时获取。

缺乏事务控制

事务控制机制通常用于保证并发环境下的数据一致性,而这个系统缺乏事务控制。假设客户端 A 在仓库中读取数据并进行长时间操作,此时如果没有事务锁定,其他客户端无法获得数据是否已被最终写入或更新的信息。由于缺乏事务回滚与提交机制,任何错误或中断都可能导致仓库中数据的不一致。 数据一致性要求所有客户端在每次操作结束后都能立即看到相同的数据版本,但是这个场景没有实现任何事务处理或两阶段提交协议等方法来管理这一点。

自伺服系统的优势

而换到自伺服系统中,仓库并不再是类似一个静态磁盘一样的地方,而是一个运行中的数据库系统,可以同时处理所有客户端的请求,并且可以缓存下来同一时间不同客户端的修改操作提交,即使它合并冲突或者同步请求的策略非常粗暴,由于最终可以向所有客户端同时广播一份一样的数据,使得它的同步性能依旧要好得多。因为自伺服系统具备并发访问、事务管理、缓存合并和实时数据广播的能力,可以在处理并发请求时确保最终数据一致性,从而避免数据滞后问题。 这也解释了,为什么对象存储已经是目前世界上广泛应用的最高效的网络数据存储,在思源上依旧显得只是不限带宽的同步网盘而已,在我部署过的无数项目中,例如 anytype,affine,appflowy 等等等等,他们同样使用了对象存储作为自己的后端存储,但他们并不是让客户端直接操作对象存储,翻看他们的 docker compose 文件,他们都有刚才我提到的类似于数据中心的实例,会单独起一个服务,在客户端与对象储存之间作为 24h 值班人员,来处理各个客户端的并发请求和一致性广播,并将一致性数据在一个内网或者同域的安全稳定的环境中传入对象存储(除非你使用了分布式部署对象存储)。

思源的同步悖论

说到这里,思源作为一款本地化软件,貌似被披上了一层悖论,永远无法做到优秀的同步性能,那么本地化和 自伺服/拥有数据中心 的同步方式是对立的关系吗,从来都不是,即使拥有以上同步机制,我们依旧可以让客户端默认总是确保所有的完整的数据都被拉取到本地,当失去了云端,也就是数据中心后,我们仅仅失去了我们的云同步功能,但是我们的数据依旧是完整的在本地的。 作为官方订阅的同步方式,思源至今还是主要采用本地化加上静态存储设备的方式来进行同步。社区版的思源其实已经提供了很大的启示,可以直接连接到 docker 部署的思源实例,可以作为一个数据中心来实现以上的操作,但由于是社区二开,稳定性和通用性都存在非常多的问题,无法真正投入使用。之前我还在群里讨论过云内核的实现方法,思路也是类似的,为每一个官方订阅用户提供一个 24 小时运行的云端内核,可以和每个客户端建立长连接,来确保高效的数据传输和数据一致性。同样还设计过一个简单的后端请求转发器,由于思源前后端采用 HTTP 通信, 我尝试拦截所有的后端请求然后转发到另一个客户端上,效果居然意外的不错,可惜最终也是因为必须所有的客户端都全程在线,或者需要做好请求的长时间缓存导致技术难度陡增而放弃。

与成本控制和解

到最后我还是发现,我对思源要求还是太苛刻了,我想我的不满主要来源于官方订阅还提供低效的同步,虽然所有数据还是留存在本地,但是我相信很多人买官方订阅,而不选择功能特性里的 S3 同步,其实有很多一部分都是抱着市面上成熟的云笔记的心态去用,自己看不到自己的数据究竟被放在了哪里,通过什么样的方式进行传输和管理,只知道官方负责我数据的多端一致性,我买的是官方同步,由思源笔记的服务器来负担,理应比自己买对象存储要安全和稳定很多,如果当初的心态只是把官方订阅当做是一个小容量的不计流量包年对象存储,不用自己填相关的配置,一个官方提供的静态备份服务,在思源笔记已经如此开放,营收手段如此少,开发资源也紧张,不得不考虑成本控制的情况下,其实也就还好。可惜这样做对于开发者自己也是有代价的,因为如果想解决,甚至只是优化开头的那几个问题,随之而来要解决的逻辑问题就会几何倍数增加且越发复杂,即使将来尝试引入一些无中心的方案,比如 webrtc 和 P2P,在目前的技术结构上,例如在基于文档/文件级别的粒度上同步,坑也会增加,anytype 对于冲突块的解决方式是自动在两个客户端换行生成新的块来显式全量存储两个冲突块,而思源目前的快照机制,还需要大量的重构才能达到相应的效果,同时,单单它的同步核心 any-sync(包含非常多的子部件)都由两个以上的人员开发,我想它也用自己的复杂度和工程量之大亲身实践告诉我们,点对点方案只适合作为一个新鲜的特性来引入,作为成本控制,也是不适合作为中心化的廉价替代方案的。

展望与建议

这一章其实是 AI 帮我分章节的时候生成的,我个人很难给出什么具体的或者专业的建议(除了加钱),只能在已经做好的成熟的数据一致性系统之间进行肤浅的对比和解读,写这篇文章主要也是让更多的人了解并且理解在很多场景下思源一直以来的同步困境,很多时候,在不断的需求受限中,现实的与成本控制和解,才是解决矛盾的折中办法。

  • 思源笔记

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

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

    22926 引用 • 92174 回帖 • 1 关注
1 操作
muhanstudio 在 2024-10-16 10:54:49 更新了该帖

相关帖子

优质回帖
  • 我再插一句,实际上并不只是多端修改同一个文件会导致这样的问题,我亲身测试,甲设备修改 A 文档,乙设备修改 B 文档,然后甲点击同步,甲同步完成之后,乙点击同步,如果乙没有同步完成,甲上线开始打开 B 文档,开始编辑修改,同时乙同步完成了,触发甲的同步,思源目前会直接拿乙修改的 B 覆盖甲的 B,导致编辑内容丢失,且是瞬间发生的,不会有数据快照,如果乙同步完了,甲上线开始打开 B 文档,开始编辑修改,然后点击同步,会直接触发冲突,可怕的是,我们甚至没有在同一时间编辑同一个文档,甚至是在编辑完成之后点击的同步

    这是其中一个悖论,也就是文章中提到的一个本质上无关技术的逻辑问题,而要解决这个逻辑问题,你需要更加复杂的技术去勉强解决

  • zxhd86 1 赞同

    你可以认为是原理上没有问题,实现上有问题。但是事实上来说,因为平台的差异性和边界条件导致的实现有问题,这永远是难以完整考虑的。你说完善,至少我所提到的这几个问题都有在进行完善,比如说在开启的时候先给你设置为只读状态,时间戳只保留到秒,而不是毫秒,这几个都是我看着跟进的。而其他在我不清楚的情况下进行完善的实现更多,那到现在都已经完善了两三年了,可依然还会有人遇到问题,就说明了这个实现的完善有多难了。

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • Akkuman

    关于你说到的有一个中心服务器来协调同步,但其实不可避免还是会遇到你说的 "A 设备和 B 设备当前版本持有不一致,然后同时修改" 的问题,即使有一个中心服务器,如果不对这种冲突情况做处理,还是会出现覆盖的问题。

    从这个角度上来说,s3 和 中心服务器区别并不大,只是基于 s3 的互斥锁并不是完全并发安全的,某些极端情况下会有并发问题出现,这个问题我之前尝试研究过,参见 修正并发情况下锁的正确性 by akkuman · Pull Request #4 · siyuan-note/dejavu (github.com),但是发现无法实现 100% 的并发安全,如果基于中心服务器是可以实现 100% 并发安全的同步互斥锁的

    官方对于你提出的问题目前的方案是依靠快照,来靠用户手动恢复解决冲突,可能看起来有些刀耕火种,不过虽说手动比较麻烦,但是是有效的。

    如果考虑到更现代的,可能需要引入一些冲突合并算法,类似于现代的一些协同编辑软件,使用 OT 或者 CRDT,这样即使是基于 s3,也是能实现协同编辑的效果的。我搜索了一下 issue,好像之前作者已经提出过,但由于开发成本的问题,并没有进行下去。

    2 回复
  • 非常赞同,这种情况确实不可避免的发生,不同的是中心化服务器在面对各种请求处理时,相比 S3,总可以通过更为简单的逻辑来进行快速且实时的操作来解决问题,随之而来的就是成本增加,开发成本与设备成本权衡之下,我现在还是比较认同思源的同步机制的。

  • 关于锁的问题,我其实觉得锁的问题并不是 s3 或者说非中心服务器同步的问题,而是思源独有的问题。因为思源要达成一个在其他备份软件都根本没有考虑到的问题:只下载需要的、最新的快照。

    两个要求共同导致了这种复杂局面:

    第一个导致了思源不能把全部快照全下载下来,这样就不用考虑锁的问题。

    第二个要求导致思源必须要有某种手段得知当前最新的快照是哪一个。

    那很自然的方法是加个元文件,然后围绕这个元文件的读写就变成复杂的并发加锁问题,而且哪怕你的实现毫无问题,一个 s3 cdn 就能让你的设计沦为空谈。

    那有没有绕过的方案呢?其实也是有的,除了每次都下载全部索引,然后挨个确认哪个是最新的,其实一个最简单的方案就是在索引的名称上下功夫,在索引的命名上加入时间戳和 hash 信息,然后想办法获取索引的列表,这样就能在不下载索引的情况下获取最新的索引是那一个了。

    但是这有个新的问题:列出的索引太多怎么办?本地处理肯定没有问题,但云端问题很大,s3 是有最大列出数量限制的,而且数量大了响应也很慢。

    我想出来的处理方案有两个:削减索引的数量,只列出需要的索引。

    我只要保留需要用的索引,那么索引的数量是可以很小的,全部列出来都不会造成很大压力。比如可以按照 restic 的这种方案保留:保留最近的 30 个快照,1 个星期内每天 3 个,3 个月内每天一个,1 年内每周一个,等等。这样能在保证快照可用的情况下,极大削减快照数量,得以保证列出速度。

    不过这个已经 over 了,第一步想要增加删除指定快照能力的 pr 已经被否了。目前来说,下一步也不用考虑了。

    第二个就是只列出指定的索引。s3 是有前缀搜索的 api 的,因此我们只需要把索引的命名中时间戳放在前面,然后比对上一次上传快照的时间戳与当前时间戳的相同部分作为前缀,就能轻松的找到这段时间中云端更新的快照。

    然后这个也 over 了,原因是思源还有 webdav 的支持。webdav 不支持前缀搜索,只支持列出文件夹。要实现类似 s3 前缀搜索的效果,就要修改索引的文件夹结构,把时间戳的一部分作为文件夹,然后列出对应的文件夹。考虑到目前官方对于同步机制的保守意见,我不认为这个 pr 能通过。

    但其实抽象来看,官方的保守态度,其实正是这种情况的具象化:任何对同步的改进都必须面对对当前同步同步效果满意并且不希望有任何不稳定性的用户,而鉴于同步问题的复杂性,在大多数情况下这个问题的答案都是 no。

    综上所述,大抵思源的同步机制在现有情况下,确实没法做到更好了。

    1 操作
    zxhd86 在 2024-10-16 11:58:32 更新了该回帖
  • YRJ0422

    我全都设置成手动同步了,目前还没遇到过同步问题

    1 回复
  • Williamlau

    小白求教一下:

    ① 现在的电脑端的同步云端已经设置好了;

    ② 手机版本也更新最新,但是手机版里面要怎么去同步云端的内容至手机内?

    ③ 关于电脑版本的是不是可以直接用手机在局域网内伺服查阅?如何设置呢?

    期待大神回复~ 万分感谢~

    1 回复
  • DrEgg

    既然思源是单用户的,根据时间戳只采用最后的版本就可以了吧。单用户的话不会出现同时在两个终端修改同一份文档的问题吧。每次修改后只推送修改过的文件,修改前拉取修改的文件,这样应该就可以确保一致性了。

    我没有深入了解思源的同步逻辑,但是我遇到过旧版本的笔记同步到 s3 之后覆盖了我本地的新笔记,这可能是没有基于时间同步机制导致的。思源单用户的特性加上时间戳应该可以做到不错的同步。

    2 回复
  • YRJ0422

    跟电脑一样填好 s3 服务器的内容就行了,秘钥保持一致

  • shanky

    目前用 webdav 进行同步需求,刚开始用内容不多,但是同步真的真的真的真的,狠狠狠慢 😭

    1 回复
  • 该回帖仅作者和楼主可见
    2 回复
    1 操作
    strugglesharp 在 2024-11-06 20:47:23 更新了该回帖
  • wyesheng

    我个人认为,WEBDAV 实际上适合的是小体量的文件同步使用,大文件用到 WEBDAV,会不稳定。建议可以试下 S3,我感觉它 OK。

    1 回复
  • 出门在外使用笔记本编辑思源文件然后没联网进行同步,就会造成了。

    这种场景虽说少,但也不能说就没有了。

  • git 有一个优势:操作的基本上是纯文本文件。也就是内容判断上按照行、字符进行比较就可以。

    思源采用了“JSON”进行存储,对比的时候,还有层级结构上的差异之类的。

    看你这段的时候,我想到了思源能不能直接上下显示冲突内容。比如:

    <======(提示的段落)

    这是旧内容

    =======

    这是新内容

    ======>

    用户如果需要,直接删掉多余的就好。

    但是这样还有 id 重复的问题。

    另外,思源的对比逻辑,应该没到文件内部吧,工作量也不小。


    所以 git 能实现,很大一部分得益于纯文本格式。

    1 回复
  • huaji 所以提供公网能访问的伺服模式,yyds。快来加入光荣的进化吧。

    PS:如果官方要提升,我觉得内部支持填入远端地址,实现从远端读写的模式是唯一可行并且简单的方式了。类似于社区版。

    但是这个方案,能不能做到一个 app 里,有待商榷。

    最后,来吧,PWA 等着你。

  • 错误的,思源就是使用时间机制的,但是很敏感,边界问题很多。举个例子来说,思源正在同步文件回来,这时候你打开了这个文件,光标移动,好,修改了!这下就判定你这个文件更新日期更前了。

    还有一种情况,思源为了使用修改时间进行判断,他会同步过来后修改文件的修改时间以跟快照匹配。举个例子来说,你的文件修改时间是 2024.10.14,10.15 同步到手机上,那实际上你手机上被同步过去的文件修改时间是 10.15。所以思源需要修改这个时间为 10.14,但鬼知道什么原因,这个 api 有时候工作不正常。然后就会判定为更新,进行同步,快照实际内容没有变,但是快照对比一片红,因为 id 变了……

    反正使用更新时间作为判断依据就是现在采用的,但是边界问题确实挺多的。

    1 回复
  • 手机伺服解君愁

  • siyuan 的同步模式就是近似于 git 的 push、pull、merge,客户端、历史记录都有,问题是思源的文件不是这么好合并的……想的简单了点。

    另外,思源需要实现同步量最小,git 的全量模式会同步到你脸皮发麻的。

    1 回复
  • 该回帖仅作者和楼主可见
    1 回复
    2 操作
    strugglesharp 在 2024-11-06 20:46:58 更新了该回帖
    strugglesharp 在 2024-10-17 20:12:27 更新了该回帖
  • 该回帖仅作者和楼主可见
    2 回复
    1 操作
    strugglesharp 在 2024-11-06 20:46:33 更新了该回帖
  • 我插一句,思源的笔记对于 git 来说一样是纯文本,因为.sy 本质上是 json 而已,就像 git 提交普通的程序代码一样,但是,压缩后的.sy 里面的 json 没有换行,只有一整行,也就是说 git 做不到想 diff 代码文件一样一行一行的显示冲突,但是也不是没有办法细粒度的对比差异,可以直接解析 json 来进行细粒度的对比,我估计性能开销会不小,目前思源也暂时还没有这么做,这个就属于逻辑越来越复杂,坑越来越多的情况,表示理解

    2 回复
  • 感觉你并没有理解我的意思,无论怎么说思源在同步笔记数据上都是 git 的加强版。建议可以自行使用 git init 一下尝试效果。

    对同一个大文件反复修改,应该不是常态吧

    我不了解为啥要突出大文件,实际上无论大小,多端同一个文件修改就是造成冲突的问题。

    只要还有同步机制,都要做文件合并机制

    嗯,确实,那是否有看到什么富文本、xml、json 合并的良好方案?目前大概只有纯文本的合并比较好做吧。任何想要离线完成合并操作的,都无法绕过这个问题。在线可以直接云端协调,确保实际上只有一个文件在修改。

    1 回复
  • 解析 json 自动完成合并操作是不现实的,因为这实际上是树的合并,类比到代码中就是生成 ast-patch,你可以看看有哪个软件实现了这个功能。

    或者说,假如发生了文件修改冲突,git 目前的合并机制能保证最后生成的是一个合法的代码文件吗?以我的经验来说,是不能的。

    代码文件的格式合法化要求还低于 json 呢。

    1 回复
  • 不过只要比对……这个其实还行,但是没法展示啊。展示这个 json 界面也很难手动修正,这还不如渲染成 html,然后直接比较不同 html 里 id updated 的区别,然后染色。我记得插件集市里有做到这个的吧

    1 回复
  • 我再插一句,实际上并不只是多端修改同一个文件会导致这样的问题,我亲身测试,甲设备修改 A 文档,乙设备修改 B 文档,然后甲点击同步,甲同步完成之后,乙点击同步,如果乙没有同步完成,甲上线开始打开 B 文档,开始编辑修改,同时乙同步完成了,触发甲的同步,思源目前会直接拿乙修改的 B 覆盖甲的 B,导致编辑内容丢失,且是瞬间发生的,不会有数据快照,如果乙同步完了,甲上线开始打开 B 文档,开始编辑修改,然后点击同步,会直接触发冲突,可怕的是,我们甚至没有在同一时间编辑同一个文档,甚至是在编辑完成之后点击的同步

    这是其中一个悖论,也就是文章中提到的一个本质上无关技术的逻辑问题,而要解决这个逻辑问题,你需要更加复杂的技术去勉强解决

  • 你说的可能是盲合并?但是思源的 json 是有迹可循的啊,远远用不到 AST-patch,自动合并 JSON 并非完全不现实。许多工具和库(例如 jqjsonmergedeepmerge)可以合并 JSON 数据。它们可以按照预定义的规则来合并思源块结构,尽管可能不是处理所有情况的万能方案,但对于多数常见场景,尤其是思源的规则较少的情况,完全可行。

    但是逻辑上还是会越来越复杂,坑越来越多。

    1 回复
  • 其实我觉得无法很好的单线展示差异这个坑是超级块埋下来的,因为它使得思源的 json 拥有了向下无限嵌套的可能性,,,但是我们依然可以继续上手段,只做为文档做一次顶层平行解析,超级块或者其他什么乱七八糟的嵌套都只当做一行,然后提供手动调整平行解析深度的选项,如果想更细粒度的“diff”,就增加深度。

    但是还是我说的,方案永远用不完,逻辑可以无限复杂,坑也会越来越多

  • 粗略看了一下 jsonmerge(python 和 npm 的都看了下)和 deepmerge,我确定起码他们都无法处理同文档块移动的情况,也可能是我看的不完善。

    2 回复
  • 只要嵌套深度不发生改变,你需要考虑的就只有当前内容对比,不需要考虑内容是从哪里来的,到哪里去了。

    如果嵌套深度发生改变,我们也有其他的手段,例如,就像我刚才说的,对于超级块套娃嵌套的取消,我们只关注它最顶层的所有内容,不用非要一次性解析到它最深处。

    1 回复
  • 不是,我是说这种情况:

    a = [{"id":1},{"id":2},{"id":3},{"id":4}]
    
    b = [{"id":4},{"id":3},{"id":2},{"id":1}]
    

    貌似它们都不能处理这种情况

  • 组合一下就行了,一步到位难就打组合拳,jq 提取顶层数据,或用 deepmerge 处理嵌套合并,再结合自定义脚本进一步处理块移动和深度解析,例如顺序重排和解析层数。

    但是我有点疲于探讨到底有什么方案和能不能实现了,因为我一开始想表达的只是,这些都会加剧逻辑复杂度,坑也会越来越多,在我们的客户端本来就不能同时并发和及时互相沟通的情况下,性能可能会不升反降。

    1 操作
    muhanstudio 在 2024-10-17 21:45:53 更新了该回帖
  • 我跟 @zxhd86 讨论过,技术方案都有,但稳定可行、简单易实现的方案没有。

    如果你们觉得有方案能实现既保留 A 设备留下的 1-1-1,也能保留 B 设备留下的移动操作,并且还能保证 id 不重复,以及引用 1-1 的块引不出问题,我很高兴听到回答。

    image.png

    @strugglesharp


    关于 @zxhd86 提到的案例。

    @muhanstudio 你说组合一些就行,跟我提的这个案例差不多。如何组合?保留两个 id 相同的节点?如果不保留,那么引用了 id: 2 的块引,最终引用的结果应该是哪个?

    我的结论:

    我是伺服党,甚至半年多,马上要一年没关心过同步这件事了。

    哪怕只是在本机单独使用时,我也遇到过数据丢了的情况。

    2 回复
  • DrEgg

    这感觉是实现有没有考虑的部分,时间同步本身没有问题,只是实现机制有问题。如果能完善基于时间的同步机制,应该会好很多吧

    1 回复
  • zxhd86 1 赞同

    你可以认为是原理上没有问题,实现上有问题。但是事实上来说,因为平台的差异性和边界条件导致的实现有问题,这永远是难以完整考虑的。你说完善,至少我所提到的这几个问题都有在进行完善,比如说在开启的时候先给你设置为只读状态,时间戳只保留到秒,而不是毫秒,这几个都是我看着跟进的。而其他在我不清楚的情况下进行完善的实现更多,那到现在都已经完善了两三年了,可依然还会有人遇到问题,就说明了这个实现的完善有多难了。

  • 该回帖仅作者和楼主可见
    2 回复
    1 操作
    strugglesharp 在 2024-11-06 20:45:45 更新了该回帖
  • shanky 1 评论

    哦哦,有免费的 s3 可以试用吗?😋

    2 回复
    S3 很便宜的,免费的就没必要了
    JeffreyChen 1 赞同
  • 有没有可能,你说的就是思源当前的解决方案?不要对你完全不了解的事情加以评价啊……正常人能想到的、能遇到的坑在这两年都填过了,现在想要的解决方案是当前方案的所达不到的上限,任何分布式的同步方案都无法解决的东西。思源的机制在笔记场景上就是威力加强版的 git,原版的 git 除了导致大文件的同步效果暴跌、同步量暴涨外不会有任何新的区别,有也是负面的。除非,上 crdt。

  • Godsing

    阿里云在非大陆地区(例如香港)有提供免费的 5GB 空间,流量又不收费,反正我用来存笔记够够的了。

    1 回复
  • 同步时需要用代理吗

  • huaji 咱就是说,有没有可能现在的思源就是,假设 A 出现冲突了,直接就会生成两个 A 文件在那呢?

    思源目前的粒度已经到文件级别了,如果产生冲突,会在原文档的位置产生一篇同名带 conflict 后缀的文档,用户可以自行选择要保留的内容。

    至于实现文件内部逐块对比的级别,至少近期(1~2 年)我觉得不太可能。

  • wyesheng

    可以自建一个。WINDOWS 平台的就 OK 了。

  • 需要一个监听主,否则每个客户端即使拉取同一份数据,由于自己的数据不是都一样的,里面最后就会各有各的保留决策,如果有一个监听主,或者决策主,就好多了

请输入回帖内容 ...