[Google Doc] Fanout Data Flow

请问老师,问题1: Document Service 在做 图1 第5步 compute transform for each client 的时候, 是需要知道each client 的 current version id么? 我的理解是这个是必须要知道的,否则没法compute transform. 那么这个信息是存储在server端还是client端?如果是存在server端,那么client端做edit的时候需要发送start version ID(图2 第1步)就是不必要的。但是如果是存在client端,那么compute transform 前就需要向client询问其current version, 感觉cost很高并不合理。

问题2:
图3描述的场景是client在edit的同时也在接收fanout,是不是只有在这个场景下才会有图2 第3步中的返回extra transform? 如果只是单纯client edit的话图2 第3步只用send find version id? 同时,如果client只是单纯接收fanout的话,就只有图3中的第3步?

图1

图2

图3

  1. 计算时需要知道 client 发送的变化基于的版本号。在服务器端会存储版本变化的历史和其中的所有版本号。Client edit 时仍然需要发送 start version id,因为 client 并不一定是基于最新版本进行的更新。
  2. 图二描述的是服务器和客户端之间的数据流,可以支持两台以上的机器同步。图三描述的是 OT 的算法,讲的是两台机器如何同步。讨论的问题不一样,所以不是一一对应的关系。图三因为讨论的是两台机器之间的情况所以没有fanout的概念。图二的第三步是从服务器向客户端发送客户端需要做的修改,肯定是需要最终版本号+更新的,否则客户端没办法根据服务器端接收到的其他客户端的更新请求来更新本地的状态。

老师,我有几个问题:
1.如果在高并发的场景下,一个客户端发送出去的request之后进入等待,课上说之后必须等到response之后才可以继续进行修改。那么这个response不一定是它自己做修改的response,也可能是和它同时编辑其他用户做的修改产生的response fanout过来的么?它只能等到它自己的request得到相应的response之后,才可以继续做update的request
2. 如果whatever response回来了,用户都进入下一次编辑的状态,那么它连续发的两个request,会不会出现后发先至?如果发生了,Document 会怎么处理这个问题?尤其是怎么处理一个版本号明显晚的情况,它会从Document DB中把过往历史拿出来,从头再生成出一个新的文档,然后fanout每个用户说怎么修改?
3. 如果出了丢包的现象,如果是真丢包了怎么办?timeout了么?然后重新发请求?如果是假丢包,客户端怎么办,服务器怎么办?尤其是假丢包的request最终造访服务器,服务器咋处理?
4. 这个version对于Document Service,就是一个编辑的起始点么?类似time的作用么?还是说它也是个乐观锁的感觉?

老师,抱歉,越想越有点乱。

现在如果有多于一个人去对同一个文档做编辑,document service是要汇总所有参与者的update和版本号,去figure out出一个最终版本,是这样的么?

如果每个人来的版本号各不相同,有的是version1,有的是version2,它计算的过程是调老的变化记录,重新生成一个新的版本?计算出每个客户需要作出各自相应的变化,然后fanout给每个递交request 的用户?那问题是,这个汇总得有个时间间隔吧,高并发下,所有人都在发东西,没有个头,它汇总是一种增量stream的方式,还是一种batch的方式?

如果是增量的方式,来一个request就搞一次计算,然后fanout所有,这样会不会产生大量的message?如果是batch的方式,这个积累多少算一个batch?

上面图2是一种抽象的想法,但是我会有个误解,就是这个response会是针对于当前用户的update对应给回来一个response,但是我觉得实际上这个response,client也应该不停收到其他用户修改造成的transform吧。那么也就是说如果有别人编辑的情况下,我就是不做修改,我也不停的收到别人fanout回来的结果,那如果在高并发下,我其实基本上感觉到的就是我在连续的发消息,因为response可能都是别人做输入给回来的,我拿到瞬息万变的版本号,也就可以不停的发消息了。是这意思么。

核心思想是在服务器端存有唯一的一串文件修改记录,每一个是一个版本号对应一组修改。
回答一下你的几个问题:

  1. 好问题。客户端可以在发送 Request 后到收到相对应的 Response 之间忽略其他的 fanout reponse,服务器也可以选择性地不发。
  2. 用户不能同时发两个 Request,必须等待收到 Response 才能发下一个。
  3. 每个 Request 可以有 timeout,如果时间太长可以再次发送。
  4. Version 表示改动基于的版本。
  5. 每个版本都是服务器基于一个用户发来的更新计算出来的。
  6. 服务器处理同一个文件的更新是排队的,一次处理一个改动,这个意义上没有并发。
  7. 见 1