• 【脱敏迁移】两种脱敏迁移模式的再思考


    在近期从事的数据库表迁移脱敏工作中,我逐渐归纳出两种迁移方式:

    一.BlockMigrater:这种模式是一行行读取ResultSet的内容,凑足一万行后向目标库提交,提交完毕后再继续读取,再提交,直到处理完所有数据;

    二.UnblockMigrater:这种模式读取时还是一行行读取ResultSet的内容,凑足一万行后使用线程/线程池向目标端异步提交,主线程不阻塞,马上就再读取提交....;

    按普遍的认知来说,第二种方式会更快,因为读取源端和写入目标端是异步进行的,互不阻滞。

    但这是理想中情况,前提是分支的写线程比读线程快很多。如果不满足这个条件,UnblockMigrater就容易出乱子。

    笔者的环境中有两种DB,Oracle和greenplum,简称o和pg,源端和目标端DB是二者之一。

    从读写速度方面来说,使用jdbc的ExecuteBatch方式写一万行数据进oracleDB比读取一万行快很多,因此UnblockMigrater在两端都是Oracle数据库时能充分展现优势;

    而pg数据库的读取速度要高于Oracle约五成,而写速度慢得让人发指,是同等条件下oracle库的十分之一到百分之一。

    当pg作为源端,oracle作为目标端,数据量超过四五百万行记录时,如果使用UnblockMigrater进行迁移,会出现堆内存耗尽异常,我猜是读取速度较快,大批写线程携带万行数据在线程池外或是目标端外等待,不断堆积导致的堆内存耗尽;

    当pg或oracle作为源端,pg作为目标端,这时pg写入慢的弊端就彻底显现了,堆内存耗尽很快会发生,原因和上面一样,都是大批等待的写线程携带的数据把内存耗尽了。

    到这里,可以发现,多线程程序并非就比单线程好,不考察读写速度的差异,多线程也会带来麻烦。

    在找到更好的办法前,我换用了BlockMigrater来应对上面两种情况,程序如期在平稳中完成了任务。

    这并不出人意料,因为写数据时就万行,写完就置空让gc回收了,用完一万就释放,没有多个线程把着不放的事发生,这就不会导致堆内存耗尽异常。

    虽然BlockMigrater模式写数据时读取在等待,但整体速度也可以,一千三百万行数据,70字段的表从pg迁移到o端,虚拟机上只用20分钟,这用户也能接受。

    但用户接受不了出错,锁死和OOM,因此我在源端或目标端存在PG时就使用BlockMigrater类,在两端都是Oracle时采用UnblockMigrater类。

    事后看来,BlockMigrater类是最先采用的,也是最经得起考验的方式,无论数据量大小,无论DB类型是什么,它都能稳定地完成任务,速度也能让人接受,故我将其改名为StableMigrater;

    UnblockMigrater是后采用的,虽然在两端都是Oracle即写入远快于读取时能达到高速,但应用面窄,以其速度命名为FastMigrater。

    二者可能要并存下去,也存在前者独霸天下的可能,实际运行效果就是砝码。

    END

  • 相关阅读:
    常用的正则表达式
    Nginx反向代理
    docker-day1-安装和基本使用
    Nginx + Keepalived
    Nginx源码安装
    apache-实战(二)
    apache-实战(一)
    apache--配置文件属性介绍
    软件目录结构规范
    python常用模块(二)
  • 原文地址:https://www.cnblogs.com/heyang78/p/16467836.html
Copyright © 2020-2023  润新知