Treasure DataにDBT3のデータをロードしてみる

         

最近は噂のビッグデータ的なシステムのインフラ関連にも手を出しつつあるのですが、気になっているのがTreasure Dataなのです。

何と言っても500GBまで、無料でクラウド型のHadoopが使えるというのがお試しには最適。

さらに、fluentd用のインターフェースもありの、Hiveも使えるのですぐ利用できる状態にありの、魅力がたくさん。

まずはサインアップなのですがここいいね!

Let’s get started with Treasure Data! Treasure Data is a Hadoop-based Cloud Data Warehousing service. Forget about the servers, storage, and infrastructure needed to store your billions of records and focus on analyzing your data instead.

簡単に言うと、「インフラ周りのこと気にしないで解析だけに集中してください!」てところでしょうか。
インフラを担当するものとしてはありがたいお言葉(T_T)

クライアント側のセットアップはCentOS使ってますが、配布されているシェルで一発です。
インストール後はtdコマンドでクライアント操作ができるようになります。

早速なのですが、DBT3でも試してみようかと思い、データをロード(import)することにしました。
既にDBT3環境のデータがありましたのでそれを流用します。

テーブル作成はこんな感じで一瞬で。

$ td account -f

$ td db:create dbt3

$ td table:create dbt3 supplier
$ td table:create dbt3 customer
$ td table:create dbt3 orders
$ td table:create dbt3 lineitem
$ td table:create dbt3 part
$ td table:create dbt3 partsupp
td table:create dbt3 nation
td table:create dbt3 region

$ td table:list dbt3
+----------+----------+------+-------+--------+--------+
| Database | Table | Type | Count | Size | Schema |
+----------+----------+------+-------+--------+--------+
| dbt3 | customer | log | 0 | 0.0 GB | |
| dbt3 | lineitem | log | 0 | 0.0 GB | |
| dbt3 | nation | log | 0 | 0.0 GB | |
| dbt3 | orders | log | 0 | 0.0 GB | |
| dbt3 | part | log | 0 | 0.0 GB | |
| dbt3 | partsupp | log | 0 | 0.0 GB | |
| dbt3 | region | log | 0 | 0.0 GB | |
| dbt3 | supplier | log | 0 | 0.0 GB | |
+----------+----------+------+-------+--------+--------+
8 rows in set

簡単すぎる・・・カラム定義をしなくて良いのは当たり前だけど楽。

さて、dbt3のデータロードですが、さくらVPSからロードするので、ローカルには大きなファイルは置きたくない。

ということで、圧縮しておいたtblデータをFIFOで流し込むことに。

その前に・・・CSVはそのままではimportができないことが判明。。。

msgpackかjsonでないとだめとのこと。(そもそもmsgpackてなにかしらない・・??)

特に新たなインストールなどセットアップの必要がない、awkで実行することに。

こんな感じに
awkでcsvをjsonに変換してみる

上の例は、dbt3のlineitemの例ですが、他のテーブルもカラム名と数を変えて流用できます。

以下、FIFOからのimportの手順です。
あらかじめ作って圧縮してあったdbt3用のテーブルデータを、csvからjsonに変換しながらimportしていきます。

#!/bin/sh

for TABLE in customer nation part partsupp region supplier
do

echo "${TABLE} import start `date`"

# fifoの作成
mkfifo ${TABLE}.fifo

# 先にimportコマンドを実行
td table:import dbt3 ${TABLE} --json -t CREATED ${TABLE}.fifo &

# テーブルデータをzcatで展開しながら、各テーブルごとに作成したawkスクリプトをfifoに流し込む
zcat ${TABLE}.tbl.gz | awk -f csvTojson_${TABLE}.awk > ${TABLE}.fifo

# レコード件数を調べて終わり(Hive便利!)
echo "${TABLE} count `date`"
td query -d dbt3 -w "select count(*) from ${TABLE}"

rm -f ${TABLE}.fifo

echo "${TABLE} import done `date`"

done

※lineitemとordersは履歴っぽいので別の絡むを-tで指定しました。

lineitem → L_SHIPDATE
orders →  O_ORDERDATE

ロード後にテーブルデータを確認してみました。

$ td table:list dbt3
+----------+----------+------+-----------+---------+--------+
| Database | Table | Type | Count | Size | Schema |
+----------+----------+------+-----------+---------+--------+
| dbt3 | customer | log | 4500000 | 0.2 GB | |
| dbt3 | lineitem | log | 179998372 | 3.0 GB | |
| dbt3 | nation | log | 25 | 0.0 GB | |
| dbt3 | orders | log | 45000000 | 1.2 GB | |
| dbt3 | part | log | 6000000 | 0.1 GB | |
| dbt3 | partsupp | log | 24000000 | 0.7 GB | |
| dbt3 | region | log | 5 | 0.0 GB | |
| dbt3 | supplier | log | 300000 | 0.01 GB | |
+----------+----------+------+-----------+---------+--------+
8 rows in set

確かにデータ量が増えています。
count(*)しなくても元々記録されてるんですね!知らなかった。。。

以上でとりあえずのimportは完了です。

あとはDBT3のクエリを移植して、実行時間の確認ですね。
Hiveなので、修正しなくてもそれなりに動くとは思います。

こちらのブログを参考にさせていただきました。
ありがとうございました。
Treasure Data でモテモテ
Treasure Data Analytics 第3回 〜ブックレビューデータセットによるデータ解析入門(準備編)〜
→ こちら中の方ですね!?

(追記1)
import時にこんなエラーが出ることが。これは改行のみのレコードで発生している模様。
JSONは少なくとも各レコードが16byte以上必要ということかな?

skipped: A JSON text must at least contain two octets!: "\n"

(追記2)
レコードのimportが以下のエラーで失敗していたので、調べてみたところ、importするレコードのタイムスタンプの項目がUNIXTIMEだったのが駄目だったみたい。awkで「strftime("%Y/%m/%d %H:%M:%S", systime())」の時間データを作成し、そこを指定することで解消しました。

skipped: argument out of range

コメントを残す