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
aws configure set default.s3.multipart_threshold 20MB

说白了还是自己不够仔细,没注意到文档里的那句话,从而没有调整default.s3.multipart_threshold的值,导致的etag不符合预期


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!