<b>2.3 rados与librados</b>
<b></b>
librados模块是客户端用来访问rados对象存储设备的。ceph存储集群提供了消息传递层协议,用于客户端与ceph monitor与osd交互,librados以库形式为ceph client提供了这个功能,librados就是操作rados对象存储的接口。所有ceph客户端可以用librados或librados里封装的相同功能和对象存储交互,librbd和libcephfs就利用了此功能。你可以用librados直接和ceph交互(如与ceph兼容的应用程序、ceph接口等)。下面是简单描述的步骤。
第1步:获取librados。
第2步:配置集群句柄。
第3步:创建io上下文。
第4步:关闭连接。
librados架构图,如图2-5所示。
先根据配置文件调用librados创建一个rados,接下来为这个rados创建一个radosclient,radosclient包含3个主要模块(finisher、messager、objector)。再根据pool创建对应的ioctx,在ioctx中能够找到radosclient。再调用osdc对生成对应osd请求,与osd进行通信响应请求。
下面分别介绍librados的c语言、java语言和python语言示例。
1. librados c语言示例
下面是librados c语言示例。
#include <stdio.h>
#include <string.h>
#include <rados/librados.h>
int main (int argc, char argv**)
{
/*声明集群句柄以及所需参数 */
rados_t cluster;
char cluster_name[] = "ceph"; //集群名称
char user_name[] = "client.admin"; //指定访问集群的用户,这里用admin
uint64_t flags;
rados_ioctx_t io; //rados上下文句柄
char *poolname = "data"; //目标pool名
char read_res[100];
char xattr[] = "en_us";
/* 指定参数初始化句柄*/
int err;
err = rados_create2(&cluster, cluster_name, user_name, flags);
if (err < 0) {
fprintf(stderr, "%s: couldn't create the cluster handle! %s\n", argv[0], strerror(-err));
exit(exit_failure);
} else {
printf("\ncreated a cluster handle.\n");
}
/* 读取配置文件用来配置句柄*/
err = rados_conf_read_file(cluster, "/etc/ceph/ceph.conf");
fprintf(stderr, "%s: cannot read config file: %s\n", argv[0], strerror(-err));
printf("\nread the config file.\n");
/* 分解参数 */
err = rados_conf_parse_argv(cluster, argc, argv);
fprintf(stderr, "%s: cannot parse command line arguments: %s\n", argv[0], strerror(-err));
printf("\nread the command line arguments.\n");
/* 连接集群*/
err = rados_connect(cluster);
fprintf(stderr, "%s: cannot connect to cluster: %s\n", argv[0], strerror(-err));
printf("\nconnected to the cluster.\n");
//创建rados句柄上下文
err = rados_ioctx_create(cluster, poolname, &io);
fprintf(stderr, "%s: cannot open rados pool %s: %s\n", argv[0], poolname, strerror(-err));
rados_shutdown(cluster);
printf("\ncreated i/o context.\n");
//写对象
err = rados_write(io, "hw", "hello world!", 12, 0);
fprintf(stderr, "%s: cannot write object \"hw\" to pool %s: %s\n", argv[0], poolname, strerror(-err));
rados_ioctx_destroy(io);
exit(1);
printf("\nwrote \"hello world\" to object \"hw\".\n");
//设置对象属性
err = rados_setxattr(io, "hw", "lang", xattr, 5);
fprintf(stderr, "%s: cannot write xattr to pool %s: %s\n", argv[0], poolname, strerror(-err));
printf("\nwrote \"en_us\" to xattr \"lang\" for object \"hw\".\n");
rados_completion_t comp;
//确认异步rados句柄成功创建
err = rados_aio_create_completion(null, null, null, &comp);
fprintf(stderr, "%s: could not create aio completion: %s\n", argv[0], strerror(-err));
printf("\ncreated aio completion.\n");
/* next, read data using rados_aio_read. */
//异步读对象
err = rados_aio_read(io, "hw", comp, read_res, 12, 0);
fprintf(stderr, "%s: cannot read object. %s %s\n", argv[0], poolname, strerror(-err));
printf("\nread object \"hw\". the contents are:\n %s \n", read_res);
//等待对象上的操作完成
rados_wait_for_complete(comp);
// 释放complete句柄
rados_aio_release(comp);
char xattr_res[100];
//获取对象
err = rados_getxattr(io, "hw", "lang", xattr_res, 5);
fprintf(stderr, "%s: cannot read xattr. %s %s\n", argv[0], poolname, strerror(-err));
printf("\nread xattr \"lang\" for object \"hw\". the contents are:\n %s \n", xattr_res);
//移除对象属性
err = rados_rmxattr(io, "hw", "lang");
fprintf(stderr, "%s: cannot remove xattr. %s %s\n", argv[0], poolname, strerror(-err));
printf("\nremoved xattr \"lang\" for object \"hw\".\n");
//删除对象
err = rados_remove(io, "hw");
fprintf(stderr, "%s: cannot remove object. %s %s\n", argv[0], poolname, strerror(-err));
printf("\nremoved object \"hw\".\n");
rados_ioctx_destroy(io); //销毁io上下文
rados_shutdown(cluster); //销毁句柄
}
2. librados java语言示例
下面是librados java语言示例。
import com.ceph.rados.rados;
import com.ceph.rados.radosexception;
import java.io.file;
public class cephclient {
public static void main (string args[]){
try {
//获取句柄
rados cluster = new rados("admin");
system.out.println("created cluster handle.");
file f = new file("/etc/ceph/ceph.conf");
//读取配置文件
cluster.confreadfile(f);
system.out.println("read the configuration file.");
//连接集群
cluster.connect();
system.out.println("connected to the cluster.");
} catch (radosexception e) {
system.out.println(e.getmessage()+":"+e.getreturnvalue());
}
3. librados python语言示例
下面是librados python语言示例。
#!/usr/bin/python
#encoding=utf-8
import rados, sys
cluster = rados.rados(conffile='/etc/ceph/ceph.conf') #获取句柄
print "\n\ni/o context and object operations"
print "================================="
print "\ncreating a context for the 'data' pool"
if not cluster.pool_exists('data'):
raise runtimeerror('no data pool exists')
ioctx = cluster.open_ioctx('data') #获取pool的io上下文句柄
print "\nwriting object 'hw' with contents 'hello world!' to pool 'data'."
ioctx.write("hw", "hello world!") #写入对象
print "writing xattr 'lang' with value 'en_us' to object 'hw'"
ioctx.set_xattr("hw", "lang", "en_us") #设置对象的属性
print "\nwriting object 'bm' with contents 'bonjour tout le monde!' to pool 'data'."
ioctx.write("bm", "bonjour tout le monde!")
print "writing xattr 'lang' with value 'fr_fr' to object 'bm'"
ioctx.set_xattr("bm", "lang", "fr_fr")
print "\ncontents of object 'hw'\n------------------------"
print ioctx.read("hw") #读取对象
print "\n\ngetting xattr 'lang' from object 'hw'"
print ioctx.get_xattr("hw", "lang") #读取对象属性
print "\ncontents of object 'bm'\n------------------------"
print ioctx.read("bm")
print "\nclosing the connection."
ioctx.close() #关闭io上下文
print "shutting down the handle."
cluster.shutdown() #销毁句柄