一、安裝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(); } }