记一次Minio ComposeObject无法在ceph上合并文件的异常运维

您所在的位置:网站首页 合并文件时出错 记一次Minio ComposeObject无法在ceph上合并文件的异常运维

记一次Minio ComposeObject无法在ceph上合并文件的异常运维

2024-05-31 14:27| 来源: 网络整理| 查看: 265

问题复现

直接使用minio java sdk(8.3.3版本)对ceph集群中的compose桶中的已存在的多个文件(test1,test2)进行合并(test),代码如下

@Test void contextLoads() throws Exception{ MinioClient minioClient = MinioClient.builder() .endpoint("http://172.23.27.119:7480") .credentials("4S897Y9XN9DBR27LAI1L", "WmZ6JRoMNxmtE9WtXM9Jrz8BhEdZnwzzAYcE6b1z") .build(); composeObject(minioClient,"compose","compose",List.of("test1","test2"),"test"); } public boolean composeObject(MinioClient minioClient,String chunkBucKetName, String composeBucketName, List chunkNames, String objectName) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException { List sourceObjectList = new ArrayList(chunkNames.size()); for (String chunk : chunkNames){ sourceObjectList.add( ComposeSource.builder() .bucket(chunkBucKetName) .object(chunk) .build() ); } minioClient.composeObject( ComposeObjectArgs.builder() .bucket(composeBucketName) .object(objectName) .sources(sourceObjectList) .build() ); return true; }

运行报错

报错为400,BadDigest

完全一脸懵逼o((⊙﹏⊙))o,说好的兼容S3呢?

问题排查 日志

第一点想到的就是查看rgw日志,看看究竟出错是什么原因

日志如下:(在此只截取了部分日志)

image-20211104143431795

日志经过分析之后,之前的两次head request(获取test1和test2的元数据信息)以及init multipartUpload都是成功的,但是最终在第一次上传第一块的时候出现了错误(也就是test1),报了400的错误,op状态码为-2005,报了等于没有报错,这不搞笑吗?我咋知道-2005啥意思?

不行,去看看rgw源码中-2005究竟是啥(唉,笔者C++只知道一些语法,不太会,以下都是随机分析的结果,有点破案的感觉)

最终在rgw下面的

好家伙,终于找到2005这个错误码

image-20211104144053320

​ 成功了一半了,哈哈哈哈(现在回过头来看看还是自己太年轻了。。。。)

继续跟踪ERR_BAD_DIGEST,出现的位置

最终在rgw_op.cc下面找到了藏身之处,看名字,嗯,应该是处理上传的代码,一共出现了4次,要排查的地方还不多,内心暗自高兴

image-20211104144411842

首先看到了第三处和第四处,发现如果是这两处报错的,一定会有对应的日志输出,但是明显之前的rgw日志值没有对应的错误日志,因此排除

image-20211104144621243

那么剩下的只剩下第一处和第二处,这两处代码几乎都是一致的,如下

if (supplied_md5_b64 && strcmp(calc_md5, supplied_md5)) { op_ret = -ERR_BAD_DIGEST; return; }

貌似是在对提供的md5(supplied,命名有点意思)进行校验,但是不太确定

随后我仔细看了一下两处所在对应的方法

image-20211104145132572 可以很明显的看到第一处为Put,第二处为Post,而我的rgw日志是Put请求,因此锁定在第一处(就快要找到真相了) ![image-20211104145215146](https://img-blog.csdnimg.cn/img_convert/b5ce8c0abcbfd2853c85c60cadb9249d.png)

继续分析第一处的代码

发现这个东西

image-20211104145527793 由于这几处都是出现在一起的,第一个是supplied_md5_b64,但是还是不太确定是不是`Content-MD5`,但是下面的几个和请求头中的非常像 ![image-20211104145703581](https://img-blog.csdnimg.cn/img_convert/8c45dff24c0291946829de5962e4696a.png) 因此我就怀疑是请求头中的MD5了 对比日志

为了有对比参考的样本,和报错的rgw日志比较,我决定使用aws s3的sdk进行一次实验,原理和minio的一样,也是将compose中原本存在test1,test2进行合并,需要注意点就是partNumber是从1开始的,不是从0开始,从0开始会报错,别问我为啥知道,因为踩过坑了。。。。

@Test public void test1(){ String bucketName = "compose"; String keyName = "test"; AWSCredentials awsCredentials = new BasicAWSCredentials("4S897Y9XN9DBR27LAI1L","WmZ6JRoMNxmtE9WtXM9Jrz8BhEdZnwzzAYcE6b1z"); AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(awsCredentials)) .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://172.23.27.119:7480","")) .withPathStyleAccessEnabled(true) .build(); InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest("compose","test"); InitiateMultipartUploadResult initResponse = s3Client.initiateMultipartUpload(initRequest); List partETags = new ArrayList(); List list = List.of("test1","test2"); for (int i = 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3