对象缓存服务的思考和实现

写在前面

目前在很多业务中,存储都大量的依赖了云存储,比如阿里云的 oss、华为云的 obs 等。但是如果有大量的上传/下载任务,云存储上的网络 I/0 就变成了一个很大的瓶颈。

于是我们打算在内网实现一个对象缓存服务,具体表现为:托管内网上传的对象,并最终转发到云存储;hold 住内网的下载请求,并从云存储把对象下载下来并缓存返回,这样下次该对象的请求就能直接由内网处理。

需要实现的功能

  • 上传/下载接口必须与云存储的一致。这样内部服务接入的时候不用关心是内网还是外网;
  • 域名一致。实现在内网访问,域名转发到缓存服务;在外网访问,域名转发到云存储服务;
  • 缓存服务和云存储服务的交互;比如:内网删除了对象,云储存服务能感知到;云存储服务删除了对象,内网能感知到;
  • 权限问题。缓存服务和云存储服务具有相同共用的权限;

实现思路

上传/下载接口必须与云存储的一致。这一点就是相同的接口分别对应两种实现,一种部署在内网,一种部署在在外网;

域名一致。解析问题找公司的运维配置不同的 DNS 解析即可;

缓存服务和云存储服务的交互问题。就是两个不同环境服务之间的通信问题,大致实现方案有:

  • websocket 长连接
  • 轮询
  • 长轮询
  • SSE
  • 消息队列

相关资料:

认识长轮询:配置中心是如何实现推送的?
Server-Sent Events 教程
SSE技术详解:一种全新的HTML5服务器推送事件技术
Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE

最终在实现上选择了长轮训的方案,理由是:即时响应、实现简单、没有很大的连接需求要用到 ws 的地步。

权限问题。权限问题我们参考了 s3-client 的设计思路,颁发给接入端 ak/sk, 然后接入端通过 ak/sk + 参数来生成签名,生成的签名当作认证信息通过 Authorization Header 传递给服务端,和服务端生成的相比较,如果一致则说明认证通过,这样的校验思路不仅能达到认证的目的,也顺便把验签的问题解决了。

值得注意的是,既然叫缓存服务,它就是可以不用保证完全可靠,它应该被设计的足够轻量,尽可能少的依赖外部,并且能够随时被拿掉而不会影响云存储服务。因此在设计上我们选择了依赖 h2 数据库,并且直接用 guava 做内存缓存。

posted @ 2022-07-31 23:07  JMCui  阅读(66)  评论(0编辑  收藏  举报