一种加快数据从opengauss加载到dataframe的方法
技术领域
1.本发明涉及计算机数据处理技术领域,具体而言,涉及一种加快数据从opengauss加载到dataframe的方法。
背景技术:2.数据通常存储在数据库管理系统(dbms)中,但dataframe(数据帧)库在数据科学家中得到广泛使用。一个重要但具有挑战性的问题是如何弥补数据库和dataframe之间的差距。
3.例如pandas、dask和modin(均为常见的python第三方库)等dataframe库被广泛的使用于数据操作和数据分析中。一般情况下,企业环境会将其数据存储在数据库管理系统中,因此,大多数数据科学分析软件第一步都是从dbms中加载数据。但是这个数据加载过程不仅是出了名的缓慢,而且还消耗了大量的客户端内存,这很容易导致内存不足或性能下降的问题。这个问题是亟待解决的,因为读取数据这个操作处于很多数据科学任务的关键路径上,而且在某些真实的机器学习管道中,它可能消耗超过50%的时间。因此,弥补数据库和dataframe之间的差距是学术界和工业界面临的重要问题。
4.为了解决这个问题,现有的方法可以从两个方面概括:
5.一是服务器端增强,通过元组级协议从数据库系统访问数据是出了名的慢。之前的工作表明现有的有线协议受到冗余信息和昂贵的(反)序列化的影响,因此需要提出了一个新的协议来解决这些问题。更多的方法倾向于使用现有的数据格式(如parquet,orc(两种列式存储格式)等)通过避免元组级的访问来加快这个过程。除此之外,并行性是另一种加速数据传输的有效方法。服务器端增强的问题在于都需要用户修改数据库服务器的源代码或者切换到新服务器的源代码,这在现实场景中是不可行的,因为想要支持这些解决方案,就需要提供额外的管理。
6.二是客户端优化,机器学习和数据分析工具倾向于采用dataframe作为数据操作的抽象,其中许多工具通过各种优化工作提供本机dbms的i/o支持。例如pandas支持分块,通过一次加载一个数据块来减少内存压力。modin,dask,spark通过客户端查询分区利用多个内核等。但是现有的方法仅限于具有特定接口的客户端驱动程序,且大多都只针对特定的一个或几个dataframe,因此具有很大的局限性。
7.此外,opengauss(一种开源关系型数据库)作为一种常用的数据库也面临着这些问题,现有的连接方案psycopg2(python的一个第三方库,可以用来连接数据库)和pygresql(同psycopg2)无论是时间消耗还是内存占用都比较大,无法满足更快的读取速度的需求。
技术实现要素:8.本发明在于提供一种加快数据从opengauss加载到dataframe的方法,其能够缓解上述问题。
9.为了缓解上述的问题,本发明采取的技术方案如下:
10.本发明提供了一种加快数据从opengauss加载到dataframe的方法,通过传入连接字段conn、sql查询语句query,以及匹配opengauss的protocol字段,使本地计算机通过connectorx连接至opengauss数据库管理系统;
11.connectorx的工作流包括以下步骤:
12.s1、根据sql查询语句query从opengauss获取元数据;
13.s2、根据元数据类型进行源分区,并创建若干numpy数组;
14.s3、将sql查询语句query拆分若干个子查询并行执行,得到多个查询结果;
15.s4、将查询结果转换为待写的查询结果数据;
16.s5、将待写的查询结果数据写入numpy数组并生成dataframe。
17.在本发明的一较佳实施方式中,连接字段conn由dbms类型、用户名、密码、主机号、端口号以及数据库名组成。
18.在本发明的一较佳实施方式中,protocol字段为cursor字段。
19.游标(cursor)是系统为用户开设的一个数据缓冲区,存放sql语句的执行结果,每个游标区都有一个名字,用户可以用sql语句逐一从游标中获取记录,交由主语言进一步处理。
20.在本发明的一较佳实施方式中,connectorx包括依次数据连接的源模块、类型映射连接模块和目标模块,所述源模块包括opengauss。
21.源模块的代码定义了cx连接至dbms的方法,这里在源模块中添加新的dbms,即opegauss。现有技术的源模块支持连接mysql,postgresql等数据库,不支持连接opengauss数据库,本发明通过对源模块中代码匹配的部分进行重写,加入了opengauss这个选项,使的connectorx可以支持连接opengauss数据库。
22.数据库中的数据按建表时的规定格式存储,被查询后按该格式输出;传入cx后根据数据库不同选择对应的rust宏定义,再将数据转换成规定格式(由于各数据库格式上并不统一,此步骤能统一待写数据的格式,简化预分配内存的操作);再将统一格式后的数据写入预分配的numpy数组中,最后转换为pandas.dataframe。
23.将opengauss作为源模块,相当于扩展了connectorx可以连接的数据库种类,在代码中,首先新增了opengauss这一个选项,connectorx发现用户请求连接的是opengauss数据库后,会调用专用的opengauss的连接方法,也就是上面叙述的新的连接字段和连接协议,通过这种方法,完成connectorx和opengauss的连接。
24.在本发明的一较佳实施方式中,当connectorx检测到opengauss的输入时,匹配至连接字段conn,并调用匹配opengauss的protocol字段,以实现根据sql查询语句query从opengauss获取元数据。
25.在本发明的一较佳实施方式中,类型映射连接模块用于根据查询结果数据类型及rust宏定义,将查询结果转换为待写的查询结果数据。
26.在本发明的一较佳实施方式中,目标模块用于将待写的查询结果数据写入numpy数组并生成dataframe。
27.与现有技术相比,本发明的有益效果是:
28.与connectorx现有的连接方式相比,使用了新的连接字段(conn)和连接协议
(protocol),将connectorx适配到了opengauss数据库,显著提高了opengauss将数据读取到dataframe的速度;
29.pandas可以将数据直接读取为dataframe,但是在读取大量数据时消耗的时间更长,内存占用更大,而本发明通过connectorx读取数据可以减少四分之三的时间消耗和三分之二的内存消耗;
30.与opengauss现有的使用python第三方库psycopg2相比,读取数据的时间消耗减少了二分之一,内存消耗仅为使用psycopg2的八分之一;
31.pygresql不能将数据直接保存为dataframe格式,也需要一个数据格式转换的过程(从array转换为dataframe),增加了时间消耗和内存消耗,而本发明通过connectorx读取数据可以将使用pygresql的时间消耗和内存消耗都减少到九分之一甚至十分之一。
32.此外,通过使用connectorx来优化读取数据的过程,避免了修改数据库服务器和客户端驱动程序,在不同的情况下,connectorx在速度,内存使用方面都明显优于opengauss现有的方法。
33.为使本发明的上述目的、特征和优点能更明显易懂,下文特举本发明实施例,并配合所附附图,作详细说明如下。
附图说明
34.为了更清楚地说明本发明实施例的技术方案,下面将对实施例中所需要使用的附图作简单地介绍,应当理解,以下附图仅示出了本发明的某些实施例,因此不应被看作是对范围的限定,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他相关的附图。
35.图1是本发明中connectorx工作流的示意图;
36.图2是本发明中connectorx的整体架构示意;
37.图1和图2从不同角度展示cx库的工作原理,突出内容不同,可以简单将图1的connectorx+cx worker视为图2中间部分。
具体实施方式
38.为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本发明一部分实施例,而不是全部的实施例。
39.请参照图1和图2,本发明提供了一种加快数据从opengauss加载到dataframe的方法,通过传入连接字段conn、sql查询语句query,以及匹配opengauss的protocol字段,使本地计算机通过connectorx连接至opengauss数据库管理系统。
40.其中,连接字段conn由dbms类型、用户名、密码、主机号、端口号以及数据库名组成,protocol字段为cursor字段。
41.dbms类型指定与connectorx连接的数据库类型,原本的connectorx支持mysql,postgresql等数据库,但是不支持opengauss,这里使connectorx可以支持openguass。用户名和密码是登录opengauss需要的用户和密码,主机号和端口号是用来连接数据库所需要的参数,数据库名指的是opengauss数据库中存在的数据集合。
42.connectorx主要由三个部分组成:
43.源(source)模块:在connectorx现有的源模块基础上,添加了opengauss作为新的源模块,当connectorx检测到opengauss的输入时,会匹配到我们新定义的连接字段并调用符合opengauss的代码段,客户端将重写后的查询语句查询传入数据库,dbms执行该查询并将查询结果传入类型映射模块,生成待转换的数据。
44.类型映射(type mapper)连接模块:类型映射模块接收来自源模块传入的待转换数据,根据传入的数据类型及rust宏定义,将带转换数据转换为规定的数据类型,生成待写入的数据。
45.根据读取的不同的数据类型,需转换生成的对应的格式,规定在类型映射连接模块中自行定义(如int(i32)拓展至int(i64),varchar(string)转换成str(string))。
46.目标模块:将类型转换模块生成的待写入数据写入内存,直至达到规定数量后再填入提前构造并分配好的numpy数组中。
47.在现有技术中,opengauss当前的连接和加载数据的方法为使用python第三方库psycopg2,pygresql或是选择应用广泛的的pandas,无论是数据加载速度还是内存占用都处于比较高的状态。在本发明中,connectorx的使用可以很好的解决这些问题。
48.现有技术的connectorx支持了包括mysql,postgres等数据库,但是并不能直接用于opengauss,因此,本发明通过对connectorx连接方式进行改进,即使用新的连接字段conn和适用于opengauss的协议,将connectorx引入了opengauss并可以正常使用,使从opengauss读取数据的时间消耗和内存占用大幅减少。
49.此外,当opengauss使用python第三方库psycopg2或pygresql时,需要手动安装libpq、ssl、crypto等动态库或者配置postgresql(一种对象-关系数据库服务器)环境,对用户的使用造成了一定的困难,本发明使用connectorx,可以在opengauss中直接引入而免去了复杂的环境配置过程。
50.在数据读取过程中,opengauss当前使用的方法获得的为单一的数组类型,想要获得dataframe需要调用pandas再次进行转换,这一步骤增加了整个过程的资源占用。本发明改用connectorx后,可以指定获取的数据的格式,免去了复杂的格式转换的过程,减少了不必要的时间消耗和内存占用。
51.本发明所述connectorx的整体工作流程采用流式工作方式,主要分为准备阶段和执行阶段,如图1所示。
52.准备阶段包括:
53.1)根据sql查询语句query从opengauss获取元数据。
54.2)根据元数据类型进行源分区,并创建若干numpy数组。
55.3)为了充分利用客户端的多个内核,将sql查询语句query拆分若干个子查询并行执行,得到多个查询结果。这里得到的查询结果即待转换数据,在被转换前为数据在数据库中的规定格式。query拆分的子查询的数量可以由用户自己定义,通过对数据量的分析可以选择合适的分区数量,也就是子查询的数量。
56.4)将查询结果转换为待写的查询结果数据。
57.即如图1所示,将查询结果传入cx后再根据rust宏定义转换为对应的规定格式。操作时,每次从dbms获取一小部分查询结果,再通过cx转换为对应的规定格式。
58.5)将待写的查询结果数据写入numpy数组并生成dataframe。
59.在本发明中,在获取元数据的过程中,需要使用我们新添加的opengauss源模块,当connectorx通过匹配检测到opengauss输入时,匹配至连接字段conn,并调用匹配opengauss的protocol字段,以实现根据sql查询语句query从opengauss获取元数据。然后相应地分配numpy数组来构造最终的pandas.dataframe。
60.在本发明中,执行阶段以流方式迭代进行。connectorx将每个分区查询分配给一个专用的工作线程,该线程将部分查询结果从dbms独立并行地流式传输到dataframe中,在每次迭代中,从dbms中获取一小批查询结果,将每个单元格转换成正确的数据格式,将值直接写入数据帧,重复此过程直到完成所有的查询。
61.其中,正确的数据格式为用户要求的返回类型(return_type),这里默认pandas.dataframe,而numpy数组是用于保存查询结果的中间数据,通过numpy数组来生成pandas.dataframe。
62.以上所述仅为本发明的优选实施例而已,并不用于限制本发明,对于本领域的技术人员来说,本发明可以有各种更改和变化。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。