刚发布的FastCFS V3.2提供系统调用API(如 open、write、writev、read、readv、close 等)和 C API(如fopen、fwrite、fread、fclose等)两大类POSIX API,应用程序可以通过这两类API使用FastCFS存储。FastCFS在POSIX API名称前面加上前缀 fcfs_,比如 fcfs_open、fcfs_read等等,函数原型及用法和POSIX API完全一致。
FastCFS可以通过FUSE mount为本地文件目录,为什么还要推出POSIX API呢?应用程序直接调用FastCFS提供的POSIX 接口,主要有两大好处:1. 减少FUSE这个中间环节,部署和运维更加简单方便;2. 直接在用户态调用接口,不存在FUSE在用户态和内核态的交互行为,性能更高,CPU占用明显降低(fused进程对CPU消耗比较大)。单机实测发现随机写IOPS提升 20+%,随机读大约提升 5%。
FastCFS提供的动态库和头文件,可以采用装包或者源码编译方式,推荐使用装包方式。CentOS 和 RHEL下包名为 FastCFS-api-devel,Debian和Ubuntu下包名为 fastcfs-api-dev。动态库为/usr/lib64/libfcfsapi.so,你的程序在编译时需要增加动态库选项 -lfcfsapi。源码需要引用两个头文件,如下所示:
#include "fastcfs/api/std/papi.h"
#include "fastcfs/api/std/capi.h"
程序初始化调用:
//必须放置在daemon_init, fork或clone调用之后
fcfs_posix_api_init_start();
或者:
//可以放置在daemon_init, fork或clone调用之前
fcfs_posix_api_init();
//必须放置在daemon_init, fork或clone调用之后
fcfs_posix_api_start();
程序退出前需要调用 fcfs_posix_api_stop() 完成收尾工作。示例程序参见FastCFS项目下的 src/api/tests/test_papi_copy.c
不修改程序代码的情况下,可以使用FastCFS提供的preload动态库访问FastCFS存储。使用示例如下:
LD_PRELOAD=/usr/lib64/libfcfspreload.so ls -l /opt/fastcfs/fuse
或者:
export LD_PRELOAD=/usr/lib64/libfcfspreload.so
ls -l /opt/fastcfs/fuse
注意:第二种方式下环境变量LD_PRELOAD一直生效,除非退出终端或者执行:
unset LD_PRELOAD
动态库使用的配置文件默认为/etc/fastcfs/fcfs/fuse.conf,可以通过环境变量 FCFS_PRELOAD_CONFIG_FILENAME 设置。
受限于glibc实现方式,preload机制对于部分Linux命令会失效,比如 md5sum、dd。因此我们提供的这种方式是试验性的,感兴趣的朋友可以进行测试和验证。下面列举preload机制失效的4种场景:
1. 静态编译(不采用动态库方式);
2. 程序设置了 suid 标志;
3. 通过汇编调用函数(比如glibc打开文件通过汇编调用syscall);
4. 采用了内联函数(比如glibc的 feof_unlocked 和 ferror_unlocked等函数)。
感兴趣的朋友请点击 FastCFS开源项目,欢迎大家测试和体验。