ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Ceph librados 开发指南:用 RADOS API 构建自定义存储接口

Ceph librados 开发指南:用 RADOS API 构建自定义存储接口 Ceph librados 开发指南用 RADOS API 构建自定义存储接口【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址: https://gitcode.com/gh_mirrors/ce/cephCeph 存储集群Ceph Storage Cluster在底层由 RADOSReliable Autonomic Distributed Object Store驱动同时向上提供对象、块和文件三类存储服务但你不必局限于 RESTful、块设备或 POSIX 接口——基于 RADOS 的libradosAPI 允许你为 Ceph 存储集群编写属于自己的客户端接口。本指南以 librados-intro.rst 为主线从环境安装、集群句柄配置、I/O 上下文创建到会话关闭完整演示 C/C、Python、Java 与 PHP 四种绑定的接入流程并结合仓库源码librados.h、librados.hpp、rados.pyx 及 examples/librados 下的示例说明底层机制使读者能够独立完成“连接集群 → 读写对象 → 清理资源”的完整开发闭环。1. 理解 librados对象、块、文件三种接口的统一底座Ceph 存储集群提供了最基本的存储服务使 Ceph 能够在同一套统一系统中提供对象、块和文件三种存储形态。关键在于这些上层接口都构建在同一个底层协议之上——RADOS。librados就是这个底层协议的原生编程接口它让你能够绕开 RBD、RGW 等现成服务直接与存储集群对话自由定义自己的访问方式。使用libradosAPI 时客户端应用需要与存储集群中的两类守护进程交互Ceph Monitor监视器维护集群地图Cluster Map的主副本负责集群状态、认证与协调Ceph OSD Daemon对象存储守护进程以对象为单位把数据存放到存储节点上并负责数据的复制与恢复。librados是 Ceph 的“母语”——RBD块设备、RGW对象网关、CephFS文件系统在仓库中无一例外地构建在它之上。例如 src/librbd 与 src/rgw 的代码都以librados作为唯一的存储后端这正体现了“一套底座、三种接口”的设计哲学。2. 环境准备安装各语言绑定使用 API 前需要一个正在运行的 Ceph 存储集群部署可参考 安装指南Quick。librados本身用 C 编写并提供了 C、Python、Java 与 PHP 的语言绑定针对不同发行版需要安装不同的开发包。2.1 C/C 开发包Debian/Ubuntu 系列sudo apt-get install librados-devRHEL/CentOS 系列sudo yum install librados2-devel libradospp-devel安装完成后C/C 所需的头文件位于/usr/include/rados可用以下命令确认ls /usr/include/rados其中librados.h是 C 接口头文件librados.hpp是 C 接口头文件——两者都定义了完整的 API 声明与详细的文档注释如 librados.h 中rados_create2、rados_connect、rados_conf_read_file等函数的签名与前置条件说明。2.2 Python 绑定rados模块为 Python 应用提供librados支持安装python3-rados包即可# Debian/Ubuntu sudo apt-get install python3-rados # RHEL/CentOS sudo yum install python3-rados # SLE/openSUSE sudo zypper install python3-rados模块位置因发行版而异Debian 系统通常位于/usr/share/pysharedCentOS/RHEL 通常位于/usr/lib/python*/site-packages。该绑定由 Cython 编写主实现在 src/pybind/rados/rados.pyx其中定义了Rados集群类第 390 行起与IoCtx上下文类并把 C 错误转换为 Python 异常。2.3 Java 绑定Java 绑定基于 JNA 调用 C 库需要按以下步骤安装安装jna.jarDebian/Ubuntusudo apt-get install libjna-javaCentOS/RHELsudo yum install jnaJAR 文件位于/usr/share/java。克隆rados-java仓库并构建git clone --recursive https://github.com/ceph/rados-java.git cd rados-java ant将构建出的 JAR 复制到公共位置并确保其与 JNA JAR 都在 JVM 的 classpath 中sudo cp target/rados-0.1.3.jar /usr/share/java/rados-0.1.3.jar sudo ln -s /usr/share/java/jna-3.2.7.jar /usr/lib/jvm/default-java/jre/lib/ext/jna-3.2.7.jar sudo ln -s /usr/share/java/rados-0.1.3.jar /usr/lib/jvm/default-java/jre/lib/ext/rados-0.1.3.jar构建文档可执行ant docs。2.4 PHP 扩展安装 php-devDebian/Ubuntusudo apt-get install php5-dev build-essentialCentOS/RHELsudo yum install php-devel克隆并编译phpradosgit clone https://github.com/ceph/phprados.git cd phprados phpize ./configure make sudo make install在php.ini中添加一行启用扩展extensionrados.so3. 核心概念客户端如何找到数据在使用 API 之前先理解客户端的数据定位流程Ceph 客户端通过librados与 OSD 直接交互来存取数据。为了与 OSD 通信客户端应用必须调用librados并先连接到一个 Ceph Monitor连接成功后librados从 Monitor 获取集群地图Cluster Map。当客户端要读写数据时它创建一个I/O 上下文I/O Context并绑定到某个存储池Pool。池关联了一条CRUSH 规则该规则定义了数据在集群中的放置方式。经由 I/O 上下文客户端把对象名交给libradoslibrados结合对象名与集群地图即集群拓扑计算出对象所属的放置组Placement Group以及负责该 PG 的 OSD随后客户端即可直接读写数据——客户端应用完全不需要了解集群的物理拓扑。关于 PG 的计算细节见 计算 PG IDPG 到 OSD 的映射见 将 PG 映射到 OSDOSD 负责复制与“智能守护进程”机制见 智能守护进程实现超大规模。整个流程可概括为客户端从 Monitor 拉取集群地图 → 创建 I/O 上下文绑定到 Pool → Pool 通过 CRUSH 规则决定数据放置 → 客户端直接与 OSD 通信。4. 第二步创建并配置集群句柄集群句柄Cluster Handle封装了客户端连接所需的全部配置rados_create()使用的用户 ID如admin或rados_create2()使用的用户名如client.admin推荐使用后者因为它允许完整指定名字与集群名cephx 认证密钥Monitor ID 与 IP 地址日志级别与调试级别。因此使用集群的第一步是① 创建集群句柄② 用该句柄连接集群。连接时应用必须提供 Monitor 地址、用户名和认证密钥CephX 默认启用。提示连接不同的 Ceph 存储集群或以不同用户连接同一个集群都需要不同的集群句柄。RADOS 提供了多种设置所需值的方式。对 Monitor 与加密密钥设置而言最便捷的办法是确保 Ceph 配置文件中包含指向 keyring 文件的keyring路径以及至少一个 Monitor 地址如mon_host。例如[global] mon_host 192.168.1.1 keyring /etc/ceph/ceph.client.admin.keyring创建句柄之后你可以通过三种途径为其注入配置读取 Ceph 配置文件rados_conf_read_file()若传入NULL路径则按$CEPH_CONF→/etc/ceph/ceph.conf→~/.ceph/config→ 当前目录下ceph.conf的顺序查找默认位置见 librados.h 中rados_conf_read_file的注释解析命令行参数rados_conf_parse_argv()支持任何 Ceph 命令行选项例如--mon-host 10.0.0.1:6789、--mon_host 10.0.0.1:6789与-m 10.0.0.1:6789三者等价解析环境变量rados_conf_parse_env()默认读取CEPH_ARGS环境变量其内容按命令行选项语法解析。部分语言包装可能未实现这些便捷方法需要自行实现。值得注意的是rados_create()在调用时就会读取 Ceph 环境变量——如果$CEPH_ARGS已经指定了连接所需的一切就无需进一步配置。连接成功后仅凭集群句柄即可调用影响整个集群的函数例如获取集群统计信息、执行池操作存在性检查、创建、列举、删除、读取与设置配置。而 Ceph 的强力特性之一是能够绑定不同的池每个池可有不同的放置组数量、对象副本数与复制策略——例如 SSD 承载热数据的“热池”或使用纠删码的“冷池”。C 绑定与 C/Java/Python 这类面向对象绑定最大的差异在于后者使用对象来抽象集群句柄、I/O 上下文、迭代器与异常等概念。4.1 C 示例创建句柄并连接#include stdio.h #include stdlib.h #include string.h #include rados/librados.h int main (int argc, const char **argv) { /* 声明集群句柄与所需参数。 */ rados_t cluster; char cluster_name[] ceph; char user_name[] client.admin; uint64_t flags 0; /* 以 ceph 集群名和 client.admin 用户初始化集群句柄。 */ int err; err rados_create2(cluster, cluster_name, user_name, flags); if (err 0) { fprintf(stderr, %s: Couldnt create the cluster handle! %s\n, argv[0], strerror(-err)); exit(EXIT_FAILURE); } else { printf(\nCreated a cluster handle.\n); } /* 读取 Ceph 配置文件来配置集群句柄。 */ err rados_conf_read_file(cluster, /etc/ceph/ceph.conf); if (err 0) { fprintf(stderr, %s: cannot read config file: %s\n, argv[0], strerror(-err)); exit(EXIT_FAILURE); } else { printf(\nRead the config file.\n); } /* 解析命令行参数。 */ err rados_conf_parse_argv(cluster, argc, argv); if (err 0) { fprintf(stderr, %s: cannot parse command line arguments: %s\n, argv[0], strerror(-err)); exit(EXIT_FAILURE); } else { printf(\nRead the command line arguments.\n); } /* 连接集群。 */ err rados_connect(cluster); if (err 0) { fprintf(stderr, %s: cannot connect to cluster: %s\n, argv[0], strerror(-err)); exit(EXIT_FAILURE); } else { printf(\nConnected to the cluster.\n); } }编译并链接librados-lradosgcc ceph-client.c -lrados -o ceph-client仓库中的 hello_world_c.c 提供了一个更完整的 C 参考实现它使用rados_create()rados_conf_parse_argv()rados_conf_read_file()完成初始化随后创建自有池、写对象、异步读回、设置 xattr最后删除池并rados_shutdown()优雅退出——该文件头部注释明确提示“install the librados-dev package to get this”与上文安装步骤呼应。4.2 C 示例Ceph 项目在ceph/examples/librados目录提供了 C 示例。C 使用librados::Rados集群句柄对象#include iostream #include string #include rados/librados.hpp int main(int argc, const char **argv) { int ret 0; /* 声明集群句柄与所需变量。 */ librados::Rados cluster; char cluster_name[] ceph; char user_name[] client.admin; uint64_t flags 0; /* 以 ceph 集群名和 client.admin 用户初始化集群句柄。 */ { ret cluster.init2(user_name, cluster_name, flags); if (ret 0) { std::cerr Couldnt initialize the cluster handle! error ret std::endl; return EXIT_FAILURE; } else { std::cout Created a cluster handle. std::endl; } } /* 读取 Ceph 配置文件。 */ { ret cluster.conf_read_file(/etc/ceph/ceph.conf); if (ret 0) { std::cerr Couldnt read the Ceph configuration file! error ret std::endl; return EXIT_FAILURE; } else { std::cout Read the Ceph configuration file. std::endl; } } /* 解析命令行参数。 */ { ret cluster.conf_parse_argv(argc, argv); if (ret 0) { std::cerr Couldnt parse command line options! error ret std::endl; return EXIT_FAILURE; } else { std::cout Parsed command line options. std::endl; } } /* 连接集群。 */ { ret cluster.connect(); if (ret 0) { std::cerr Couldnt connect to cluster! error ret std::endl; return EXIT_FAILURE; } else { std::cout Connected to the cluster. std::endl; } } return 0; }编译源文件并链接libradosg -g -c ceph-client.cc -o ceph-client.o g -g ceph-client.o -lrados -o ceph-client对应地examples/librados/hello_world.cc 展示了完整的 C 流程其中特别指出bufferlist是 Ceph 原生的传输类型设计上尽量减少拷贝只要 bufferlist 仍在使用就不要释放其内存。C 示例还用到了ObjectWriteOperation把“写数据 设置 xattr xattr 条件比较”合并为一次原子操作cmpxattr条件不满足时写入失败展示了 librados 对象操作的强大表达能力。仓库中的 Makefile 同时给出了针对构建树内 librados 与系统 libradosmake all-system两种编译方式并链接了-lrados -lradosstriper。4.3 Python 示例Python 绑定默认使用admin用户和ceph集群名当conffile参数设为空字符串时会读取标准的ceph.conf文件。Python 绑定把 C 错误转换为异常import rados try: cluster rados.Rados(conffile) except TypeError as e: print(Argument validation error: {}.format(e)) raise e print(Created cluster handle.) try: cluster.connect() except Exception as e: print(connection error: {}.format(e)) raise e finally: print(Connected to the cluster.)执行示例验证连接python ceph-client.py从源码看rados.pyx 中的Rados.__init__会做参数校验connect()第 674 行与pool_exists()第 731 行、open_ioctx()第 975 行等方法都直接封装了对应的 C 函数并把返回值转换为 Python 异常类型。4.4 Java 示例Java 需要指定用户 IDadmin或用户名client.admin默认使用ceph集群名。Java 绑定同样把 C 错误转换为异常import com.ceph.rados.Rados; import com.ceph.rados.RadosException; import java.io.File; public class CephClient { public static void main (String args[]){ try { Rados cluster new Rados(admin); System.out.println(Created cluster handle.); File f new File(/etc/ceph/ceph.conf); cluster.confReadFile(f); System.out.println(Read the configuration file.); cluster.connect(); System.out.println(Connected to the cluster.); } catch (RadosException e) { System.out.println(e.getMessage() : e.getReturnValue()); } } }编译并运行若已将 JAR 复制到/usr/share/java并从ext目录做了符号链接则无需指定 classpathjavac CephClient.java java CephClient4.5 PHP 示例启用 RADOS 扩展后PHP 中创建集群句柄非常直接?php $r rados_create(); rados_conf_read_file($r, /etc/ceph/ceph.conf); if (!rados_connect($r)) { echo Failed to connect to Ceph cluster; } else { echo Successfully connected to Ceph cluster; }保存为rados.php并运行php rados.php5. 第三步创建 I/O 上下文并进行对象读写获得集群句柄并成功连接后就可以创建I/O 上下文I/O Context开始读写数据。I/O 上下文把连接绑定到特定池用户必须具备访问该池的相应CAPS 权限——例如只有读权限的用户只能读数据。关于用户管理与授权能力CAPS的配置详见 用户管理。I/O 上下文提供的功能包括读写数据与扩展属性xattr列举并迭代对象与扩展属性对池做快照、列举快照等。RADOS 同时支持同步与异步交互。一旦拥有 I/O 上下文读写操作只需知道对象/xattr 的名字即可封装在librados中的 CRUSH 算法利用集群地图确定合适的 OSDOSD 守护进程负责复制见 智能守护进程实现超大规模librados同时负责把对象映射到放置组见 计算 PG ID。以下示例使用默认的data池。当然也可以用 API 列举池、确认池存在或创建、删除池——写入操作展示同步模式读取操作展示异步模式。重要使用 API 删除池务必谨慎删除池将导致池及其全部数据永久丢失。5.1 C 示例读写对象与 xattr#include stdio.h #include stdlib.h #include string.h #include rados/librados.h int main (int argc, const char **argv) { /* 承接前一个 C 示例集群句柄与连接已建立。先声明 I/O 上下文。 */ rados_ioctx_t io; char *poolname data; err rados_ioctx_create(cluster, poolname, io); if (err 0) { fprintf(stderr, %s: cannot open rados pool %s: %s\n, argv[0], poolname, strerror(-err)); rados_shutdown(cluster); exit(EXIT_FAILURE); } else { printf(\nCreated I/O context.\n); } /* 同步写入数据。 */ err rados_write(io, hw, Hello World!, 12, 0); if (err 0) { fprintf(stderr, %s: Cannot write object \hw\ to pool %s: %s\n, argv[0], poolname, strerror(-err)); rados_ioctx_destroy(io); rados_shutdown(cluster); exit(1); } else { printf(\nWrote \Hello World\ to object \hw\.\n); } char xattr[] en_US; err rados_setxattr(io, hw, lang, xattr, 5); if (err 0) { fprintf(stderr, %s: Cannot write xattr to pool %s: %s\n, argv[0], poolname, strerror(-err)); rados_ioctx_destroy(io); rados_shutdown(cluster); exit(1); } else { printf(\nWrote \en_US\ to xattr \lang\ for object \hw\.\n); } /* 异步读数据。首先建立异步 I/O 完成回调。 */ rados_completion_t comp; err rados_aio_create_completion(NULL, NULL, NULL, comp); if (err 0) { fprintf(stderr, %s: Could not create aio completion: %s\n, argv[0], strerror(-err)); rados_ioctx_destroy(io); rados_shutdown(cluster); exit(1); } else { printf(\nCreated AIO completion.\n); } /* 使用 rados_aio_read 读取数据。 */ char read_res[100]; err rados_aio_read(io, hw, comp, read_res, 12, 0); if (err 0) { fprintf(stderr, %s: Cannot read object. %s %s\n, argv[0], poolname, strerror(-err)); rados_ioctx_destroy(io); rados_shutdown(cluster); exit(1); } else { printf(\nRead object \hw\. The contents are:\n %s \n, read_res); } /* 等待操作完成。 */ rados_aio_wait_for_complete(comp); /* 释放异步 I/O 完成句柄避免内存泄漏。 */ rados_aio_release(comp); char xattr_res[100]; err rados_getxattr(io, hw, lang, xattr_res, 5); if (err 0) { fprintf(stderr, %s: Cannot read xattr. %s %s\n, argv[0], poolname, strerror(-err)); rados_ioctx_destroy(io); rados_shutdown(cluster); exit(1); } else { printf(\nRead xattr \lang\ for object \hw\. The contents are:\n %s \n, xattr_res); } err rados_rmxattr(io, hw, lang); if (err 0) { fprintf(stderr, %s: Cannot remove xattr. %s %s\n, argv[0], poolname, strerror(-err)); rados_ioctx_destroy(io); rados_shutdown(cluster); exit(1); } else { printf(\nRemoved xattr \lang\ for object \hw\.\n); } err rados_remove(io, hw); if (err 0) { fprintf(stderr, %s: Cannot remove object. %s %s\n, argv[0], poolname, strerror(-err)); rados_ioctx_destroy(io); rados_shutdown(cluster); exit(1); } else { printf(\nRemoved object \hw\.\n); } }注rados_write(io, oid, buf, len, offset)的最后一个参数是写入偏移量本例为 0 表示从对象头部写入。异步接口rados_aio_read的返回只表示请求是否成功提交真正的读取结果要通过 completion 等待与检查见 librados.h 中 aio 系列接口注释。5.2 C 示例#include iostream #include string #include rados/librados.hpp int main(int argc, const char **argv) { /* 承接前一个 C 示例。先声明 I/O 上下文。 */ librados::IoCtx io_ctx; const char *pool_name data; { ret cluster.ioctx_create(pool_name, io_ctx); if (ret 0) { std::cerr Couldnt set up ioctx! error ret std::endl; exit(EXIT_FAILURE); } else { std::cout Created an ioctx for the pool. std::endl; } } /* 同步写入一个对象。 */ { librados::bufferlist bl; bl.append(Hello World!); ret io_ctx.write_full(hw, bl); if (ret 0) { std::cerr Couldnt write object! error ret std::endl; exit(EXIT_FAILURE); } else { std::cout Wrote new object hw std::endl; } } /* 给对象添加一个 xattr。 */ { librados::bufferlist lang_bl; lang_bl.append(en_US); ret io_ctx.setxattr(hw, lang, lang_bl); if (ret 0) { std::cerr failed to set xattr version entry! error ret std::endl; exit(EXIT_FAILURE); } else { std::cout Set the xattr lang on our object! std::endl; } } /* 异步读回对象。 */ { librados::bufferlist read_buf; int read_len 4194304; // 创建 I/O Completion。 librados::AioCompletion *read_completion librados::Rados::aio_create_completion(); // 发送读请求。 ret io_ctx.aio_read(hw, read_completion, read_buf, read_len, 0); if (ret 0) { std::cerr Couldnt start read object! error ret std::endl; exit(EXIT_FAILURE); } // 等待请求完成并检查是否成功。 read_completion-wait_for_complete(); ret read_completion-get_return_value(); if (ret 0) { std::cerr Couldnt read object! error ret std::endl; exit(EXIT_FAILURE); } else { std::cout Read object hw asynchronously with contents.\n read_buf.c_str() std::endl; } } /* 读取 xattr。 */ { librados::bufferlist lang_res; ret io_ctx.getxattr(hw, lang, lang_res); if (ret 0) { std::cerr failed to get xattr version entry! error ret std::endl; exit(EXIT_FAILURE); } else { std::cout Got the xattr lang from object hw! lang_res.c_str() std::endl; } } /* 移除 xattr。 */ { ret io_ctx.rmxattr(hw, lang); if (ret 0) { std::cerr Failed to remove xattr! error ret std::endl; exit(EXIT_FAILURE); } else { std::cout Removed the xattr lang from our object! std::endl; } } /* 移除对象。 */ { ret io_ctx.remove(hw); if (ret 0) { std::cerr Couldnt remove object! error ret std::endl; exit(EXIT_FAILURE); } else { std::cout Removed object hw. std::endl; } } }C 的IoCtx类在 librados.hpp 中声明了完整的操作集write_full第 923 行、aio_read第 1144 行起、aio_write/aio_append/aio_remove第 1205-1229 行等。仓库 examples/librados/hello_world.cc 还展示了cmpxattr条件原子更新先构造一个 xattr 条件不满足的写操作验证其失败再用正确的条件值完成“比较-写-更新 xattr”的三合一原子操作。5.3 Python 示例print(\n\nI/O Context and Object Operations) print() print(\nCreating a context for the data pool) if not cluster.pool_exists(data): raise RuntimeError(No data pool exists) ioctx cluster.open_ioctx(data) print(\nWriting object hw with contents Hello World! to pool data.) ioctx.write(hw, bHello World!) print(Writing XATTR lang with value en_US to object hw) ioctx.set_xattr(hw, lang, ben_US) print(\nWriting object bm with contents Bonjour tout le monde! to pool data.) ioctx.write(bm, bBonjour tout le monde!) print(Writing XATTR lang with value fr_FR to object bm) ioctx.set_xattr(bm, lang, bfr_FR) print(\nContents of object hw\n------------------------) print(ioctx.read(hw)) print(\n\nGetting XATTR lang from object hw) print(ioctx.get_xattr(hw, lang)) print(\nContents of object bm\n------------------------) print(ioctx.read(bm)) print(\n\nGetting XATTR lang from object bm) print(ioctx.get_xattr(bm, lang)) print(\nRemoving object hw) ioctx.remove_object(hw) print(Removing object bm) ioctx.remove_object(bm)Python 的write/read/set_xattr/get_xattr/remove_object等方法的底层实现同样位于 rados.pyx 的IoCtx类中对 C API 做了面向对象封装并统一抛出异常。5.4 Java 示例import com.ceph.rados.Rados; import com.ceph.rados.RadosException; import java.io.File; import com.ceph.rados.IoCTX; public class CephClient { public static void main (String args[]){ try { Rados cluster new Rados(admin); System.out.println(Created cluster handle.); File f new File(/etc/ceph/ceph.conf); cluster.confReadFile(f); System.out.println(Read the configuration file.); cluster.connect(); System.out.println(Connected to the cluster.); IoCTX io cluster.ioCtxCreate(data); String oidone hw; String contentone Hello World!; io.write(oidone, contentone); String oidtwo bm; String contenttwo Bonjour tout le monde!; io.write(oidtwo, contenttwo); String[] objects io.listObjects(); for (String object: objects) System.out.println(object); io.remove(oidone); io.remove(oidtwo); cluster.ioCtxDestroy(io); } catch (RadosException e) { System.out.println(e.getMessage() : e.getReturnValue()); } } }5.5 PHP 示例?php $io rados_ioctx_create($r, mypool); rados_write_full($io, oidOne, mycontents); rados_remove(oidOne); rados_ioctx_destroy($io);注意PHP 示例中创建的池名为mypool与默认的data池不同——使用前需确认该池已存在且当前用户具备相应 CAPS 权限。6. 第四步关闭会话与资源清理应用结束对 I/O 上下文与集群句柄的使用后应当关闭连接并关闭句柄。对于异步 I/O还应确保所有挂起的异步操作已完成——C API 文档特别提醒rados_shutdown()并不保证异步写入已经完成必须先对全部打开的 I/O 上下文调用rados_aio_flush()见 librados.h 中rados_shutdown的注释同时它隐式调用rados_watch_flush()如果使用了 watch 机制应在销毁相关 IoCtx 前显式调用。各语言关闭方式对照/* C */ rados_ioctx_destroy(io); rados_shutdown(cluster);// C io_ctx.close(); cluster.shutdown();// Java cluster.ioCtxDestroy(io); cluster.shutDown();# Python print(\nClosing the connection.) ioctx.close() print(Shutting down the handle.) cluster.shutdown()?php rados_shutdown($r);仓库示例 examples/librados/hello_world_c.c 与 examples/librados/hello_world.cc 都在out:标签处统一执行rados_ioctx_destroy/rados.pool_delete/rados_shutdown是资源清理的标准范式即使中途出错也要先销毁 ioctx再删除自建测试池最后关闭集群句柄。7. 从入门到实践参考路径清单入门与 API 总览librados-intro.rst本文对应原文档、C API 参考、C API 参考、Python API 参考、API 索引C 接口声明src/include/rados/librados.h含rados_create/rados_create2、rados_conf_read_file、rados_conf_parse_argv、rados_connect、rados_shutdown及全部 aio 接口的完整签名与注释C 接口声明src/include/rados/librados.hppRados集群类、IoCtx上下文类、AioCompletion、ObjectWriteOperationPython 绑定实现src/pybind/rados/rados.pyxRados类与IoCtx类的 Cython 实现可运行示例examples/libradosC 版 hello_world_c.c、C 版 hello_world.cc、构建脚本 Makefile测试用例src/test/libradosaio.cc/aio_cxx.cc覆盖异步 I/Oio.cc/io_cxx.cc覆盖对象读写pool.cc覆盖池操作watch_notify.cc覆盖 watch/notify 机制可作为 API 行为验证的权威参考配套概念文档集群架构、用户管理与 CAPS、池操作、计算 PG ID、智能守护进程与高可用掌握上述流程后你便可以从零构建基于librados的自定义存储客户端先安装对应语言的开发包创建并配置集群句柄配置文件/命令行/环境变量三种注入方式连接 Monitor 获取集群地图再创建绑定到池的 I/O 上下文以同步或异步方式读写对象与扩展属性最后规范地关闭会话释放资源。【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址: https://gitcode.com/gh_mirrors/ce/ceph创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表