Nebula Graph源码分析

技术Nebula Graph源码分析本篇内容介绍了“Nebula Graph源码分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够

本文介绍了“星云图源代码分析”的相关知识。很多人在实际案例的操作中会遇到这样的困难。接下来,让边肖带领大家学习如何应对这些情况!希望大家认真阅读,学点东西!

00-1010对于一些初始联系人

对于Bulagraph开源库的朋友来说,刚开始和我一样,他们可能想提升自己,看看大神们的代码,尝试做点什么,也许能修复一个看起来没那么难的Bug。但是面对这么多代码,我破解了,不知道怎么下手。最后,我硬着头皮,一遍又一遍地读代码,在运行了一个又一个用例后,终于得到了线索。

让我们分享一下学习星云图开源代码的过程。也希望刚接触星云图的朋友们能够少走弯路,快速上手。此外,星云图本身也使用了一些开源库。详见附录。

在本文中,我们将通过数据流快速学习星云图,这样用户就可以在客户端输入一个nGQL语句。

例如,SHOW SPACES使用GDB跟踪输入语句时星云图是如何被调用和运行的。

导读

Nebula  Graph源码分析

一个完整的星云图包含三个服务,即查询服务、存储服务和元服务。每个服务都有自己的可执行二进制文件。

查询服务主要负责

客户端连接的管理

将来自客户端的nGQL语句解析为抽象语法树AST,并将抽象树AST解析为一系列执行动作。

优化执行动作。

执行优化的执行计划。

存储服务主要负责

基于

元服务主要负责

添加、删除、检查和修改模式

集群管理

用户认证

这次主要分析查询服务。

00-1010开头,可以得到一个源码包,解压。可以先看看代码的层次关系。不同包装的主要功能是什么?下面只列出了src目录:

| - src

|-客户端//客户端代码

|-common//提供了一些常见的基本组件。

| -控制台

| -守护进程

| -数据员

|-graph//包含了QueryService的大部分代码。

|-interface//主要指元、存储、图形的通信接口定义。

| - jni

| - kvstore

|-Meta//与元数据管理相关

|-解析器//主要负责词法和语法分析n

bsp;  
    |--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 进入ExecutionPlan
execute 函数内部,然后执行到

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源码分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/85705.html

(0)

相关推荐

  • C#如何实现前台与后台方法互调

    技术C#如何实现前台与后台方法互调本篇文章为大家展示了C#如何实现前台与后台方法互调,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。前台与后台方法互调是很多读者关心的功能。下面提供

    攻略 2021年11月24日
  • 编辑html文件一般用哪些软件

    技术编辑html文件一般用哪些软件这篇文章主要为大家展示了“编辑html文件一般用哪些软件”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“编辑html文件一般用哪些软件”这篇文

    攻略 2021年11月18日
  • mysql drop与truncate差别(mysql存储过程truncate)

    技术mysql中TRUNCATE AND DELETE有什么用这篇文章主要介绍了mysql中TRUNCATE AND DELETE有什么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下

    攻略 2021年12月20日
  • Tomcat运行Java Web内存溢出的示例分析

    技术Tomcat运行Java Web内存溢出的示例分析这篇文章主要介绍Tomcat运行Java Web内存溢出的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!如果JVM里运行的程序, 它的

    攻略 2021年12月11日
  • 人用C#开发ActiveX控件并使用web调用

    技术人用C#开发ActiveX控件并使用web调用人用C#开发ActiveX控件并使用web调用,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。入职差不多两个

    攻略 2021年10月29日
  • linux mac地址怎么查(macoslinux系统命令区别)

    技术在Linux以及Mac OS X如何启用F#这篇文章主要介绍了在Linux以及Mac OS X如何启用F#,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下

    攻略 2021年12月16日