亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Nebula Graph源碼分析

發布時間:2021-11-12 11:49:09 來源:億速云 閱讀:193 作者:iii 欄目:數據庫

本篇內容介紹了“Nebula Graph源碼分析”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

導讀

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

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

在本文中,我們將通過數據流快速學習 Nebula Graph,以用戶在客戶端輸入一條 nGQL 語句 SHOW SPACES 為例,使用 GDB 追蹤語句輸入時 Nebula Graph 是怎么調用和運行的。

整體架構

Nebula Graph源碼分析

一個完整的 Nebula Graph 包含三個服務,即 Query Service,Storage Service 和 Meta Service。每個服務都有其各自的可執行二進制文件。

Query Service 主要負責

  • 客戶端連接的管理

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

  • 對執行動作進行優化

  • 執行優化后的執行計劃

Storage Service 主要負責

  • 數據的分布式存儲

Meta Service 主要負責

  • 圖 schema 的增刪查改

  • 集群的管理

  • 用戶鑒權

這次,我們主要對 Query Service 進行分析

目錄結構

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

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

代碼跟蹤

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

Nebula Graph源碼分析

啟動后通過 nebula.service status all 查看當前的服務狀態

Nebula Graph源碼分析

然后 gdb 運行 bin 目錄下的 nebula-graphd 二進制程序

gdb> set args --flagfile  /home/mingquan.ji/1.0/nebula-install/etc/nebula-graphd.conf   //設置函數入參
gdb> set follow-fork-mode child   // 由于是守護進程,所以在 fork 子進程后 gdb 繼續跟蹤子進程
gdb> b main         // 在 mian 入口打斷點

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

由于 Nebula Graph 使用 FBThrift 來定義生成不同服務的通訊代碼,在 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<GraphService>();
status = interface->init(ioThreadPool);
gServer->setInterface(std::move(interface));
gServer->setAddress(localIP, FLAGS_port);

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

此時重新打開一個終端進入 nebula 安裝目錄,通過 ./nebule -u=root -p=nebula 來連接 nebula 服務,再在客戶端輸入 SHOW SPACES ,此時客戶端沒有反應,是因為服務端還在阻塞調試中,回到服務端輸入 continue,如下所示:

Nebula Graph源碼分析

經過 session 驗證后,進入 executionEngine->execute() 中,step 進入函數內部

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

繼續 step 進入ExecutionPlanexecute 函數內部,然后執行到

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

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

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;
    }

其在匹配到對應到 go 語句時,就構造對應的節點,然后由 bison 處理,最后生成一個抽象的語法樹。

詞法語法分析后開始執行模塊,繼續 gdb,進入 excute 函數,一直 step 直到進入ShowExecutor::execute 函數。

Nebula Graph源碼分析

繼續 next 直到 showSpaces()step 進入此函數

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 數據,之后通過回調函數 cb 回傳拿到的數據,至此 nGQL 語句 SHOW SPACES; 已經執行完畢,而其他復雜的語句也可以以此類推。

  • 如果是正在運行的服務,可以先查出該服務的進程 ID,然后通過 gdb attach PID 來調試該進程;

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

    1. 通過對應目錄下的 CMakeLists.txt 文件找到對應的模塊名

    2. 在 build 目錄下 make 模塊名,在 build/bin/test 目錄下生成對應的二進制程序

    3. gdb 跟蹤調試該程序

“Nebula Graph源碼分析”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

应用必备| 杭锦后旗| 金山区| 壶关县| 广东省| 镇远县| 清水县| 合阳县| 岳池县| 湘乡市| 藁城市| 神木县| 陈巴尔虎旗| 伊通| 大姚县| 双鸭山市| 武功县| 河北省| 井冈山市| 晋中市| 石狮市| 德钦县| 达拉特旗| 怀化市| 新邵县| 开远市| 泸州市| 西充县| 临海市| 科技| 霍城县| 宁河县| 长治市| 富平县| 中山市| 汤原县| 西乌珠穆沁旗| 岑溪市| 抚顺市| 科技| 垫江县|