Scaleway Object Storage 不稳定和 Mastodon 迁移备份笔记

我的长毛象实例 douchi.space 一直采用 Scaleway 的 Object Storage,因为它们前 75G 免费,对于这种小服务很划算。但是最近一个月连续发生两次故障,因为是免费 tier 所以客服修复的时间也没有保证。本文记述了故障可能的产生原因、debug 过程、修复方法和以后可能采取的 precaution messures。

Incident

先叙述一下事件经过,想要直接看解决方案的可以点此链接跳转

首先造成本站用户两天发图看图全部碰运气这个事的锅在我。第一次出现故障的时候我就做了备份,但是因为客服在一天之内解决了问题所以我就没有启用那个备份。

短短不到一个月,第二次故障又出现了:

这次客服回的慢很多,我又听说荷兰区服务没有巴黎稳定,于是参考这篇 object storage 跨区迁移教程装了个 rclone 开始把本站在荷兰区的媒体迁移到巴黎区的 bucket 上。(aws s3 cli 看了半天文档也没找到如何快速在两个 endpoint 间迁移,怀疑要写 ACL,犯懒弃坑)

怪我高估了这个迁移 script 的性能,想说服务器好说有 20Mbs 的 IO 吧,应该用不了几个小时。结果实际上奇慢无比,跑了几小时基本是 1G/h 的速度,我就有点慌了,才开始用 mastodon cli 清理了一下媒体文件,从本来的 80G 降到只保留一周缓存的 30G 左右。

但为时已晚,rclone sciprt 还在无休止地跑,本站用户发图看图极为不便。于是我今天痛下杀手把 mastodon 挂在新的巴黎 bucket 上了。反正能发新图看新图有些老图看不了总比不能发新的看新的强。截止 2/25 2:40pm PST,这次 incident 总计 impact 两天半,要是上班发生这种事我不被 fire 也得写 COE 了🤦🏻‍♀️(咦这篇不就是 COE )感谢长毛象友的包容。

2/26 11AM 更新:时隔 3 天半客服终于回邮件声称解决了,root cause 是“bucket was desynchronized”,以后可以直接拿来当关键词找客服。

Potential Root Cause

虽然曾在亚麻工作,但我对 object storage 底层原理并不了解,平时也只是拿来就用。因此以下仅为本人推测:

Object storage 管理媒体文件的服务运行不畅(index or cache slow, need fix or restart),因此即使媒体文件即使已经传输到存储空间上,但对外界来说”找不到“这个媒体文件。

作为 object storage 的用户(我),无法直接接触存储服务器上运行的底层服务,因此只能等 Scaleway 方面客服踢给 engineer team 解决。但由于客服对底层服务也不熟悉,一个问题可能有多种成因,因此在踢皮球期间我的媒体服务继续不稳定。

Impact

我到现在也不是特别确定这次和月初那次是同一个 root cause。具体表现:

期间本站图片可以上传,但上传之后无法显示(图裂)。外站图片也是图裂,但可以点击发布时间到对方的服务器上直接查看(因为裂的只是本站的缓存),但如果对方锁嘟的话便无法用此方法查看(因为去外站相当于匿名用户查看)。

我在后台 debug 则发现在 Scaleway console 里,有时候这个 object 会存在,有时候则不存在。此外 Mastodon sidekiq 里也没有 S3 相关错误,证明图片本身确实被正确上传到了媒体存储上,因此断定是 Saleway 那边的锅,于是发 ticket 给客服。

Solution

  1. 在 object storage 给客服开 ticket,描述问题、问题发生时间,以及提供一两个受此问题影响的 object public link。
  2. 清理 mastodon 媒体文件,减少需要迁移的文件数。(我一开始没有做这一步,追悔莫及)
  3. 在备份目标放创建一个新 bucket,用这篇教程在自己的任意 instance 上安装 rclone 并备份媒体。
    • 任何 server 都行,但我图方便直接在我运行 mastodon 的服务器上跑了。如果你有 dedicated server 应该可以改改 param 让 rclone 跑得更快。我没有这么做是因为我懒了,并且很后悔……
    • 由于近一个月发生了两次类似事件,我把备份媒体从本来在用的荷兰区换到了据说比较稳定的巴黎区。
  4. 备份完成(在我这里是接近完成)后,参考这篇云存储 setup 教程把现在在使用的媒体存储迁移到新的 bucket 上。需要改的地方有:
    1. nginx (如果你有设置的话),如果你之前是按上面提到 pullopen 那篇教程设置的话,应该在 /etc/nginx/sites-available/media
      1. location /SOURCE_BUCKET_NAME/-> location /DEST_BUCKET_NAME/ 这步不改的话旧的媒体可以显示,但新传图会 503.
      2. proxy_pass 改成新的 endpoint
    2. .env.production 下面几项分别改成新的 bucket 名和地区
      1. S3_BUCKET=SOURCE_BUCKET_NAME
      2. S3_ENDPOINT=SOURCE_BUCKET_ENDPOINT
      3. S3_REGION
    3. 重启 Nginx 和 Mastodon
      1. sudo nginx -s reload && systemctl reload nginx
      2. sudo systemctl restart mastodon-websudo && systemctl restart mastodon-streaming && sudo systemctl restart mastodon-sidekiq (不一定三个全部重启,但我一般怕出幺蛾子都一起重启)
  5. 这时你的 Mastodon 就已经在使用新的 bucket 了,为了保险起见我会时不时再 run rclone sync --progress old_bucket new_bucket 确保期间漏掉的媒体同步(这个命令默认不会删除 old_bucket 里没有的媒体,所以可以放心)

Precaution Messures

为了杜绝上述问题在未来发生,几个 precaution measures 可以采取:

  1. 定期清理 mastodon 缓存,不要觉得反正不到 75G 就懒得清理。偷懒一时爽,备份火葬场。(毕竟清理缓存也经常要跑好几个小时)
    1. RAILS_ENV=production ./bin/tootctl media remove --days 7 --verbose
    2. RAILS_ENV=production ./bin/tootctl media remove-orphans
    3. RAILS_ENV=production ./bin/tootctl preview_cards remove --days 7 --verbose
  2. 留一个备份 bucket,定期 run rclone sync 来备份,这样主 bucket 有问题时候可以快速 sync 然后切换到新 bucket 上。当然大家也可以做个 cron job 来定期自动备份,但是懒如我怎么会做这种事情呢……定期备份就已经很给面子了。记得跑备份的时候要开 screen

这篇算是我写了这么久博客第一次写 COE 吗……果然自己捣鼓比上班用心多了。


如果喜欢本文的话,欢迎在 Patreon 给我打赏顺便解锁一下小 perks(不喜欢月费的话页面最下方可以 make custom pledge 输入自定义金额 (ง •̀_•́)ง)。Patreon 里提供诸如 1:1 聊天和博客选题投票等金主特权,如果想多聊几毛钱欢迎来成为金主:Become a Patron!
Loading spinner

Leave a Reply

Your email address will not be published. Required fields are marked *

seventeen − 7 =