溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

glusterfs通信rpc怎么用

發(fā)布時(shí)間:2022-01-05 09:11:18 來(lái)源:億速云 閱讀:131 作者:iii 欄目:云計(jì)算

這篇文章主要介紹“glusterfs通信rpc怎么用”,在日常操作中,相信很多人在glusterfs通信rpc怎么用問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”glusterfs通信rpc怎么用”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

在glusterfs中,gluster與glusterd通信請(qǐng)求對(duì)卷的操作、集群的操作、狀態(tài)的查看等;glusterd與glusterfsd通信完成對(duì)卷的操作,集群的操作,狀態(tài)的查看;glusterfs與glusterfsd通信完成文件的存儲(chǔ)。所有這些通信都是通過(guò)內(nèi)部的RPC模塊來(lái)完成的。

=========================================

從代碼的組織來(lái)看,RPC的服務(wù)端邏輯上可分為四層,server-app、rpc-server、rpc-transport、protocol,每一層都提供相應(yīng)的接口供上一層調(diào)用,同時(shí),上一層會(huì)提供回調(diào)函數(shù)供下一層來(lái)調(diào)用;同樣,RPC的客戶(hù)端邏輯上也可分為四層,cli-app、rpc-cli、rpc-transport、protocol。目前,protocol提供了tcp(socket)和rdma兩種方式,且都以動(dòng)態(tài)庫(kù)的方式提供,rpc-transport會(huì)根據(jù)配置加載不同的動(dòng)態(tài)庫(kù)。我們以gluster與glusterd的通信并選用tcp的方式為例來(lái)看看RPC相關(guān)流程。

1. 服務(wù)端的初始化

需要注意的是:rpc_transport_load時(shí)會(huì)根據(jù)協(xié)議的類(lèi)型加載(使用dlopen)不同的動(dòng)態(tài)庫(kù),調(diào)用socket_listen時(shí)將fd與回調(diào)函數(shù)添加事件驅(qū)動(dòng)器中。當(dāng)有讀寫(xiě)事件時(shí),事件驅(qū)動(dòng)器回調(diào)socket_server_event_handler函數(shù)(用于服務(wù)端的accept)或者socket_event_handler函數(shù)(用于一般的請(qǐng)求),然后依次回調(diào)rpc_transport_notify、rpcsvc_notify處理RPC請(qǐng)求。

2. 客戶(hù)端的初始化

socket_connect函數(shù)會(huì)將fd以及回調(diào)處理函數(shù)注冊(cè)到事件驅(qū)動(dòng)器中。

3. 一次完整的RPC流程

(1) 客戶(hù)端發(fā)送RPC請(qǐng)求

客戶(hù)端通過(guò)調(diào)用rpc_clnt_submit函數(shù)發(fā)送RPC請(qǐng)求,該函數(shù)又會(huì)一層層調(diào)用,最終在socket_submit_request中通過(guò)writev將請(qǐng)求發(fā)送出去。在調(diào)用rpc_clnt_submit時(shí)會(huì)準(zhǔn)備好RPC所需要的相關(guān)數(shù)據(jù),例如程序號(hào),程序版本號(hào),過(guò)程號(hào),參數(shù)信息等等,然后逐層按照接口組織好相關(guān)的數(shù)據(jù)。

例如: 執(zhí)行 gluster volume info命令,其內(nèi)部關(guān)鍵代碼:

int32_t gf_clie_1_get_volume(call_frame_t * frame, xlator_t * this)
{
    ...
    ret = cli_cmd_submit(&req,
                         frame,
                         cli_rpc_prog, //包含程序名,程序號(hào),程序版本號(hào)等信息
                         GLUSTER_CLI_GET_VOLUME, //過(guò)程號(hào)
                         NULL,
                         this,
                         gf_cli3_1_get_volume_cbk, //結(jié)果處理回調(diào)函數(shù)
                         (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) 服務(wù)端處理RPC請(qǐng)求

服務(wù)端收到請(qǐng)求后,從socket_event_handler回調(diào)到rpc_transport_notify,再回調(diào)到rpcsvc_notify,最終調(diào)用rpcsvc_handle_rpc_call函數(shù)。在這個(gè)函數(shù)中,解析客戶(hù)端RPC請(qǐng)求中包含的程序號(hào),過(guò)程號(hào)以及相關(guān)參數(shù)等,然后根據(jù)這些程序號(hào),過(guò)程號(hào)找到對(duì)應(yīng)的處理函數(shù)。而這些處理函數(shù)就是先前通過(guò)rpcsvc_program_register函數(shù)注冊(cè)的。對(duì)應(yīng)的處理函數(shù)處理完成后調(diào)用相關(guān)函數(shù)答復(fù)客戶(hù)端。

注: actor并不是一個(gè)真正的函數(shù),僅標(biāo)識(shí)不同RPC請(qǐng)求的處理函數(shù).

(3) 客戶(hù)端處理RPC的回復(fù)

客戶(hù)端在發(fā)送請(qǐng)求時(shí),會(huì)將請(qǐng)求的相關(guān)信息緩存下來(lái),當(dāng)收到服務(wù)器的回應(yīng)后,再根據(jù)程序號(hào)、過(guò)程號(hào)找到對(duì)應(yīng)的請(qǐng)求信息,然后調(diào)用相應(yīng)的回調(diào)函數(shù)對(duì)請(qǐng)求結(jié)果進(jìn)行處理。

到此,關(guān)于“glusterfs通信rpc怎么用”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI