天天看點

Ceph分布式存儲實2.3 RADOS與LIBRADOS

<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 &lt;stdio.h&gt;

#include &lt;string.h&gt;

#include &lt;rados/librados.h&gt;

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(&amp;cluster, cluster_name, user_name, flags);

        if (err &lt; 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, &amp;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, &amp;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()                      #銷毀句柄