zoukankan      html  css  js  c++  java
  • Hbase基础(十八):亿级数据从 MySQL 到 Hbase 的三种同步方案与实践(二)亿级MySQL数据插入

    原文:https://blog.csdn.net/rlnlo2pnefx9c/article/details/108288956

    本节题目为:亿级数据从 MySQL 到 Hbase 的三种同步方案与实践,首先需要了解如何快速插入MySQL。

    那么MySQL数据插入将会从以下几个方法入手:

    • load data infile

    • Python 单条插入

    • Python 多线程插入

    当然也可以使用其他语言进行实现!!!

    下面来逐步谈谈数据插入!

    数据插入之前,需要了解我们的数据,先来看一下数据字段描述:

    数据以ASCII文本表示,以逗号为分隔符,以回车换行符(0x0D 0x0A)结尾。数据项及顺序:车辆标识、触发事件、运营状态、GPS时间、GPS经度、GPS纬度,、GPS速度、GPS方向、GPS状态
    车辆标识:6个字符
    触发事件:0=变空车,1=变载客,2=设防,3=撤防,4=其它
    运营状态:0=空车,1=载客,2=驻车,3=停运,4=其它
    GPS时间:格式yyyymmddhhnnss,北京时间
    GPS经度:格式ddd.ddddddd,以度为单位。
    GPS纬度:格式dd.ddddddd,以度为单位。
    GPS速度:格式ddd,取值000-255内整数,以公里/小时为单位。
    GPS方位:格式ddd,取值000-360内整数,以度为单位。
    GPS状态:0=无效,1=有效
    结束串:回车符+换行符

    数据举例:

    154747,4,2,20121130001607,116.6999512,39.9006233,0,128,1
    078245,4,0,20121130001610,116.3590469,39.9909782,0,92,1
    194086,4,1,20121130001610,116.5017776,40.0047951,25,220,1

    那么只需要将上述的数据字段与数据对上就行了,一行为一条数据记录。

    首先编写创建数据库与表命令:

    create database loaddb;
    CREATE TABLE loadTable(id int primary key not null auto_increment,
    carflag VARCHAR(6),touchevent CHAR(1),opstatus CHAR(1),gpstime DATETIME,
    gpslongitude DECIMAL(10,7),gpslatitude DECIMAL(9,7),gpsspeed TINYINT,
    gpsorientation SMALLINT,gpsstatus CHAR(1))engine=MyISAM;

    注意:上述选择了MyISAM引擎是因为load命令使用的时候,保证数据插入的效率!

    3.1 load data infile

    load data infile在导入大数据场景下非常的快!具体的说明后面会在比较的时候详细说,这里说一下使用语法,如下:

    load data local infile "/home/light/mysql/gps1.txt" into table loadTable fields terminated by ',' lines terminated by "
    "  (carflag, touchevent, opstatus,gpstime,gpslongitude,gpslatitude,gpsspeed,gpsorientation,gpsstatus);

    在使用这个命令的时候,是在MySQL的clinet端使用,登陆后敲这个命令即可!在数据字段描述中大家会看到几个关键点:以逗号为分隔符,以回车换行符,对应于上述代码是:

    fields terminated by ',' lines terminated by "
    "

    注意:更换自己的数据集路径!

    3.2 Python 批量插入

    Python单条插入使用的是pymysql库。下面是部分代码,完整代码见:

    批量提交源码

    with open('/home/light/mysql/gps1.txt', 'r') as fp:
        for line in fp:
            ...
            ...
            ...
            count += 1
            if count and count%70000==0:
                # 执行多行插入,executemany(sql语句,数据(需一个元组类型))
                self.cur.executemany(sql, data_list)
                # 提交数据,必须提交,不然数据不会保存
                self.conn.commit()
                data_list = []
                print("提交了:" + str(count) + "条数据")
     
    if data_list:
        # 执行多行插入,executemany(sql语句,数据(需一个元组类型))
        self.cur.executemany(sql, data_list)
        # 提交数据,必须提交,不然数据不会保存
        self.conn.commit()
        print("提交了:" + str(count) + "条数据")
    self.cur.close()  # 关闭游标
    self.conn.close()  # 关闭pymysql连接

    上述有个关键点需要说明一下:

    (1)使用executemany而非execute,这个提交速度要快!(2)使用批量插入,而非单条插入提交,这样会提升效率!

    3.3 Python 多线程插入

    原始数据为一个gps1.txt文件,这个数据太大,如果直接使用多线程插入,不太方便,所以先使用文件切分方法,然后进行多线程的插入。

    关于文件切分,可以点击这里:文件切分源码。

    Python中使用多线程源码

    def multicore(self):
        file_list = [1,2324,4648,6972,9298]
        m1 = mp.Process(target=self.run, args=(file_list[0],file_list[1],'m1',))
        m2 = mp.Process(target=self.run, args=(file_list[1]+1,file_list[2],'m2',))
        m3 = mp.Process(target=self.run, args=(file_list[2]+1,file_list[3],'m3',))
        m4 = mp.Process(target=self.run, args=(file_list[3]+1,file_list[4],'m4',))
        m1.start()
        m2.start()
        m3.start()
        m4.start()
        m1.join()
        m2.join()
        m3.join()
        m4.join()

    具体插入思路是使用四个线程分别读取每个区间段的数据,然后再对数据进行批量插入!如果这一块不懂的伙伴,欢迎留言哈~

    3.4 MySQL数据导入方法对比

    load命令与普通的insert区别

    相同点不同点
    两者都是通过读取本地txt文件,按照相同的分隔来读取进行插入。 程序插入法实质为insert语句间接执行。load data设计用于在单个操作中大量加载表格数据。

    效率比较

    两者耗时如下:

    第一种:load data (这里截取的是Innodb引擎表的插入结果,当使用MyISAM时,会比现在还快!)

    enter image description here

    用时1h11分。

    第二种:程序插入法(这里只截取了批量插入的!)

    用时:27322.45/36=7.58h

    上述对比可知,load data效率非常高,原因在于使用的是load data infile方式,而第二种则为传统的insert方式。

    究其根源主要是MySQL内部对于load 和 insert的处理机制不同。

    Load的处理机制是:在执行load之前,会关掉索引,当load全部执行完成后,再重新创建索引.

    Insert的处理机制是:每插入一条则更新一次数据库,更新一次索引.

    另外,load与insert的不同还体现在load省去了sql语句解析,sql引擎处理,而是直接生成文件数据块,所以会比Insert快很多.

    本文来自博客园,作者:秋华,转载请注明原文链接:https://www.cnblogs.com/qiu-hua/p/14128357.html

  • 相关阅读:
    sql: update from
    sql: 查询,select
    english: 遭遇
    sql: sybase与oracle中insert into select和select into的用法
    lcd参数解释及刷新率计算,LCD时序
    Camera Binning Mode
    页框分配器【转】
    (一)洞悉linux下的Netfilter&iptables:什么是Netfilter?
    网络中的NAT模式
    组播、单播、多播
  • 原文地址:https://www.cnblogs.com/qiu-hua/p/14128357.html
Copyright © 2011-2022 走看看