Skip to content

基于 Golang 模拟百度网盘云存储,涉及有Golang、Redis、Ceph、阿里OSS、docker及Kubernets等技术栈。

Notifications You must be signed in to change notification settings

metashops/filestore-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

以下是该项目的笔记,随手记录,仅供参考

1、项目概述

项目主要做什么?

  • 基于 Golang 实现分布式文件上传服务系统
  • 结合开源存储 Ceph 公有云(阿里OSS)、支持断点续传及秒传功能
  • 微服务化及容器部署

项目收获

  • Redis / RabbitMQ ,结合缓存服务,rabbitMQ将同步逻辑转换成异步来执行,服务只需要往MQ发送数据就行,不需要关心具体是谁来消费提交的任务
  • Docker / Kubernets 进行部署
  • 分布式对象存储Ceph
  • 阿里云 OSS 对象存储服务

收获那些?

  • 文件分块断点上传 & 秒传
  • 了解对象从 Ceph 迁移到阿里云 OSS的经验

2、简洁版云盘

主要接口:

接口描述 接口URL
上传 POST /file/upload
查询 GET /file/query
下载 GET /file/download
删除 POST /file/delete
修改 POST /file/update

思考?上传文件后,如果需要去查询,怎么查?关键点是,需要每次上传的文件内容记录下来作为文件唯一标志,唯一标志一般我们使用 hash 、sha1、md5这些,记录比如文件ID、文件名、上传时间、文件大小、存储的路径等等都要保留下来。这样方便在查询时,把这些信息返回给用户。

如何记录下来呢,怎么实现?定义一个结构体来存储即可。

3、系统升级

上面我们是把文件上传后存储到本地内存的,这样关闭服务就没有了,我们需要将文件存储到MySQL中。

MySQL 采用主从集群,master 和 slave

数据库表是如何设计的?

文件表:filesha1,filename.filesize,file_adder,create_at创建时间,update_at文件更新时间,status状态

Go 操作MySQL

  • 在Go访问数据库,通过sql.DB来管理数据库连接对象
  • 通过sql.Open 来创建协程安全的sql.DB对象(一般是长连接的,不需要每次调用Open方法)
  • 优先使用 prepared statement 可以防止sql注入

4、注册登录模块

支持用户注册与登录 在DB模块新加一个用户注册方法,也就是往MySQL的用户表插入使用一条新的记录

登录接口,需要生成访问凭证,我们也将token存在数据库token表中

总结:

  • 用户注册接口逻辑

    • (1)判断请求是否为get请求,直接返回注册页面;反之执行下一步

    • (2)校验参数是否有效(用户名长度及密码是否有非法)

    • (3)加密用户密码

    • (4)将用户名密码等存入数据库tbl_user表及返回结果

  • 用户登录接口

    • (1)校验用户名及密码

    • (2)生成访问凭证(token)

    • (3)存储 token 到数据库 tbl_user_token 表

    • (4)返回 username,token,重定向URL等信息

  • 用户信息查询接口

    • (1)解析请求参数

    • (2)验证token是否有效

    • (3)查询用户信息

    • (4)组装并且响应用户数据

  • 拦截器验证 token

    • 首先获取 username 和 token

    • 然后判断 token 是否有效,无效直接返回错误信息给客户端

    • 有效的话,传递到具体的handle函数中进行逻辑处理

5、秒传模块:

1、妙传原理:首先用户上传文件,然后上传server接受到数据流之后,它会一边将数据存到本地,一边通知hash计算模块 通过它计算当前文件内容的哈希值,等整个文件上传完成之后,就会得到整个文件的哈希值,上传server将哈希值写入到唯一文件表, 最后,将文件元信息关联到用户文件表里面,下次查询时通过用户文件表进行查询,如果发送秒传情况下,直接将用户元信息关联到用户文件表里面

2、场景:

(1)用户上传

(2)离线下载

(3)好友分享

3、关键点:

(1)记录每个文件的 hash 值,一般使用MD5或SHA1等计算,这样用户下一次上传文件时,只要哈希相同,可以省去重复上传

(2)用户文件关联

4、数据库设计,有用户文件表

5、总结

  • Hash 算法的应用场景与对比

  • 秒传的原理和简单实现:其实就是后端做了文件的共享,相同内容的文件只会上传一份,同时也只会保持一份

6、分块上传与断点续传:

(1)概念

  • 分快上传:文件切成多块,独立传输、上传完成后合并

  • 断点续传:基于分块上传实现的,传输暂停或异常中断后,可基于原来进度重传

  • 分块说明:对于小文件不建议分块上传;可并行上传分块,且无序传输;减少传输失败重试的流量及时间

(2)实现说明:初始化上传;上传分块;通知上传

(3)总结

7、Ceph 集群

1、Ceph 介绍,官网

Ceph 提供对象、块和文件存储,

2、Ceph 架构,官网

Ceph 集群特点:

  • 一个Ceph存储集群至少需要一个Ceph Monitor和两个OSD守护进程。但是,如果要运行Ceph文件系统客户端,那就还需要部署一个元数据服务器Metadata Server.
  • Ceph OSDs 负责存储数据,处理数据的的复制、恢复、回填、再均衡,并通过检查其他OSD守护进程的心跳来向Ceph Monitors提供一些监控信息。
  • Ceph Monitors 维护者展示集群状态的各种图表
  • MDSs 元数据服务器,为Ceph文件系统存储元数据。Ceph块存储和Ceph对象存储不需要MDS。

3、分布式存储

把对象映射给 PG,再把 PG 映射给 OSD

Ceph把客户端的数据保存为存储池内的对象,通过CRUSH算法,Ceph可以计算出哪个PG应该持有的对象,然后进一步计算出哪个OSD守护进程持有该PG。CRUSH算法使得Ceph存储集群可以动态地伸缩、再均衡和修复。

8、阿里云 OSS

已经通过 Ceph 搭建的私有云存储后,接下来学习阿里云OSS,也就是公有云对象存储服务。

因为开发并且运营一个项目,很多时候团队或者企业都是考虑技术能力、人力成本、时间成本等等因素。

文件存储系统,用户量少的情况下,使用 Ceph 之后,用户上传文件,随便什么存储,但是文件存储规模巨大情况下,就需要增加机器节点拓展集群的规模,或者提高机器配置,另外还要解决高并发带来的各种性能问题,这样运维成本就上去了,考虑这样情况,我们将文件存储到第三方公有云上,这样数据运维部分工作抛给第三方。

阿里云 OSS

1、为什么选择阿里云OSS?

因为阿里云目前的OSS也是比较成熟稳定,用起来也是比较放心。

2、OSS是什么?

OSS 是对象存储服务,适用于存放任意类型文件,以及各种网站。

3、OSS的特点

  • 可靠性

  • 安全性

  • 易使用,官方文档

  • 处理能力强,处理海量规模;图片处理;音频视频转码

4、OSS 相关术语

英文 中文
Bucket 存储空间,桶
Object 对象或文件
Endpoint OSS访问域名
ACL 存储空间或文件权限
//

5、登录管理控制台

6、代码实现

9、RabbitMQ 与 异步任务

客户端——》上传到服务——》OSS
OSS——》到服务器——》客户端

上面客户端传输到OSS在返回,这个过程耗时有点长,可以使用异步解决这个问题。

上传节点到服务器某个临时节点,然后可以可以立即向客户端返回响应结果,然后文件从上传节点,传输到OSS这个过程是随后某个时间点完成,这过程也是对客户端不可见。

异步逻辑架构:

  • 上传流程:文件从客户端传到上传节点的缓冲区,再写到某个指定的目录(临时节点),然后程序往队列扔一条记录,最后返回给客户文件已经存储完毕(但实际是存在临时节点,只是一个异步处理而已)。
  • 转移流程:转移流程我们单独或起一组程序监听任务队列,只要队列有记录,那么将队列获取数据进行解析或一定规则读取出来,然后再传到OSS。最后的话临时节点可以删除了

RabbitMQ 工作原理和转发模式:

概述:MQ 是一种遵循 AMQP 协议的 MQ 服务的,它可以解决逻辑耦合,异步任务场景,消息持久化,削峰。

特点:可靠性(持久化、传输确认、发布确认)、可扩展性(可以多个节点)、多语言客户端支持

安装:

docker pull rabbitmq
docker run -d --hostname rabbit-svr --name rabbit -p 5672:5672 -p 15672:15672 -p 25672:25672 -v /mydata/rabbitmq:/var/lib/rabbitmq rabbitmq:nagement

架构微服务化

优化:将项目进行微服务化,原来一个系统包含很多模块的(账号管理、文件上传下载、文件转移及数据库管理等等模块)如果其中一个模块出现故障那么整个系统就不可用。所以我将这样一个单体系统打散出来,独立成多个微型服务,然后每个服务都提供比较单一功能,并且也可以单独运行、部署及升级等。

Gin 框架

Gin 运行原理:

首先web 程序初始化时候,通过创建engine对象,然后通过这个对象向net.http注册请求对应的handler,在基础之上进行封装路由规则,然后根据http请求方法进行处理用户的请求。

如有问题,欢迎关注我的微信公众号:

About

基于 Golang 模拟百度网盘云存储,涉及有Golang、Redis、Ceph、阿里OSS、docker及Kubernets等技术栈。

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published