Ceph使用KAEzip对大于4MB文件压缩报错问题
问题现象描述
Ceph对象存储,测试zlib硬算压缩率,使用超过4MB的文件进行测试时,出现“Compression error: compress unused input”的报错信息。
关键过程、根本原因分析
关键过程:
- 触发场景
- 用户直接使用zlib的deflate接口进行压缩。
- 对4MB以上大文件进行块模式压缩。
- 且输出缓存比较小需要分批的时候,会导致
KAEzip 未压缩最后一笔数据,提前退出,返回Z_OK,且strm.vaild_in未处理完成。 - 若应用软件未判断需要压缩的有效数据为0(strm.vaild_in)。
- 影响范围
- 问题代码示例
int err = deflateInit(&strm, level); if (err != Z_OK) return err; strm.avail_out = 0; strm.avail_in = sourceLen; //大于4M strm.next_in = (Bytef*)source; int flush = Z_FINISH; char* szBuf = new char[CEPH_PAGE_SIZE]; do { memset(szBuf, 0, CEPH_PAGE_SIZE); //CEPH_PAGE_SIZE=64*1024 strm.next_out = (Bytef*)szBuf; strm.avail_out = CEPH_PAGE_SIZE; ret = deflate(&strm, flush); /* no bad return value */ if (ret == Z_STREAM_ERROR) { deflateEnd(&strm); return -1; } have = CEPH_PAGE_SIZE - strm.avail_out; memcpy(dest + outnum, szBuf, have); outnum += have; } while (strm.avail_out == 0); //退出压缩时,问题场景下,ret = Z_OK且strm.avail_in != 0 *destLen = outnum; if (strm.avail_in != 0) { deflateEnd(&strm); return -1; //错误返回。 }
如果客户没有按照zlib标准使用用例,没有作如下图所示判断,则会出现最后一笔压缩数据未完成。
根本原因:
因为KAEzip内部对于压缩输出有缓存,当外部传入的空间不够时,KAEzip将当次的没有传出的数据缓存在内部。在下次调用压缩接口的时候,会先去取缓存里面的内容,如果这次是最后一次,那么KAEzip逻辑上取完缓存就不再进行压缩处理而退出了。
结论、解决方案及效果
该问题在KAE 1.3.10及以下版本存在,在1.3.11版本已经修复(2021年5月20日已经发布),请将KAEzip软件包升级到1.3.11版本。
- 如果是通过rpm或者deb包安装的KAEzip加速引擎软件,升级操作请参考以下步骤进行处理。
- 如果是通过源码方式安装的KAEzip加速引擎软件,升级操作请参考以下步骤进行处理。
父主题: 软件类