注意
本文档适用于 Ceph 的开发版本。
LazyIO
LazyIO 放宽了 POSIX 语义。即使文件被多个客户端上的多个应用程序打开,也允许进行缓冲读/写。应用程序负责自行管理缓存一致性。
Libcephfs 自 nautilus 版本开始支持 LazyIO。
启用 LazyIO
可以通过以下方式启用 LazyIO。
client_force_lazyio选项为 libcephfs 和 ceph-fuse 挂载全局启用 LAZY_IO。ceph_lazyio(...)和ceph_ll_lazyio(...)在 libcephfs 中为文件句柄启用 LAZY_IO。
使用 LazyIO
LazyIO 包括两种方法 lazyio_propagate() 和 lazyio_synchronize()。启用 LazyIO 后,在调用 lazyio_propagate() 之前,写入可能对其他客户端不可见。在调用 lazyio_synchronize() 之前,读取可能来自本地缓存(无论其他客户端对文件所做的更改如何)。
lazyio_propagate(int fd, loff_t offset, size_t count)- 确保客户端在特定区域(offset 到 offset+count)中的任何缓冲写入已传播到共享文件。如果 offset 和 count 都为 0,则对整个文件执行操作。目前仅支持此功能。lazyio_synchronize(int fd, loff_t offset, size_t count)- 确保客户端在后续读取调用中能够读取已更新的文件,其中包含所有其他客户端已传播的写入。在 CephFS 中,这是通过使与 inode 相关的文件缓存失效来实现的,从而强制客户端从已更新的文件重新获取/重新缓存数据。此外,如果调用客户端的写入缓存是脏的(未传播),lazyio_synchronize() 也会将其刷新。
下面给出了一个示例用法(利用 libcephfs)。这是并行应用程序中特定客户端/文件描述符的示例 I/O 循环
/* Client a (ca) opens the shared file file.txt */
int fda = ceph_open(ca, "shared_file.txt", O_CREAT|O_RDWR, 0644);
/* Enable LazyIO for fda */
ceph_lazyio(ca, fda, 1));
for(i = 0; i < num_iters; i++) {
char out_buf[] = "fooooooooo";
ceph_write(ca, fda, out_buf, sizeof(out_buf), i);
/* Propagate the writes associated with fda to the backing storage*/
ceph_propagate(ca, fda, 0, 0);
/* The barrier makes sure changes associated with all file descriptors
are propagated so that there is certainty that the backing file
is up to date */
application_specific_barrier();
char in_buf[40];
/* Calling ceph_lazyio_synchronize here will ascertain that ca will
read the updated file with the propagated changes and not read
stale cached data */
ceph_lazyio_synchronize(ca, fda, 0, 0);
ceph_read(ca, fda, in_buf, sizeof(in_buf), 0);
/* A barrier is required here before returning to the next write
phase so as to avoid overwriting the portion of the shared file still
being read by another file descriptor */
application_specific_barrier();
}