对象存储
目前,对象存储(Object Store)在网站中的文件下载、图床、附件存储等领域得到了广泛应用,如chatGPT的文件训练数据也存储在对象存储中。
对象存储具有以下优势:低成本、高可靠、低费用、通用接口、海量扩容、数据更安全、数据可加密
。
它将数据作为对象进行管理,与其他存储架构不同。
-
• 文件系统将数据作为
文件层次结构
进行管理 -
• 块存储则将数据作为扇区和轨道内的
块
进行管理
国内公有云厂商,主要有:阿里的OSS、百度的BOS和腾讯的COS、华为的OBS。
国外就是亚马逊的S3,于2006年3月首次亮相,Microsoft Azure Blob存储、以及2010年5月发布的谷歌云存储。
阿里云OSS在2011年正式上线,据说能提供99.9999999999%(12个9)的数据持久性,99.995%的数据可用性。
即便如此,去年底也曾经爆发过将近1小时的服务不可用,对我们的DHub服务带来了不少的影响。
详见2023-11-19:由上周末的阿里云事故想到的
S3的基本概念
S3,全称Simple Storage Service,是对象存储的一种,由AWS(全球最大的云服务商)提供。
表现为一个超大的硬盘,对象存储理论上是一个全球存储区域网络(SAN),可以实现跨区域、跨节点、跨数据中心的海量数据调度。
可以在其中存储和检索数字资产,进行无上限的文件存储。
从技术上讲,亚马逊的架构有一些不同,通过S3协议存储和检索的资产被称为对象,对象存储在存储段(bucket)中。
S3除了是亚马逊的存储名称外,另外也是一种对象存储的读取访问协议。
与硬盘一样,对象和存储段也可以通过统一资源标识符(Uniform Resource Identifier,URI)查找。
2个典型应用场景
1、企业私有化存储需求:
- • 可以采用混合云存储技术,部分数据存储在公有云上,部分存储在私有云上。
2、如果公司尚未开通或购买对象存储服务、或者研发是在内网开发,可以按下面步骤来处理:
1、下载安装MinIO,可以在本机进行调试,因为它提供了标准的S3接口。
2、当产品部署时,将协议和地址更改为公有云厂商的接口。
MinIO
IMinioClient minioClient = new MinioClient()
.WithEndpoint("play.min.io")
.WithCredentials("Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG")
.WithSSL()
.Build();
对比
AWS S3
IIMinioClient minioClient = new MinioClient()
.WithEndpoint("s3.amazonaws.com")
.WithCredentials("YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY")
.WithSSL()
.Build();
MinIO
MinIO应该是目前最好、最快的对象存储了。
其创始人是Google Gluster
存储的核心骨干,离职后创立了MinIO。
MinIO非常简单,步骤如下:
1、下载
https://dl.min.io/server/minio/release/windows-amd64/minio.exe
2、将minio.exe
文件加入到系统启动的PATH
3、启动MinIO
.\minio.exe server D:\MinIO --console-address :9090
D:\MinIO代表:MinIO 存储数据的路径
启动成功后访问:http://127.0.0.1:9090/login
界面如下:
默认用户名/密码:minioadmin
/minioadmin
可以看到,存储数据的文件夹
建了2个bucket,superwinner
和superworks
。
注意:bucket名称只能小写。
上传一张图纸试试:
创建Access Key。 这个下面编码需要用。
如何开发中使用?
典型的部署图
示例代码
详见官方开发文档:
https://min.io/docs/minio/linux/developers/dotnet/minio-dotnet.html
1、实现一个本地文件的上传。
using System.Net;
using Minio;
using Minio.DataModel.Args;
namespace FileUploader;
/// <summary>
/// 这个例子首先会检查bucket是否已经存在,
/// 如果不存在则创建一个新的bucket,
/// 接着会将一个文件上传到这个bucket中,
/// 这个文件名为 "D:\高压一次方案图.pdf",
/// 你可以创建一个同名的文件,或者在下面定义的位置更改文件名。
/// </summary>
public static class FileUpload
{
private static bool IsWindows()
{
return OperatingSystem.IsWindows();
}
private static async Task Main(string[] args)
{
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
// | SecurityProtocolType.Tls11
// | SecurityProtocolType.Tls12;
var endpoint = "127.0.0.1:9090";
var accessKey = "Y5OcTZCfFNs5UfO24ex2";
var secretKey = "8ip9O3n5oikIOhsoewPZ4oSWyHd87LpLmrH9nzcm";
try
{
using var minio = new MinioClient()
.WithEndpoint(endpoint)
.WithCredentials(accessKey, secretKey)
.Build();
await Run(minio).ConfigureAwait(false);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
if (IsWindows()) _ = Console.ReadLine();
}
/// <summary>
/// 上传文件到Bucket的任务
/// </summary>
/// <param name="minio"></param>
/// <returns></returns>
private static async Task Run(IMinioClient minio)
{
// 创建一个名为mymusic的新Bucket。
var bucketName = "superworks";
// 对象名
var objectName = "高压一次方案图.pdf";
// 待上传的本地文件
var filePath = "D:\\高压一次方案图.pdf";
var contentType = "application/octet-stream";
try
{
var bktExistArgs = new BucketExistsArgs()
.WithBucket(bucketName);
var found = await minio.BucketExistsAsync(bktExistArgs).ConfigureAwait(false);
if (!found)
{
var mkBktArgs = new MakeBucketArgs()
.WithBucket(bucketName);
await minio.MakeBucketAsync(mkBktArgs).ConfigureAwait(false);
}
var putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName)
.WithObject(objectName)
.WithFileName(filePath)
.WithContentType(contentType);
_ = await minio.PutObjectAsync(putObjectArgs).ConfigureAwait(false);
Console.WriteLine($"\n成功上传:{objectName}\n");
}
catch (Exception e)
{
Console.WriteLine(e);
}
// 为方便Windows用户,如果没有这行,测试运行完成后窗口会立即消失。
if (IsWindows()) _ = Console.ReadLine();
}
}
2、效果如下: