CN109213751B - 一种基于Spark平台的Oracle数据库并行迁移方法 - Google Patents
一种基于Spark平台的Oracle数据库并行迁移方法 Download PDFInfo
- Publication number
- CN109213751B CN109213751B CN201810883604.3A CN201810883604A CN109213751B CN 109213751 B CN109213751 B CN 109213751B CN 201810883604 A CN201810883604 A CN 201810883604A CN 109213751 B CN109213751 B CN 109213751B
- Authority
- CN
- China
- Prior art keywords
- oracle
- data table
- block
- spark
- file
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Images
Landscapes
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
本发明公开了一种基于Spark平台的Oracle数据库并行迁移方法,使用Spark来作为数据迁移的工具,并且Oracle也有特定的rowid来作为特定的字段来分割表,然后指定Spark某个excutor读取特定的分区。本发明解决了Spark并行读取Oracle,必须要指定特殊的字段来分割表的问题,提高了Spark并行读取Oracle的通用性,不用考虑数据表的结构和内容。与此同时,可以手动按照需求设定每个分区的数据量,充分利用Oracle数据库机器的性能,避免性能浪费,提高数据迁移效率。
Description
技术领域
本发明涉及数据库迁移技术,具体是一种一种基于Spark平台的Oracle数据库并行迁移方法。
背景技术
由于目前很多公司的业务系统设计时间较早,系统架构和数据存储选择了关系型数据库Oracle只满足于当时的业务需求,随着数据量的增大以及业务需求的越来越复杂,使用Oracle来做较复杂的数据分析效率就比较低,不能满足需求。若想满足这些需求就需要引入大数据系统来进行数据的分析和处理。
引入大数据系统,这就涉及到了两个系统之间的数据交换,也就是数据迁移。在使用目前现有的数据迁移工具Sqoop发现效率很低。Sqoop脚本开始执行时,会将我们定义的脚本按照Sqoop自身的内部逻辑转换成MapReduce任务。MapReduce是Hadoop生态圈的一种编程模型,主要分为两部分map端和reduce端。而Sqoop脚本在转换为MapReduce任务时需要指定-m参数,-m的缺省值为1,如果不指定-m就意味着map端的任务只有一个线程来执行,效率非常非常低。若想指定-m参数就必须要指定-split-by参数,split-by的作用就是切分表,假设有一张表test,Sqoop命令指定参数-split-by‘id’,-m10。首先Sqoop会去查表的元数据,向关系型数据库比如mysql发送一个命令:selectmax(id),min(id)fromtest。然后会把max、min之间的区间平均分为10分,最后10个并行的map去找数据库。然而,并不是所有的表都有适合平均分配数据条数的字段。-split-by对非数字类型的字段支持不好,使用Sqoop导入大批量的表就会有数据倾斜引起的效率问题。但是很多数据表不具备明确的可以用作分割表的字段的条件,所以更改使用Spark来代替Sqoop进行数据迁移。
Spark默认读取Oracle是单线程读取,若想并行读取,需要指定特定的分割列,这样就有一定的局限性,使得很多表不能并行读取或者并行读取出现数据倾斜,最终效率很低。
Spark读取Oracle数据库示例代码:
PropertiesconnectionProperties=newProperties();
connectionProperties.put(″user″,″username″);
connectionProperties.put(″password″,″password″);
Dataset<Row>jdbcDF2=Spark.read()
.jdbc(″jdbc:postgresql:dbserver″,″schema.tablename″,connectionProperties);
这样是单线程读取数据,效率很低,不能发挥Spark分布式计算引擎的优势。若想发挥Spark优势就需要用到官网的并行读取的示例代码:
defjdbc(
url:String,
table:String,
columnName:String,#根据该字段分区,需要为整形,比如id等
lowerBound:Long,#分区的下界
upperBound:Long,#分区的上界
numPartitions:Int,#分区的个数
connectionProperties:Properties):DataFrame
这个方法虽然可以比较高效的读取数据,但是局限性太高,columnName必须要是整形而且需要数据均匀分布在lowerBound和upperBound之间,否则会出现数据倾斜,影响效率。第二种并行读取的方式示例代码:
jdbc(
url:String,
table:String,
predicates:Array[String],
connectionProperties:Properties):DataFrame
其中参数为:
valpredicates=
Array(
″AAAR3sAAEAAAACXAAA″->″AAAR3sAAEAAAACXAAB″,
″AAAR3sAAEAAAACXAAC″->″AAAR3sAAEAAAACXAAD″,
″AAAR3sAAEAAAACXAAE″->″AAAR3sAAEAAAACXAAF″,
″AAAR3sAAEAAAACXAAG″->″AAAR3sAAEAAAACXAAH″,
″AAAR3sAAEAAAACXAAI″->″AAAR3sAAEAAAACXAAJ″
).map{
case(start,end)=>
s″rowid>=date′$start′″+s″AND<=date′$end′″
}
predicates参数是一个字符串数组,Spark内部会根据数组来分割表数据,交给不同的executor来进行读取。这个方法的缺点是必须手动指定分区。且每个分区的数据数量分配要接近,这对大数量的Oracle数据库的自动化迁移是不现实的。由此可以看出,若想并发的读取Oracle数据,只能选择最后一种并行的读取方式,并且程序要具有很高的通用性,就需要找一个所有Oracle数据表都存在的列。也就是Oracle数据库特有的列rowid。
发明内容
本发明的目的是提高Spark读取Oracle数据库的表的效率,且很大程度提高Spark并行读取Oracle的通用性,对Oracle数据表字段类型和表内容没有特殊要求。
为实现上述发明目的,采用的技术方案如下:
一种基于Spark平台的Oracle数据库并行迁移方法,包括如下步骤:
(1)spark平台根据oracle数据表名获取当前MaxRowid、MinRowid和记录总数,并设置spark平台上每个executor处理记录的条数,若数据表的记录总数小于设置的记录条数,不用进行分区,直接进行整张数据表的迁移操作。
(2)若数据表的记录总数大于设置的记录条数,则进行初步分区操作,在该步骤中,判断MaxRowid和MinRowid的FILE_ID是否相同。
(3)如果MaxRowid和MinRowid的FILE_ID相同,则分别截取10-12位的BLOCK_ID,并通过base64解码,获得最大的BLOCK_ID和最小的BLOCK_ID;最大的BLOCK_ID减去最小的BLOCK_ID后加1得到数据表切分的数据块的总块数,最后执行迁移操作。
(3)如果二者FILE_ID不同,则将FILE_ID和BLOCK_ID结合起来用base64解码,然后计算数据表的分区数目,最后完成迁移操作。
本发明的有益效果:
1、解决了Spark并行读取Oracle,必须要指定特殊的字段来分割表的问题,提高了Spark并行读取Oracle的通用性,不用考虑数据表的结构和内容。
2、可以手动按照需求设定每个分区的数据量,充分利用Oracle数据库机器的性能,避免性能浪费,提高数据迁移效率。
附图说明
图1:为本发明rowid组成结构示意图。
图2:为本发明工作流程图。
具体实施方式
下面,结合附图及实施例对本发明进行详细说明。
实施例一:
本发明使用Spark来作为数据迁移的工具,就是利用Spark分布式的优势,并且Oracle也有特定的rowid来让我们使用作为特定的字段来分割表。然后指定Spark某个excutor读取特定的分区。
Oracle数据库的表中的每一行数据都有一个唯一的标识符,或者称为rowid,在Oracle内部通常就是使用它来访问数据的。rowid需要10个字节的存储空间,并用18个字符来显示。该值表明了该行在Oracle数据库中的物理具体位置。可以在一个查询中使用rowid来表明查询结果中包含该值。
如图1所示,Oracle的物理扩展rowid有18位,每位采用64位编码,分别用A~Z、a~z、0~9、+、/共64个字符表示。A表示0,B表示1,……Z表示25,a表示26,……z表示51,O表示52,……,9表示61,+表示62,/表示63。
其中OBJECT_ID为数据库对象编号,FILE_ID为文件编号,BLOCK_ID是块编号,ROW_NUMBER为行号。
一张表的OBJECT_ID一定是相同,不同的只能是rowid的后12位,若这张表的数据较小也可能FILE_ID也相同。所以本发明就利用rowid的这一特性将rowid作为分割表的字段。
本发明具体读取步骤为:
如图2所示,一种基于Spark平台的Oracle数据库并行迁移方法,包括如下步骤:
(1)spark平台根据oracle数据表名获取当前MaxRowid、MinRowid和记录总数count,查询公式为:selectmax(rowid),min(rowid),count(1)fromtableName。
我们这里暂定设置每个excutor处理的数据位100万,若查到的count小于100万,就不会进行分区,直接进行整张表的操作,若count大于100万,则进行初步分区操作。
以下步骤均是基于count数大于100万的操作。
(2)根据rowid的规则可以分为两类来处理:
第一类:MaxRowid和MinRowid的FILE_ID相同;
第二类:MaxRowid和MinRowid的FILE_ID不相同;
当MaxRowid和MinRowid的FILE_ID相同时,则分别截取10-12位的BLOCK_ID,并通过base64解码,获得最大的BLOCK_ID和最小的BLOCK_ID;最大的BLOCK_ID减去最小的BLOCK_ID后加1得到数据表切分的数据块的总块数,最后执行迁移操作。
具体为:
假设上一步骤查到的count=700万,MaxRowid=AAAO0DAAJAAAAMYAAA,MinRowid=AAAO0DAAJZAEAMYAAA,然后截取到前9位rowid,并且截取10-12位的BLOCK_ID,并通过base64解码,得到最大和最小的BLOCK_ID:
lower=JHelper.base64ToLong(minBlockld)
upper=JHelper.base64ToLong(maxBlockld)
由num=upper-lower+1就可以得到。
上一步骤查到的count=700万,设定的每个excutor处理100万,那就相当于要分区7个。但是真实的分区情况取决于num和count/100万的比较,这里会取这两者中的小者minNum。
valrange=((upper-lower+1).doubleValue()/n).ceil.longValue()
range就是每个分区读取几块,这样就得到了初步分区:
(lower,lower+range,lower+range,lower+range*2,……)
在分区最开始的时候可以设置分区的循环次数,如果某个分区的数据量不满足设定情况,就循环执行分区方法,直到所有的分区都符合要求或者达到了预先设定的循环次数,这就会得到初始分区。
当MaxRowid和MinRowid的FILE_ID不同时,则将FILE_ID和BLOCK_ID结合起来用base64解码,然后计算数据表的分区数目。
在得到一组[(lower1,upper1),(lower2,upper2),(lower3,upper3),……]这样的数据之后,就满足了Spark的并行读取Oracle的必要条件。
这样分区之后可能存在的问题是有的分区可能数据量很小,很小的数据量也交给一个excutor来处理,所以在这里我们又采用了动态规划算法合并相邻分区,根据初步分区的每个分区分配的数据量,按照相应的顺序记录相邻的分区的数据量进行合并,并且记录相应的合并位置。然后根据位置,将相应的分区进行合并。使每个分区与期望记录数的差异之和最小化,这样即比较平均地分配了数据的条数,也防止了由于某个分区分到的数据较小而造成的资源浪费。
经过实际的数据迁移测试,效果有明显的提升,测试结果如下表:
最后应说明的是:以上实施例仅用以说明本发明而并非限制本发明所描述的技术方案;因此,尽管本说明书参照上述的各个实施例对本发明已进行了详细的说明,但是,本领域的普通技术人员应当理解,仍然可以对本发明进行修改或等同替换;而一切不脱离本发明的精神和范围的技术方案及其改进,其均应涵盖在本发明的权利要求范围中。
Claims (1)
1.一种基于Spark平台的Oracle数据库并行迁移方法,其特征在于,包括如下步骤:
A)spark平台根据oracle数据表名获取当前MaxRowid、MinRowid和记录总数,并设置spark平台上每个executor处理记录的条数,若oracle数据表的记录总数小于设置的记录条数,不用进行分区,直接进行整张oracle数据表的迁移操作;
B)若oracle数据表的记录总数大于设置的记录条数,则进行初步分区操作,在该步骤中,判断MaxRowid和MinRowid的FILE_ID是否相同;
C)如果MaxRowid和MinRowid的FILE_ID相同,则分别截取10-12位的BLOCK_ID,并通过base64解码,获得最大的BLOCK_ID和最小的BLOCK_ID;最大的BLOCK_ID减去最小的BLOCK_ID后加1得到oracle数据表切分的数据块的总块数,最后执行迁移操作;
D)如果二者FILE_ID不同,则将FILE_ID和BLOCK_ID结合起来用base64解码,然后计算oracle数据表的分区数目,最后完成迁移操作;
所述MaxRowid为oracle数据表的Rowid的最大值;
所述MinRowid为oracle数据表的Rowid的最小值;
所述FILE_ID是所述oracle数据表对应的Rowid中的文件编号;
所述BLOCK_ID是所述oracle数据表对应的Rowid中的块编号。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201810883604.3A CN109213751B (zh) | 2018-08-06 | 2018-08-06 | 一种基于Spark平台的Oracle数据库并行迁移方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201810883604.3A CN109213751B (zh) | 2018-08-06 | 2018-08-06 | 一种基于Spark平台的Oracle数据库并行迁移方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN109213751A CN109213751A (zh) | 2019-01-15 |
CN109213751B true CN109213751B (zh) | 2021-11-23 |
Family
ID=64988041
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201810883604.3A Active CN109213751B (zh) | 2018-08-06 | 2018-08-06 | 一种基于Spark平台的Oracle数据库并行迁移方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN109213751B (zh) |
Families Citing this family (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN110287038A (zh) * | 2019-06-10 | 2019-09-27 | 天翼电子商务有限公司 | 提升Spark Streaming框架的数据处理效率的方法及系统 |
CN111400299A (zh) * | 2020-06-04 | 2020-07-10 | 成都四方伟业软件股份有限公司 | 一种多种数据融合质量检验的方法及系统 |
Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN105279280A (zh) * | 2015-11-16 | 2016-01-27 | 天津南大通用数据技术股份有限公司 | 快速迁移Oracle数据到MPP数据库的方法及工具 |
CN106293938A (zh) * | 2016-08-05 | 2017-01-04 | 飞思达技术(北京)有限公司 | 解决大数据计算过程中数据倾斜的方法 |
CN108052557A (zh) * | 2017-11-30 | 2018-05-18 | 山东鲁能软件技术有限公司 | Gis电网图形数据接入全业务数据中心的方法及系统 |
CN108334532A (zh) * | 2017-09-27 | 2018-07-27 | 华南师范大学 | 一种基于Spark的Eclat并行化方法、系统及装置 |
Family Cites Families (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
TR201809901T4 (tr) * | 2013-05-22 | 2018-07-23 | Striim Inc | Dağınık bir ortamda ardışık düzende olay işlemeye yönelik aparat ve yöntem. |
US10380114B2 (en) * | 2014-09-26 | 2019-08-13 | Oracle International Corporation | System and method for generating rowid range-based splits in a massively parallel or distributed database environment |
CN106709067B (zh) * | 2017-01-19 | 2020-01-17 | 中国测绘科学研究院 | 一种基于Oracle数据库的多源异构空间数据流转方法 |
-
2018
- 2018-08-06 CN CN201810883604.3A patent/CN109213751B/zh active Active
Patent Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN105279280A (zh) * | 2015-11-16 | 2016-01-27 | 天津南大通用数据技术股份有限公司 | 快速迁移Oracle数据到MPP数据库的方法及工具 |
CN106293938A (zh) * | 2016-08-05 | 2017-01-04 | 飞思达技术(北京)有限公司 | 解决大数据计算过程中数据倾斜的方法 |
CN108334532A (zh) * | 2017-09-27 | 2018-07-27 | 华南师范大学 | 一种基于Spark的Eclat并行化方法、系统及装置 |
CN108052557A (zh) * | 2017-11-30 | 2018-05-18 | 山东鲁能软件技术有限公司 | Gis电网图形数据接入全业务数据中心的方法及系统 |
Also Published As
Publication number | Publication date |
---|---|
CN109213751A (zh) | 2019-01-15 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US20170083573A1 (en) | Multi-query optimization | |
CN102129458B (zh) | 关系型数据库的存储方法及装置 | |
US20120303633A1 (en) | Systems and methods for querying column oriented databases | |
CN108563923B (zh) | 一种基因变异数据分布式存储方法及系统 | |
Krueger et al. | Fast updates on read-optimized databases using multi-core CPUs | |
US8099440B2 (en) | Method for laying out fields in a database in a hybrid of row-wise and column-wise ordering | |
WO2015106711A1 (zh) | 一种为半结构化数据构建NoSQL数据库索引的方法及装置 | |
US11048753B2 (en) | Flexible record definitions for semi-structured data in a relational database system | |
CN107145537B (zh) | 一种表格数据导入方法及系统 | |
US8812489B2 (en) | Swapping expected and candidate affinities in a query plan cache | |
CN106471501B (zh) | 数据查询的方法、数据对象的存储方法和数据系统 | |
CN102663116A (zh) | 面向列存储数据仓库的多维olap查询处理方法 | |
US8583655B2 (en) | Using an inverted index to produce an answer to a query | |
US9218394B2 (en) | Reading rows from memory prior to reading rows from secondary storage | |
CN103309958A (zh) | Gpu和cpu混合架构下的olap星型连接查询优化方法 | |
CN105989015B (zh) | 一种数据库扩容方法和装置以及访问数据库的方法和装置 | |
Chattopadhyay et al. | Procella: Unifying serving and analytical data at YouTube | |
CN109213751B (zh) | 一种基于Spark平台的Oracle数据库并行迁移方法 | |
CN106599052A (zh) | 一种基于ApacheKylin的数据查询系统及其方法 | |
Liu et al. | DGFIndex for smart grid: Enhancing hive with a cost-effective multidimensional range index | |
CN106844541B (zh) | 一种联机分析处理方法及装置 | |
CN104408128A (zh) | 一种基于b+树异步更新索引的读优化方法 | |
CN101639851A (zh) | 一种数据存储、查询的方法和装置 | |
CN106909623B (zh) | 一种支持高效海量数据分析和检索的数据装置及数据存储方法 | |
WO2021004266A1 (zh) | 数据插入方法、装置、设备和储存介质 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant | ||
TR01 | Transfer of patent right |
Effective date of registration: 20230927 Address after: Room 711, Building 2, Guigu Building, No. 2000 Xinbei Road, Ningwei Street, Xiaoshan District, Hangzhou City, Zhejiang Province, 311200 Patentee after: Hangzhou Aorong Wenzhou Technology Co.,Ltd. Address before: 100000 rooms 312803 and 312805, unit 1, building 5, yard 1, Futong East Street, Chaoyang District, Beijing Patentee before: BEIJING SUOWEN DATA TECHNOLOGY Co.,Ltd. |
|
TR01 | Transfer of patent right |