”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 了解无冲突复制数据类型

了解无冲突复制数据类型

发布于2024-11-07
浏览:120

无冲突复制数据类型 (CRDT) 是一类数据结构,可在分布式系统中实现无缝协作和数据同步,从而实现无冲突的协作更新。 CRDT 旨在实现跨多个数据副本的最终一致性,确保即使更新独立发生,所有副本也能收敛到相同状态,而不需要复杂的冲突解决机制。

在这篇博文中,我们将深入研究 CRDT 是什么,探索它们的用途和类型,了解它们的工作原理,并学习如何实现它们,重点关注 JavaScript 和强大的 Yjs 库。

CRDT 的用例

CRDT 在实时协作和离线支持至关重要的场景中特别有用:

  1. 协作文本编辑器:Google Docs、Notion 和 Etherpad 使用类似 CRDT 的结构进行实时编辑。
  2. 协作设计工具:Figma 是一种流行的基于 Web 的设计工具,它使用 CRDT 来实现设计项目的实时协作。多个设计人员可以同时处理同一个文件,所有用户之间的更改可以无缝同步。
  3. 分布式数据库:RxDB 和 Riak 使用 CRDT 进行无冲突复制。
  4. 多人游戏:用于保持玩家之间一致的游戏状态。

CRDT 的类型

CRDT 主要有两种类型:

  1. 基于状态的 CRDT:它们复制数据结构的整个状态。合并是通过比较和协调不同副本的状态来完成的。
  2. 基于操作的 CRDT:它们复制对数据结构执行的操作。合并是通过以交换方式应用来自不同副本的操作来完成的。

CRDT 的工作原理

CRDT(无冲突复制数据类型)的运行原理可确保所有数据副本的最终一致性,即使是同时进行更新或发生网络分区时也是如此。让我们更深入地研究一下机制:

主要特性

  1. 交换性:该属性确保运算顺序不会影响最终结果。例如,在计数器 CRDT 中,先递增 2,然后再递增 3,与先递增 3,然后再递增 2 产生的结果相同。
  2. 关联性:这意味着操作的分组并不重要。再次使用计数器示例,(1 2) 3 与 1 (2 3) 相同。
  3. 幂等性:多次应用相同的操作与应用一次效果相同。这对于处理分布式系统中的重复消息至关重要。

冲突解决

CRDT 通过设计自动解决冲突:

  • 对于基于状态的 CRDT (CvRDT),这是通过组合两个副本的状态的合并函数来实现的。此合并函数必须是可交换的、关联的和幂等的。
  • 对于基于操作的 CRDT (CmRDT),操作被设计为可交换的,确保以任何顺序应用它们都会导致相同的最终状态。

逻辑时钟

许多 CRDT 实现使用逻辑时钟(例如版本向量或点分版本向量)来跟踪操作的因果历史。这有助于确定并发操作的顺序以及确定副本已经看到哪些更新。

在 JavaScript 中使用 CRDT 和 Yjs

从头开始实施 CRDT 可能很复杂。但是,有一些库可以简化该过程。对于 JavaScript,最流行的 CRDT 库之一是 Yjs。它是一个高性能的CRDT实现,支持各种数据类型。让我们使用 Yjs 创建一个简单的待办事项列表应用程序,模拟多个用户处理内存中的同一文档。

下面是如何使用 Yjs 实现共享待办事项列表的示例:
Understanding Conflict-Free Replicated Data Types

让我们使用创建的 ydocs :
Understanding Conflict-Free Replicated Data Types

在此示例中,我们创建两个 Yjs 文档(ydoc1 和 ydoc2)来模拟两个用户处理同一待办事项列表。每个文档都有自己的待办事项共享地图。

我们定义了添加、更新和删除待办事项的函数,以及用于手动同步两个文档之间的状态的syncDocs函数。这模拟了在客户端之间交换更新的网络环境中会发生的情况。

结论

CRDT 为构建可在线和离线无缝工作的协作分布式应用程序提供了强大的解决方案。虽然底层概念可能很复杂,但像 Yjs 这样的库使开发人员可以更轻松地在其应用程序中利用 CRDT 的强大功能。随着分布式系统变得越来越普遍,理解和利用 CRDT 将成为开发人员越来越有价值的技能。

有用的链接

  1. Yjs
  2. CRDT
  3. Tiptap - 协作文本编辑器
版本声明 本文转载于:https://dev.to/adityasajoo/understanding-conflict-free-replicated-data-types-57jc?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 大批
    大批
    [2 数组是对象,因此它们在JS中也具有方法。 切片(开始):在新数组中提取部分数组,而无需突变原始数组。 令ARR = ['a','b','c','d','e']; // USECASE:提取直到索引作...
    编程 发布于2025-04-06
  • 找到最大计数时,如何解决mySQL中的“组函数\”错误的“无效使用”?
    找到最大计数时,如何解决mySQL中的“组函数\”错误的“无效使用”?
    如何在mySQL中使用mySql 检索最大计数,您可能会遇到一个问题,您可能会在尝试使用以下命令:理解错误正确找到由名称列分组的值的最大计数,请使用以下修改后的查询: 计数(*)为c 来自EMP1 按名称组 c desc订购 限制1 查询说明 select语句提取名称列和每个名称...
    编程 发布于2025-04-06
  • 为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    在CSS 问题:不正确的代码: 全球范围将所有余量重置为零,如提供的代码所建议的,可能会导致意外的副作用。解决特定的保证金问题是更建议的。 例如,在提供的示例中,将以下代码添加到CSS中,将解决余量问题: body H1 { 保证金顶:-40px; } 此方法更精确,避免了由全局保证金重置引...
    编程 发布于2025-04-06
  • 如何将来自三个MySQL表的数据组合到新表中?
    如何将来自三个MySQL表的数据组合到新表中?
    mysql:从三个表和列的新表创建新表 答案:为了实现这一目标,您可以利用一个3-way Join。 选择p。*,d.content作为年龄 来自人为p的人 加入d.person_id = p.id上的d的详细信息 加入T.Id = d.detail_id的分类法 其中t.taxonomy =...
    编程 发布于2025-04-06
  • 如何处理PHP文件系统功能中的UTF-8文件名?
    如何处理PHP文件系统功能中的UTF-8文件名?
    在PHP的Filesystem functions中处理UTF-8 FileNames 在使用PHP的MKDIR函数中含有UTF-8字符的文件很多flusf-8字符时,您可能会在Windows Explorer中遇到comploreer grounder grounder grounder gro...
    编程 发布于2025-04-06
  • 如何有效地转换PHP中的时区?
    如何有效地转换PHP中的时区?
    在PHP 利用dateTime对象和functions DateTime对象及其相应的功能别名为时区转换提供方便的方法。例如: //定义用户的时区 date_default_timezone_set('欧洲/伦敦'); //创建DateTime对象 $ dateTime = ne...
    编程 发布于2025-04-06
  • 如何在Java中正确显示“ DD/MM/YYYY HH:MM:SS.SS”格式的当前日期和时间?
    如何在Java中正确显示“ DD/MM/YYYY HH:MM:SS.SS”格式的当前日期和时间?
    如何在“ dd/mm/yyyy hh:mm:mm:ss.ss”格式“ gormat 解决方案: args)抛出异常{ 日历cal = calendar.getInstance(); SimpleDateFormat SDF =新的SimpleDateFormat(“...
    编程 发布于2025-04-06
  • 在GO中构造SQL查询时,如何安全地加入文本和值?
    在GO中构造SQL查询时,如何安全地加入文本和值?
    在go中构造文本sql查询时,在go sql queries 中,在使用conting and contement和contement consem per时,尤其是在使用integer per当per当per时,per per per当per. [&​​&&&&&&&&&&&&&&&默元组方法在...
    编程 发布于2025-04-06
  • Python读取CSV文件UnicodeDecodeError终极解决方法
    Python读取CSV文件UnicodeDecodeError终极解决方法
    在试图使用已内置的CSV模块读取Python中时,CSV文件中的Unicode Decode Decode Decode Decode decode Error读取,您可能会遇到错误的错误:无法解码字节 在位置2-3中:截断\ uxxxxxxxx逃脱当CSV文件包含特殊字符或Unicode的路径逃...
    编程 发布于2025-04-06
  • 如何使用Depimal.parse()中的指数表示法中的数字?
    如何使用Depimal.parse()中的指数表示法中的数字?
    在尝试使用Decimal.parse(“ 1.2345e-02”中的指数符号表示法表示的字符串时,您可能会遇到错误。这是因为默认解析方法无法识别指数符号。 成功解析这样的字符串,您需要明确指定它代表浮点数。您可以使用numbersTyles.Float样式进行此操作,如下所示:[&& && && ...
    编程 发布于2025-04-06
  • 如何使用“ JSON”软件包解析JSON阵列?
    如何使用“ JSON”软件包解析JSON阵列?
    parsing JSON与JSON软件包 QUALDALS:考虑以下go代码:字符串 } func main(){ datajson:=`[“ 1”,“ 2”,“ 3”]`` arr:= jsontype {} 摘要:= = json.unmarshal([] byte(...
    编程 发布于2025-04-06
  • 您可以使用CSS在Chrome和Firefox中染色控制台输出吗?
    您可以使用CSS在Chrome和Firefox中染色控制台输出吗?
    在javascript console 中显示颜色是可以使用chrome的控制台显示彩色文本,例如红色的redors,for for for for错误消息?回答是的,可以使用CSS将颜色添加到Chrome和Firefox中的控制台显示的消息(版本31或更高版本)中。要实现这一目标,请使用以下模...
    编程 发布于2025-04-06
  • 如何使用PHP从XML文件中有效地检索属性值?
    如何使用PHP从XML文件中有效地检索属性值?
    从php PHP陷入困境。使用simplexmlelement :: attributes()函数提供了简单的解决方案。此函数可访问对XML元素作为关联数组的属性: - > attributes()为$ attributeName => $ attributeValue){ echo ...
    编程 发布于2025-04-06
  • 如何使用Regex在PHP中有效地提取括号内的文本
    如何使用Regex在PHP中有效地提取括号内的文本
    php:在括号内提取文本在处理括号内的文本时,找到最有效的解决方案是必不可少的。一种方法是利用PHP的字符串操作函数,如下所示: 作为替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式来搜索特...
    编程 发布于2025-04-06
  • HTML格式标签
    HTML格式标签
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    编程 发布于2025-04-06

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3