皆様こんにちは。
アドテク本部カラムーデータベースゼミチームです。
今回の記事ではゼミチームが行った検証結果について発表させていただきます。
また、この記事につきましては 11/12 に行われた db tech showcase Tokyo 2014 にて発表させて頂きました内容になります。
※追記
Impala / Presto の File Format についてご指摘を頂きましたのでデータロード及びまとめの部分に追記しました。
アドテクスキルアップゼミ
カラムナーデータベース検証まとめ
目的
広告システムでは大量のデータをデータベースに入れて解析を行います。
小規模から中規模なデータはRDBMSで行えますが、数TBを超えると
RDBMS以外の選択肢を探さないといけません。
ビッグデータ用のデータベースは比較資料が少なく、
また、あったとしても検証条件が不明な物や、データ量が少ない物しかないため
今回はビッグデータに対応できるカラムナーデータベースを比較し、
データ量ごとに最適なデータベースを検証することにしました。
アドテクスキルアップゼミとは
本題の前に、ちょっとアドテクスキルアップゼミについて説明させていただきます。
アドテクノロジー領域におけるサイバーエージェントグループ横断組織の
アドテクスタジオではアドテクスキルアップゼミという制度があり、
研究の成果を事業に生かすことを目的とした研究費用サポート制度があります。
ビッグデータの性能検証には大量のデータをインポート・処理しないといけないため
結構な費用がかかるのですが、研究費用から捻出されています。
また、大量のデータをインポートする検証作業にはとても長い時間がかかりますが、
制度では80時間まで通常業務の時間を使っても良いというルールがあり、
今回はその限られた時間の中で行いました。
検証データベース
今回は下記のデータベースを検証することにしました。
- Redshift (AWSで利用できるSaasのDWH用データベース)
- Matrix (Redshiftの元になっているActian社製データベース)
- InfiniDB (InfiniDB社(旧Calpont社)製データベース)
- Impala (Cloudera Hadoop)
- Presto "connect to Hive" (Facebook社製のHadoop上で動く分散SQLエンジン)
- BigQuery (Google Cloud Platformで提供されているSaas)
検証データ
検証データには実際に本番(Redshift)で利用されている実データを利用しました。
データセットは約1.5TB、約10TBの2つのパターンを用意し、それぞれ本番の環境であるRedshift上から取得しています。
1.5TBと10TBは未圧縮状態でのサイズです。
RedshiftからUnloadコマンドでデータをS3へ取得する時間は、10TBで約9時間で、
ベンチマークには実際に使われているQueryを使って検証しました。
検証環境
検証環境はBigQuery以外はAWSで行っています。
Redshiftで使えるインスタンスとまったく同じものを選択することができず、
各ミドルウェアで必要なメモリ量・ディスク量などによって検証する構成を変えています。
ただ、どのデータベースも違う構成だと検証にならないため、選定基準を決めています。
下記に検証データベースごとの検証環境をまとめます。
検証データベース | インスタンスタイプ | インスタンス費用/h | インスタンス選定理由 |
---|---|---|---|
Redshift | dw1.xlarge x 8 | $9.52 | 元データで使われている構成と同一 |
Matrix | hs1.8xlarge x 3 | $13.8 | インストール要件などの関係でこの構成 |
InfiniDB | hs1.8xlarge x 2 | $9.2 | Redshiftと同程度の金額 |
Impala | c3.4xlarge x 9 | $9.19 | Redshiftと同程度の金額 |
Presto | c3.4xlarge x 9 | $9.19 | Redshiftと同程度の金額 |
BigQuery | - | - | 課金体系が違うため記載なし |
Redshift
RedshiftはSaasなのでAWS Management Consoleで
立ち上げるインスタンスと数を入力して作成。
Matrix
インサイトテクノロジー社にサポートして頂き、
EC2上にインストール。
InfiniDB
AWS MarketplaceよりAMIから起動。
Impala
Cloudera Managerを利用してインストール。
Presto
BigQuery
S3にGzip圧縮されているデータをインポートするため
解凍するためにGCEを利用。
データロード編
データインポート時間
検証データベース | 1.5TB | 10TB |
---|---|---|
Redshift | 9時間15分21秒 | 24時間57分47秒 |
Matrix | - | 約50時間 |
InfiniDB | 約8時間 | 約40時間 |
Impala | 数分 | 数分 |
Presto | 数分 | 数分 |
BigQuery | 約1時間40分 | 約12時間 |
※約がついているものについては全て計測していなかったため、
1ファイルをロードした際にかかった秒数で容量を割り、
全体の容量から試算したものです。
Redshift
今回インポートするデータは元々がRedshiftからUnloadしたものなので、
元クラスタのテーブル作成時のクエリーを使用してテーブルを作成しました。
データのロードはcopyコマンドでs3からロードしています。
計測表に記載した時間はこのロード時間を表します。
1.5TBのロード時間が約9時間に対して、約7倍のデータである10TBが(9時間の7倍である)63時間でなく、約25時間であるのはインスタンスの台数やテーブル数の関係しているかと思います。
10TBはインスタンスが1.5TBの2倍あります。これらのことから約25時間であったと考えます。
Matrix
ETLツールであるKNIMEというGUIツールを利用してインポートを行いました。
S3から直接データをロードしようとしましたが、ETLツールにバグがあり、
一度S3からHDFS上にデータを移動させて、HDFSからロードを行っています。
(既にこのバグはActian社で修正済み)
このため実際のインポートよりは遅い可能性があります。
ロード自体はETLツールでGUIから直感的に行えるので一番簡単でした。
計測表に記載した時間はHDFSからMatrixへのロード時間を表します。
InfiniDB
インポートツールのcpimportを利用してインポートを行いました。
S3から直でロードすることができないため、
s3cmdを利用して一旦ローカルへダウンロードしてからインポートしています。
計測表に記載した時間はローカルからcpimportでロードした時間を表します。
Impala
S3からHDFSへのデータダウンロードはhadoopコマンドを利用して実行しました。sudo -u hdfs hadoop fs -cp s3n://[AWS_ACCESS_KEY]:[AWS_SECRET_KEY]@path /user/hdfs/
S3上のデータは圧縮されているため、HDFS上でデータを解凍しました。sudo -u hdfs hadoop fs -cat /user/hdfs/filename.gz | pigz -d | sudo -u hdfs hadoop fs -put - /user/hdfs/filename.txt
Hiveメタストアから同期。HiveへのロードはHueにログインし、Metadataストアから実行しました。
計測表に記載した時間は解凍されたファイルからロードした時間を表します。
追記) File Format の指定をしていなかったので TEXTFILE 形式となります
Presto
HiveメタストアにConnectするため、インポートのフローはImpalaと同じです。
計測表に記載した時間は解凍されたファイルからロードした時間を表します。
追記) File Format の指定をしていなかったので TEXTFILE 形式となります
BigQuery
BigQueryにはGoogle Cloud Storageからロードを行いました。
このためAmazon S3に置いてあるデータをGCEインスタンスで取得し、解凍を行ってからGoogle Cloud Storageに配置しました。
計測表に記載した時間はGoogle Cloud StorageからBigQueryへのロードした時間を表します。
今回は試せませんでしたが、GCS Online Cloud Importを利用すればデータをS3からCloud Storageに直接持ってくることも可能なようです。
https://cloud.google.com/storage/docs/online-cloud-import
計測編
計測クエリーについて
計測クエリーは実際に使われているクエリーなので公開出来ませんが、1.5TBで1種類、10TBで4種類のクエリーを試しています。
下記にクエリーの特徴をまとめます。
1.5TBの1個目はLIKEで前方一致を行うクエリーです。
例: SELECT DISTINCT id FROM table WHERE str LIKE 'string%'10TBの1個目はGROUP BYを行ってcountを行うクエリーです。
例: SELECT id,count(*) FROM table GROUP BY idx10TBの2個目はサブクエリーの結果をさらにGROUP BYするクエリーです。
例: SELECT id,count() FROM (SELECT id, count() as count FROM table GROUP BY id ORDER BY count DESC LIMIT x) as table WHERE column = column GROUP BY id,count10TBの3個目はサブクエリーによるテーブル2つをJOINしてWHEREをかけるクエリーです。
例: SELECT id FROM
(SELECT id,count() as count FROM table GROUP BY count DESC LIMIT x) as table1,
(SELECT id,count() as count FROM table GROUP BY count DESC LIMIT x) as table2
WHERE table1.id = table2.id10TBの4個目はGROUP BYとORDER BYをした上で、min,count関数を使うクエリーです。
例: SELECT min(id),count(*) FROM table WHERE column = 'string' GROUP BY id ORDER BY count DESC
クエリー実行時間
検証データベース | 1.5TB | 10TB:1 | 10TB:2 | 10TB:3 | 10TB:4 |
---|---|---|---|---|---|
Redshift | 639.7s | 60.9s | 73.0s | 72.8s | 176.2s |
Matrix | - | 19.3s | 53.5s | 35.8s | 109.9s |
InfiniDB | 1123.0s | 209.2s | 300.3s | 275.6s | 1778.3s |
Impala | 4725.8s | 6309.9s | 6381.7s | 6364.7s | 6339.5s |
Presto | 5096s | 9295s | Failed | 9502s | 6274s |
BigQuery | 6.5s | 12.0s | 9.1s | 8.6s | 8.4s |
Redshift
元々Redshiftで実行していたクエリーなのでそのまま実行します。
Matrix
こちらもRedshiftと互換があるためそのまま実行します。
InfiniDB
こちらもそのままで実行します。
Impala
こちらもそのままで実行します。
Presto
こちらもそのままで実行します。 10TB:2のクエリーだけエラーが発生し、結果を取得できませんでした。
BigQuery
BigQueryではそのままのSQLでは動かない部分がありましたので、一部クエリーの書き換えが必要でした。
まとめ編
総評
既にRedshiftによる運用をしているということもあり、Redshitを基準としました。かなり主観的な部分がありますが、そこはご容赦ください。
あくまで今回の検証のデータおよび環境ではこのようになったということで、参考にして頂ければと思います。
項目 | Redshift(基準) | Matrix | InfiniDB | Impala | Presto | BigQuery |
---|---|---|---|---|---|---|
環境構築のしやすさ | ○ | △ | ○ | ○ | ○ | ◎ |
データロードのしやすさ | ○ | ◎ | × | ○ | ○ | ○ |
インスタンスタイプ選択肢 | ○ | ◎ | ◎ | ◎ | ◎ | - |
インポート性能 | ○ | ○ | ○ | ◎ | ◎ | ◎ |
クエリ性能 | ○ | ○ | ○ | △ | △ | ◎ |
SQL互換性 | ○ | ○ | ○ | ○ | ○ | △ |
コストパフォーマンス | ○ | ○ | ○ | △ | △ | ◎ |
Redshift
導入のしやすさやパフォーマンスではかなり良い選択肢だと思います。
ただ、データが数TB、数十TBということになってくるとかなりコストが増えていくということには注意する必要があると思います。
Matrix
今回ETLツールのバグによりロードするまでに時間がかかりましたが、
バグの報告から1週間後には修正してくれたようで、
Actian社のサポート力の高さが分かりました。
構成上、3台のインスタンスを使っていますが1台はMasterノードでCompute Nodeが2台です。
Redshiftと比較すると、Redshiftの方が速いクエリーもあればMatrixの方が速いクエリーもありました。
ただ、それほど差は無く全体的にRedshiftと同等のパフォーマンスが出ています。
今回クエリーを実行している際にTOPコマンドでリソースの使用状況を確認しましたが、
Disk IOが殆ど使われていなく、CPUで頭打ちになっていました。
hs1.8xlargeは35ECUしかないインスタンスタイプでE5-2650 1つ分の様です。
オンプレミスでCPUをスケールアップすればRedshiftより性能を出すことが可能であると思われます。
InfiniDB
今回検証してから今回のまとめ記事を書く間に開発元が解散してしまったようです。
AMIから簡単にインスタンスを作成でき、
既存がMySQLにデータが入っているようであれば互換性も高かっただけに残念です。
Impala / Presto
今回の構成ではクエリーがとても遅かったです。
Redshiftと比べるとEC2上でやる場合にはコスト的に不利だと思います。
しかし、オンプレミス環境であれば話も違ってくるかもしれません。
HDFSからのデータロードがとても速く、
既存でHadoopを使っている場合には選択肢としてよさそうです。
Presto はまだ出てきてから間もないということもあり、今後に期待したいと思います。
追記)こちら構築時の設定不備により、File Format が TEXTFILE となっていたようです
結果として今回の検証では比較対象としてふさわしくありませんでした。お詫び申し上げます。
BigQuery
とにかく速かったです。とはいえ JOIN を多用するような複雑なクエリーを回そうとすると処理がタイムアウトになりました。
第一正規形のテーブルを回したり、アプリケーション内でどうにかするのであればビッグデータ最強のデータベースだと思います。
単純にデータベースを他から移行するのは難しく、既存システムの移行は設計段階から見直す必要もありそうです。
回すクエリー次第で値段が高くなることも考えられますが、 データを貯めておく費用がとても安く、リザーブドの仕組みもあります。
データ量が大きくなっても処理時間が変わらないというのは、 データ分析において非常に重要で他の製品にはない強みがあります。
データ量が大きくなることが見込まれる場合は他の製品ではいつか限界がくる為、 データの消し込み等を考慮する必要があります。
BigQueryではそこの運用を考慮しないでいいという点が非常に優位な点だと思います。
その為、データ量が大きくなればなるほどBigQueryはその優位性を発揮することになると思います。
以上、いかがだったでしょうか。
今回のケースでは性能面で BigQuery が圧勝ということになりましたが、データ分析に求められる要件は必ずしも性能ではありません。
運用コストやオペレーションのしやすさ等様々な比較要素があります。
大事なことはデータ分析の要件にあったプロダクトを選択することです。
今回の記事がみなさまのプロダクト選定の助けになれば幸いです。