java操作ceph之rbd基本操作

一、安装librados和librbd

Ceph存储集群提供了基本的存储服务,允许Ceph在一个统一的系统中唯一地传送对象,块和文件存储。 但是,不限于使用RESTful,块或POSIX接口。 基于RADOS,Librados API使您能够创建自己的Ceph存储群集接口。Librados API使您能够与Ceph存储集群中的两种守护程序进行交互:

 1)Ceph监视器,其维护集群映射的主副本。
 2)Ceph OSD守护程序(OSD),它将数据作为对象存储在存储节点上。

要安装librados-dev和librbd-dev,因为java的Rados类需要用到librados-dev,而Rbd类需要用到librbd-dev

,需要执行以下步骤:

 1)安装librados和librbd。

   对于Debian / Ubuntu,执行:

apt-get install librados-dev
apt-get install librbd-dev

  对于 CentOS/RHEL,执行:

yum install librados2-devel
yum install librbd1-devel

为开发人员安装库后,可以在/usr/include/rados下找到C / C ++所需的头文件

也可以下载下面的4个rmp包:

wget http://vault.centos.org/7.2.1511/storage/x86_64/ceph-hammer/librados2-0.94.5-1.el7.x86_64.rpm

wget http://vault.centos.org/7.2.1511/storage/x86_64/ceph-hammer/librados2-devel-0.94.5-1.el7.x86_64.rpm

wget http://vault.centos.org/7.2.1511/storage/x86_64/ceph-hammer/librbd1-0.94.5-1.el7.x86_64.rpm

wget http://vault.centos.org/7.2.1511/storage/x86_64/ceph-hammer/librbd1-devel-0.94.5-1.el7.x86_64.rpm

然后执行:

yum install librados2-0.94.5-1.el7.x86_64.rpm librados2-devel-0.94.5-1.el7.x86_64.rpm -y
yum install librbd1-0.94.5-1.el7.x86_64.rpm librbd1-devel-0.94.5-1.el7.x86_64.rpm -y

 

 2)克隆rados-java工程:

git clone https://github.com/ceph/rados-java.git

 3)构建rados-java工程:

cd rados-java-master
mvn install -Dmaven.test.skip=true

JAR文件位于rados-java-master/target下

4)新建一个maven工程cephDemo,用来调用ceph

工程目录如下所示:

《java操作ceph之rbd基本操作》

 

下面引用的rados-0.4.0-SNAPSHOT.jar是由上面的mvn install后生成的jar包,实情情况版本可能有变

pom.xml配置如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.ceph.test</groupId>
  <artifactId>cephDemo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>cephDemo</name>
  <dependencies>
            <dependency>
                <groupId>com.ceph</groupId>
                <artifactId>rados</artifactId>
                <version>0.4.0-SNAPSHOT</version>
        </dependency>
  </dependencies>
</project>

 

二、应用程序调用ceph原理

 

 下图提供了初始连接的高级流程。

《java操作ceph之rbd基本操作》

以下是java对ceph中image的基本操作示例:

package com.ceph.rbd;

import java.io.File;
import java.util.Arrays;
import java.util.List;

import com.ceph.rados.IoCTX;
import com.ceph.rados.Rados;
import com.ceph.rados.exceptions.RadosException;
import com.ceph.rbd.jna.RbdImageInfo;
import com.ceph.rbd.jna.RbdSnapInfo;

public class RbdDao {
    
    private static Rados rados;
    private static IoCTX ioctx;
    private static Rbd rbd;
     /**
      * 连接上ceph环境
      */
     public static void connectCeph(){
           try {
                rados = new Rados("admin");
                //rados.confSet("mon_host", "10.111.131.125");
                //rados.confSet("key", "AQBngfhYpHvLKhAAtmVZTyR3NJxx1WOVeLo5pQ==");
                rados.confSet("mon_host", "172.16.60.41");
                rados.confSet("key", "AQCdP9pYGI4jBBAAc96J8/OconCkVKWPBNU2vg==");
                rados.connect();
                ioctx = rados.ioCtxCreate("rbd");
                rbd = new Rbd(ioctx);
                System.out.println("successs connetc");
          } catch (Exception e) {
              e.printStackTrace();
            // TODO: handle exception
         }
     }
     
     /**
      * 返回所有的image,并展示其详细信息
      * @return
      */
     public static List<String> imageList(){
          List<String> imageList=null;
          try {
            imageList = Arrays.asList(rbd.list());
            for(String s:imageList){
                showDetailOfImage(s);
            }
        } catch (RbdException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
          return imageList;
     }
     
     /**
      * 显示image的详细信息
      * @param imageName
      */
     public static void showDetailOfImage(String imageName){
         RbdImage image;
        try {
              image = rbd.open(imageName);
              RbdImageInfo info = image.stat();
              System.out.println("=================================================================");
              System.out.println("imageName:    "+imageName);
              System.out.println("imageSize:    "+info.size);
              System.out.println("order:   "+info.order);
              rbd.close(image);
        } catch (RbdException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       
     }
     
     /**
      * 以格式1创建image
      * @param imageName 名称
      * @param imageSize 大小
      */
     public static void createRbd_format1(String imageName, long imageSize){
            try {
                rbd.create(imageName, imageSize);
                RbdImage image = rbd.open(imageName);
                boolean oldFormat = image.isOldFormat();
                System.out.println("imageFormat:==========================="+oldFormat);
               
                rbd.close(image);
            } catch (RbdException e) {
                System.out.println(e.getMessage() + ": " + e.getReturnValue());
            }
     }
     
     /**
      * 以格式2创建image,ceph 仅支持克隆 format 2 映像(即用 rbd create –format 2 创建的),而且内核 rbd 模块还不支持。
  所以现在你 只能用 QEMU/KVM 或 librbd直接访问克隆品
      * @param imageName 名称
      * @param imageSize 大小
      */
     public static void createRbd_format2(String imageName, long imageSize){
            try {
                int features = (1<<0);
                System.out.println("features=============="+features);
                rbd.create(imageName, imageSize,features, 0);
                RbdImage image = rbd.open(imageName);
                boolean oldFormat = image.isOldFormat();
                System.out.println("imageFormat:==========================="+oldFormat);               
                rbd.close(image);
                image.flatten();
            } catch (RbdException e) {
                System.out.println(e.getMessage() + ": " + e.getReturnValue());
            }
     }
     
     /**
      * 方法创建一个image并对重设置大小为初始化大小的2倍
      * @param imageName
      */
     public static void resizeImage(String imageName){
            long initialSize = 10485760;
            long newSize = initialSize * 2;
            try {
                int features = (1<<0);
                System.out.println("features=============="+features);
                rbd.create(imageName, initialSize,features, 0);
                RbdImage image = rbd.open(imageName);
                image.resize(newSize);
                rbd.close(image);
            } catch (RbdException e) {
                System.out.println(e.getMessage() + ": " + e.getReturnValue());
            }
     }
     
     /**
      * 创建映像的快照
      * @param imageName 映像名称
      * @param snapName 快照名称
      */
     public static void createSnap(String imageName,String snapName){
         try {
            RbdImage image = rbd.open(imageName);
            //创建快照
            image.snapCreate(snapName);
            //保护快照可以防止快照被删除
            image.snapProtect(snapName);
            //返回一个image的所有快照
            List<RbdSnapInfo> snaps = image.snapList();
            for(RbdSnapInfo rbds:snaps){
                System.out.println("快照名称:"+rbds.name);
                System.out.println("快照大小:"+rbds.size);
            }
        } catch (RbdException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
     }
     
     /**
      * 通过快照克隆出新的image
      * @param parentImageName 快照对应的image名称
      * @param snapName 快照的名称
      * @param newImageName 生成的新的image的名称
      */
     public static void copySnapToNewImage(String parentImageName,String snapName,String newImageName){
         int features = (1<<0);
         try {
            rbd.clone(parentImageName, snapName, ioctx, newImageName, features, 0);
        } catch (RbdException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
     }
     
     /**
      * 删除某个image的名叫 snapName的快照,需要注意的是要删除快照,必须保证快照没有copy的子image,否则会删除失败。
      * @param imageName
      * @param snapName
      */
     public static void deleteSnap(String imageName,String snapName){
         try {
            RbdImage image = rbd.open(imageName);
            image.snapUnprotect(snapName);
            image.snapRemove(snapName);
        } catch (RbdException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
     }
     
     /**
      * 删除某一个image
      * @param r
      * @param io
      * @param imageName
      * @throws RadosException
      * @throws RbdException
      */
    public static void cleanupImage(Rados r, IoCTX io, String imageName) {
        try {
            if (r != null) {
                if (io != null) {
                    Rbd rbd = new Rbd(ioctx);
                    RbdImage image = rbd.open(imageName);
                    rbd.close(image);
                    rbd.remove(imageName);
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
        }  
     }
    
     
     public static void main(String[] args){
         connectCeph();
         //createRbd_format1("mysql-hzb-2",10737418240l);
        //createRbd_format2("imageformat2",10485760);
        //cleanupImage(rados,ioctx,"mysql-hzb");
         //resizeImage("mysql-hzb");
         
        // createSnap("imageformat3","imageformat3-snap");
        //copySnapToNewImage("imageformat3","imageformat3-snap","imageformat3-copy");
         //deleteSnap("imageformat3","imageformat3-snap");
        imageList();
     }
}

 

点赞