Java、Rust 技术交流群: 783303214
Ceph对Swift的支持
和Ceph一样,(No Taylor)Swift也是优秀的分布式的对象存储系统,OpenStack开发Swift的攻城狮对二者进行过比较,简单来说,就是各司其职,Ceph在块存储方面很优秀,是强一致性的(读写多并发时要求写完就能被后续访问读到,且数据一致),Swift只做对象存储,是最终一致性的(读写多并发时在一段时间后能被后续访问读取,且数据一致),关于这二者的比较以及分布式系统一致性的比较,参见: Ceph和Swift的比较 以及 CAP原理、一致性透析,就我个人而言,更偏向于ceph,它有着比Swift更多的应用场景,这些对比在前面那篇OpenStack的工程师写的文章里都有介绍。
Ceph 的SwiftAPI功能和Amazon S3相仿,不做多的阐述,详细见:Ceph object storageSwift api,注意两点:1.编码方式
2.集群生成的密码字符串的处理:
其他都很简单了,直接贴代码吧里面都有详细的注释:
import org.javaswift.joss.client.factory.AccountConfig;
import org.javaswift.joss.client.factory.AccountFactory;
import org.javaswift.joss.client.factory.AuthenticationMethod;
import org.javaswift.joss.model.Account;
import org.javaswift.joss.model.Container;
import org.javaswift.joss.model.StoredObject;
import java.io.File;
import java.util.*;
*
* Created by BBSee rolltion.zhang@foxmail.com on 2017/6/12.
*
public class SwiftClient {
private static String username = "testuser";//注意!在ceph集群里面创建user后如果需要支持Swift Api需要在当前user下创建一个subuser来作为这里的参数,不能直接使用radosgw的账户!
private static String password = "244 fz2gSqoHwR3lYtSbIyomyPHf3i7rgSJrF/IA";//密码是集群创建账号时对应的Swift的Secret_key而不是access_key
private static String authUrl = "xx.1x.14x.11x:748x/auth/1.0";// 有域名就写域名,没有就写IP:端口号
private static Account account;
static {
AccountConfig config = new AccountConfig();
config.setUsername(username);
config.setPassword(password);
config.setAuthUrl(authUrl);
config.setAuthenticationMethod(AuthenticationMethod.BASIC);
account = new AccountFactory(config).createAccount();
}
*
* 该方法用于创建容器
* @return
*/
public boolean createContainer(String containName) {
Container container = account.getContainer(containName);
container.create();
return container.exists();
}
*
* 该方法用于创建存储时的对象
* @param containName
* @param objectName
* @param filePath
* @return
*/
public boolean createObject(String containName,String objectName,String filePath) {
Container container = account.getContainer(containName);
StoredObject object = container.getObject(objectName);
object.uploadObject(new File(filePath));
return object.exists();
}
*
* 该方法用于元数据的添加或者更新
* @param containerName
* @param objectName
* @param newKey
* @param newValue
*
public void addNupdateObjectMetadata(String containerName,String objectName,String newKey,String newValue) {
Container container = account.getContainer(containerName);
StoredObject object = container.getObject(objectName);
Map metadata = new TreeMap();
metadata.put(newKey,newValue);
object.setMetadata(metadata);
}
**
* 列举当前用户已创建的容器名
*
* @return
*
public List listContainer() {
List list = new ArrayList();
Collection containers = account.list();
for (Container currentContainer : containers) {
list.add(currentContainer.getName());
System.out.println(currentContainer.getName());
}
return list;
}
*
* 该方法用于列举指定容器的内容
* @param containerName
* @return
*
public List getContent(String containerName){
List list=new ArrayList();
Container container = account.getContainer(containerName);
Collection objects = container.list();
for (StoredObject currentObject : objects) {
list.add(currentObject.getName());
System.out.println(currentObject.getName());
}
return list;
}
*
* 该方法用于获取Object到本地文件系统
* @param containerName
* @param objectName
* @param outpath
*
public void retrieveObject(String containerName,String objectName,String outpath){
Container container = account.getContainer(containerName);
StoredObject object = container.getObject(objectName);
object.downloadObject(new File(outpath));
}
**
* 该方法用于删除指定对象
* @param containerName
* @param objectName
* @return
*
public boolean deleteObject(String containerName,String objectName){
Container container = account.getContainer(containerName);
StoredObject object = container.getObject(objectName);
object.delete();
return !object.exists();
}
**
* 该方法用于删除指定的容器
* 你也许会看到官方这样写道:"The container must be empty! Otherwise it won’t work!",和S3一样,这里我们已经做了处理,忽略这个提示。
* @param containerName
* @return
*
public boolean deleteContainer(String containerName){
Container container = account.getContainer(containerName);
if(this.getContent(containerName).isEmpty()){
container.delete();
}else{
for(String str:this.getContent(containerName)){
this.deleteObject(containerName,str);
}
container.delete();
}
return !container.exists();
}
}