Apache Spark のラボ:CSV で DataFrame と Spark SQL を学ぶ

このラボは、各生徒に、24件の注文の CSV ファイルを DataFrame として読み込み済みの、小さな Apache Spark を渡します。Spark は仕事をジョブに分けてデータの表を扱う道具で、生徒は DataFrame のコードと SQL の2通りで問い合わせ、そのあと Spark UI を開いて何が行われたかを見ます。

攻撃のラボではありません。コピーにはインターネットへの経路も、ほかの生徒への経路もないので、何かをダウンロードすることも、ほかの誰かに届くこともありません。

生徒が学ぶこと

DataFrame とは、Spark がファイルから読み込む表であることです。列と、Spark が判断した型を見て、filter で一部の行を残し、groupBy と count で要約し、同じ名前の表に対して同じ種類の問いを SQL でも立てます。どちらの方法でも同じ種類の実行計画ができること、データを読む必要のあるクエリはすべてジョブになり、Spark UI の Jobs タブと SQL / DataFrame タブで見つかることを確かめます。データエンジニアリング、ビッグデータ、データベースの入門に向いています。正確な文言はお使いの認定機関の単元で確認してください。ここでは引用していません。

ブラウザーで動かす

ラボは spark というサービスを1つ起動し、ファイルを読み込み終えるまで待ちます。約6秒かかります。Spark はローカルモードで、ドライバーとワーカースレッドを1つのプロセスが持つので、コピーのメモリに収まります。起動や停止をするマスターとワーカーはありません。ターミナルには Spark がないので、サービスはポート 8000 でも答えます。curl で /sql に SQL のクエリを、または /df に DataFrame の式を1つ送ると、結果が表で返ります。

  1. コンテナーのページを開く. バーの「つくる」を開き、「コンテナーを実行」を選びます。ページは誰でも開けて、Git ラボと SQL ラボはアカウントなしで起動できます。ほかのラボには無料アカウントが必要です。アカウントを作成してサインインし、「起動」を押します。
  2. ラボを探す. 「サンプルラボ」のカードにすべてのサンプルが並んでいます。Apache Spark:DataFrame と SQLを探します。
  3. 「起動」を押す. 「起動」はそのまま1回の操作で実行します。「先にファイルを編集」は compose ファイルを開くので、起動する前に変更できます。
  4. 開く. ラボのページのラボバーに「Spark UI」というリンクがあります。押すと、ブラウザーで Spark UI が開き、Jobs、Stages、SQL / DataFrame のタブが見られます。次に「ターミナルを開く」を押して、curl -s -d 'SELECT * FROM orders LIMIT 5' http://spark:8000/sql と入力すると、最初の5件の注文が見られます。/df に orders.count() を送ると 24 と答えます。

何を提出させるか

生徒が自分で書いた、ファイルに対するクエリの結果を提出させます。たとえば国ごとの売上合計(quantity かける unit_price の大きい順で、日本が 717.5 で先頭になります)、表示された表、そのクエリを Spark UI で表示した画面のスクリーンショットです。そのうえで、Spark が何をしたかを自分の言葉で1、2文書かせます。自動では何も採点されないので、その文章で理解しているかが分かります。さらに進める場合は、同じ答えを DataFrame のコードと SQL の両方で求めさせてください。

このラボの基本レッスン

Spark Basics は、このラボで行う小さなレッスンです。生徒は最初の数行を見て、英国の注文を絞り込み、国ごとに注文を集計して数え、SQL で各国の売上を求め、それらのクエリを Spark UI で見つけます。

無料の個人アカウントでは「ホーム」にある Basics モジュールで使え、各学校はライブラリの Basics フォルダーからコピーでき、新しい学校には Lab Basics (Sample) というモジュールに入っています。あえて小さくしてあり、ラボで行うレッスンがどんなものかを先生に見せるためのもので、残りはラボが担います。変更するには、自分のモジュールにコピーしてください。

GitHub のコード

compose ファイルに Dockerfile はなく、Apache Spark プロジェクト自身の公開イメージを1つ、バージョンを固定し、権限のないユーザーで、512 MB のメモリで動かします。Apache Spark のライセンスは Apache-2.0 で、私たちは配布していません。ファイルは起動時に CSV と小さなクエリサービスも書き出すので、ビルドするものはありません。限界は正直に言うと、Spark は1つでクラスターではなく、データは24行なので所要時間は実際の負荷について何も語らず、コピーのメモリを大きく超えるクエリは失敗し、ラボにはインターネットへの出口がありません。ラボを止めると何も残りません。

課題として出す

課題には、何を提出するかを書いてください。

  1. ラボを作る. モジュールで課題を追加し、「コンテナーラボ」のカードを選んでから「GitHub リポジトリ」を選びます。https://github.com/mitsurutech/lab-spark とブランチ main を指定します。compose ファイルは既定の compose.yaml です。変更したい場合は、たとえば自分の CSV ファイルを使うときは、先にリポジトリをフォークしてください。
  2. 公開して試す. 「公開」すると、確認したコミットに固定されるので、あとでリポジトリを変更しても、すでに出したラボは変わりません。まず自分のコピーを起動してください。
  3. 配布する. ほかの課題と同じように配布します。期限を付けることもでき、課題には何をするか、何を提出するかを書いておきます。
  4. 提出物を採点する. 生徒のコピーを開いて提出された内容を確認し、採点します。足りない場合は理由を書いて差し戻します。

よくある質問

これは Spark クラスターですか?
いいえ。ローカルモードの Spark で、1つのプロセスがマスターとワーカーの仕事をします。コピーのサービスは 512 MB で、ワーカーだけでもそれ以上必要だからです。DataFrame と SQL の側を学ぶもので、複数のマシンに仕事を分ける方法は扱いません。
ターミナルで pyspark や spark-sql ではなく curl を使うのはなぜですか?
ラボのターミナルには curl、psql などのクライアントがあり、Spark も Java もありません。Spark のサービスは HTTP で送られたクエリに答えて結果を表示するので、curl で足ります。ご自分のマシンでは、同じ考え方で pyspark を使えます。
生徒は自分のデータを使えますか?
コピーの中では使えません。コピーにはファイルを入れる口がないからです。リポジトリをフォークし、compose.yaml の CSV に自分の行を入れ、そのフォークをラボとして設定してください。