大家好,我是前端西瓜哥,今天我们来聊聊 OT 算法是什么。

OT 的英文全称是 Operational transformation,是一种处理协同编辑的算法。

它常用于实现协同文档的底层算法,支持多个用户同时编辑文档,不会因为并发修改导致冲突,而使结果不一致或数据丢失。

冲突的处理方式

假设 A 和 B 在同时编辑同一个内容,我们处理冲突的方式有:

  1. 加锁。用户 A 在编辑时,就锁住文档,只能 A 进行更新。用户 B 就不能编辑,或编辑后提交修改被服务器丢弃;

  2. 覆盖。谁最后修改,就全量使用他的修改,更早一些的其他人的修改会被丢弃。

  3. 用户自行处理冲突。就像 git merge 导致的冲突一样,会提示哪个地方被同时修改了,让合并者手动选择使用哪一个修改;

  4. 使用一致性算法。比如我们要介绍的 OT 算法,可以让用户编辑进行算法处理进行调整,在多个客户端生成一致的修改结果。

对于在线协同文档,

加锁体验太差,一个人在编辑时其他人就要干等着。

覆盖则是导致用户的修改来回彼此覆盖,辛苦编辑的内容突然被别人覆盖掉了心情低落。

自行处理冲突则需要额外的操作步骤和成本,实时性很差,不适合高频同时修改的场景。

一致性算法是最好的选择,对用户最友好,不过带来了实现的复杂。

一致性问题

我们先来看看不使用 OT 导致的冲突问题。

假设用户 A 和用户 B 同时在编辑同一个文档,文档内容为 “12”。

  1. 用户 A 在末尾添加一个字符 “A”,这个修改先应用在本地,内容变成了 “12A”,之后客户端发送一个数据 insert(2, "A") 给服务端,代表在位置 2 的地方插入 “A”。服务端会将修改消息推送给其他客户端,但这需要时间;

  2. 用户 B 在收到推送消息前,也在 “12” 的尾部添加了内容 “B”,在本地变成了 “12B”,并将 insert(2, "B") 的修改描述提交服务器;

  3. 用户 B 收到了 insert(2, "A") 消息,应用后,将 “12B” 变成了 “12AB”;

  4. 用户 A 则收到 insert(2, "B") 消息,应用后,将 “12B” 变成了 “12BA”;

结果是,用户 A 看到的内容是 “12BA”,用户 B 看到的内容是 “12AB”,内容不一致,不符合预期。

使用 OT

OT 算法可以解决一致性问题,我们来看看 OT 到底做了什么。

同样,原始内容是 “12”。

  1. 用户 A 在末尾添加 “A”,本地变成 “12A”,并发送 insert(2, A),这个操作计作 OA;

  2. 用户 B 在末尾添加 “B”,本地变成 “12B”,并发送 insert(2, B),这个操作计作 OB;

  3. 用户 A 收到 OB,执行 transform(OA, OB),得到修正后的操作 insert(3, B),记为 OB’,相比 OB,它将插入位置从 2 修正为 3,于是 “12A” 变成了 “12AB”;

  4. 用户 B 则收到 OA,同样执行 transform(OA, OB),得到修正操作 insert(2, A),记为 O1’,让内容从 “12A” 变成 “12AB”。transform 方法会同时产生 OA’ 和 OB’。

最后,用户 A 和用户 B 看到的是 一致 的 “12AB”。

这里的核心在于这个 transfrom 方法,它能够对操作进行修正。transform 没有固定实现,要根据实际需求自行实现。

这里有一个经典的菱形示意图。

从起始版本 T 开始,它接受了两个 并发操作 A 和 B。我们使用 trasform 方法生成 A’ 和 B’。我们有:

S + A + B' = T
S + B + A' = T

这样,从 S 得到相同的 T,保证了一致性。

下面使用了 ot.js 库,演示了一下从 ‘12’ 到 ‘12AB’ 的过程。

const s = '12'; // 原始文案(版本 1)// 在位置 3 插入 'A'
const oA = new TextOperation().retain(2).insert('A');// 上述操作后得到结果 '12A'(版本 2)
const t1 = oA.apply(s);// 收到 oB 操作:在位置 2 插入 'B'
const oB = new TextOperation().retain(2).insert('B');// transform 拿到修正后的 [oA', oB']
// 我们这里只需要 oB',它被修正为在位置 3 插入 'B'
const [oAp, oBp] = TextOperation.transform(oA, oB);// 应用 oB',结果为:12AB (版本 3)
const t2 = oBp.apply(t1);

线上 demo 链接为:

https:/ /codesandbox.io/s/b8ds8h

transform 操作既发生在服务端:将基于某个版本的并发操作对象转换成串行操作。

也发生在客户端,本地的修改还没来得及提交,就收到了服务端推送。

如果你想要深入研究 OT 算法,可以考虑参考 ot.js 库的代码实现,里面还附带了一个 OT 可视化过程

https:/ /github.com/Operational-Transformation/ot.js/

结尾

OT 算法能够在实时保证多个客户端数据的一致性,被广泛用于协同编辑场景。

我是前端西瓜哥,欢迎关注我,学习更多前端知识。

协同编辑中使用的 OT 算法是什么?相关推荐

  1. Yjs + quill:快速实现支持协同编辑的富文本编辑器

    大家好,我是前端西瓜哥,这次来看看 Yjs 如何帮助我们实现协同编辑能力的. Y.js 是一个支持 协同编辑 的开源库.只要我们将自己的数据转换为 Y.js 提供的 Y.Array.Y.Map 类型, ...

  2. Confluence 6 管理协同编辑

    2019独角兽企业重金招聘Python工程师标准>>> 协同编辑能够让项目小组中的协同合作达到下一个高度.这个页面对相关协同编辑中的问题进行了讨论,能够提供给你所有希望了解的内容. ...

  3. Confluence 6 管理协同编辑 - 关于 Synchrony

    协同编辑能够让项目小组中的协同合作达到下一个高度.这个页面对相关协同编辑中的问题进行了讨论,能够提供给你所有希望了解的内容. 进入 Collaborative editing 页面来获得项目小组是如何 ...

  4. OT算法在协同编辑器中的应用

    1 背景 最近3年疫情的原因,导致面试者无法现场面试,于是远程面试成了当前面试的主流.对于开发岗位来说,写代码那是必须可少的功能,所以完善的面试系统有一个重要功能就是协同编辑,下面就让我来带大家分析一 ...

  5. 手把手玩转协同编辑(1):AST (Address Space Transformation)地址空间转换算法 基本介绍...

    写在前面的话 加入实验室已经有大半年的时间了,科研上一直没有取得什么重大突破.除去自身的实力问题之外,最大的问题恐怕就是对于自己或导师提出的一个问题往往不知道从何入手去研究,如何快速的了解相关工作的现 ...

  6. 在线协作编辑OT算法简介

    一.背景 在线文档,简单的来说,这些产品的模式都是富文本编辑器+后台,富文本编辑器产生内容.展示内容,然后后台负责保存. 富文本编辑器的产品和技术已经非常成熟了,像codeMirror,当然本身实现也 ...

  7. 再谈OT算法的协同文档制作的底层基础架构记录

    关于OT算法的协同的核心算法部分已经写完了. 再简单谈一下关于协同文档底层架构的问题,因为目前我的方案还没有最终落地所以并不清楚实际情况中会出现哪些问题, 说一下传输层,传输层是用的MQTT,得益于R ...

  8. 由树莓派折腾中联想到的一个需求---基于Wiki的分布式协同编辑百科学习笔记本

    我的树莓派学习笔记- 上述是我的树莓派学习笔记,知识爆炸时代,我发现很多东西已经有人做了一个开头,而单个人的精力时间是有限的,所以当先辈前赴后继开拓的时候,我们应该善于利用已有的资源进一步前行,站在别 ...

  9. word 编辑过程中变为只读_WPS?教程 | WPS?云办公如何多人协同编辑

    WPS⁺云办公是金山办公为企业提供的一站式云办公SaaS服务,包括多平台的WPS Office.云端存储.协同办公.移动会议.企业管理后台等模块,为满足企业随时随地.安全高效办公提供解决方案. WPS ...

  10. 因为某种原因阻止文本引擎初始化_文本文档的协同编辑实现

    背景 atom 编辑器新增一个 teletype 的功能,可以实现多人在线编辑代码.效果看起来挺炫酷,想了解一下是怎么实现的,于是研究了一下. 抽象一下文本文档的协同编辑这个问题,就是同步多个设备之间 ...

最新文章

  1. java 读取远程文件夹_java读取远程共享文件 | 学步园
  2. java的三种代理模式
  3. 【官方文档】《暗黑世界V1.4》API说明!
  4. Linux显示中文乱码解决方法
  5. PC智能自媒体高效运营管理工具
  6. deepdive连接mysql数据库_如何从Error Code获取Message
  7. 有人说智能制造装备前景大好,那么智能制造装备产业园的潜力如何?
  8. c++用数组初始化向量_用C ++初始化向量
  9. 2018-2019-2 20162318《网络对抗技术》Exp2 后门原理与实践
  10. Android Framework 全面分析 FallbackHome
  11. 增长率用计算机怎么算,操作方法:Excel使用公式来计算增长率教程
  12. 如何修改host文件权限
  13. Minio Utils
  14. bash:/home/xxxx/catikin_ws/setup.bash:没有那个文件或者目录
  15. 计算机操作系统--Linux初试03
  16. FastDFS文件同步机制分析
  17. windows XP无法使用suspend to RAM (s3)功能的解决过程
  18. drools rule (三) RHS语法详解
  19. 手把手教您搭建 AWS 大数据云平台
  20. 计算机可以辅助英语写作吗,计算机辅助大学英语写作

热门文章

  1. Linux 误删文件后恢复文件
  2. Mac常用快捷键组合
  3. PS人像磨皮——高低频修图法
  4. python将PDF文件转换为图片
  5. python图像的手绘效果代码_python实现手绘效果图
  6. 努比亚 Z17s (Nubia NX595J) 解锁BootLoader 并刷入recovery ROOT
  7. springboot实现短信验证码登录注册
  8. centos7 yum安装时遇到错误:Header V3 RSA/SHA256 Signature, key ID 352c64e5: NOKEY
  9. java动态二维数组定义_Java动态定义二维数组问题
  10. Excel怎么设置单元格的边框