sequoiadb 数据库引擎处理查询语句流程

 

 

最近国内的一个类mongodb的nosql数据库--SequoiaDB开源了,做为一个开源爱好者,抱着玩玩的心态,从他们官网上下载了个最新的安装包和源代码,自行研究了下。下面的内容是我在试玩过程中,记录下的一些笔记,大概是结合它的源码来解析如何执行一条query语句的过程。

 

         按照它官网上的技术文档,在pc机上安装并成功部署一个集群,文档还算详细,也没遇到什么问题。接着尝试在本地命令行上,连接数据库,创建数据库,创建表格,插入数据,查询数据,玩法基本与mongodb没啥大的区别,感觉还行。

 

     然后再看了下它的基础架构,从官方文档上得知,一个集群主要由三个部分组成,协调节点,编目节点,数据节点。其中这里的协调节点主要接收用户的请求,并转发这些请求到相应的数据节点上。而编目结点,类似集群里的metadata的功能吧,记录了这个集群的数据节点分布,数据库,表格等相关信息。而数据节点,应该就是最终存储真实数据的地方。

  

     在了解了它的基本架构后,便开始查看它的源代码实现,主要看了c驱动和它的引擎入口函数那块的功能实现,代码写得比较精简,但是注释不够详细,有些部分看得不太懂。

然后就开始想着围绕命令行的几条命令,来分析下它的命令执行流程和具体的处理过程。

 

     接着打开一个命令行窗口,输入var db = new Sdb(‘localhost’,11810); 然后看了下协调节点的日志,发现确实打了几条日志,内容就是与11810 这个端口创建连接成功。但是它的日志Level为Warning,这个日志级别应该是可以更改的,于是为了想获取更多的日志信息,我查看了下它的配置信息文档,然后把这个级别修改为Debug级别,但是修改了后,好像没有生效,有点纳闷。最后发现,修改了配置文件后,需要重启这个节点,配置才会生效。

然后就重新执行了一遍 var db = new Sdb(‘localhost’,11810); db.test.test.find() 这两条命令,根据这两条命令的产生的日志,来分析数据库内部的处理流程。

 

首先,经过阅读源代码发现,在命令行中执行db = new Sdb(‘locahost’,11810)之类的命令时,在后台实际上都会通过js的函数映射,映射到c驱动的某个函数上,C驱动的源码主要在client.c这个文件上。通过阅读c驱动代码,connetction(ip,svc_name,user,passwd) 实际上就是在本地封装了一个socket并创建到db协调节点的连接。而db.test.test.find(),则会映射为对应的函数,并通过这个创建好的socket把相应的请求数据,发送到db的协调节点上,db那边经过处理后,把响应的数据返回给客户端的socket上。例如,执行一个find操作,db向客户端返回的是一个cursor,这个cursor实际上是db返回给客户端的一串指定结构的长字符串,而cursor仅仅指向了这段字符串的指针。通过cursor.next() 函数,让cursor指向下一条数据。当cursor指向最一条数据时,再通过socket发送get more指令(包含cursor的offset)到db上,db再返回这个offset开始的后面的数据。其中可以看出,db返回的数据是查询结果的部分数据,不是全部数据。

 

下面再来看看后台的协调节点是如何处理客户端发来的请求的,下面是协调节点的debug日志

sequoiadb 数据库引擎处理查询语句流程_第1张图片

sequoiadb 数据库引擎处理查询语句流程_第2张图片

sequoiadb 数据库引擎处理查询语句流程_第3张图片


从上面的日志,可以发现监听socket连接是一个叫pmdAgentEntryPoint的函数,通过在源码中查找“Receivedpacket size”可以确定,接收客户端报文确实是这个函数。这个函数主要的作用就是根据不同的节点类型来处理不同的请求。

 sequoiadb 数据库引擎处理查询语句流程_第4张图片

进入到pmdProcessAgentRequest这个函数中继续跟踪下去,并查找下一句日志内容的在源代码的打印处。可以发现,会进入到一个语句操作类型的判断中,判断这个操作是query还是get more操作

接着进入到rtnCoordOperator.cpp文件中,通过与编目节点的数据交互,获得处理query中需要用到的group和node,还有node的ip信息,并生成一个包含所有groupid的list,在这里使用一个map(grouplist)来存放groupid,grouplist[groupid] = groupid ;

接着进入到rtnCoordQuery.cpp中,在得到了所需要的group和node信息后,通过queryToDataNodeGroup这个函数,把数据请求发送到对应的数据节点组上,数据结点组选取其中一个数据节点进行数据的请求,并把查询到的结果通过socket返回给协调节点,协调节点再把数据返回给客户端。

 

后台数据库引擎处理数据报文的过程比较复杂,涉及到的函数与文件数量比较多,上面只是我对这个处理过程的一个浓缩,可能会存在一些错误的地方,如果给其它开源爱好者带来一些误导的话,请见谅,哈哈。希望这篇文章能给大家带来帮助。

你可能感兴趣的:(other)