真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

NebulaGraph源碼分析-創(chuàng)新互聯(lián)

本篇內(nèi)容介紹了“Nebula Graph源碼分析”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

站在用戶的角度思考問題,與客戶深入溝通,找到準(zhǔn)格爾網(wǎng)站設(shè)計(jì)與準(zhǔn)格爾網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗(yàn)好的作品,建站類型包括:成都網(wǎng)站建設(shè)、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊、虛擬主機(jī)、企業(yè)郵箱。業(yè)務(wù)覆蓋準(zhǔn)格爾地區(qū)。

導(dǎo)讀

對于一些剛開始接觸 Nebula Graph 開源庫的小伙伴來說,剛開始可能和我一樣,想要提高自己,看看大神們的代碼然后試著能夠做點(diǎn)什么,或許能夠修復(fù)一個看起來并不是那么困難的 Bug。但是面對如此多的代碼,我裂開了,不知道如何下手。最后硬著頭皮,再看了一遍又一遍代碼,跑了一個又一個用例之后終于有點(diǎn)眉目了。

下面就分享下個人學(xué)習(xí) Nebula Graph 開源代碼的過程,也希望剛接觸 Nebula Graph 的小伙伴能夠少走彎路,快速入門。另外 Nebula Graph 本身也用到了一些開源庫,詳情可以見附錄。

在本文中,我們將通過數(shù)據(jù)流快速學(xué)習(xí) Nebula Graph,以用戶在客戶端輸入一條 nGQL 語句 SHOW SPACES 為例,使用 GDB 追蹤語句輸入時 Nebula Graph 是怎么調(diào)用和運(yùn)行的。

整體架構(gòu)

Nebula Graph源碼分析

一個完整的 Nebula Graph 包含三個服務(wù),即 Query Service,Storage Service 和 Meta Service。每個服務(wù)都有其各自的可執(zhí)行二進(jìn)制文件。

Query Service 主要負(fù)責(zé)

  • 客戶端連接的管理

  • 解析來自客戶端的 nGQL 語句為抽象語法樹 AST,并將抽象樹 AST 解析成一系列執(zhí)行動作。

  • 對執(zhí)行動作進(jìn)行優(yōu)化

  • 執(zhí)行優(yōu)化后的執(zhí)行計(jì)劃

Storage Service 主要負(fù)責(zé)

  • 數(shù)據(jù)的分布式存儲

Meta Service 主要負(fù)責(zé)

  • 圖 schema 的增刪查改

  • 集群的管理

  • 用戶鑒權(quán)

這次,我們主要對 Query Service 進(jìn)行分析

目錄結(jié)構(gòu)

剛開始,可以拿到一個 source 包,解壓,可以先看看代碼的層級關(guān)系,不同的包主要功能是干什么的 下面只列出 src 目錄:

|--src
    |--client // 客戶端代碼
    |--common // 提供一些常用的基礎(chǔ)組件
    |--console
    |--daemons
    |--dataman
    |--graph // 包含了Query Service的大部分代碼                         
    |--interface // 主要是一些 meta、storage 和 graph 的通訊接口定義     
    |--jni
    |--kvstore
    |--meta // 元數(shù)據(jù)管理相關(guān) 
    |--parser // 主要負(fù)責(zé)詞法和語法分析       
    |--storage // 存儲層相關(guān)
    |--tools
    |--webservice

代碼跟蹤

通過 scripts 目錄下的腳本啟動 metad 和 storaged 這兩個服務(wù):

Nebula Graph源碼分析

啟動后通過 nebula.service status all 查看當(dāng)前的服務(wù)狀態(tài)

Nebula Graph源碼分析

然后 gdb 運(yùn)行 bin 目錄下的 nebula-graphd 二進(jìn)制程序

gdb> set args --flagfile  /home/mingquan.ji/1.0/nebula-install/etc/nebula-graphd.conf   //設(shè)置函數(shù)入?yún)?gdb> set follow-fork-mode child   // 由于是守護(hù)進(jìn)程,所以在 fork 子進(jìn)程后 gdb 繼續(xù)跟蹤子進(jìn)程
gdb> b main         // 在 mian 入口打斷點(diǎn)

在 gdb 中輸入 run 開始運(yùn)行 nebula-graphd 程序,然后通過 next 可以一步一步運(yùn)行,直到遇到 gServer->serve();  // Blocking wait until shut down via gServer->stop(),此時 nebula-graphd 的所有線程阻塞,等待客戶端連接,這時需要找到客戶端發(fā)起請求后由哪個函數(shù)處理。

由于 Nebula Graph 使用 FBThrift 來定義生成不同服務(wù)的通訊代碼,在 src/interface/graph.thrift 文件中可以看到 GraphService 接口的定義如下:

service GraphService {
    AuthResponse authenticate(1: string username, 2: string password)
    oneway void signout(1: i64 sessionId)
    ExecutionResponse execute(1: i64 sessionId, 2: string stmt)
}

gServer->serve() 之前有

auto interface = std::make_shared();
status = interface->init(ioThreadPool);
gServer->setInterface(std::move(interface));
gServer->setAddress(localIP, FLAGS_port);

可以知道是由 GraphService 對象來處理客戶端的連接和請求,因此可以在 GraphService.cpp:``future_execute 處打斷點(diǎn),以便跟蹤后續(xù)處理流程。

此時重新打開一個終端進(jìn)入 nebula 安裝目錄,通過 ./nebule -u=root -p=nebula 來連接 nebula 服務(wù),再在客戶端輸入 SHOW SPACES ,此時客戶端沒有反應(yīng),是因?yàn)榉?wù)端還在阻塞調(diào)試中,回到服務(wù)端輸入 continue,如下所示:

Nebula Graph源碼分析

經(jīng)過 session 驗(yàn)證后,進(jìn)入 executionEngine->execute() 中,step 進(jìn)入函數(shù)內(nèi)部

auto plan = new ExecutionPlan(std::move(ectx));
plan->execute();

繼續(xù) step 進(jìn)入ExecutionPlanexecute 函數(shù)內(nèi)部,然后執(zhí)行到

auto result = GQLParser().parse(rctx->query());

parse 這塊主要使用 flex & bison,用于詞法分析和語法解析構(gòu)造對象到抽象語法樹,其詞法文件是 src/parser/scanner.lex,語法文件是 src/parser/parser.yy,其詞法分析類似于正則表達(dá)式,語法分析舉例如下:

go_sentence
    : KW_GO step_clause from_clause over_clause where_clause yield_clause {
        auto go = new GoSentence();
        go->setStepClause($2);
        go->setFromClause($3);
        go->setOverClause($4);
        go->setWhereClause($5);
        if ($6 == nullptr) {
            auto *cols = new YieldColumns();
            for (auto e : $4->edges()) {
                if (e->isOverAll()) {
                    continue;
                }
                auto *edge  = new std::string(*e->edge());
                auto *expr  = new EdgeDstIdExpression(edge);
                auto *col   = new YieldColumn(expr);
                cols->addColumn(col);
            }
            $6 = new YieldClause(cols);
        }
        go->setYieldClause($6);
        $$ = go;
    }

其在匹配到對應(yīng)到 go 語句時,就構(gòu)造對應(yīng)的節(jié)點(diǎn),然后由 bison 處理,最后生成一個抽象的語法樹。

詞法語法分析后開始執(zhí)行模塊,繼續(xù) gdb,進(jìn)入 excute 函數(shù),一直 step 直到進(jìn)入ShowExecutor::execute 函數(shù)。

Nebula Graph源碼分析

繼續(xù) next 直到 showSpaces(),step 進(jìn)入此函數(shù)

auto future = ectx()->getMetaClient()->listSpaces();
auto *runner = ectx()->rctx()->runner();
'''
'''
std::move(future).via(runner).thenValue(cb).thenError(error);

此時 Query Service 通過 metaClient 和 Meta Service 通信拿到 spaces 數(shù)據(jù),之后通過回調(diào)函數(shù) cb 回傳拿到的數(shù)據(jù),至此 nGQL 語句 SHOW SPACES; 已經(jīng)執(zhí)行完畢,而其他復(fù)雜的語句也可以以此類推。

  • 如果是正在運(yùn)行的服務(wù),可以先查出該服務(wù)的進(jìn)程 ID,然后通過 gdb attach PID 來調(diào)試該進(jìn)程;

  • 如果不想啟動服務(wù)端和客戶端進(jìn)行調(diào)試,在 src 目錄下的每個文件夾下都有一個 test 目錄,里面都是對對應(yīng)模塊或者功能進(jìn)行的單元測試,可以直接編譯對應(yīng)的單元模塊,然后跟蹤運(yùn)行。方法如下:

    1. 通過對應(yīng)目錄下的 CMakeLists.txt 文件找到對應(yīng)的模塊名

    2. 在 build 目錄下 make 模塊名,在 build/bin/test 目錄下生成對應(yīng)的二進(jìn)制程序

    3. gdb 跟蹤調(diào)試該程序

“Nebula Graph源碼分析”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


網(wǎng)站標(biāo)題:NebulaGraph源碼分析-創(chuàng)新互聯(lián)
鏈接地址:http://weahome.cn/article/gphgh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部