公開付費的非關係資料庫:百度物件儲存BOS
今天收到百度BCS的郵件通知:
百度物件儲存BOS(Baidu Object Storage),提供穩定、安全、高效以及高擴充套件儲存服務,支援單檔案最大5TB的文字、多媒體、二進位制等任何型別的資料儲存。資料多地域跨叢集的儲存,以實現資源統一利用,降低使用難度,提高工作效率。
特性
靈活管理資料
-
建立、檢視、刪除Bucket
- 使用者最多可以建立100個Bucket。
- 使用者可以修改、檢視Bucket的訪問許可權。
-
上傳、檢視、刪除Object
- 使用者可以儲存的Object沒有數量限制。
- Object支援文字、多媒體、二進位制等任何型別的資料。
- 每個Object可包含從0位元組到5TB的資料。
- 使用者可使用通用的和自定義的元資訊機制來定義資源屬性。
大檔案分塊上傳/斷點下載
- 對於超過5GB的超大檔案,使用者可以使用分塊上傳機制;超過5MB但不超過5GB的檔案可以由使用者選擇是否需要分塊上傳。
- 使用者將一個超大檔案拆分成子Object(又稱Part),分別上傳這些子Object,上傳完成後BOS將自動檢查資料,並將子Object組合成一個Object,完成分塊上傳。
- 分塊後的單個Part不能超過5GB,除最後一個Part外,單個Part不能小於5MB。
- 該功能在網路條件較差,或上傳檔案前無法確定檔案大小等場景下具有非常好的表現。
完善的API和開發工具
- BOS提供標準的REST介面,可與任何Internet開發工具包搭配使用。
- BOS基於原生的REST API,主要提供了以下三類API:
- Bucket操作
- Object操作
- ACL操作
- BOS提供了多種語言的SDK,Java、Python、PHP等。
功能完善的管理平臺
- 使用者可以通過Web管理平臺方便的操作Bucket和Object。
- 使用者可以通過Web管理平臺中的ACCESSKEY管理功能輕鬆的建立和管理自己的Access Key ID / Secret Access Key。
- 使用者可以通過Web管理平臺提供的監控功能,實時監控Bucket的讀寫情況和佔用空間等資訊。
海量資料儲存
- BOS支援任何型別資料的儲存、分享及使用。允許使用者將整個儲存基礎設施轉移到雲端,利用BOS的擴充套件性和按需付費的優勢,以處理不斷增長的儲存需求。
- BOS支援最大5TB的單檔案儲存,利用斷點上傳及下載功能,可以儲存多媒體視訊、軟體包等超大檔案。
應用場景
內容儲存和分享
BOS允許企業使用者和開發者將整個儲存基礎設施轉移到雲端,支援按需使用和付費。BOS支援任何型別資料(文字、圖片、音樂、視訊、日誌、應用程式等)的儲存,使用者既可以直接訪問,也可以把BOS作為應用程式的後端儲存,還可以將指定內容共享。
用於資料分析的儲存
無論是儲存用於分析的商業或科學資料,用於調整的圖片,還是用於轉碼的視訊,BOS都是企業使用者和開發者儲存原始資料的理想場所。BOS支援使用者使用BMR及雲媒體服務進行訪問和計算,在BMR和BOS之間的資料傳輸不會產生任何費用,降低使用者使用成本。
災備系統
BOS為災備系統提供穩定、安全、低成本和高可擴充套件的儲存支援,適用於政府和企事業單位關鍵資料的定期備份和異常恢復,有效保障核心資料的高安全性和高可用性。
網盤服務
BOS為網盤服務提供豐富的資料型別支援,滿足海量的資料儲存需求。儲存容量彈性擴充套件,儲存資料安全穩定,有力支援網盤業務需求的不斷增長,有效降低成本,提升使用者體驗。
專案實際使用驗證
直接使用JAR包
步驟如下:
1.在官方網站下載Java SDK壓縮工具包。
2.將下載的bce-java-sdk-version.zip
解壓後,複製到工程資料夾中。
3.在Eclipse右鍵“工程 -> Properties -> Java Build Path -> Add JARs”。
4.新增SDK工具包lib/bce-java-sdk-version.jar
和第三方依賴工具包third-party/*.jar
。
其中,version
為版本號,經過上面幾步之後,使用者就可以在工程中使用BOS Java SDK。
執行環境
Java SDK工具包可在jdk1.6、jdk1.7、jdk8環境下執行。
版本動態
本文件針對BOS Java SDK 0.8.2版本,歷史更新如下:
版本 0.8.2
無針對BOS的更新,使用者可以繼續使用上一版本而不受影響。
版本 0.8.1
更新copyObject中對copy_source的處理方法,當source object為非標準ASCII字元(例如:中文)時使用老版本Java SDK的使用者會出現簽名無法通過的現象,請及時進行版本更新。
Java驗證程式碼
Bucket
package com.boonya.bos.bucket;
import java.util.ArrayList;
import java.util.List;
import com.baidubce.services.bos.BosClient;
import com.baidubce.services.bos.model.BucketSummary;
import com.baidubce.services.bos.model.CannedAccessControlList;
import com.baidubce.services.bos.model.Grant;
import com.baidubce.services.bos.model.Grantee;
import com.baidubce.services.bos.model.Permission;
public class Bucket
{
/**
* 建立bucket
*
* @param client
* @param bucketName
*/
public void createBucket(BosClient client, String bucketName)
{
// 新建一個Bucket
client.createBucket(bucketName);
}
/**
* 獲取bucket列表
*
* @param client
*/
public void listBuckets(BosClient client)
{
// 獲取使用者的Bucket列表
List<BucketSummary> buckets = client.listBuckets().getBuckets();
// 遍歷Bucket
for (BucketSummary bucket : buckets)
{
System.out.println(bucket.getName());
}
}
/**
* 判斷Bucket是否存在
*
* @param client
* @param bucketName
*/
public boolean doesBucketExist(BosClient client, String bucketName)
{
// 獲取Bucket的存在資訊
boolean exists = client.doesBucketExist(bucketName);
// 輸出結果
if (exists)
{
System.out.println("Bucket exists");
} else
{
System.out.println("Bucket not exists");
}
return exists;
}
/**
* 刪除Bucket
*
* @param client
* @param bucketName
*/
public void deleteBucket(BosClient client, String bucketName)
{
// 刪除Bucket
client.deleteBucket(bucketName);
}
/**
* 設定Bucket的訪問許可權
*
* @param client
* @param bucketName
*/
public void setBucketPrivate(BosClient client, String bucketName)
{
client.setBucketAcl(bucketName, CannedAccessControlList.Private);
}
/**
* 設定指定使用者對Bucket的訪問許可權
*
* @param client
*/
public void SetBucketAclFromBody(BosClient client)
{
List<Grant> grants = new ArrayList<Grant>();
List<Grantee> grantee = new ArrayList<Grantee>();
List<Permission> permission = new ArrayList<Permission>();
// 授權給特定使用者
grantee.add(new Grantee("UserId_1"));
grantee.add(new Grantee("UserId_2"));
// 授權給Everyone
grantee.add(new Grantee("*"));
// 設定許可權
//Permission中的許可權設定包含三個值:READ、WRITE、FULL_CONTROL
permission.add(Permission.READ);
permission.add(Permission.WRITE);
grants.add(new Grant().withGrantee(grantee).withPermission(permission));
//client.setBucketAcl("bucketName", grants);
}
}
Object
package com.boonya.bos.object;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import com.baidubce.services.bos.BosClient;
import com.baidubce.services.bos.model.BosObject;
import com.baidubce.services.bos.model.BosObjectSummary;
import com.baidubce.services.bos.model.CopyObjectRequest;
import com.baidubce.services.bos.model.CopyObjectResponse;
import com.baidubce.services.bos.model.GetObjectRequest;
import com.baidubce.services.bos.model.ListObjectsResponse;
import com.baidubce.services.bos.model.ObjectMetadata;
import com.baidubce.services.bos.model.PutObjectResponse;
public class Object
{
/**
* BOS Java SDK本質上是呼叫後臺的HTTP介面,因此BOS服務允許使用者自定義Object的Http Header
*
* @param client
* @param bucketName
* @param objectKey
* @param content
*/
public void setHttpHeader(BosClient client, String bucketName, String objectKey, String content)
{
// 初始化上傳輸入流
ObjectMetadata meta = new ObjectMetadata();
// 設定ContentLength大小
meta.setContentLength(1000);
// 設定ContentType
meta.setContentType("application/json");
client.putObject(bucketName, objectKey, content, meta);
}
/**
* 使用者自定義元資料
*
* @param client
* @param bucketName
* @param objectKey
* @param content
*/
public void selfDefinitedObject(BosClient client, String bucketName, String objectKey, String content)
{
// 初始化上傳輸入流
ObjectMetadata meta = new ObjectMetadata();
// 設定ContentLength大小
meta.setContentLength(1000);
// 設定自定義元資料name的值為my-data
meta.addUserMetadata("name", "my-data");
// 上傳Object
client.putObject(bucketName, objectKey, content, meta);
}
/**
* 新增物件到Bucket
*
* @param client
* @param bucketName
* @param objectKey
* @param content
*/
public void putObject(BosClient client, String bucketName, String objectKey, String content)
{
// 以字串上傳Object
PutObjectResponse putObjectResponseFromString = client.putObject(bucketName, objectKey, content);
// 列印ETag
System.out.println(putObjectResponseFromString.getETag());
}
/**
* BOS一共支援四種形式的Object上傳,參考如下程式碼
*
* @param client
* @param bucketName
* @param objectKey
* @param byte1
* @param string1
* @throws FileNotFoundException
*/
public void PutObject(BosClient client, String bucketName, String objectKey, byte[] byte1, String string1) throws FileNotFoundException
{
// 獲取指定檔案
File file = new File("/path/to/file.zip");
// 獲取資料流
InputStream inputStream = new FileInputStream("/path/to/test.zip");
// 以檔案形式上傳Object
PutObjectResponse putObjectFromFileResponse = client.putObject(bucketName, objectKey, file);
// 以資料流形式上傳Object
PutObjectResponse putObjectResponseFromInputStream = client.putObject(bucketName, objectKey, inputStream);
// 以二進位制串上傳Object
PutObjectResponse putObjectResponseFromByte = client.putObject(bucketName, objectKey, byte1);
// 以字串上傳Object
PutObjectResponse putObjectResponseFromString = client.putObject(bucketName, objectKey, string1);
// 列印ETag
System.out.println(putObjectFromFileResponse.getETag());
}
/**
* 列出Bucket中的Object
*
* @param client
* @param bucketName
*/
public void listObjects(BosClient client, String bucketName)
{
// 獲取指定Bucket下的所有Object資訊
ListObjectsResponse listing = client.listObjects(bucketName);
// 遍歷所有Object
for (BosObjectSummary objectSummary : listing.getContents())
{
System.out.println("ObjectKey: " + objectSummary.getKey());
}
}
/**
* 簡單的讀取Object
*
* @param client
* @param bucketName
* @param objectKey
* @throws IOException
*/
public void getObject(BosClient client, String bucketName, String objectKey) throws IOException
{
// 獲取Object,返回結果為BosObject物件
BosObject object = client.getObject(bucketName, objectKey);
// 獲取ObjectMeta
ObjectMetadata meta = object.getObjectMetadata();
// 獲取Object的輸入流
InputStream objectContent = object.getObjectContent();
// 處理Object
// ...
// 關閉流
objectContent.close();
}
/**
* 簡單的讀取Object
*
* @param client
* @param bucketName
* @param objectKey
* @throws IOException
*/
public void getObject2(BosClient client, String bucketName, String objectKey)
{
// 新建GetObjectRequest
GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectKey);
// 獲取0~100位元組範圍內的資料
getObjectRequest.setRange(0, 100);
// 獲取Object,返回結果為BosObject物件
BosObject object = client.getObject(getObjectRequest);
}
/**
* 下載Object到檔案
*
* @param client
* @param bucketName
* @param objectKey
*/
public void downloadObjectToFile(BosClient client, String bucketName, String objectKey)
{
// 新建GetObjectRequest
GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectKey);
// 下載Object到檔案
ObjectMetadata objectMetadata = client.getObject(getObjectRequest, new File("/path/to/file"));
}
/**
* 只獲取ObjectMetadata
*
* @param client
* @param bucketName
* @param objectKey
*/
public ObjectMetadata getObjectMetadata(BosClient client, String bucketName, String objectKey)
{
ObjectMetadata objectMetadata = client.getObjectMetadata(bucketName, objectKey);
return objectMetadata;
}
/**
* 獲取下載Object的URL
*
* @param client
* @param bucketName
* @param objectKey
* @param expirationInSeconds
* @return
*/
public String generatePresignedUrl(BosClient client, String bucketName, String objectKey, int expirationInSeconds)
{
URL url = client.generatePresignedUrl(bucketName, objectKey, expirationInSeconds);
return url.toString();
}
/**
* 刪除Object
*
* @param client
* @param bucketName
* @param objectKey
*/
public void deleteObject(BosClient client, String bucketName, String objectKey)
{
// 刪除Object
client.deleteObject(bucketName, objectKey);
}
/**
* 拷貝Object
*
* @param client
* @param srcBucketName
* @param srcKey
* @param destBucketName
* @param destKey
*/
public void copyObject(BosClient client, String srcBucketName, String srcKey, String destBucketName, String destKey)
{
// 拷貝Object
CopyObjectResponse copyObjectResponse = client.copyObject(srcBucketName, srcKey, destBucketName, destKey);
// 列印結果
System.out.println("ETag: " + copyObjectResponse.getETag() + " LastModified: " + copyObjectResponse.getLastModified());
}
/**
* 拷貝Object
*
* @param client
* @param srcBucketName
* @param srcKey
* @param destBucketName
* @param destKey
*/
public void copyObject2(BosClient client, String srcBucketName, String srcKey, String destBucketName, String destKey)
{
// 建立CopyObjectRequest物件
CopyObjectRequest copyObjectRequest = new CopyObjectRequest(srcBucketName, srcKey, destBucketName, destKey);
// 設定新的Metadata
Map<String, String> userMetadata = new HashMap<String, String>();
userMetadata.put("<user-meta-key>", "<user-meta-value>");
ObjectMetadata meta = getObjectMetadata(client, destBucketName, destKey);
meta.setUserMetadata(userMetadata);
copyObjectRequest.setNewObjectMetadata(meta);
// 複製Object
CopyObjectResponse copyObjectResponse = client.copyObject(copyObjectRequest);
System.out.println("ETag: " + copyObjectResponse.getETag() + " LastModified: " + copyObjectResponse.getLastModified());
}
}
BosClient
package com.boonya.bos.samle;
import java.io.IOException;
import com.baidubce.auth.DefaultBceCredentials;
import com.baidubce.services.bos.BosClient;
import com.baidubce.services.bos.BosClientConfiguration;
import com.boonya.bos.bucket.Bucket;
import com.boonya.bos.object.Object;
public class Sample
{
public static void main(String[] args)
{
/**
* ACCESS_KEY_ID對應控制檯中的“Access Key ID”
*/
String ACCESS_KEY_ID = "02b45c338869400a869aecbe3";
/**
* SECRET_ACCESS_KEY對應控制檯中的“Access Key Secret”
*/
String SECRET_ACCESS_KEY = "4abf9389c29c4b36aaa9241d8";
// 初始化一個BosClient
BosClientConfiguration config = new BosClientConfiguration();
config.setCredentials(new DefaultBceCredentials(ACCESS_KEY_ID, SECRET_ACCESS_KEY));
//上面的方式使用預設域名作為BOS的服務地址,如果使用者需要自己制定域名,可以通過傳入ENDPOINT引數來指定
/**
* 注意:ENDPOINT引數只能用指定的包含Region的域名來進行定義,目前BOS只提供北京一個Region,因此ENDPOINT支援主域名http://bj.bcebos.com和備域名http://bj.baidubos.com,隨著Region的增加將會開放其他可以支援的域名。
*/
String ENDPOINT = "http://bj.bcebos.com";
config.setEndpoint(ENDPOINT);
BosClient client = new BosClient(config);
Bucket bucket=new Bucket();
String bucketName="boonyabucket";
if(!bucket.doesBucketExist(client, bucketName))
{
bucket.createBucket(client, bucketName);
}
Object obj=new Object();
obj.putObject(client, bucketName, "boonyakey","hello,bos!");
try
{
obj.getObject(client, bucketName, "boonyakey");
} catch (IOException e)
{
System.out.println("BOS獲取物件,異常:"+e.getMessage());
}
}
}
結果
Bucket感覺就是資料庫表(或者說是儲存區域),而Object就是資料,跟非關係資料庫的儲存方式很像,但BOS是一個開放的儲存物件平臺或者是公用資料庫儲存叢集。