最近在做一个剪切板同步的小工具。但是遇到了一些问题,emmm,目前还没有好的解决方案。
问题描述:
- 这是一个分布式的剪贴板。意思是,机器A, B, C, D, E, A在剪贴板上粘贴了字符串a,B、C、D、E会得到一份copy。这样,你在机器B、C、D、E上可以用来粘贴。A、B、C、D、E上的数据要满足一致性。
- 为保证机器之间的数据交互能够比较高效地进行,大概率可能采用组播监听的方式来维护剪贴板的历史同步。这样除了达到免去逐一发送的路由相关繁杂问题以外,还企图解决没有中心怎么办的问题。
- 协议分为两部分:设备上线与心跳协议,设备数据传输协议。
- 设备上线与心跳协议规定了设备在上线的时候,应该向组内的成员发送上线的advertising。在一定时间内,机器会告诉在座的各位,我还在线。(你们都是。。)(逃)
- 数据同步协议除了需要把数据传输到在座各位,还要保证我的数据顺序是正确的,在座各位也是正确的。
例如在某一个时刻:
- 剪贴板cluster(emmm怎么翻译好)的链条中,主链为a--b--c--d。
- A机器包含:a--b--c--d
- B : a--b--c
- C: a--b--c--d
- D: a--b--c--d
- 此时,A在剪贴板中粘贴了数据e。(A组播发送了e给在座各位)
- C、D收到了:在自己的板子上默默地加上了e
- 然而,B,说,这不对!我的链条错了,快给我修复一下!然后B从其他人那里拿数据d、e。
- 最后,大家的链条与主链同步。
最后实现一个,拥有多机同步历史记录的剪贴板。
那么问题来了,如何实现一种协议,来同步机器之间的数据?
部分解决方案:
目前只能想到,有或可能有缺陷的解决方案。所以这还是一个未解决的问题。
1. 时间戳+数据哈希。
数据payload里包含了递增时间戳,上一个数据包的哈希,本数据包的哈希(可选)。这样,通过数据差错仲裁就可以知道谁出了问题。同样引用上面例子:
+ B收到包含pre_hash == d.hash的包,广播自己的last-timestamp或last-hash(c.hash)。其他人收到之后,也立刻广播last-timestamp或last-hash (d.hash) 。这样,少数服从多数,B错了,B从其他正确链条同步d。
那么问题来了,如果我在一个错误的链条上粘贴,却想要得到正确的结果,我就必须:
+ B广播:我粘贴了e!
+ 在座:你pre_hash错了,我们最后的数据是d。看你的操作时间戳,你确实是在粘贴了。
+ B:大哥们我错了,请其中一个把hash为pre_hash的数据给我吧。(单播获取欠缺数据)
这样的做法导致一个问题:多个数据链节丢失,你只能得到最后一个正确的节点。而且如果你再错一次,emmm,问题比较麻烦了,推理起来比较烦。当然,这里可以一次把所有丢失的节点发过去,这又是另外一回事了。以及,不同机器时间不一致怎么办。
2. raft
这个论文我还没看完,不知道管用否,以及是否适合这个微不足道的小工具。咱也不知道,咱也不敢问。。。
3. syncthing? 我参考了syncthing的代码,组播发现主机,tcp增量同步数据,看上去数据交互会有点重。但不失为一个方法。然后一路单播投递下去,也还行。再不济去找找gossip的某些实现。粗暴。
意见或建议
如果各位有好的意见或建议,衷心感谢各位留言(唱),或在我的repo发issue(跳),或者发email 给我 i@wxk.at(rap),或者发pr(篮球),都行!