如何实现文件增量同步——算法

简介:

问题:

如何增量同步文件,例如一个文本文件有10M,分别存放在A,B两个地方,现在两个文件是完全一样的,但是我马上要在A上对这个文件进行修改,B如何实现自动和A上的文件保持一致,并且网络的传输量最少。

 

应用场景:

这样的使用场景太多,这里随便列举几个

1.A机器为线上运营的机器,现在需要一台备份的机器B,当A发生宕机的时候,或者硬盘损坏等各种认为非人为原因导致数据不可用时,可以很快从B恢复

2.SVN这样的应用场景,不需要每次修改都向服务器发送并替换掉一个文件,而是只发送被修改的部分

3.手机客户端对一个文本修改,如果那个文本有2M,难道我每次更新都需要上传整个文件吗?每次2M,傻子才用! 

等等.... 

 

解决方案:

.分而治之

计算机最重要的基本算法思路就是分而治之,在我们眼里,一个文件不是一个文件,而是一堆存储块,每个存储块可能20Byte大小,至于这个值具体多大,你可以自己设定,这里的20Byte仅提供参考。通过这样的方法,一个文件被分成了很多个块,我们只需要比对块是否相同就可以得出哪个部分做了相应修改。

 

.快速校验

刚上面提到如何比对文件,当然这里肯定不会把文件的每个块上传去比对,那样做就没有意义了。快速比对这不禁让我想起了哈希规则,哈希表可以通过O(1)的复杂度查找某个key,为什么?  因为它通过计算hash值来初步验证key,一个key的hash值是唯一的。但是仅仅验证hash值是不可靠的,因为hash值有可能会冲突,所以在验证完hash值后,我们在进行key的比较来确定要找的值...

通过哈希的思路,我们可以使用类似的方法来实现文件增量同步,把每一个存储块,通过MD5计算其值,然后传递MD5值到服务器,让服务器比对MD5来确定有没有被修改,如若MD5值不相等,则判定这个文件块有被修改过

为什么是MD5?

1)能够将任意长度的字符串转换为128位定长字符串(MD5 16) 

2)MD5能够保证绝大部分情况下不同的值hash之后其hash值不一样,哈希冲突比较少

这样就可以了吗?

No,MD5的生成需要占用比较长的CPU时间,所以我们需要寻找一种更简洁的校验方式,这里选用Alder32 是一个比较通用的解决方案

 

Alder32有两个优点: 
1、计算非常快,比MD5快多了,成本小;
2、当我们有了从0-k长度的校验和后,计算出1-k或者2-k等其他校验和非常方便,只要少量运算即可。(k可以理解为上面的20Byte)

 

当然,它的缺点也很明显,就是碰撞率比MD5高多了,所以,我们客户端需要同时计算出Alder32校验和与MD5值,传给服务器,而服务器,为了节省CPU时间,第一步只生成Alder32进行校验,当值相等时,在进行MD5校验,这样服务器就节省了很大的开支。

Alder32算法实现:

 
 A = 1 + D1 + D2 + ... + Dn (mod 65521)
 B = (1 + D1) + (1 + D1 + D2) + ... + (1 + D1 + D2 + ... + Dn) (mod 65521)
   = n×D1 + (n−1)×D2 + (n−2)×D3 + ... + Dn + n (mod 65521)

 Adler-32(D) = B × 65536 + A

C实现版本

复制代码
复制代码
const int MOD_ADLER = 65521;
 
unsigned long adler32(unsigned char *data, int len) /* where data is the location of the data in physical memory and 
                                                       len is the length of the data in bytes */
{
    unsigned long a = 1, b = 0;
    int index;
 
    /* Process each byte of the data in order */
    for (index = 0; index < len; ++index)
    {
        a = (a + data[index]) % MOD_ADLER;
        b = (b + a) % MOD_ADLER;
    }
 
    return (b << 16) | a;
}
复制代码
复制代码

 

三.实现更改

因为已经找出来了文件不同的地方,所以只需要按需上传更改的部分到服务器,然后服务器做更改就可以了。 

 

 

实例分析: 

理论概述完毕,来点小例子子

客户端文件内容是: 

 taohuiissoman

而服务器的文件内容是:

itaohuiamsoman

 

首先,客户端开始分块并计算出MD5和Alder32值。

如上图,像taoh是一块,对taoh分别计算出MD5和alder32值。以此类推,最后一个n字母不足4位保留。于是,客户端把计算出的MD5和alder32按顺序发出,最后发出字符n。

 

服务器收到后,先把自己保存的File.2的内容按4字节划分。

划分出itao、huia、msom、an,当然,这些串的Alder32值肯定无法从File.1里划分出的:taoh、uiis、soma、n找出相同的。于是向后移一个字节,从t开始继续按4字节划分。

从taoh上找到了alder32相同的块,接着再比较MD5值,也相同!于是记下来,跳过taoh这4个字符,看uiam,又找不到File.1上相同的块了。继续向后跳1个字节从i开始看。还是没有找到Alder32相同,继续向后移,以此类推。

到了soma,又找到相同的块了。

 

重复上面的步骤,直到File.2文件结束。

 

通过这个简单的例子,可以设想一下其他任何的增删查改功能 

 

 

参考资料:http://cs.anu.edu.au/techreports/1996/TR-CS-96-05.pdf 

目录
相关文章
|
6月前
|
传感器 算法 计算机视觉
基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
该内容是关于一个基于肤色模型和中值滤波的手部检测算法的描述,包括算法的运行效果图和所使用的软件版本(matlab2022a, vivado2019.2)。算法分为肤色分割和中值滤波两步,其中肤色模型在YCbCr色彩空间定义,中值滤波用于去除噪声。提供了一段核心程序代码,用于处理图像数据并在FPGA上实现。最终,检测结果输出到&quot;hand.txt&quot;文件。
|
5月前
|
算法
基于ADM自适应增量调制算法的matlab性能仿真
该文主要探讨基于MATLAB的ADM自适应增量调制算法仿真,对比ADM与DM算法。通过图表展示调制与解调效果,核心程序包括输入输出比较及SNR分析。ADM算法根据信号斜率动态调整量化步长,以适应信号变化。在MATLAB中实现ADM涉及定义输入信号、初始化参数、执行算法逻辑及性能评估。
|
4月前
|
算法
Ngnix02 --- Ngnix的功能特性及常见功能,Ngnix常用的功能模块,有不同算法,根据不同算法进行转发,ip_hash、url_hash、fair,核心组成 ngnix二进制可执行文件
Ngnix02 --- Ngnix的功能特性及常见功能,Ngnix常用的功能模块,有不同算法,根据不同算法进行转发,ip_hash、url_hash、fair,核心组成 ngnix二进制可执行文件
|
6月前
|
算法 关系型数据库 MySQL
实时计算 Flink版产品使用合集之哪个版本可以做增量快照算法
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
5月前
|
算法 Shell C语言
数据结构与算法——希尔排序(引例、希尔增量序列、原始希尔排序、代码、时间复杂度、Hibbard增量序列、Sedgewick增量序列)
数据结构与算法——希尔排序(引例、希尔增量序列、原始希尔排序、代码、时间复杂度、Hibbard增量序列、Sedgewick增量序列)
57 0
|
6月前
|
机器学习/深度学习 算法 搜索推荐
Python用机器学习算法进行因果推断与增量、增益模型Uplift Modeling智能营销模型
Python用机器学习算法进行因果推断与增量、增益模型Uplift Modeling智能营销模型
154 12
|
6月前
|
算法 TensorFlow 算法框架/工具
基于直方图的图像阈值计算和分割算法FPGA实现,包含tb测试文件和MATLAB辅助验证
这是一个关于图像处理的算法实现摘要,主要包括四部分:展示了四张算法运行的效果图;提到了使用的软件版本为VIVADO 2019.2和matlab 2022a;介绍了算法理论,即基于直方图的图像阈值分割,通过灰度直方图分布选取阈值来区分图像区域;并提供了部分Verilog代码,该代码读取图像数据,进行处理,并输出结果到&quot;result.txt&quot;以供MATLAB显示图像分割效果。
|
6月前
|
算法 计算机视觉 异构计算
基于直方图相似性的图像分类算法FPGA实现,包括tb测试文件和MATLAB辅助验证
该内容包含了一段关于图像处理算法的摘要,主要包括: 1. 展示了MATLAB和FPGA的测试结果图像,显示了图像读取完成的标志和相似性指标,其中图1与图2有较强相似性,图1与图3相似性较弱。 2. 算法使用的是vivado 2019.2和matlab 2022A版本。 3. 算法原理涉及图像直方图统计和直方图相似性度量,通过计算直方图的差异来衡量图像相似度,FPGA实现包括图像采集、直方图计算、比较和分类决策步骤。 4. 提供了一个部分核心Verilog程序,用于读取图像数据并在FPGA上进行直方图相似性计算。
|
6月前
|
并行计算 算法 调度
【操作系统】同步和互斥详细讲解(算法+源码)
【操作系统】同步和互斥详细讲解(算法+源码)
|
6月前
|
编解码 算法 计算机视觉
基于FPGA的图像最近邻插值算法verilog实现,包括tb测试文件和MATLAB辅助验证
基于FPGA的图像最近邻插值算法verilog实现,包括tb测试文件和MATLAB辅助验证