环境
运行java的程序的主机必须安装libcephfs!!!
wget https://mirrors.aliyun.com/centos/7/storage/x86_64/ceph-luminous/libcephfs2-12.2.5-0.el7.x86_64.rpm
wget https://mirrors.aliyun.com/centos/7/storage/x86_64/ceph-luminous/libcephfs_jni1-12.2.5-0.el7.x86_64.rpm
yum install -y libcephfs2-12.2.5-0.el7.x86_64.rpm libcephfs_jni1-12.2.5-0.el7.x86_64.rpm
之后,在/usr/lib64中会生成libcephfs_jni.so.1,libcephfs_jni.so.1.0.0,java程序还是找不到,所以还要建立软连接到/usr/lib
ln -s /usr/lib64/libcephfs_jni.so.1 /usr/lib/libcephfs_jni.so.1
ln -s /usr/lib64/libcephfs_jni.so.1.0.0 /usr/lib/libcephfs_jni.so
注:最后一行必须是so结尾,而不是so.1.0.0
Java API
方便测试,建立一个普通的mvn工程,pom.xml文件如下
<?xml version="1.0" encoding="UTF-8"?>
<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.shaoyan</groupId>
<artifactId>cephfs-test</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.ceph</groupId>
<artifactId>libcephfs</artifactId>
<version>0.80.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.ceph/rados -->
<dependency>
<groupId>com.ceph</groupId>
<artifactId>rados</artifactId>
<version>0.3.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>CephFSTest</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>assembly</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
说明:
- 使用maven-assembly-plugin,否则打包出来的jar没有包含其他maven依赖。
- 在在项目的目录下执行 mvn clean package,会在项目下生成 target 文件夹,并有两个jar包,一个包含依赖,一个不包含
archive-tmp classes
cephfs-test-1.0-SNAPSHOT-jar-with-dependencies.jar maven-archiver
cephfs-test-1.0-SNAPSHOT.jar maven-status
为方便测试每一个api,这里尽可能将其一一分开测试,测试程序如下:
package com.shaoyan.ceph;
import com.ceph.fs.CephFileExtent;
import com.ceph.fs.CephMount;
import com.ceph.fs.CephStat;
import java.io.IOException;
import java.util.Arrays;
public class CephOperate {
private CephMount mount;
private String username;
private String monIp;
private String userKey;
public CephOperate(String username, String monIp, String userKey, String mountPath) {
this.username = username;
this.monIp = monIp;
this.userKey = userKey;
this.mount = new CephMount(username);
this.mount.conf_set("mon_host", monIp);
mount.conf_set("key",userKey);
mount.mount(mountPath);
}
//查看目录列表
public void listDir(String path) throws IOException {
String[] dirs = mount.listdir(path);
System.out.println("contents of the dir: " + Arrays.asList(dirs));
}
//新建目录
public void mkDir(String path) throws IOException {
mount.mkdirs(path,0755);//0表示十进制
}
//删除目录
public void delDir(String path) throws IOException {
mount.rmdir(path);
}
//重命名目录or文件
public void renameDir(String oldName, String newName) throws IOException {
mount.rename(oldName, newName);
}
//删除文件
public void delFile(String path) throws IOException {
mount.unlink(path);
}
//读文件
public void readFile(String path) {
System.out.println("start read file...");
int fd = -1;
try{
fd = mount.open(path, CephMount.O_RDWR, 0755);
System.out.println("file fd is : " + fd);
byte[] buf = new byte[1024];
long size = 10;
long offset = 0;
long count = 0;
while((count = mount.read(fd, buf, size, offset)) > 0){
for(int i = 0; i < count; i++){
System.out.print((char)buf[i]);
}
offset += count;
}
} catch (IOException e){
e.printStackTrace();
} finally {
if(fd > 0){
mount.close(fd);
}
}
}
//复制文件
public void copyFile(String sourceFile, String targetFile){
System.out.println("start write file...");
int readFD = -1, createAA = -1, writeFD = -1;
try{
readFD = mount.open(sourceFile, CephMount.O_RDWR, 0755);
writeFD = mount.open(targetFile, CephMount.O_RDWR | CephMount.O_CREAT, 0644);
// createAA = mountLucy.open("aa.txt", CephMount.O_RDWR | CephMount.O_CREAT | CephMount.O_EXCL, 0644);//若文件已有, 会异常
System.out.println("file read fd is : " + readFD);
byte[] buf = new byte[1024];
long size = 10;
long offset = 0;
long count = 0;
while((count = mount.read(readFD, buf, size, -1)) > 0){
mount.write(writeFD, buf, count, -1);//-1指针跟着走,若取值count,指针不动
System.out.println("offset: " + offset);
offset += count;
System.out.println("writeFD position : " + mount.lseek(writeFD, 0, CephMount.SEEK_CUR));
}
} catch (IOException e){
e.printStackTrace();
} finally {
if(readFD > 0){
mount.close(readFD);
}
if(writeFD > 0){
mount.close(writeFD);
}
}
}
//写文件
public void writeFileWithLseek(String path, long offset, int type){
if(type <= 0){
type =CephMount.SEEK_CUR;
}
System.out.println("start write file...");
int writeFD = -1;
try{
writeFD = mount.open(path, CephMount.O_RDWR | CephMount.O_APPEND, 0644);
long pos = mount.lseek(writeFD, offset, type);
System.out.println("pos : " + pos);
String msg = " asdfasdfasdf123123123 \n";
byte[] buf = msg.getBytes();
mount.write(writeFD, buf, buf.length, pos);
} catch (IOException e){
e.printStackTrace();
} finally {
if(writeFD > 0){
mount.close(writeFD);
}
}
}
// 判断是目录还是文件
public void listFileOrDir(){
int writeFD = -1;
try{
String[] lucyDir = mount.listdir("/");
for(int i = 0; i < lucyDir.length; i++){
CephStat cephStat = new CephStat();
mount.lstat(lucyDir[i], cephStat);
System.out.println(lucyDir[i] + " is dir : " + cephStat.isDir()
+ " is file: " + cephStat.isFile()
+ " size: " + cephStat.size
+ " blksize: " + cephStat.blksize);//cephStat.size就是文件大小
}
writeFD = mount.open("lucy1.txt", CephMount.O_RDWR | CephMount.O_APPEND, 0644);
CephFileExtent cephFileExtent = mount.get_file_extent(writeFD, 0);
System.out.println("lucy1.txt size: " + cephFileExtent.getLength());//4M
System.out.println("lucy1.txt stripe unit: " + mount.get_file_stripe_unit(writeFD));//4M
long pos = mount.lseek(writeFD, 0, CephMount.SEEK_END);
System.out.println("lucy1.txt true size: " + pos);//30Byte
} catch (IOException e){
e.printStackTrace();
} finally {
if(writeFD > 0){
mount.close(writeFD);
}
}
}
//set current dir (work dir)
public void setWorkDir(String path) throws IOException{
mount.chdir(path);
}
//外部获取mount
public CephMount getMount(){
return this.mount;
}
//umount
public void umount(){
mount.unmount();
}
}
package com.shaoyan.ceph;
import com.ceph.fs.CephMount;
import java.io.IOException;
public class CephFSTest {
public static void main(String[] args) throws IOException{
System.out.println("start...." + CephMount.class);
String username = "admin";
String monIp = "192.168.16.4:6789;192.168.16.5:6789;192.168.16.6:6789";
String userKey = "AQC/tCxb/IKAERAAaHxoJyxP01pE7JT+f0vT5Q==";
String mountPath = "/";
CephOperate cephOperate = new CephOperate(username, monIp, userKey, mountPath);
CephMount cephMount = cephOperate.getMount();
cephMount.symlink("/lucy/bb.txt", "/jerry/softlink.txt");
cephMount.link("/lucy/bb.txt", "/jerry/hardlink.txt");
String content = cephMount.readlink("/jerry/softlink.txt");//"/lucy/bb.txt"
System.out.println(content);
System.out.println("hard link... ");
cephOperate.readFile("/jerry/hardlink.txt");
System.out.println("soft link... ");
cephOperate.readFile("/jerry/softlink.txt");
cephOperate.writeFileWithLseek("/jerry/softlink.txt", 0, 0);
cephOperate.umount();
}
}
问题
- 虽然cephfs支持随机写,但java api并不完全支持(可以随机进行定位,但是无法插入内容,即旧数据会被新数据覆盖)
- ceph未提供用户认证和权限管理的api,即无法通过java python go等进行用户管理和用户权限管理的操作
网友评论