In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-05 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)05/31 Report--
这篇文章主要介绍"glusterfs通信rpc怎么用",在日常操作中,相信很多人在glusterfs通信rpc怎么用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"glusterfs通信rpc怎么用"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
在glusterfs中,gluster与glusterd通信请求对卷的操作、集群的操作、状态的查看等;glusterd与glusterfsd通信完成对卷的操作,集群的操作,状态的查看;glusterfs与glusterfsd通信完成文件的存储。所有这些通信都是通过内部的RPC模块来完成的。
=========================================
从代码的组织来看,RPC的服务端逻辑上可分为四层,server-app、rpc-server、rpc-transport、protocol,每一层都提供相应的接口供上一层调用,同时,上一层会提供回调函数供下一层来调用;同样,RPC的客户端逻辑上也可分为四层,cli-app、rpc-cli、rpc-transport、protocol。目前,protocol提供了tcp(socket)和rdma两种方式,且都以动态库的方式提供,rpc-transport会根据配置加载不同的动态库。我们以gluster与glusterd的通信并选用tcp的方式为例来看看RPC相关流程。
1. 服务端的初始化
需要注意的是:rpc_transport_load时会根据协议的类型加载(使用dlopen)不同的动态库,调用socket_listen时将fd与回调函数添加事件驱动器中。当有读写事件时,事件驱动器回调socket_server_event_handler函数(用于服务端的accept)或者socket_event_handler函数(用于一般的请求),然后依次回调rpc_transport_notify、rpcsvc_notify处理RPC请求。
2. 客户端的初始化
socket_connect函数会将fd以及回调处理函数注册到事件驱动器中。
3. 一次完整的RPC流程
(1) 客户端发送RPC请求
客户端通过调用rpc_clnt_submit函数发送RPC请求,该函数又会一层层调用,最终在socket_submit_request中通过writev将请求发送出去。在调用rpc_clnt_submit时会准备好RPC所需要的相关数据,例如程序号,程序版本号,过程号,参数信息等等,然后逐层按照接口组织好相关的数据。
例如: 执行 gluster volume info命令,其内部关键代码:
int32_t gf_clie_1_get_volume(call_frame_t * frame, xlator_t * this){ ... ret = cli_cmd_submit(&req, frame, cli_rpc_prog, //包含程序名,程序号,程序版本号等信息 GLUSTER_CLI_GET_VOLUME, //过程号 NULL, this, gf_cli3_1_get_volume_cbk, //结果处理回调函数 (xdrproc_t)xdr_gf_cli_req); ..}int cli_cmd_submit(void *req, call_frame_t * frame, rpc_clnt_prog_t * prog, int procnum, struct iobref * iobref, xlator_t * this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc){ ... ret = cli_submit_request(req, frame, prog, procnum, NULL, this, cbkfn, xdrproc); ...}int cli_submit_request(void * req, call_frame_t * frame, rpc_clnt_prog_t * prog, int procnum, struct iobref * iobref, xlator_t * this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc){ ... ret = rpc_clnt_submit(global_rpc, prog, procnum, cbkfn, &iov, count, NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL)}int rpc_clnt_submit(struct rpc_clnt * rpc, rpc_clnt_prog_t * prog, int procnum, fop_cbk_fn_t cbkfn, struct iovec * proghdr, int proghdrcount, struct iovec * progpayload, int progpayloadcount, struct iobref * iobref, void * frame, struct iovec * rsphdr, int rsphdr_count, struct iovec * rsp_payload,int rsp_payload_count, struct iobref * rsp_iobref){ struct iobuf * request_iob = NULL; rpc_transport_req_t req; ... request_iob = rpc_clnt_record(rpc, frame, prog, procnum, proglen, &rpchdr, callid); req.msg.rpchdr = &rpchdr; req.msg.rpchdrcount = 1; req.msg.proghdr = proghdr; req.msg.proghdrcount = proghdrcount; req.msg.progpayload = progpayload; req.msg.progpayloadcount = progpayloadcount; req.msg.iobref = iobref; ... ret = rpc_transport_submit_request(rpc->conn.trans, &req); ...}int32_t rpc_transport_submit_request(rpc_transport_t * this, rpc_transport_req_t * req){ ret = this->ops->submit_request(this, req);}int32_t socket_submit_request(rpc_transport_t * this, rpc_transport_req_t * req){ struct ioq * entry = NULL; entry = __socket_ioq_new(this, &req->msg); ret = __socket_ioq_churn_entry(this, entry); ...}int __socket_ioq_churn_entry(rpc_transport_t *this, struct ioq * entry){ ret = __socket_writev(this, entry->pending_vector, entry->pending_count, &entry->pending_vector, &entry->pending_count); ...}int __socket_writev(rpc_transport_t * this, struct iovec * vector, int count, struct iovec **pending_vector, int *pendint_count){ ret = __socket_rwv(this, vector, count, pending_vector, pending_count, NULL, 1); ...}int __socket_rwv(rpc_transport_t *this, struct iovec *vector, int count, struct iovec **pending_vector, int * pending_count, size_t * bytes, int write){ int opcount = 0; struct iovec * opvector = NULL; opvector = vector; opcount = count; while(opcount) { if(write) { ret = wrtiev(sock, opvector, opcount); } ... } ...}
(2) 服务端处理RPC请求
服务端收到请求后,从socket_event_handler回调到rpc_transport_notify,再回调到rpcsvc_notify,最终调用rpcsvc_handle_rpc_call函数。在这个函数中,解析客户端RPC请求中包含的程序号,过程号以及相关参数等,然后根据这些程序号,过程号找到对应的处理函数。而这些处理函数就是先前通过rpcsvc_program_register函数注册的。对应的处理函数处理完成后调用相关函数答复客户端。
注: actor并不是一个真正的函数,仅标识不同RPC请求的处理函数.
(3) 客户端处理RPC的回复
客户端在发送请求时,会将请求的相关信息缓存下来,当收到服务器的回应后,再根据程序号、过程号找到对应的请求信息,然后调用相应的回调函数对请求结果进行处理。
到此,关于"glusterfs通信rpc怎么用"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.