[置顶] glusterfs 源码框架学习归纳总结

时间:2021-09-30 13:44:36
[置顶]        glusterfs 源码框架学习归纳总结[置顶]        glusterfs 源码框架学习归纳总结        网上有关glusterfs的源码分析文章还是挺多,这里总结我看过的理解,及其相关资源。        当然,由于挺久没看代码了,现在主要凭印象,再加上自己收集的网页和笔记,感觉深刻的写出来,重点是讲的是思想而非技术细节。        另外,本人能力有限,再加上主要利用业余时间看,不是工作性质,看的也就没那么深那么细节,更多是框架相关,比较适合入门看感觉。        有错误,望指正! 有好资源望共享,有不同想法观点望交流!共勉交流万岁!

1.服务端(glusterfsd),客户端(glusterfs),管理程序(glusterd)同一main入口 

        首先,glusterfs这个框架类似于网络协议栈框架,xlator结构体就是代表一个功能层(相当于一个网络协议层),  这个glusterfsd.c:main 主要就是搭建起xlator这棵树和必要的资源,具体功能在的相应的xlator中,可以看出该架构垂直扩展,添加功能很容易  。即这个main就是通用的初始化流程, 该程序是服务端还是客户端等等,就看这颗树是咋堆xlator的。        相关源码分析资料参考(大体流程没啥出入):

          glusterFS源码结构分析.pdf - 下载频道 - CSDN.NET 

         GlusterFS 主函数工作流程_百度文库 


2. xlator 架构

     glusterfs架构最核心的结构体, xlator就相当于用c语言实现的对象(OO), 参考 GlusterFS:xlator基础源码研究 这篇写的就很好了。 此外,个人觉得,看源码时候,适时用面向对象思想看,不要只跟数据流走,走通不意味着理解深刻,比较好。  这里主要说明:    1 .IO流中, 相关的xlator中未定义的文件系统POSIX接口是用defaults.c中默认的。       2. 每个xlator可以看做对象, 都有notify函数,既都会有被通知发生了事件并做相应的处理, 这个就有些观察者模式意思。让别人对此感兴趣的人来调用,通知该层的xlator发生了啥事件,然后该xlator就做相应的动作,源码理解就是外部调用该xlator的notify函数,我想这也是借鉴网络协议栈思想。    默认的notify是在defaults.c:default_notify函数,   默认调用parent的notify:[置顶]        glusterfs 源码框架学习归纳总结[置顶]        glusterfs 源码框架学习归纳总结
    3. STACK_WIND ()跟STACK_WIND_TAIL()宏主要区别就是否复用parent的call_frame_t结构体。call_frame_t可以看做该层xlator的上下文(每次接口调用)。    
    4.可以看到采用这架构,垂直来看,扩展功能很容易,只要追加一层xlaor就行了而且不影响;水平角度看来,太对称了,会增加实现复杂度吧。各有利弊吧。 有机会看看ceph,好好对比。。。

3 .mem_pool && hash

    mem_pool采用的思想就是linux内核的slab思想 ,本质就是空间换时间思想,hash本质思想也如此,印象中,glusterfs挺多结构体组织就是采用hash链表来管理的,典型就是glustefs中 inode && entry&& inode_tables。    我想,hash在文件系统跟交换机上有很大的应用场景吧,毕竟在追求高效率下,空间换时间思想是经常采用的

参考GlusterFS之内存池(mem-pool)实现原理及代码详解  GlusterFS 主函数工作流程_百度文库 这篇也有相关实现章节,个人觉得实现采用“malloc+slab思想”。


4. 线程池

      glusterfs自己实现的线程池,也有自己的简单线程调度机制, 也算多并发来提高glusterfs的性能吧, synctask_new()即创建一个synctask,可以看到挺多地方用到的:[置顶]        glusterfs 源码框架学习归纳总结[置顶]        glusterfs 源码框架学习归纳总结我想采用线程池技术 多用在服务端,毕竟可以充分利用多核多cpu来提高并发,来提高处理速度。可以看到RPC server端的rpcsvc_handle_rpc_call函数中也调用到了。[置顶]        glusterfs 源码框架学习归纳总结[置顶]        glusterfs 源码框架学习归纳总结


5. RPC模块

  glusterfs自己实现RPC协议框架,作为各个主机上的进程间通信基础。   可以参考  Glusterfs之rpc模块源码分析(中)之Glusterfs的rpc模块实现(1) 系列,分析比较细了,不过主要以数据流分析为主, 看完后跳出来用面向对象看待相关结构体直接关系,效果比较好,对其他模块也试用 。

补充一点  :

    1. 服务端 rpcsvc_program结构体中的synctask 变量作用是否使用多线程,值为synctask true,即使用线程池来处理,提高服务端处理效率进而提高性能
[置顶]        glusterfs 源码框架学习归纳总结

实际代码(在rpcsvc_handle_rpc_call):

[置顶]        glusterfs 源码框架学习归纳总结

6.event_pool

 事件管理池,在使用tcp/ip协议下,主要由socket.c这个文件夹使用,  抽象统一管理每个socket连接, 实现对于 每个socket连接 采用同步非阻塞式;event_register()来注册事件通知的载体,这里采用epool或pool ,默认采用epool:           [置顶]        glusterfs 源码框架学习归纳总结[置顶]        glusterfs 源码框架学习归纳总结可以看到glusterd.c:main 最后将阻塞死循在  event_dispatch (ctx->event_pool)   。即:event_dispatch_epoll函数 。(采用pthread_cond_wait +epoll_wait 实现 ,基本都这样实现框架的吧)         

7 . IO流入口   

  主要有3个入口(FUSE,NFS,libgfapi), 参考 GlusterFS分布式文件系统 (下图来自此处):  1.FUSE      客户端调用mount.glusterfs时,如图,使用fuse方式,fuse是用户空间文件系统常用接口,由于用户态和内核态切换且拷贝数据,会影响性能。        [置顶]        glusterfs 源码框架学习归纳总结
     源码分析 &疑问:     追踪调试,可以发现fuse使用自己的协议,当GF_EVENT_CHILD_UP等事件来时,fuse-bridge.c :notify()调用线程 fuse_thread_proc()来处理,该函数是单线程死循环,是接口调用处理入口:       readv(/dev/fuse) //接受数据,然后分析处理协议        fuse_ops[finh->opcode] (this, finh, msg);  //最后调用具体的接口。
  疑问:跟我在网上搜索到的标准fuse接口协议不一样,只要open(/dev/fuse),就可以使用自己的协议,不受内核fuse模块接口协议影响?   即内核fuse跟glusterfs咋交互的,比较迷惑)


2. libgfapi  如图客户程序调用libgfapi,就避免数据多次在用户态和内核态拷贝和切换,会提高一定的性能。[置顶]        glusterfs 源码框架学习归纳总结
   源码入口比较简单,就是调用相关的API就行了,看源码例子就了解了:glfsxmp.c。

3 .NFS没看过追踪过。不过也是glusterfs自己实现或基于第三方模块剪裁修改过的吧。 上链接:Glusterfs之nfs模块源码分析(中)之Glusterfs实现NFS服务器系列(该blog主glusterfs系列文章还是很不错的。)


待续 。。。。