对象存储
目前,对象存储(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、效果如下: