Skip to content

Latest commit

 

History

History
307 lines (276 loc) · 21.1 KB

README_cn.md

File metadata and controls

307 lines (276 loc) · 21.1 KB

release license PRs Welcome +issue Welcome

Build Status

中文版 | english

hsynz 是一个用使用同步算法来进行增量更新的库,类似于 zsync
通过http(s)实现rsync;在客户端实现同步算法,服务器端只需要提供http(s)的CDN。支持zstd、libdeflate和zlib压缩,支持大文件和目录(文件夹),支持多线程。

适用的场景:旧版本数量非常多 或者 无法得到旧版本(没有保存或被修改等) 从而无法提前计算出全部的增量补丁,这时推荐使用hsynz同步分发技术。

服务端使用hsync_make对最新版本的数据进行一次处理,将新版本数据按块生成摘要信息文件(hsyni),同时也可以选择对新版本数据分块进行压缩得到发布文件(hsynz),如果不压缩新版本原文件就是hsynz等价文件。

客户端先从服务端或其他用户分享处下载hsyni文件,根据自己的旧版本计算出需要下载的更新块,并根据hsyni中的信息得知这些块在hsynz中的位置,选择一种通讯方式从服务端的hsynz文件中按需下载,下载好的块和本地已有数据合并得到最新版本的数据。

hsync_demo提供了一个测试客户端demo,用于本地文件测试。
hsync_http提供了一个支持http(s)的下载客户端demo,支持从提供http(s)文件下载服务的服务端(比如支持HTTP/1.1的多range请求的CDN服务器)进行同步更新。
提示:你也可以自定义其他通讯方式用于同步。


特性和 zsync 对比

  • 除了支持源和目标为文件,还为文件夹(目录)提供了支持。
  • 除了支持zlib压缩发布包;还支持libdeflate和zstd压缩,提供更好的压缩率,即下载的补丁包更小。
  • 服务端make时提供了多线程并行加速的支持。
  • 对客户端的diff速度进行了优化,并且提供了多线程并行加速的支持。

二进制发布包

从 release 下载 : 分别运行在 Windows、Linux、MacOS操作系统的命令行程序; .so 库用以支持安卓系统进行同步打补丁。
( 编译出这些发布文件的项目路径在 hsynz/builds )

自己编译

Linux 或 MacOS X

$ cd <dir>
$ git clone --recursive https://github.com/sisong/hsynz.git
$ cd hsynz
$ make

Windows

$ cd <dir>
$ git clone --recursive https://github.com/sisong/hsynz.git

Visual Studio 打开 hsynz/builds/vc/hsynz.sln 编译

安卓库 libhsynz.so

  • 先安装好 Android NDK
  • $ cd <dir>/hsynz/builds/android_ndk_jni_mk
  • $ build_libs_static.sh (或者在 windows 系统上执行 $ build_libs_static.bat, 就可以得到 *.so 文件)
  • 安卓项目添加 com/github/sisong/hsynz.java (路径在 hsynz/builds/android_ndk_jni_mk/java/) 和 .so 库文件, java代码中就可以调用libhsynz.so中的同步补丁函数了。

hsync_make 命令行使用说明:

hsync_make: [options] newDataPath out_hsyni_file [out_hsynz_file]
  newDataPath可以是文件或目录, 如果newDataPath是文件并且不使用压缩参数 -c-... , 那out_hsynz_file
    参数可以为空.(因为这时out_hsynz_file和newDataPath文件完全一致,不需要重新再复制一个)
选项:
  -s-matchBlockSize
      匹配块大小matchBlockSize>=128, 默认为-s-2k, 推荐设置值 1024,4k,... (一般文件越大设置值建议越大)
  -b-safeBit
      设置允许patch时因hash冲突而失败的概率为: 1/2^safeBit;
      安全比特数safeBit>=14, 默认为 -b-24, 推荐 20,32... 
      (safeBit=24,也就是对任意一个旧版本大概有1/2^24的概率patch一定会失败;而值越大out_hsyni_file信息文件越大)
  -p-parallelThreadNumber
      设置线程数parallelThreadNumber>1时,开启多线程并行模式;
      默认为4;需要占用较多的内存。
  -c-compressType[-compressLevel]
      设置out_hsynz_file输出文件使用的压缩算法和压缩级别等, 默认不压缩;
      所有的压缩算法都支持多线程并行压缩;
      支持的压缩算法、压缩级别和字典大小等:
        -c-zlib[-{1..9}[-dictBits]]     默认级别 9
            压缩字典比特数dictBits可以为9到15, 默认为15。
        -c-gzip[-{1..9}[-dictBits]]     默认级别 9
            压缩字典比特数dictBits可以为9到15, 默认为15。
            使用zlib算法来压缩, out_hsynz_file输出文件将是一个标准的.gz格式文件。
            (会比 -c-zlib 生成的文件稍大一点)
        -c-ldef[-{1..12}]    默认级别 12
            压缩字典比特数dictBits总是设置为15。
            使用libdeflate算法来压缩, 兼容zlib的deflate编码。
        -c-lgzip[-{1..12}]   默认级别 12
            压缩字典比特数dictBits总是设置为15。
            使用libdeflate算法来压缩, out_hsynz_file输出文件将是一个标准的.gz格式文件。
        -c-zstd[-{10..22}[-dictBits]]   默认级别 21
            压缩字典比特数dictBits 可以为15到30, 默认为24。
  -C-checksumType
      设置块数据的强校验算法, 默认为-C-xxh128;
      支持的校验选项:
        -C-xxh128
        -C-md5
        -C-sha512
        -C-sha256
        -C-crc32
            警告: crc32不够强和安全!
  -n-maxOpenFileNumber
      当newDataPath为文件夹时,设置最大允许同时打开的文件数;
      maxOpenFileNumber>=8, 默认为48; 合适的限制值可能不同系统下不同。
  -g#ignorePath[#ignorePath#...]
      当newDataPath为文件夹时,设置忽略路径(路径可能是文件或文件夹); 忽略路径列表的格式如下:
        #.DS_Store#desktop.ini#*thumbs*.db#.git*#.svn/#cache_*/00*11/*.tmp
      # 意味着路径名称之间的间隔; (如果名称中有“#”号, 需要改写为“#:” )
      * 意味着匹配名称中的任意一段字符; (如果名称中有“*”号, 需要改写为“*:” )
      / 如果该符号放在名称末尾,意味着必须匹配文件夹;
  -f  强制文件写覆盖, 忽略输出的路径是否已经存在;
      默认不执行覆盖, 如果输出路径已经存在, 直接返回错误;
      如果设置了-f,但路径已经存在并且是一个文件夹, 那么会始终返回错误。
  --patch
      切换命令行到hsync_demo模式; 可以支持hsync_demo命令行的相关参数和功能。
  -v  输出程序版本信息。
  -h 或 -?
      输出命令行帮助信息 (该说明)。

hsync_http command line usage:

下载文件    : [options] -dl#hsyni_file_url hsyni_file
创建本地补丁: [options] oldPath hsyni_file hsynz_file_url -diff#diffFile
本地打补丁  : [options] oldPath hsyni_file -patch#diffFile outNewPath
查询同步信息: [options] oldPath hsyni_file [-diffi#cacheTempFile]
同步打补丁  : [options] oldPath [-dl#hsyni_file_url] hsyni_file hsynz_file_url outNewPath [-diffi#cacheTempFile] 
  oldPath可以是文件或文件夹;oldPath可以为空, 输入参数为 ""
选项:
  -dl#hsyni_file_url
    在同步打补丁开始前,将hsyni_file_url对应的文件下载为本地文件hsyni_file; 
  -diff#outDiffFile
    开始打补丁前,创建oldPath到hsyni_file描述的新版间的diffFile补丁文件,本地没有的块按需从hsynz_file_url下载;
  -patch#diffFile
    对oldPath应用diffFile补丁文件后得到outNewPath;
  -diffi#cacheTempFile
    获得的同步信息保存到一个临时缓存文件cacheTempFile,同步打补丁的时候,就可以跳过同步信息的耗时计算过程;
  -cdl
    开启断点续传;默认关闭;
  -r-stepRangeNumber
    默认 -r-32, 推荐 16,20,...
    从.hsynz下载时,限制在单次请求步骤中的最大区域(range)数;
    如果http(s)服务器不支持多区域(muti-ranges)请求, 必须设置为 -r-1
  -p-parallelThreadNumber
    设置线程数parallelThreadNumber>1时,开启多线程并行模式;
    默认为4;
    注意: 当前下载数据时使用的是单线程。
  -n-maxOpenFileNumber
      当路径为文件夹时,设置最大允许同时打开的文件数;
      maxOpenFileNumber>=8, 默认为24; 合适的限制值可能不同系统下不同。
  -g#ignorePath[#ignorePath#...]
      当oldPath为文件夹时,设置忽略路径(路径可能是文件或文件夹); 忽略路径列表的格式如下:
        #.DS_Store#desktop.ini#*thumbs*.db#.git*#.svn/#cache_*/00*11/*.tmp
      # 意味着路径名称之间的间隔; (如果名称中有“#”号, 需要改写为“#:” )
      * 意味着匹配名称中的任意一段字符; (如果名称中有“*”号, 需要改写为“*:” )
      / 如果该符号放在名称末尾,意味着必须匹配文件夹;
  -f  强制文件写覆盖, 忽略输出的路径是否已经存在;
      默认不执行覆盖, 如果输出路径已经存在, 直接返回错误;
      如果设置了-f,但outNewPath已经存在并且是一个文件:
        如果patch输出一个文件, 那么会执行写覆盖;
        如果patch输出一个文件夹, 那么会始终返回错误。
      如果设置了-f,但outNewPath已经存在并且是一个文件夹:
        如果patch输出一个文件, 那么会始终返回错误;
        如果patch输出一个文件夹, 那么会执行写覆盖, 但不会删除文件夹中已经存在的无关文件。
  -v  输出程序版本信息。
  -h 或 -?
      输出命令行帮助信息 (该说明)。

hsync_demo command line usage:

该程序功能用于本地同步测试,用本地文件代替实际中的URL远程文件,详见hsync_http命令行。


hsynz 和 zsync 性能对比:

测试用例(从 OneDrive 下载):

新版本文件 <-- 旧版本 新版本大小 旧版本大小
1 7-Zip_22.01.win.tar <-- 7-Zip_21.07.win.tar 5908992 5748224
2 Chrome_107.0.5304.122-x64-Stable.win.tar <-- 106.0.5249.119 278658560 273026560
3 cpu-z_2.03-en.win.tar <-- cpu-z_2.02-en.win.tar 8718336 8643072
4 curl_7.86.0.src.tar <-- curl_7.85.0.src.tar 26275840 26030080
5 douyin_1.5.1.mac.tar <-- douyin_1.4.2.mac.tar 407940608 407642624
6 Emacs_28.2-universal.mac.tar <-- Emacs_27.2-3-universal.mac.tar 196380160 257496064
7 FFmpeg-n_5.1.2.src.tar <-- FFmpeg-n_4.4.3.src.tar 80527360 76154880
8 gcc_12.2.0.src.tar <-- gcc_11.3.0.src.tar 865884160 824309760
9 git_2.33.0-intel-universal-mavericks.mac.tar <-- 2.31.0 73302528 70990848
10 go_1.19.3.linux-amd64.tar <-- go_1.19.2.linux-amd64.tar 468835840 468796416
11 jdk_x64_mac_openj9_16.0.1_9_openj9-0.26.0.tar <-- 9_15.0.2_7-0.24.0 363765760 327188480
12 jre_1.8.0_351-linux-x64.tar <-- jre_1.8.0_311-linux-x64.tar 267796480 257996800
13 linux_5.19.9.src.tar <-- linux_5.15.80.src.tar 1269637120 1138933760
14 Minecraft_175.win.tar <-- Minecraft_172.win.tar 166643200 180084736
15 OpenOffice_4.1.13.mac.tar <-- OpenOffice_4.1.10.mac.tar 408364032 408336896
16 postgresql_15.1.src.tar <-- postgresql_14.6.src.tar 151787520 147660800
17 QQ_9.6.9.win.tar <-- QQ_9.6.8.win.tar 465045504 464837120
18 tensorflow_2.10.1.src.tar <-- tensorflow_2.8.4.src.tar 275548160 259246080
19 VSCode-win32-x64_1.73.1.tar <-- VSCode-win32-x64_1.69.2.tar 364025856 340256768
20 WeChat_3.8.0.41.win.tar <-- WeChat_3.8.0.33.win.tar 505876992 505018368

测试PC: Windows11, CPU R9-7945HX, SSD PCIe4.0x4 4T, DDR5 5200MHz 32Gx2
参与测试的程序版本: hsynz 1.1.1, zsync 0.6.2 (更多程序的对比测试结果见 HDiffPatch)
程序测试参数:
zsync 运行 make 参数 zsyncmake -b 2048 -o {out_newi} {new},
客户端同步 diff&patch 时参数 zsync -i {old} -o {out_new} {newi} (所有文件都在本地)
zsync -z 运行 make 参数 zsyncmake -b 2048 -z -u {new.gz} -o {out_newi} {new}
hsynz 运行 make 参数 hsync_make -s-2k {new} {out_newi} [{-c-?} {out_newz}],
客户端同步 diff&patch 时参数 hsync_demo {old} {newi} {newz} {out_new} (所有文件都在本地)
hsynz p1 运行 make 时没有压缩器,也没有压缩文件out_newz输出, 添加了参数 -p-1
hsynz p8 运行 make 时没有压缩器,也没有压缩文件out_newz输出, 添加了参数 -p-8
hsynz p1 -zlib 运行 make 时添加 -p-1 -c-zlib-9 (运行 hsync_demo 时添加 -p-1)
hsynz p8 -zlib 运行 make 时添加 -p-8 -c-zlib-9 (运行 hsync_demo 时添加 -p-8)
hsynz p1 -gzip 运行 make 时添加 -p-1 -c-gzip-9 (运行 hsync_demo 时添加 -p-1)
hsynz p8 -gzip 运行 make 时添加 -p-8 -c-gzip-9 (运行 hsync_demo 时添加 -p-8)
hsynz p1 -ldef 运行 make 时添加 -p-1 -c-ldef-12 (运行 hsync_demo 时添加 -p-1)
hsynz p8 -ldef 运行 make 时添加 -p-8 -c-ldef-12 (运行 hsync_demo 时添加 -p-8)
hsynz p1 -lgzip 运行 make 时添加 -p-1 -c-lgzip-12 (运行 hsync_demo 时添加 -p-1)
hsynz p8 -lgzip 运行 make 时添加 -p-8 -c-lgzip-12 (运行 hsync_demo 时添加 -p-8)
hsynz p1 -zstd 运行 make 时添加 -p-1 -c-zstd-21-24 (运行 hsync_demo 时添加 -p-1)
hsynz p8 -zstd 运行 make 时添加 -p-8 -c-zstd-21-24 (运行 hsync_demo 时添加 -p-8)

测试平均结果:

程序 压缩率 make内存 速度 sync内存 最大内存 速度
zsync 52.94% 1M 353.9MB/s 7M 23M 34MB/s
zsync -z 20.67% 1M 14.8MB/s 12M 37M 28MB/s
hsynz p1 51.05% 5M 2039.5MB/s 5M 19M 307MB/s
hsynz p8 51.05% 21M 4311.9MB/s 12M 27M 533MB/s
hsynz p1 zlib 20.05% 6M 17.3MB/s 6M 22M 273MB/s
hsynz p8 zlib 20.05% 30M 115.1MB/s 13M 29M 435MB/s
hsynz p1 gzip 20.12% 6M 17.3MB/s 6M 22M 268MB/s
hsynz p8 gzip 20.12% 30M 115.0MB/s 13M 29M 427MB/s
hsynz p1 ldef 19.57% 15M 7.8MB/s 6M 22M 272MB/s
hsynz p8 ldef 19.57% 96M 57.0MB/s 13M 29M 431MB/s
hsynz p1 lgzip 19.64% 15M 7.9MB/s 6M 22M 267MB/s
hsynz p8 lgzip 19.64% 96M 56.9MB/s 13M 29M 419MB/s
hsynz p1 zstd 14.96% 532M 1.9MB/s 24M 34M 264MB/s
hsynz p8 zstd 14.95% 3349M 10.1MB/s 24M 34M 410MB/s

输入Apk文件进行测试:

case list:

app newFile <-- oldFile newSize oldSize
1 cn.wps.moffice_eng_13.30.0.apk <-- 13.29.0 95904918 94914262
2 com.achievo.vipshop_7.80.2.apk <-- 7.79.9 127395632 120237937
3 com.adobe.reader_22.9.0.24118.apk <-- 22.8.1.23587 27351437 27087718
4 com.alibaba.android.rimet_6.5.50.apk <-- 6.5.45 195314449 193489159
5 com.amazon.mShop.android.shopping_24.18.2.apk <-- 24.18.0 76328858 76287423
6 com.baidu.BaiduMap_16.5.0.apk <-- 16.4.5 131382821 132308374
7 com.dragon.read_5.5.3.33.apk <-- 5.5.1.32 45112658 43518658
8 com.ebay.mobile_6.80.0.1.apk <-- 6.79.0.1 61202587 61123285
9 com.eg.android.AlipayGphone_10.3.0.apk <-- 10.2.96 122073135 119046208
10 com.google.android.apps.translate_6.46.0.apk <-- 6.45.0 48892967 48843378
11 com.google.android.googlequicksearchbox_13.38.11.apk <-- 13.37.10 190539272 189493966
12 com.jingdong.app.mall_11.3.2.apk <-- 11.3.0 101098430 100750191
13 com.netease.cloudmusic_8.8.45.apk <-- 8.8.40 181914846 181909451
14 com.reddit.frontpage_2022.36.0.apk <-- 2022.34.0 50205119 47854461
15 com.sankuai.meituan.takeoutnew_7.94.3.apk <-- 7.92.2 74965893 74833926
16 com.sankuai.meituan_12.4.207.apk <-- 12.4.205 93613732 93605911
17 com.sina.weibo_12.10.0.apk <-- 12.9.5 156881776 156617913
18 com.smile.gifmaker_10.8.40.27845.apk <-- 10.8.30.27728 102403847 101520138
19 com.ss.android.article.news_9.0.7.apk <-- 9.0.6 54444003 53947221
20 com.ss.android.ugc.aweme_22.6.0.apk <-- 22.5.0 171683897 171353597
21 com.taobao.taobao_10.18.10.apk <-- 10.17.0 117218670 117111874
22 com.tencent.mm_8.0.28.apk <-- 8.0.27 266691829 276603782
23 com.tencent.mobileqq_8.9.15.apk <-- 8.9.13 311322716 310529631
24 com.tencent.mtt_13.2.0.0103.apk <-- 13.2.0.0045 97342747 97296757
25 com.tripadvisor.tripadvisor_49.5.apk <-- 49.3 28744498 28695346
26 com.twitter.android_9.61.0.apk <-- 9.58.2 36141840 35575484
27 com.ubercab_4.442.10002.apk <-- 4.439.10002 69923232 64284150
28 com.ximalaya.ting.android_9.0.66.3.apk <-- 9.0.62.3 115804845 113564876
29 com.xunmeng.pinduoduo_6.30.0.apk <-- 6.29.1 30896833 30951567
30 com.youdao.dict_9.2.29.apk <-- 9.2.28 110624682 110628778
31 org.mozilla.firefox_105.2.0.apk <-- 105.1.0 83078464 83086656
32 tv.danmaku.bili_7.1.0.apk <-- 7.0.0 104774723 104727005

调整测试程序:
zsync ... make 参数 -b 2048 修改为 -b 1024
hsynz ... make 参数 -s-2k 修改为 -s-1k

测试平均结果:

程序 压缩率 make内存 速度 sync内存 最大内存 速度
zsync 62.80% 1M 329.8MB/s 6M 12M 76MB/s
zsync -z 59.56% 1M 19.8MB/s 8M 19M 56MB/s
hsynz p1 62.43% 4M 1533.5MB/s 4M 10M 236MB/s
hsynz p8 62.43% 18M 2336.4MB/s 12M 18M 394MB/s
hsynz p1 zlib 58.67% 5M 22.7MB/s 4M 11M 243MB/s
hsynz p8 zlib 58.67% 29M 138.6MB/s 12M 19M 410MB/s
hsynz p1 gzip 58.95% 5M 22.6MB/s 4M 11M 242MB/s
hsynz p8 gzip 58.95% 29M 138.9MB/s 12M 19M 407MB/s
hsynz p1 ldef 58.61% 14M 23.7MB/s 4M 11M 242MB/s
hsynz p8 ldef 58.61% 96M 149.1MB/s 12M 19M 413MB/s
hsynz p1 lgzip 58.90% 14M 23.6MB/s 4M 11M 240MB/s
hsynz p8 lgzip 58.90% 96M 149.1MB/s 12M 19M 405MB/s
hsynz p1 zstd 57.74% 534M 2.7MB/s 24M 28M 234MB/s
hsynz p8 zstd 57.74% 3434M 13.4MB/s 24M 28M 390MB/s

联系

[email protected]