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
工程目录如下所示:
下面引用的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中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(); } }