連載
» 2017年01月16日 05時00分 UPDATE

きょうから試せる Hadoop“スモールスタート”ガイド(1):Hadoopとリレーショナルデータベースは「何」が違うのか (1/4)

実際にHadoopで処理を実装しながら「決して難しい技術ではないこと」を理解し、「誰にだって扱えること」を体感していく連載。初回は「Hadoopとリレーショナルデータベースの違い」「Hadoopのメリット/デメリット」を解説します。

[佐々木達也,著]

連載目次

Hadoopファーストガイド

書籍の中から有用な技術情報をピックアップして紹介する本シリーズ。今回は、秀和システム発行の書籍『Hadoopファーストガイド(2012年9月20日発行)』からの抜粋です。

ご注意:本稿は、著者及び出版社の許可を得て、そのまま転載したものです。このため用字用語の統一ルールなどは@ITのそれとは一致しません。あらかじめご了承ください。


はじめに

 近年、データサイズは増加傾向にあり、Webサイトを運営しているエンジニアやプログラマーにとって大規模データというのは身近なものになりつつあります。あなたの運営しているWebサイトではいかがでしょうか。たとえ今はリレーショナルデータベースで十分だとしても、今後も同じやり方で大丈夫だという保証はどこにもありません。

 データサイズが増えてくると最初に問題となるのはバッチ処理です。データサイズが小さいうちは問題にならなくても、データサイズが増加してくると処理時間が大幅に増加するため「大規模なデータをどうやって現実的な時間で処理するか」という問題に直面するでしょう。そういった場面で力を発揮するのが本書で取り扱うHadoopと呼ばれる分散処理のフレームワークです。複数台のサーバを利用することで処理時間を短縮することが可能です。

 とはいっても、Hadoopを利用するためには普段あまり触れることのない分散処理という考え方が必要となるため、どのように処理が行われるのか具体的なイメージがつかみにくいのかもしれません。実際、「Hadoopは興味があるから使ってみたいけどなかなか機会がない」という声を聞くことが多く、最初の一歩を踏み出すためのハードルが他の技術に比べると高い印象があります。

 Hadoopという名前や存在を知っている人はたくさんいても、実際に自分でHadoopを利用したことのある人はほとんどいないのではないでしょうか。そもそもHadoopは大規模データを処理するためのものなので必要に迫られなければ触るきっかけがないのかもしれませんが、だからといって何もしなければ必要になったときに急に使えるようにはなりません。

 本書では実際にHadoopで処理を実装することで、Hadoopが“普通の”エンジニアにとっても決して難しい技術ではなく、誰にだって扱えるんだということを知ってもらうことを目指して執筆しました。そういった方にとって最初の一歩となれば幸いです。

リレーショナルデータベースとHadoopの違い

 そもそもリレーショナルデータベースとHadoopはどのような違いがあり、どのように使い分けたら良いのでしょうか。本章ではHadoopの特徴についてリレーショナルデータベースと比較しながら見ていきましょう。

 本書ではHadoopについて扱っていますが、決してリレーショナルデータベースなど従来の方法が駄目だと言っているわけではありません。もちろんHadoopにも得意不得意はありますし、Hadoopとリレーショナルデータベースはそれぞれまったく別の処理を得意としています。特性をきちんと理解して、それぞれの技術を適材適所で利用していくことが大切です。どんなに素晴らしい技術であっても、正しく使われなければ宝の持ち腐れとなってしまいます。

 次節以降では、処理の特性を大きく「リアルタイム処理」と「バッチ処理」の2つに分けて、それぞれの処理に対して求められることと、そのためにはどういった技術を使うべきかという話をしたいと思います。

 まず、リアルタイムな応答が求められる処理について考えてみます。ツイッターやフェイスブックのようなWebアプリケーションでのデータの参照や更新などがこれに該当します。ツイッターやフェイスブックをやっていて、データの読み込みに長い時間がかかったり、データを更新したのに正しく更新されていなかったりしたら大問題です。

 こういったリアルタイムな処理では、特定のデータを素早く表示することや、特定のデータを正確に更新することが要求されます。こういった要求を満たすためには、以下のようなことが条件として必要でしょう。

  • 高速に特定のデータを見つける
  • 更新コストが小さい
  • トランザクションのサポート

 それぞれの条件について少し詳しく見ていきます。

高速に特定のデータを見つける

 これはリアルタイムにデータをやりとりするためには非常に重要な条件です。データを参照するにしても更新するにしても、まずその特定のデータを高速に見つける必要があります。そのためには既存のリレーショナルデータベースや、最近だとNoSQLデータベース(NoSQLはNot Only SQLの略)の一部でもありますが、memcachedに代表されるようなKVS(Key Value Store)が良いソリューションとなるでしょう。

 KVSではデータの取り扱いをKeyとValueというシンプルな構造とし、KeyでValueを検索するという形に制限することで、特定のKeyからValueを探し出すことが非常に高速に行えるという技術です。ただし、特定の値を含む、といった曖昧な検索は行えないため使える用途は限られてきます(図2-1)。

図2-1 KVSでは曖昧な検索はできない 図2-1 KVSでは曖昧な検索はできない(※ただし、Tokyo TyrantなどKVSでありながらも曖昧な検索が可能なものもあります)

 リレーショナルデータベースでもインデックスという仕組みを使えばデータを高速に見つけることが可能となりますが、まずはインデックスを使わない場合にどういった問題があるのかを考えてみます。

 例えば、ある本の中から特定のキーワードについて書かれたページを探したいとしましょう。皆さんであればどのようにそのページを探すでしょうか。最初のページから最後のページまで、1ページずつ探していけばどこかのページで目的のキーワードを発見することができるでしょう。ただ、このやり方は非常に効率が悪いのは明らかです。

 しかも、そのキーワードについてどこにも書かれていないという場合には最後のページまで探さないと分かりません。そのキーワードがどこかのページに書かれているにしても、探し出すのにかかる時間はページ数の増加に対して線形に増加していきます。つまり、ページ数が1000ページのときには、ページ数が100ページのときと比べて10倍の時間がかかるというわけです(図2-2)。

図2-2 ページ数が増えると線形に時間がかかる 図2-2 ページ数が増えると線形に時間がかかる

 より効率的に探したければ(というか、当たり前と言えば当たり前の話ですが)本の末尾にある索引を利用するのではないでしょうか。全てのページを1ページずつ確認するよりは確実に短い時間で、探しているキーワードがどのページに書かれているのか、もしくはどこにも書かれていないかが分かります。リレーショナルデータベースのインデックスはまさにそういった役割で、データがどこにあるのかという索引情報を事前に作っておく仕組みです。そうすることでデータの読み出しの際に全データをチェックする必要がなく、探しているデータを高速に見つけることができるというわけです。

 もちろん、リレーショナルデータベースでもデータ量が少ない間は全データがメモリに収まるため、インデックスがなくても高速にデータを読み出すことができます。しかし、データ量が増えてくるとメモリに収まらなくなりスワップが発生するようになり、データの読み出しは圧倒的に遅くなります。そうならないよう、適切なインデックスを作成して常にデータを高速に読み出せるようにしておくことが必要となります(図2-3)。

図2-3 インデックスが張ってあれば高速に読み出せる 図2-3 インデックスが張ってあれば高速に読み出せる

 Hadoopを使うのはどうなのでしょう。Hadoopは大量のデータをまとめて読み出したり、データを一気に更新したりするようなシーケンシャルアクセスに特化しているため、今回のように特定のデータを高速に見つけるようなランダムアクセスな用途には向いていません。

更新コストが小さい

 リアルタイムな処理ではユーザー情報など、特定の情報を更新することも多いかと思います。例えば、Webアプリケーションではユーザー名やパスワード、投稿内容などを変更するような場面があります。そういったときに情報を正確に更新するには更新コストが小さいことも重要です。

 例えば特定の値が複数箇所に保持されていると、その値を正確に更新するための更新コストは大きいと言えます。複数箇所を正しく更新するのももちろん大変ですが、どこにそのデータが記録されているのかきちんと把握したり、いつの間にか別の箇所にもその値が保持されていた場合、それを把握したりなどさまざまなコストが発生します(図2-4)。

図2-4 複数箇所にデータがあると更新コストが高い 図2-4 複数箇所にデータがあると更新コストが高い

 そういった場合、リレーショナルデータベースを利用している場合であれば正規化によって同じデータは基本的に1カ所のみに保持することが可能なため、更新コストが小さく抑えられます。更新時にはその1カ所だけを更新すればよいため、ミスも起こりにくいでしょう。

 逆にHadoopではデータの更新がそもそも行えません。基本的にデータは追記する形になるので、データを更新したいといった用途にはまったく向かないでしょう。

トランザクションのサポート

 トランザクションのサポートが必要となるケースもあると思います。リレーショナルデータベースではトランザクションをサポートしており、関連する複数の処理を1つの固まり(トランザクション)として扱うことができます。トランザクションとして管理された処理は「すべて成功」か「すべて失敗」のいずれかであることが保証されます。つまり、トランザクションの中の一部の処理だけが失敗してそれ以外の処理は成功しているというような状態は起こらないことが保証されるため、クリティカルな処理であっても安全に処理することができるというわけです。よくある例ですが、送金処理でのお金のやりとりを使ってトランザクションの仕組みを説明します。

 まず、トランザクションがない場合です。ユーザーが送金処理を行ったときにユーザーの口座からお金を引き出すのには成功したが、送金自体には失敗したというケースを考えてみましょう。トランザクションがなければ、送金には失敗しているのにユーザーの口座からはお金が引き出されている(残金が減っている)という矛盾した状態となってしまい、データの不整合が発生します(図2-5)。

図2-5 送金処理:トランザクションがない場合 図2-5 送金処理:トランザクションがない場合

 このような場合、トランザクションを使っていれば問題の発生を防げます。トランザクションとして管理された処理は「すべて成功」か「すべて失敗」のいずれかであることが保証されるためです。今回のようにトランザクション中に送金処理が失敗した場合、ユーザの口座からお金を引き出す処理も含めてそのトランザクションのすべての処理がロールバックされるという仕組みです(図2-6)。

図2-6 送金処理:トランザクションがある場合 図2-6 送金処理:トランザクションがある場合

 振り込んだはずなのに振り込まれておらず、しかし自分の口座からはその金額分減っている、そんなことになったら大変です。そういったクリティカルな処理ではトランザクションでデータの整合性を保証する必要があるでしょう。

 KVSやHadoopといった技術では残念ながらトランザクションはサポートされていません。そのため、そういったクリティカルな処理では従来通りリレーショナルデータベースを利用するのが最も安全だと思われます。

 以上のような理由から、リアルタイムな処理に関してはリレーショナルデータベースを使うのが良いのではないでしょうか。もちろん用途によってはKVSの利用なども候補に上がってくると思いますが、基本的にはリレーショナルデータベースが良いと考えられます。

       1|2|3|4 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。