最近用 GoFrame 重构了图床

前言

随着技术栈的转变,默默地给自己定了个小目标:用 GoLang 重构做过的一些小玩意!所以,之前开发的 ImageX 也在计划之内。

图床设计

重构的图床基本还是沿用的 ImageX 之前的思路:

  • Backblaze b2 作为背后的存储服务
  • 每个图片有唯一的 codedelete_code
  • 每个图片在实际存储时,根据 hash 值去重
  • 本地仅存储「热数据」,本地定期清理无访问量的文件

一点坑

整个实现过程并不是特别的复杂,只是简单的把 PHP 实现的逻辑,再用 GoLang 实现一遍。

唯一的区别在于:之前 b2 创建的 bucket 和 s3 不完全兼容,所以我使用了 minio 的 b2 gateway 做了一层中转;但现在这个问题不存在了,可以使用 s3 SDK 对新创建的 bucket 资源进行 CRUD。

本着「无如必要,不引入新实体」的原则,我需要做一件事:创建新的 bucket,把旧数据转到新的 bucket,然后删除旧 bucket。

创建新桶

创建新的 Bucket 其实挺简单,在网页上操作一下就行。不过要注意:新建 Bucket 的「Lifecycle Settings」使用的是「Keep all versions of the file (default)」。

也就是说,如果你对存储桶中的同名文件做了更新/删除操作,旧的文件依然会保留,并占用体积,并且在你未来的账单中体现。比如,我发现之前用来备份 Portainer 的一个 Bucket,就因为这个设定占用了 4GB,完全不符合预期。

数据迁移

Backblaze 官方推荐的迁移工具是叫 Transmit,但据说并不好用。在这里,我使用的是 rclone 这个工具。首先需要在 Backblaze 官网上生成 MasterKey,然后运行 rclone config 配置好 b2 的远端存储,具体可以参考这个 文档

然后使用 rclone copy ${remote}:${bucket1} ${remobe}:${bucket2} 命令把数据拷贝到新桶中(注意替换 remotebucket1bucket2),然后就是漫长的等待。

对于图库这种场景,保存历史版本的必要性不高。在迁移前,可以先使用 rcone cleanup ${remote}:${bucket1} 对旧数据进行一次清理:清理旧版本和已标记为删除的文件。

数据清理

因为有历史版本的存在,所以删除文件也需要分两步:先删除,后清理。

1
2
rclone delete ${remote}:${bucket1}
rclone cleanup ${remote}:${bucket1}

总结

除了数据迁移的过程中踩了点坑,花费了些时间来解决,其它都还好,用点下班时间和周末时间就搞定了。

最后,附上重构后的开源地址:endpot/ImageGo,欢迎轻拍。