本文主要介绍阿里云数据库文件存储服务DBFS的使用方式。

  1. 使用方式说明:在一个挂载点下,DBFS服务可同时支持以下3种方式使用。
    使用方式 优点 缺点 使用场景
    直接使用 Kernel态,简单易用。如同使用ext4等文件系统一样。 性能一般。 对性能要求不高的用户。
    hook接入 用户态,性能优。不用更改应用代码直接使用。 需要加LD_PRELOAD变量使用。 对性能要求高,但暂不具备源码研发能力的用户。
    SDK接入 用户态,性能优。通过SDK方式,可实现数据库一写多读或应用上层定制化使用。 需要做源码级开发。接口参考SDK API文档。 对性能要求高,有源码研发能力,期望结合应用进行定制化开发的用户。
  2. 使用方式案例:
    • 直接使用,与使用ext4等文件系统同。
      [root@iZbp156ycm6s06xjdb8acoZ ~]# df -h
      文件系统        容量  已用  可用 已用% 挂载点
      devtmpfs         16G     0   16G    0% /dev
      tmpfs            16G  288K   16G    1% /dev/shm
      dbfs_server     100G   46M  100G    1% /mnt/dbfs/v-bp196g0zi82d0pqte8r9
      
      [root@iZbp156ycm6s06xjdb8acoZ ~]# cd /mnt/dbfs/v-bp196g0zi82d0pqte8r9/
      [root@iZbp156ycm6s06xjdb8acoZ v-bp196g0zi82d0pqte8r9]# echo "dbfs test" >> test.txt
      [root@iZbp156ycm6s06xjdb8acoZ v-bp196g0zi82d0pqte8r9]# cat test.txt
      dbfs test
      [root@iZbp156ycm6s06xjdb8acoZ v-bp196g0zi82d0pqte8r9]# cp /etc/fstab  ./
      [root@iZbp156ycm6s06xjdb8acoZ v-bp196g0zi82d0pqte8r9]# touch a.txt
      [root@iZbp156ycm6s06xjdb8acoZ v-bp196g0zi82d0pqte8r9]# ls -lrt
      总用量 2048
      -rw-r--r-- 1 root root  10 2月  13 10:56 test.txt
      -rw-r--r-- 1 root root 313 2月  13 10:57 fstab
      -rw-r--r-- 1 root root   0 2月  13 10:57 a.txt
      [root@iZbp156ycm6s06xjdb8acoZ v-bp196g0zi82d0pqte8r9]# rm a.txt
      rm:是否删除普通空文件 "a.txt"?y 
      [root@iZbp156ycm6s06xjdb8acoZ v-bp196g0zi82d0pqte8r9]# ls -lrt
      总用量 2048
      -rw-r--r-- 1 root root  10 2月  13 10:56 test.txt
      -rw-r--r-- 1 root root 313 2月  13 10:57 fstab
      
      #跟ext4使用一样,起动MySQL数据库。
      #MySQL二进制位于DBFS服务目录中。
      /mnt/v-bp196g0zi82d0pqte8r9/mysql-5.7.26/bin/mysqld --defaults-file=/mnt/dbfs0/my3307/my.cnf --user=root &
      						
    • hook接入,应用程序起动时需设置“LD_PRELOAD”变量。
      #MySQL场景。
      #DBFS_HOME的中值,通过dbfs_get_home_path.sh fsid得到,其中fsid为“db8acoqte8r9”。
      DBFS_HOME="/opt/dbfs/data/44a2444a-9c11-4612-93b2-916dedad1b0f/server/db8acoqte8r9" \
      LD_PRELOAD="/usr/lib64/libdbfs_hook.so" /mnt/v-bp196g0zi82d0pqte8r9/mysql-5.7.26/bin/mysqld --defaults-file=/mnt/dbfs0/my3307/my.cnf --user=root &
      
      #其它应用场景。
      DBFS_HOME="/opt/dbfs/data/44a2444a-9c11-4612-93b2-916dedad1b0f/server/db8acoqte8r9" \
      LD_PRELOAD="/usr/lib64/libdbfs_hook.so" /opt/xxx/bin/xxx
    • SDK接入,在使用DBFS的地方包含“dbfs.h”头文件进行联合编译。 以下通过“dbfs_demo.cc”测试程序,来说明SDK的使用方式:
      步骤1:拷贝以下测试程序到“dbfs_demo.cc”文件。
      /**
       * dbfs_demo.cc
       */
      #include <gtest/gtest.h>
      #include <fcntl.h>
      #include "/usr/include/dbfs.h"
      
      TEST(dbfsTest, mount)
      {
         int ret = 0;
         int fd  = 0;
         char *wbuf = (char *)malloc(4096);
         char *rbuf = (char *)malloc(4096);
         memset(wbuf, 0x1, 4096);
         memset(rbuf, 0x0, 4096);
      
         // Connect to DBFS service
         ASSERT_EQ(0, dbfs_mount(NULL));
      
         fd = dbfs_open("testfile1", O_CREAT|O_RDWR|O_TRUNC, 0644);
         ASSERT_TRUE(fd >= 0);
         std::cout << "open ok fd " << fd << std::endl;
      
         ret = dbfs_write(fd, wbuf, 4096);
         ASSERT_EQ(4096, ret);
         std::cout << "write ok success " << ret << std::endl;
      
         ret = dbfs_close(fd);
         ASSERT_EQ(0,  ret);
         std::cout << "close ok fd " << fd << std::endl;
      
         fd = dbfs_open("testfile1",  O_RDWR, 0644);
         ASSERT_TRUE(fd >= 0);
         std::cout << "open again fd " << fd << std::endl;
      
         ret = dbfs_read(fd, rbuf, 4096);
         ASSERT_EQ(4096, ret);
         std::cout << "read ok success " << ret << std::endl;
      
         ASSERT_EQ(0, memcmp(wbuf, rbuf, 4096));
         std::cout << "memcmp ok" << std::endl;
      
         ret = dbfs_close(fd);
         ASSERT_EQ(0,  ret);
         std::cout << "close again ok fd " << fd << std::endl;
      
         ret = dbfs_unlink("testfile1");
         ASSERT_EQ(0,  ret);
         std::cout << "unlink ok fd " << fd << std::endl;
      
         fd = dbfs_open("testfile1", O_RDWR, 0644);
         ASSERT_TRUE(fd < 0);
         std::cout << "open an unlinked file fd " << fd << std::endl;
      
         // Disconnect from DBFS service
         dbfs_umount();
      
         // Free memory
         if (wbuf) {
          free(wbuf);
          wbuf = NULL;
         }
      
         if (rbuf) {
          free(rbuf);
          rbuf = NULL;
         }
      }
      
      int main(int argc, char **argv) {
        ::testing::InitGoogleTest(&argc, argv);
        return RUN_ALL_TESTS();
      }
      
      #步骤2:编译。
      g++ -g dbfs_demo.cc -o dbfs_demo -lgtest -ldbfs
      
      #步骤3:执行dbfs_demo并输出结果。
      #DBFS_HOME="/opt/dbfs/data/44a2444a-9c11-4612-93b2-916dedad1b0f/server/db8acoqte8r9" ./dbfs_demo
      [==========] Running 1 test from 1 test case.
      [----------] Global test environment set-up.
      [----------] 1 test from dbfsTest
      [ RUN      ] dbfsTest.mount
      open ok fd 738197513
      write ok success 4096
      close ok fd 738197513
      open again fd 738197513
      read ok success 4096
      memcmp ok
      close again ok fd 738197513
      unlink ok fd 738197513
      open an unlinked file fd -1
      [       OK ] dbfsTest.mount (281 ms)
      [----------] 1 test from dbfsTest (281 ms total)
      
      [----------] Global test environment tear-down
      [==========] 1 test from 1 test case ran. (281 ms total)
      [  PASSED  ] 1 test.