Google Docs系统设计

news2024/11/30 15:28:27

1 简介

谷歌文档是一种协作文档编辑服务。

协作文档编辑服务可以通过两种方式设计:

  • 设计为C/S架构的集中式设施,为所有用户提供文档编辑服务
  • 使用点对点技术设计,以便在单个文档上协作

大多数商业解决方案侧重于客户端服务体系结构,以实现更精细的控制。因此,我们将关注使用客户端服务体系结构设计服务。让我们看看在这一章节中我们将如何进展。

2 需求

2.1 功能性

文档协作

多用户应该能够同时编辑文档。此外,大量用户应该能够查看文档。

冲突解决

系统应该将一个用户做的编辑推送给所有其他协作者。如果他们正在编辑文档的同一部分,系统还应解析用户之间的冲突。

建议

用户应该能够获得有关在文档中完成常用单词、短语和关键词的建议,以及有关修复语法错误的建议。

查看计数

文档的编辑应能够看到该文档的查看计数。

历史

用户应该能够查看文档上的协作历史。

2.2 非功能性

延迟

不同的用户可以连接起来协作同一份文档。为来自不同区域的用户维护低延迟是具有挑战性的。

一致性

系统应能够解析用户并发编辑文档时之间的冲突,从而实现文档的一致视图。与此同时,不同区域的用户应看到文档的更新状态。对于连接到同一区域和不同区域的用户来说,保持一致性都是重要的。

可用性

该服务应该一直可用,并展示出对故障的鲁棒性。

可扩展性

大量用户应该能够同时使用该服务。他们可以查看相同的文档,也可以创建新文档。

3 组件

3.1 数据存储

  • 关系数据库 —— 用于保存用户信息和文档相关信息以施加特权限制

  • NOSQL —— 用于存储用户评论以获得更快的访问速度

  • 时间序列 —— 用于保存文档的编辑历史记录

  • Blob 存储 —— 用于存储文档中的视频和图像

  • 缓存 —— 分布式缓存,如 Redis 和 CDN,为最终用户提供良好的性能。使用 Redis存储不同的数据结构,包括用户会话、类型预期服务的功能、频繁访问的文档。CDN存储频繁访问的文档和重量级对象如图像和视频。

处理队列

针对每次微小字符更改使用 HTTP 调用是低效的。因此使用 WebSockets 减少开销,并通过不同用户实时观察文档的更改。

其他组件

其他组件包括会话服务器,维护用户的会话信息。通过会话服务器管理文档访问权限。本质上,还将有配置、监控、发布-订阅和日志记录服务来处理监控任务,如在服务器失败时监控和选举领导者,排队用户通知等任务,以及记录调试信息。

图 1.0: 协作文档编辑服务的详细设计:

4 工作流程

4.1 协作编辑和冲突解决

每个请求都会转发到操作队列。这是解析同一文档的不同协作者之间冲突的地方。如果没有冲突,则通过会话服务器将数据批量存储在时间序列数据库中。像视频和图像这样的数据会被压缩以优化存储,而字符会被立即处理。 历史:借助时间序列数据库,可以恢复文档的不同版本。可以使用 DIFF 操作来比较版本并标识差异以恢复同一文档的旧版本。

4.2 异步操作

通知、电子邮件、查看次数和评论都是可以通过像 Kafka 这样的发布-订阅组件排队的异步操作。API 网关生成这些请求并将它们转发到发布-订阅模块。

4.3 建议

建议以类型提前服务(typeahead service)的形式出现,该服务提供通常使用的单词和短语的自动完成功能。类型提前服务还可以从文档中提取属性和关键词并向用户提供建议。由于单词数量可能很高,我们将为此目的使用 NoSQL 数据库。此外,最常用的单词和短语将存储在像 Redis 这样的缓存系统中。

导入和导出文档

应用程序服务器执行许多重要任务,包括导入和导出文档。应用程序服务器还将文档从一种格式转换为另一种格式。例如,.doc 或 .docx 文档可以转换为 .pdf 或反之亦然。应用程序服务器也负责为类型预期服务提取特征。

5 详细设计

5.1 文档编辑器

文档由以特定顺序排列的字符组成。每个字符都有一个值和一个位置索引。字符可以是字母、数字、回车()或空格。索引表示字符在有序字符列表中的位置。

文本或文档编辑器的作用是在文档中的字符上执行插入()、删除()、编辑()等操作。下面是文档的描绘以及编辑器将如何执行这些操作。

文档编辑器如何执行各种操作

5.2 并发性

不同用户对同一文档的协作可能导致并发问题。若多个用户编辑文档的同一部分,可能出现冲突。由于用户在本地有文档的副本,服务器上的最终文档状态可能与用户在他们端看到的不同。在服务器推送更新版本后,用户会发现意外结果。

① 在同一位置索引处添加字符

两个用户修改同一字符可能导致并发问题:

② 删除同一字符

删除同一字符,可能导致意外更改:

第二个例子表明,不同用户应用相同的操作不会是幂等的。因此,在多个协作者同时编辑文档同一部分时,需冲突解决。

协作编辑中并发问题的解决方案应遵循规则:

  • 交换律:应用操作的顺序不应影响最终结果
  • 幂等性:重复的相似操作只应用一次

6 冲突解决技术

6.1 操作转换(OT)

广泛用于协作编辑中的冲突解决的技术,一种【无锁】、【非阻塞】的冲突解决方法。若协作者之间的操作冲突,OT会解析冲突并将正确的汇聚状态推给最终用户。因此,OT为用户提供一致性。

OT 使用位置索引方法执行操作来解析上面讨论的那些冲突。通过保持交换律、幂等性来解决上述问题。

OT示例:

基于 OT 的协作编辑器在满足以下两个属性时一致:

  • 因果关系保持:如果操作 a 发生在操作 b 前,那先执行操作 a,然后执行操作 b
  • 收敛:不同客户端上的所有文档副本最终相同

上述属性是 CC 一致性模型的一部分,CC 一致性模型是协作编辑中一致性维护的模型。

OT的缺点

对字符的每个操作都可能需要更改位置索引。这意味着操作之间存在顺序依赖关系。它的开发和实现具有挑战性。

OT是一组复杂算法,其正确实现在实际应用中已被证明有挑战性。Google Wave 团队花两年时间实现OT。

6.2 无冲突复制数据类型 (CRDT)

是为了改进 OT。CRDT 具有:

  • 复杂的数据结构
  • 但简化的算法

CRDT 通过为每个字符分配两个关键属性来满足交换律和幂等性:

  • 为每个字符赋予全局唯一标识
  • 全局订购每个字符

每个操作现在都有一个更新后的数据结构:CRDT 简化的数据结构

SiteID 唯一标识请求操作的用户站点,带有一个值和一个 PositionalIndex。PositionalIndex值可以是分数:

  • 某些操作不会改变其他字符的 PositionalIndex
  • 避免不同用户操作之间的顺序依赖性

示例描绘来自站点 ID 123e4567-e89b-12d3 的用户在 PositionalIndex 为 1.5 的位置插入一个值为 A 的字符。尽管添加了新字符,但使用小数索引保留了现有字符的位置索引。因此,避免了操作之间的顺序依赖性。如下所示,在 O 和 T 之间插入()并没有影响 T 的位置。

防止操作之间的顺序依赖性:

CRDT 确保用户之间的强一致性。即使一些用户处于离线状态,当他们重新联机时,最终用户处的本地副本也将汇聚。

尽管众所周知的在线编辑平台如 Google 文档、Etherpad 和 Firepad 使用 OT,但 CRDT 使协作文档编辑中的并发和一致性变得容易。事实上,使用 CRDT,可以实现无服务器点对点协作文档编辑服务。

注意

OT 和 CRDT 是协作编辑中冲突解决的良好解决方案,但我们使用 WebSockets 可以突出显示协作者的光标。其他用户将预期协作者的下一个操作的位置,并自然避免冲突。

7 评估

一致性

操作转换(OT)和冲突不定决议数据类型(CRDT)在文档中实现冲突解决的强一致性。

时间序列数据库能保留事件的顺序。一旦 OT 或 CRDT 解析了任何冲突,最终结果就保存在数据库。这有助我们在单个操作方面实现一致性。

在IDC内的不同服务器之间保持文档状态的一致性。要在同一IDC内同时复制更新后的文档状态,可使用 Gossip 协议这样的点对点协议。这不仅提高一致性,还会提高可用性。

可用性

我们的设计通过使用副本以及使用监控服务监控主副本服务器来确保可用性。操作队列和数据存储等关键组件在内部管理自己的复制。

由于使用 WebSockets,WebSocket 服务器可将用户连接到会话维护服务器,这些服务器将确定用户是否正在主动查看或协作文档。

因此,保留多个 WebSocket 服务器将增加设计的可用性。最后,采用缓存服务和 CDN 改进可用性。

可扩展性

由于使用微服务,若操作队列的请求数量超过其容量,可轻松单独扩展每个组件。可使用多个操作队列。此时,每个操作队列将负责单个文档。可将不同用户请求的与单个文档相关的操作转发到特定队列。生成的队列数量将等于活动文档的数量。因此可实现水平扩展性。

参考:

  • https://medium.com/@sureshpodeti/system-design-google-docs-93e12133a979

    本文由博客一文多发平台 OpenWrite 发布!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1255822.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

物联网AI 无线连接学习之蓝牙基础篇 协议概述

学物联网,来万物简单IoT物联网!! 1 蓝牙协议总体架构 1.1 Application层 应用属性层,通过API函数与协议栈交互; 1.2 Host层 Host层,逻辑链路控制及自适应协议层、安全管理层、属性协议层、通用访问配置…

Stable Diffusion绘画系列【1】:炫酷机甲美女

《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…

Linux系统编程 day05 进程控制

Linux系统编程 day05 进程控制 1. 进程相关概念2. 创建进程3. exec函数族4. 进程回收 1. 进程相关概念 程序就是编译好的二进制文件,在磁盘上,占用磁盘空间。程序是一个静态的概念。进程即使启动了的程序,进程会占用系统资源,如内…

win11任务栏居中/靠左设置路径

win11任务栏居中/靠左设置路径 设置-个性化-任务栏-任务栏对齐方式

Proteus仿真--基于字符液晶显示的频率计

本文介绍基于数码管的频率计(完整仿真源文件及代码见文末链接) 仿真图如下 本设计中80C51单片机作为主控,用字符液晶作为显示模块,按下按键K1后可进行频率测量并显示 仿真运行视频 Proteus仿真--基于字符液晶显示的频率计 附完…

只狼 资源分享

版本介绍 v1.06版|容量15GB|官方简体中文|支持键盘.鼠标.手柄|赠官方原声4首BGM|赠多项修改器|赠一周目全义手忍具强化通关存档|2020年01月15号更新 只狼中文设置: https://jingyan.baidu.com/article/cb5d6105bc8556005d2fe048.html 只狼键盘对应按键&#xff1…

6.1 Windows驱动开发:内核枚举SSDT表基址

SSDT表(System Service Descriptor Table)是Windows操作系统内核中的关键组成部分,负责存储系统服务调用的相关信息。具体而言,SSDT表包含了系统调用的函数地址以及其他与系统服务相关的信息。每个系统调用对应SSDT表中的一个表项…

RocketMQ相关概念与使用入门详解

文章目录 RocketMQ 相关概念消息模型MQ 的简单消息模型RocketMQ 的复杂消息模型 RocketMQ 中消息相关概念消息(Message)主题(Topic)Tags队列消息标识 RocketMQ 中的物理对象NameServerBrokerProducerConsumer NameServer 与 Broke…

ARM推出Cortex-M85的小弟Cortex-M52, 集低功耗,低成本和单片机AI于一身

Cortex-M52特色: 1、基于ARMv8.1-M架构的内核已经有M55和M85. 新出的M52是采用Arm Helium 技术的最小处理器,可提供出色的低功耗,为物联网提供低成本和高性能AI技术。 2、Cortex-M52 专为需要提高数字信号处理和机器学习性能的 AIoT 应用而…

王者荣耀Java

代码 package com.sxt;import javax.swing.*; import java.awt.*;public class Background extends GameObject {public Background(GameFrame gameFrame) {super(gameFrame);// TODO Auto-generated constructor stub}Image bg Toolkit.getDefaultToolkit().getImage("…

《C++PrimePlus》第10章 对象和类

10.1 过程性编程和面向对象编程 10.2 抽象和类 10.3 类的构造函数和析构函数 类的定义和使用&#xff08;买卖股票&#xff09; 头文件stock10.h #ifndef __STOCK00__H__ #define __STOCK00__H__#include <string>class Stock { // pravate的内容只能通过public访问 p…

王者荣耀java版

主要功能 键盘W,A,S,D键&#xff1a;控制玩家上下左右移动。按钮一&#xff1a;控制英雄发射一个矩形攻击红方小兵。按钮二&#xff1a;控制英雄发射魅惑技能&#xff0c;伤害小兵并让小兵停止移动。技能三&#xff1a;攻击多个敌人并让小兵停止移动。普攻&#xff1a;对小兵造…

坚鹏:广州银行清华大学消费金融发展趋势与创新培训圆满结束

广州银行自1996年9月成立以来&#xff0c;依托中国经济腾飞的大好形势&#xff0c;成为国内具有一定知名度与地方特色的商业银行。截至2022年12月末&#xff0c;已开业机构174家&#xff0c;包括总行1家&#xff0c;分行级机构15家(含信用卡中心)、支行152家、信用卡分中心6家&…

STM32 外部中断配置与中断函数设计

单片机学习 目录 文章目录 一、外部中断配置步骤 1.1配置RCC 1.2配置GPIO 1.3配置AFIO 1.4配置EXTI 1.5配置NVIC 二、中断函数设计 总结 一、外部中断配置步骤 第一步&#xff1a;配置RCC&#xff0c;把涉及外设的时钟打开。第二步&#xff1a;配置GPIO&#xff0c;选择…

企业如何创建和运营在线知识库?

随着企业业务的不断扩展和复杂化&#xff0c;建立一个在线知识库已经成为企业提高效率、减少重复劳动和提升服务质量的重要手段。接下来就详细介绍一下企业如何创建和运营在线知识库。 | 一、明确知识库的需求和目标 在开始建立在线知识库之前&#xff0c;企业需要明确知识库的…

ClickHouse中的物化视图

技术主题 技术原理 物化视图&#xff08;Materialized View&#xff09;是一种预先计算并缓存结果的视图&#xff0c;存储在磁盘上自动更新&#xff0c;空间换时间的思路。物化视图是一种优化技术&#xff0c;本质上就是为了加速查询操作&#xff0c;降低系统负载&#xff0c…

操作系统——解决了我的一些困惑

目录 1、电脑开机做了什么事情 2、真正实现并行的计算机 3、计算机中的淘汰算法 & 分配算法 & 调度算法 & 空间管理 4、什么是虚拟内存&#xff1f;为什么需要虚拟内存&#xff1f;最多可分配多少&#xff1f; 5、TLB&#xff08;快表&#xff09;、分页存储&…

React入门使用 (官方文档向 Part1)

文章目录 React组件:万物皆组件 JSX: 将标签引入 JavaScriptJSX 规则1. 只能返回一个根元素2. 标签必须闭合3. 使用驼峰式命名法给 ~~所有~~ 大部分属性命名&#xff01;高级提示&#xff1a;使用 JSX 转化器 在 JSX 中通过大括号使用 JavaScript使用引号传递字符串使用大括号&…

佳易王幼儿园缴费系统软件编程应用实例

佳易王幼儿园缴费系统软件编程实例 佳易王幼儿园缴费系统功能&#xff1a; 1、系统设置 2、班级设置 3、其他费用名称 4、学生信息管理 5、学生缴费 6、统计报表 7、备份全部数据 软件试用版下载可以点击下方官网卡片

前端向后端传JSON数据,使用MyBatis查询

form中向后端传的是空字符串&#xff0c;并不是null 而在MyBatis的判断中应判断是否为空字符串&#xff0c;而并非null