欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Oracle数据迁移至HBase操作记录

程序员文章站 2022-05-03 19:18:02
近期需要把Oracle数据库中的十几张表T级别的数据迁移至hbase中,过程中遇到了许多苦难和疑惑,在此记录一下希望能帮到一些有同样需求的兄弟。 HBase表设计 首先,是根据...

近期需要把Oracle数据库中的十几张表T级别的数据迁移至hbase中,过程中遇到了许多苦难和疑惑,在此记录一下希望能帮到一些有同样需求的兄弟。

HBase表设计

首先,是根据oracle的数据规划HBase的表和表结构。
从业务上看,十几张表大概可以分为两大部分:

  • 交易信息
  • 客户操作

刚开始的计划是将所有表都导入HBase中的一张大表,但是思索讨论之后发现是行不通的:

1、由于各个表之间的业务关系复杂,无法设定一个理想的Rowkey。
2、各个表的数据量也是相差万别的,都放入一张大表中会造成列簇的数据倾斜问题。
3、建立HBase表的目的理论上和建立关系型数据库的目的是一致的,想想为什么Oracle中为什么要分为十几张表而不是一张就明白了,方便业务逻辑。

接下来的思路就是根据业务逻辑划分出来的两大部分,建立两张HBase表。

由于系统业务和建表逻辑是另外一组的人负责的,交给我们的文档就是一堆sql文件,隔壁的大神根据这堆sql文件整理除了表的关联关系,为建HBase表提供了基础依据,功不可没:-)

那么接下来的事情就是为两张表设计Rowkey和列簇了。
关于Rowkey和列簇的设计原则可以参考:
https://blog.csdn.net/qq1010885678/article/details/50504941

根据业务逻辑和表字段信息,发现交易和客户信息都是以手机号码为中心的,Rowkey可以使用手机号码来实现,为了避免数据热点的问题,决定将手机号码反转之后的值作为Rowkey。

关于列簇的敲定,由于HBase列簇最好是控制在1-2个,超过3个可能会有性能问题,所以我们根据业务逻辑,分别对属于交易和客户信息两大类下的各个表再次进行划分。

第一次划分出两大类是为了建HBase表,这次的划分是为了建立表中的列簇。

例如:交易这一大部分的6个表中,有4个是经常一起做连接查询的,而另外2个表则是另一组业务逻辑经常使用的 ,那么就HBase中的交易表就可以分为两个列簇:交易业务,个人操作,分别存储着原本Oracle中4个表和2个表的数据。

客户信息表中列簇的设计同理,根据表之间的关联程度划分出三个列簇,大致可以称为:基本属性,行为属性,签署协议。

敲定了HBase的表结构之后,建表就是分分钟的事情了。

数据迁移部分

现在我们在HBase中有两张表,结构如下。

交易表:

Rowkey 交易业务列簇 个人操作列簇
手机号码反转 4张Oracle表数据 2张Oracle表数据

客户表:

Rowkey 基本属性 行为属性 签署协议
手机号码反转 4张Oracle表数据 2张Oracle表数据 3张Orale表数据

使用Sqoop进行数据迁移工作,详细操作说明见:Sqoop操作实践

但是开始迁移操作的时候发现两个问题:

  • 1、个人操作列簇中有张表的数据量是20亿,而交易业务列簇中最大的数据量才5千万,差了40倍。
  • 2、交易表的交易业务列簇中,4张表在导入HBase的时候时间戳是入库时间,但是在业务上需要使用一个该数据的生产时间。

对于第一个问题,我们采取的解决方案是:直接将20亿的个人操作列簇单独拆分为一张HBase表。
理由:避免HBase表中数据稀疏、倾斜造成性能问题,而个人操作列簇从业务和数据量上看完成可以单独作为一张表使用。

对于第二个问题,采取的方案是:先将这四张表分别导入为四张HBase临时表,之后使用mr程序修改时间戳统一导入最终的交易表。
理由:使用临时表第一是为了避免数据损坏,第二是方便mr程序修改时间戳属性。

而对于客户表,业务逻辑比较简单,可以直接使用Sqoop进行导入。

建立HBase始终是要在业务逻辑之上的,没有分析业务根本没办法知道HBase该分为几个表,每个表有几个列簇,每个列簇分别存储哪些数据,以及Rowkey的定义。

1.13更新

关于交易表的的数据版本问题,因为业务是根据手机号码和某个月份来查询的,平均每个月每个用户会查5次,那么之前的rowkey设计就是不合理的:

之前的rowkey是手机号码反转,其中一列为时间戳字段,那么每次有新的交易数据进来就会发生覆盖,之前我们一直在想设定值的版本为多少个比较好,12*5=60,也就是说每个列的值要设置为60个版本,这是极其不合理的。

现在,解决的思路是,既然是根据时间戳和手机号码来取数据的,因为每次数据入库的时候相同用户的交易数据会被新数据覆盖,那么把时间戳和手机号的组合设置为rowkey就完全可以解决这个问题。

那么这个rowkey的格式就是手机号码反转+时间戳,理由如下:

  • 手机号码提供业务查询
  • 反转避免数据热点
  • 时间戳避免每月数据被覆盖(其实最后还是只用手机号码的话rowkey会重复的问题,也就是确保rowkey的唯一性)

另注:hbase统计数据量大的表可以使用其自带的一个mr程序:$HBASE_HOME/bin/hbase org.apache.Hadoop.hbase.mapreduce.RowCounter tableName

1.21更新

从传统数据库到HBase,表设计的思路与步骤大概如下:

  • 根据业务划分hbase表
  • 根据业务划分各个表的列族
  • 判断各个列族所对应的表是否有关联关系
  • 根据关联关系和查询的业务逻辑来确定rowkey的设计
  • 如果一个列族中的表关键字或者字段有冲突,可以在rowkey后面添加后缀。
  • 如果有关联关系,导入数据时需要注意对应问题

1.25更新

oracle表中如果没有合适的字段来给–split-by参数的话,可以用rownum这个默认的字段。

--split-by rownum
  • 1
    • 1

其余遇到的困惑会再进行后续更新。