一、整体框架

                                          NFS Ganesha 分层架构图

Ganesha 是一个基于模块的程序,每个模块都负责各自的任务和目标。开发团队在写代码之前就对每个模块进行了精心的设计,保证了后期扩展的便捷性。比如缓存管理模块只负责管理缓存,任何在缓存管理模块上做出的更改不能影响其他模块。这么做大大减少了每个模块间的耦合。每个模块可以独立交给不同开发人员来进行开发、验证和测试。

NFSs-Ganesha 通过FSAL(文件系统抽象层)将一个后端存储抽象成一个统一的API,提供给Ganesha服务端,然后通过NFS协议将其挂载到客户端。在客户端上对挂出来的空间进行操作。

1、Ganesha的核心模块

1)Memory Manager(内存管理): 负责Ganesha的内存管理。

  • 内存管理

内存管理是开发Ganesha时比较大的问题,因为大多数Ganesha架构中的所有模块都必须执行动态内存分配。 例如,管理NFS请求的线程可能需要分配用于存储所请求结果的缓冲器。 如果使用常规的LibC malloc / free调用,则存在内存碎片的风险,因为某些模块将分配大的缓冲区,而其他模块将使用较小的缓冲区。 这可能导致程序使用的部分内存被交换到磁盘,性能会迅速下降的情况。

因此Ganesha有一个自己的内存管理器,来给各个线程分配需要的内存。内存管理器使用了Buddy Malloc algorithm,和内核使用的内存分配是一样的。内存分配器中调用了madvise来管束Linux内存管理器不要移动相关页。其会向Linux申请一大块内存来保持高性能表现。

  • 线程管理

Ganesha给每一个线程分配了单独的资源,这样也要求每个线程自己处理垃圾回收,并且定期重新组合它的资源。同时”dispatcher thread”提供了一些机制来防止太多线程在同一时间执行垃圾回收;在缓存层中垃圾回收被分成好几个步骤,每个步骤由单独代理处理。

(2)RPCSEC_GSS:负责使用RPCSEC_GSS的数据传输,通常使用krb5, SPKM3或LIPKEY来管理安全。

(3)NFS协议模块:负责NFS消息结构的管理

(4)Metadata(Inode)Cache: 负责元数据缓存管理

Ganesha使用了大片内存用于建立元数据和数据缓存。metadata cache存放在Cache Inode Layer(MDCache Layer)层 。每个实例对应一个命名空间中的实例(文件,符号链接,目录)。这些Cache Inode Layer中的实例对应一个FSAL中的对象,把从FSAL中读取到的对象结构映射在内存中。Cache Inode Layer将元数据与对应FSAL对象handle放入哈希表中,用来关联条目。

实例的属性会在一定的时间(可定义)后过期,过期后该实例将会在内存中删除。每个线程有一个LRU(Least Recently Used) 列表,每个缓存实例只能存在于1个线程的LRU中,如果某个线程获得了某个实例,将会要求原线程在LRU列表中释放对应条目。

每个线程需要自己负责垃圾回收,当垃圾回收开始时,线程将从LRU列表上最旧的条目开始执行。 然后使用特定的垃圾策略来决定是否保存或清除条目。由于元数据缓存应该非常大(高达数百万条目),因此占满分配内存的90%(高位)之前不会发生垃圾回收。Ganesha尽可能多得将FSAL对象放入缓存的‘树型拓扑’中,其中节点代表目录,叶子可代表文件和符号链接;叶子的垃圾回收要早于节点,当节点中没有叶子时才会做垃圾回收。

(5)File Content Cache:负责数据缓存管理

File Content Cache数据缓存并不是独立于与Inode Cache,一个对象的元数据缓存和数据缓存会一一对应(数据缓存是元数据缓存的‘子缓存’),从而避免了缓存不统一的情况。文件内容会被缓存至本地文件系统的专用目录中,一个数据缓存实例会对应2个文件:索引文件和数据文件。数据文件等同于被缓存的文件。索引文件中包含了元数据信息,其中包含了对重要的FSAL handle。索引文件主要用于重建数据缓存,当服务器端崩溃后没有干净地清掉缓存时,FSAL handle会读取索引文件中的信息来重建元数据缓存,并将其指向数据文件,用以重建数据缓存实例。

当缓存不足时,worker thread(见2、大型多线程守护程序)会查看LRU列表中很久未被打开的实例,然后开始做元数据缓存回收。当元数据缓存回收开始时,数据缓存的垃圾回收也会同时进行:在回收文件缓存实例时,元数据缓存会问询数据缓存是否认识该文件实例,如果不认识则代表该数据缓存已经无效,则元数据回收正常进行,并完成实例缓存回收;如果认识,对应的文件缓存以及数据缓存均会被回收,随后对应的元数据缓存也会被回收。这样保证了一个数据缓存有效的实例不会被回收。

(6)File System Abstraction Layer(FSAL):

非常重要的模块,通过一个接口来完成对命名空间的访问,所访问的对象随后会放置在inode cache和file content cache中。

FSAL本身给Inode Cache和File Content Cache提供了通用接口,收到请求后会调用具体的FSAL(FSAL_SNMP, FSAL_RGW等)。FSAL中的对象对应一个FSAL handle。由于FSAL的语义设计与NFSv4很相似,因此开发和可以自己编写新的FSAL API来适配Ganesha。Ganesha软件包还提供了FSAL源代码模板。

(7)Hash Tables:提供了基于红黑树的哈希表,这个模块在Ganesha里用到很多

关联寻找功能在Ganesha被大量使用,比如我们想通过对象的父节点和名称来寻找对象元数据等类似行为是很经常的,因此为了保证Ganesha整体的高性能,关联寻找功能必须非常高效。

为了达到这个目的,开发团队采用了红黑树,它会在add/update操作后自动冲平衡。由于单棵红黑树会引发进程调用冲突(多个进程同时add/update,引发同时重平衡),如果加读写锁在红黑树上,又会引发性能瓶颈。因此开发团队设计了红黑树数组来解决了这个问题,降低了两个线程同时访问一个红黑树的概率,从而避免了访问冲突。

2、大型多线程守护程序

线程分为以下不同类型:

  1. dispatcher thread: 用于监听和分发传入的NFS、MOUNT请求。它会选择处于最空闲的worker线程然后将请求添加到这个worker线程的待处理列表中。这个线程会保留最近10分钟内的请求答复,如果在10分钟内收到相同指令(存在哈希表并用RPC Xid4值寻址),则会返回以前的请求回复。
  2. worker thread: Ganesha中的核心线程,也是使用最多的线程。worker线程等待dispatcher的调度,收到请求后先对其进行解码,然后通过调用inode cache API和file content API来完成请求操作。
  3. statistics thread: 收集每个module中的线程统计信息,并定期用CSV格式记录数据,以便于进一步处理。
  4. admin gateway: 用于远程管理操作,包括清楚缓存,同步数据到FSAL存储端,关闭进程等。ganeshaadmin这个程序专门用于与admin gateway线程交互。

3、NFS(网络文件系统)服务

网络文件系统实现的核心是使用了RPC机制,即:远程过程调用协议。RPC是一种编程技术,也是协议。

如果在同一个主机上,两个进程之间可以直接通信(即进程间通信),但是当两个进程位于C/S模型上时,则需要借助另外一个应用程序(RPC),两个进程不需要考虑自己是否在网络上通信(全权由RPC处理)

RPC建立在Socket(套接字)之上,一台主机上运行的主程序,可以调用另一台主机上准备好的子程序,就像本地调用子程序一样,不需要知道底层网络实现的细节。

RPC调用的时候一般有两种方式:

  • 同步调用,客户端等待调用执行完成后并返回结果;
  • 异步调用,客户端调用后不用等待执行结果的返回,但可以通过回调通知等方式获取返回结果。如若客户端不关心调用返回的结果,则称为单向异步调用。

NFS本身不是服务,是一种文件系统(network file system)。期望本机的某一个文件系统(如:共享处去一个目录/var/shared目录),可以被网络内别的主机访问到,并且可以进行操作。当然,首先客户端必须首先挂载服务器共享的目录(mount)。

二、NFS-Ganesha的优点

Ganesha是一个全新的程序,可能对比kernel版本的NFSv4,Ganesha的性能有所欠缺,但是基于user-space的方法会带来更多有意思的功能。

  • 灵活的内存分配——只需要4GB来可以实现百万级别的数据缓存
  • 更强的可移植性——如果NFS Ganesha是kernel-space的话,那样NFS Ganesha的内部结构只能适应一款特定的OS,而很难移植到别的OS上.Ganesha设计初衷是成为一个NFSv4通用服务器,可以实现NFSv4的所有功能,因此也需要适配各种文件系统。
  • 更便捷的访问机制——内核中的NFSv4访问用户空间中的服务不是那么方便,因此其引入了rpc_pipefs机制, 用于解决用户空间服务的桥梁,并且 使用kerberos5管理安全性或idmapd守护程序来进行用户名转换。然而Ganesha不需要这些,它使用常规API来对外提供服务
  • 对接FUSE——由于NFS Ganesha是一个运行在用户空间的程序,因此它还提供了对一些用户空间文件系统(FUSE)的支持,可以让我们直接把FUSE挂载在NFS上而不需要内核的帮助。

三、NFS Ganesha对接Ceph RGW实例

                                                   NFS Ganesha workflow

1、NFS Ganesha工作流程

以open()为例来,如上图所示。首先用户或者应用程序开始调用文件操作,经过系统调用 sys_open(),到达虚拟文件系统层 vfs_open(),然后交给 NFS 文件系统nfs_open()来处理。NFS 文件系统无法操作存储介质,它调用 NFS 客户端函数nfs3_proc_open() 进行通信,把文件操作转发到NFS Ganesha服务器。

Ganesha中监听客户端请求的是Dispatcher这个进程:其中的nfs_rpc_get_funcdesc()函数通过调用svc_getargs()来读取xprt(rpc通信句柄)中的数据,从而得到用户的具体请求,然后将这些信息注入到reqdata这个变量中。随后Dispatcher这个线程会把用户请求-reqdata插入到请求队列中,等待处理。

Ganesha会选择一个最空闲的worker thread来处理请求:通过调用nfs_rpc_dequeue_req()将一个请求从等待队列中取出,随后调用nfs_rpc_execute()函数处理请求。Ganesha内部自建了一个请求/回复缓存,nfs_dupreq_start()函数会在哈希表中寻找是否有一样的请求,如果找到,则寻找到对应回复,然后调用svc_sendreply()将回复发送给客户端,从而完成一个请求的处理。

如果Ganesha没有在哈希表中找到一样的请求,nfs_dupreq_start()这个函数会在缓存中新建一个请求,随后调用service_function(),也就是nfs_open()。FSAL(filesystem abstract layer)收到nfs_open()调用请求后,会调用fsal_open2()函数。由于我们已经在初始化阶段,在ganesha.conf指定了FSAL为RGW,并且在FSAL/FSAL_RGW/handle.c文件下我们已经重定向了FSAL的操作函数,因此fsal_open2()实际会调用rgw_fsal_open2(),通过使用librgw来进行具体操作。请求完成后,回复会插入到对应哈希表中,与请求建立映射,随后回复通过svc_sendreply()发送给客户端。由此完成了sys_open()这个函数的调用。

2、VFS

VFS FSAL 可以使用任何文件提供给操作系统的 Posix 接口。唯一的要求是文件系统能够生成和使用"file handles"。VFS FSAL 还支持 Linux中EXOFS文件系统的pNFS 布局 、还支持linux和FreeBSD的 PanFS (Panasas 专有) 文件系统的pNFS 布局。它是由export定义的选项启用。

参考:

http://blog.umcloud.com/nfs-ganesha/

https://blog.csdn.net/fsx2550553488/article/details/79699519

NFS-Ganesha框架学习相关推荐

  1. RH236配置IP故障转移--配置NFS Ganesha

    RH236配置IP故障转移–配置NFS Ganesha 本章节学习配置NFS Ganesha解决高可用问题. RHCA专栏地址:https://blog.csdn.net/qq_41765918/ca ...

  2. jQuery框架学习第二天:jQuery中万能的选择器

    jQuery框架学习第一天:开始认识jQuery jQuery框架学习第二天:jQuery中万能的选择器 jQuery框架学习第三天:如何管理jQuery包装集 jQuery框架学习第四天:使用jQu ...

  3. ssm框架requestmapping找不到_框架学习,就是介么简单

    框架学习 程序员凯小白 最近实训ssm框架,SSM框架,是Spring + Spring MVC + MyBatis的缩写,这个是继SSH之后,目前比较主流的Java EE企业级框架,适用于搭建各种大 ...

  4. rose框架学习总结

    rose框架学习总结 rose框架为paoding rose框架 具体可见https://code.google.com/p/paoding-rose/ 1   对rose框架的整体认识 1.1B/S ...

  5. Hadoop学习笔记—18.Sqoop框架学习

    Hadoop学习笔记-18.Sqoop框架学习 一.Sqoop基础:连接关系型数据库与Hadoop的桥梁 1.1 Sqoop的基本概念 Hadoop正成为企业用于大数据分析的最热门选择,但想将你的数据 ...

  6. jQuery框架学习第一天:开始认识jQuery

    jQuery框架学习第一天:开始认识jQuery jQuery框架学习第二天:jQuery中万能的选择器 jQuery框架学习第三天:如何管理jQuery包装集 jQuery框架学习第四天:使用jQu ...

  7. Android接口和框架学习

    Android接口和框架学习 缩写: HAL:HardwareAbstraction Layer,硬件抽象层 CTS:CompatibilityTest Suite,兼容性测试套件 Android让你 ...

  8. selenium + python自动化测试unittest框架学习(二)

    1.unittest单元测试框架文件结构 unittest是python单元测试框架之一,unittest测试框架的主要文件结构: File >report >all_case.py &g ...

  9. SpringMVC框架--学习笔记(下)

    接上篇:SpirngMVC框架--学习笔记(上):https://blog.csdn.net/a745233700/article/details/81038382 17.全局异常处理: 系统中异常包 ...

最新文章

  1. UVA10110 Light, more light
  2. PTA数据结构与算法题目集(中文)7-45
  3. 【基本常识1】图像处理opencv
  4. 在JavaScript中深度克隆对象的最有效方法是什么?
  5. 内部人看FaceBook
  6. 数学系列 - 概率论 - 泊松分布和(负)指数分布
  7. 21世纪初最有影响力的20篇计算机视觉期刊论文 及 邓亚峰老师关于人脸识别方面总结
  8. [转]在VS中为C/C++源代码文件生成对应的汇编代码文件(.asm)
  9. SAP BC417 课程中文自学笔记
  10. Linux设备模型(总结)
  11. Gentle.Net学习笔记四:修改代码,使用Oracle数据库
  12. 使用sun misc Unsafe及反射对内存进行内省 introspection
  13. Windows 下80端口被进程 System PID=4 占用的解决方法
  14. openFeign服务调用
  15. oracle两表,有什么方法对Oracle两张表的数据比较呢?
  16. Android 测试入门之---Monkey test
  17. mysql多线程复制binlog_MySQL 不同复制模式下,如何忽略binlog事件
  18. 猴子摘香蕉问题python_用Basic STRIPS算法求解猴子和香蕉
  19. 微信扫描二维码实现下载app文件
  20. win7 eclipse调用虚拟机ubuntu部署的hadoop2.2.0伪分布(1)

热门文章

  1. wcf 高性能服务器,优化 WCF Web 服务性能
  2. SaaS、PaaS、IaaS
  3. 2007.9.16 今天
  4. 【网络安全】BGP线路是什么意思?最全BGP路由协议技术详解
  5. 护士职称计算机考试成绩查询,怎样在网上查询自己的护士职称等级
  6. 声明式编程比命令式编程更好吗? NO! 你可能陷入了声明式编程的迷幻中!
  7. 支持Xcode10和适配iPhone XS Max、iPhone XR的方法
  8. ios 查询mysql数据库操作,iOS开发-数据库-sqlite操作1
  9. nacos的CP和AP模式
  10. BRISK特征点描述算法详解