aws的各种坑-戊
太久没更新了,倒不是因为别的,而是因为有些小问题没开case后来也慢慢解决了,又没及时做记录。
这次是遇到个跟S3有关的事。背景如下:
业务那边时不时会从第三方厂商拿个固件文件,由我这边放到S3,并且每次放的时候要把这个文件的md5拿出来也放到S3,追加到一个list文件里。
- 传固件文件到S3
- 改S3上固件文件的acl设为公开可读
- 算固件文件的MD5
- 把list从S3拖到本地
- 把固件文件信息以及MD5追加到list文件
- 把list文件传到S3
- 把list文件的acl设为公开可读
我这种懒人大概也就只愿意做前面两步,因为这两步能用awscli的一条命令搞定。
至于后面那几步嘛,我想了想,文件送到S3自然会触发一个事件,这个事件应该是能被lambda捕获处理的。
去lambda一看还真有,于是自己造了个小文件传到s3,抓了putobject事件的event,当成lambda的test case,发现里面还有个etag,怎么看怎么像个md5,把小文件的md5算出来跟etag一比还真是一样的
于是动手,大概思路如下
- 把已有的list拿出来
- 固件文件上传到S3时产生的event中etag抠出来,整理成符合list格式的记录
- 将该记录放到已有list最前面
- 把list塞回s3
- list的acl也写成public-read。毕竟这个list和固件文件一样,也是要给设备直接读取的,自然得允许外网匿名下载
是这么想的,lambda里也是这么写的,看起来/验证之后一切都OK,直到后来我发现,个别固件文件的md5有问题,然后就被业务吐槽了一顿。。。
——————好长长长的背景——————
关于S3的etag,之前看文档,大意是,如果没有启用SSE-C或SSE-KMS这两种加密方式,默认情况下etag就是文件的md5。
在这篇文档里也有体现:https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/API/RESTCommonResponseHeaders.html
之前看文档的时候光注意看etag相关说明的上面一部分了『Objects created through the AWS Management Console or by the PUT Object, POST Object, or Copy operation:』
下面那一句没注意看:【Objects created by either the Multipart Upload or Part Copy operation have ETags that are not MD5 digests, regardless of the method of encryption.】
说白了意思就是,即使被操作的桶用的是标准的服务器端加密或者没启用加密,如果文件是Multipart Upload或者Part Copy,那么etag反映的也不会是相关一整个文件的md5值
这个其实很好理解,因为分块操作的是,当然是挨个算每个块的md5值。反正不是体现整个文件的md5值就对了
又看了看文档,大于5G的文件强制要求使用multipart upload,至于小于等于嘛,putobject理论上没问题
但是awscli的默认配置,关于这一部分的配置项(multipart_threshold )默认值是8兆,也就是说只要文件大于8兆就会启用这种上传方式,进而导致etag不如我的预期。
ref:https://awscli.amazonaws.com/v2/documentation/api/latest/topic/s3-config.html#multipart-threshold
而我这边上传的固件文件都是十二三兆,按照默认配置,自然是用multipart upload传的……难怪算出来的etag不但不是md5,最后竟然还是以 -2 结尾。正经哈希值都是十六进制的内容,哪还带个-
当然 multipart_threshold 这个参数也是可以调整的,只要不担心出岔子,一口气写个5G也行
1 |
|
说白了还是自己不够仔细,没注意到文档里的那句话,从而没有调整default.s3.multipart_threshold的值,导致的etag不符合预期
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!