20180720-同步推送
preface:
最近需要弄一个同步推送的功能,架构是有master-slave server,在master server更新了新的poc文件之后,希望能够同步推送到slave server上。
大致架构图:
Keyword : 同步推送
what
同步推送的本质是什么?
文件复制
文件复制有几种方式?
根据复制的发起方和触发方式不同,可分为两种
- 主动分发
- 被动同步
同步推送是属于哪个大类知识?
暂且属于内容分发与同步。
同步推送的目的是什么?
不管用什么方式,只要保证主从服务器中的poc文件夹内的文件是一模一样的就行。
保证文件一致的关键点?
跟下载东西一样,为了防止下载源或下载途中资源被篡改,大多在最后会进行完整性校验,用文件的MD5来进行校验。
增量还是全量?
除了SCP或WebDAV等主动分发方式,我们还可以采用被动同步的方式来实现文件复制,在这种情况下,接受文件的一端将主动向文件服务器发起同步请求,并根据来两端文件列表的差异,有选择性地进行更新,从而保证它和文件服务器的内容一直。
—《构建高性能Web站点》第14章-内容分发和同步 p342
如果是全量,那么就是很粗暴地将某个文件夹下的所有文件复制过去,然后覆盖掉目标服务器的对应文件夹。
如果想要增量,关键就是要比较差异:比较两边文件列表的差异,这样才能知道slave server当中缺了什么,这样才能有选择性地进行分发
同步推送有什么实现思路?
拍脑袋大致想了下有以下这些实现的思路
- 类似git的版本控制
- 实现某个文件协议来进行传输
- 用http协议、自己实现
《构建高性能Web站点》第14章-内容分发和同步提到有这几种方式
复制:
根据复制的发起方和触发方式不同,可分为两种
- 主动分发
- 被动同步
针对两种方式,如果条件允许,你完全可以自己开发软件来实现,这样的好处是你可以根据站点的需要来实现一些富有针对性的功能。
yep,我就是打算自己用flask api来实现,通过http协议来自己实现。
当然,对于大多数中等规模的站点来说,完全可以通过一系列的开源软件来实现复制。
我这里面对的需求似乎还不算大规模的文件,之前弄的elk日志分析系统就有用到书中提到的rsync来传输日志。
SSH:
SSH(Secure Shell),是建立在应用层和传输层协议上的安全协议,可以用于传输任何数据。
SSH有很多功能,它既可以代替Telnet,又可以为FTP、POP等协议提供安全的传输通道。
我们这里需要的并不是基于命令行的SSH,而是将SSH的能力集成到站点的应用程序中,幸运的是,很多用于Web开发的主流语言都拥有SSH客户端代码库或者相应的拓展。
PHP中可以通过PECL拓展来实现SSH客户端操作,更重要的是,它还实现了基于SSH的SCP和SFTP,这正是我们进行文件复制所需要的。
WebDAV:
另一种实现文件分发的简单方式是利用HTTP协议拓展协议WebDAV。
WebDAV (Web-based Distributed Authoring and Versioning) 一种基于 HTTP 1.1协议的通信协议。它扩展了HTTP 1.1,在GET、POST、HEAD等几个HTTP标准方法以外添加了一些新的方法,使应用程序可对Web Server直接读写,并支持写文件锁定(Locking)及解锁(Unlock),还可以支持文件的版本控制。
主流的Web服务器几乎都支持WebDAV拓展,比如Apache和Lighttpd都有相应的WebDAV模块。
rsync:
除了SCP或WebDAV等主动分发方式,我们还可以采用被动同步的方式来实现文件复制。
在这种情况下,接受文件的一端将主动向文件服务器发起同步请求,并根据两端文件列表的差异,有选择性地进行更新,从而保证它和文件服务器的内容一致。
对于少量文件的同步,rsync的表现基本上无可挑剔,但是当目录中存在大量的文件时,扫描的开销会很大。因为rsync在同步的时候必须扫描被同步目录中的所有文件,并根据文件最后修改时间,和本地进行对比,以找出需要复制的文件。
Hashtree:
rsynv在同步文件时需要分析目录中每一个文件的更新标记,当有多级目录时,仍然如此。
如果能让它在减少扫描范围或者次数的同时,仍然可以实现目的,这是我们希望的。
通过自己实现的同步推送功能,怎么样才能减少扫描的范围和次数呢?
事实上在大多数的时候,很多文件并没有更新。为什么不把少量文件的更新标记不断地传递到上一级目录呢?这样便可以让扫描过程中少走很多冤枉路。
如图所示,在文件服务器上,假如底层的灰色文件发生了更新,我们需要让它的上级目录也随之更新,最后修改时间,并且向上以此类推,直到顶层目录。
这样一来,从这个文件到根目录的一系列节点,都会更新最后修改时间,当同步扫描的时候,只需要遍历那些修改时间更新的目录即可,扫描次数将大大减少。
这种将文件的修改时间不断向上传递的机制体现了Hash tree的动机。
但有所不同的是,在Hash tree的存储结构中,我们通过特定的Hash算法,为树中的每个非叶节点生成一个可以描述它所有子节点唯一性的特征字符串,以便提供对节点信息完整性和正确性的验证,这样一来,一旦某个节点的信息发送变化,那么这种变化便会向上传递,体现在上级节点的特征字符串中。
这里,我们直接将文件修改时间作为Hash值,这非常适合于文件同步这种依赖时间的特殊应用,而且易于实现,几乎不需要额外的计算开销。
文件系统本身就是树形结构,hash tree的优越性在这里得到了很好的发挥。
又一个例子,根据需要处理的数据,选择合适的数据结构来存储数据。
反向代理:
略。
除了主从服务器,还有什么架构?
单级分发:
如果需要复制到更多的服务器上,容易产生以下问题:
- 由于目标服务器较多,并且部署在不同地域,分发过程会持续较长时间,这会造成一部分目标服务器表现出较大的内容更新延迟。
- 大量消耗文件服务器的本地系统资源,当分发任务较多时,本地会产生大量进程阻塞,影响其他任务的正常运行。
这个时候可以考虑多级分发的架构
多级分发的架构:
比喻?
主从服务器,单级分发有点像中央集权。master server就是中央,而slave server则是地方。
why
为什么需要同步推送?
about 需求~
- 有新的poc文件后,方便一次发布到下面多级服务器上。
- 算是一个文件复制的自动化操作
为什么选择主从服务器架构?
依据现实情况来说的话,目前的分类方法就是一级单位的下面都算是二级单位。
所以也就可以选择master-slave架构
how
如何保证文件是在不同服务器中是一致的?
- 检验文件MD5
when&where
啥时候选择多级分发架构?
目前来说,服务器较少的情况下,选择单级分发即可。
服务器多了,再选择改成多级分发吧。
每一项重大成就都会带来新的问题。任何一个发展随着时间的推移都会出现新的严重的困难。
—爱因斯坦
who
Boss:
- “poc主动更新和被动更新”
- 本质就是文件复制的主动分发和被动同步这两种
refs:
- 《构建高性能Web站点》第14章-内容分发和同步
expansion:
- SSH 系列 1:什么是 SSH、背景知识,SSH 协议需求与设计难点
- 数据结构-hashtree
Others:
- 找个时间理清逻辑链,然后再写一篇文章来总结。
- 适当多的清晰概念,才能在现实问题去抽象到一些概念中去,再拿这些概念去解决问题。