Gem Ruby ETL 工具漫谈

hooopo for Shopper+ · 发布于 2016年05月16日 · 最后由 pengedy 回复于 2016年07月11日 · 5286 次阅读
8
本帖已被设为精华帖!

activewarehouse-etl

ActiveWarehouse ETL 应该是最早的Ruby ETL工具,并且十分强大,支持各种应用场景,但缺点是年久失修,没有再维护。ActiveWarehosue ETl目标是解决全部ETL相关的需求,是一个重量型工具,一般新的ETL工具的功能很少是他没有的,但其内部结构十分复杂,并且依赖ActiveRecord。另外一个缺点是,其支持的Source和Destination太过老旧,比如,对Postgresql不友好。

kiba

Kiba 是 ActiveWarehouse ETL 的维护者新开发的一个Gem,与 ActiveWarehouse ETL恰恰相反,Kiba 是一个轻量级的ETL工具。目前非常活跃,文档丰富,并且确实很轻,几百行代码勾勒出ETL的基本结构。但缺点呢,也很明显,它空无一物,什么都没提供,就是说,如果你的项目想用 Kiba 来解决实际ELT问题还差很远,需要自己去实现很多功能,如果不是很熟悉,要踩的坑还很多。另外,Kiba和Sidekiq一样,提供Kiba Pro,收费版,据说功能很多,支持以下特性:

  • multi-threading (and later, multi-machines) - commonly requested
  • built-in sources/transforms/destinations for common tasks lookups
  • upserts / bulk load modules
  • connectors optimized for parallelism (HTTP pagination extraction)
  • connectors for the cloud (RedShift, ...)
  • built-in helpers for common operations (debugging, limiting, caching...)
  • premium support

ETL

ETL 是 Square 公司开源的一个轻量级的 ETL gem,与 ActiveWarehouse ETL 不同的是,Square ETL直接操作SQL,不依赖ActiveRecord。但可能只是解决Square公司的特定问题,目前只支持的是MySQL Source和Destination,并且Source和Destination必须在同一个Server上。另一个致命的缺点是不支持增量更新:

embulk

Embulk 的特点是其丰富的插件和并行处理能力。但其依赖JRuby和Java让Ruby开发者上手很难,并且其体系相当复杂,如果不是数据量巨大就不用考虑了。

kiba-plus

Kiba Plus是一个基于Kiba的增强,包含常用的Source和Destination实现,例如MySQL、Postgresql、CSV等。它具有以下优点:

  • 支持Postgresql:其实支持Postgresql也就意味着很容易支持基于Pg的其他数据库,比如Greenplum、CitusData、Redshift等。题外话,MySQL和Pg在OLTP领域可以说不相上下,但在OLAP领域MySQL已经被Pg甩出一条街了,支持Pg意义重大。
  • Fast Load && Insert:由于不依赖ActiveRecord和Sequel之类ORM工具,直接使用mysql2和pg gem操作SQL,能够利用更多数据库自身特性,比如streaming和mysql load infile or pg copy来更快的读取和插入。
  • Incremental Insert:增量更新是ETL中不可缺少的部分,如果没有增量更新,即使再快的插入速度和再强的并行处理能力,随着数据量增长,也不可能每次把所以数据都重新插入一遍。

一个从MySQL导入到Pg的例子:

require 'kiba/plus'

SOURCE_URL = 'mysql://root@localhost/shopperplus'

DEST_URL   = 'postgresql://hooopo@localhost:5432/crm2_dev'

source Kiba::Plus::Source::Mysql, { :connect_url => SOURCE_URL,
                           :query => %Q{SELECT id, email, 'hooopo' AS first_name, 'Wang' AS last_name FROM customers}
                         }

destination Kiba::Plus::Destination::PgBulk2, { :connect_url => DEST_URL,
                                :table_name => "customers",
                                :truncate => true,
                                :columns => [:id, :email, :first_name, :last_name],
                                :incremental => false
                              }

post_process do
  result = PG.connect(DEST_URL).query("SELECT COUNT(*) AS num FROM customers")
  puts "Insert total: #{result.first['num']}"
end

执行:

bundle exec kiba customer_mysql_to_pg.etl

输出:

# I, [2016-05-16T01:53:36.832565 #87909]  INFO -- : TRUNCATE TABLE customers;
# I, [2016-05-16T01:53:36.841770 #87909]  INFO -- : COPY customers (id, email, first_name, last_name) FROM STDIN WITH DELIMITER ',' NULL '\N' CSV
# Insert total: 428972
共收到 13 条回复
332

我们在用这个 forklift 蛮轻量级的,更新也比较频繁

775

问题来了,为什么用Ruby做ETL?

8

#1楼 @vincent 看了一下源码,感觉forklift的应用场景更适合backup tool,作为datawarehouse 工具太弱了。

比如,只有在source db和destination db是同一个db的时候才是最快的,因为使用了replace into语句。其他都情形会fallback到单条insert...

对于source和destination db不是同一个db的情况,其实是没有bulk load的,pull数据使用的是pagination(limit+offset)方式,似乎不如streaming方式。

8

#2楼 @nouse 有什么更好的推荐吗?因为熟悉Ruby啊,Ruby这种脚本语言做ETL其实还是挺好用的,处理个百万千万级还是很容易的...

775

#4楼 @hooopo 呵呵,问题应该改成为什么要ETL了,PostgreSQL有fdw,完全不需要。http://blog.taadeem.net/english/2015/03/15/70_Shades_of_Postgres

8

#5楼 @nouse 可以理解为FDW其实是ETL的一种途径,如果你的Destination恰好是Pg,并且你需要整合的资源都有对应的FDW Wapper,那么FDW确实是最简单的方式。

但我觉得像上面图中想用FDW替代ETL的想法在目前根本行不通,原因是:

A foreign table can be used in queries just like a normal table, but a foreign table has no storage in the PostgreSQL server.

FDW的数据其实仍然存储在外部服务器,Pg 服务器只存储schema,并且提供查询接口。而ETL是真的把数据搬Pg里面。FDW和ETL在这点上的区别就像View之于Materialized View。而View虽然和普通表有着相同的接口,但由于数据存储的限制,性能是一个致命问题。同样,FDW的最大问题也是性能问题。

Citusdata 做过一个测试:

结论是:

the primary benefit of foreign tables is their flexibility. With them, you can issue complex SQL queries on log files, JSON data, or MySQL. In fact, you can even join data from different sources without having to load any of it.

https://www.citusdata.com/blog/50-postgresql-foreign-file-performance

2245

@hooopo ActiveWarehouse ETL 与activerecord-oracle_enhanced-adapt好像是同一个作者rsim?记错了,是easyBI

2107

good

9楼 已删除
Eda824

为什么不通过R语言解决呢,dateframe支持内存join,merge,sample各个数据源,只要你内存能装下数据就行。

8

#10楼 @ericguo 解决的问题不一样。R是Data Science领域的工具,内建丰富的统计分析挖掘相关的库。ETL是Data Analysts领域的一个步骤,把数据从OLTP库转换到OLAP库,然后进行分析。

9695

正好搜到这个帖子,顺便回复一下。

我在用Pentaho Kettle做ETL,感觉非常好;顺便看到作者写了这么多,也只能对Ruby ETL一笑而过了。

8

#12楼 @pengedy 可以分享一下哪里好么...

9695

#13楼 @hooopo

三大特点:同时支持GUI IDE和后台任务(方便部署),支持数据库/数据仓库类型丰富,带有报表导出工具。

关键是,我几年前开始用,一直到现在,其实根本没想到会遇见上文提到的大多数问题...

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册