Spark ビッグ データ処理講義ノート 4.8 Spark SQL の典型的なケース

 

目次

0. この講義の学習目標

1. Spark SQL を使用して単語頻度統計を実現する

(1) タスクの提案

(2) 課題の達成

1. データファイルを準備する

2.Maven プロジェクトを作成する

3. ソースプログラムのディレクトリを変更する

4. 依存関係を追加し、ソース プログラム ディレクトリを設定します。

5. ログプロパティファイルの作成

6. HDFS構成ファイルの作成

7. 単語頻度統計シングルトン オブジェクトを作成する

8. プログラムを開始して結果を表示します。

9. 単語頻度統計データ変換フローチャート

2. Spark SQL を使用して合計スコアと平均スコアを計算します

(1) タスクの提案

(2) タスクを完了する

1. データファイルを準備する

2. 新しい Maven プロジェクトを作成する

3. ソースプログラムのディレクトリを変更する

4. 関連する依存関係を追加し、ソース プログラム ディレクトリを設定します。

5. ログプロパティファイルの作成

6. HDFS構成ファイルの作成

7. 合計スコアと平均スコアを計算するためのシングルトン オブジェクトを作成します。

8. プログラムを実行し、結果を表示します。

3. Spark SQL を使用してグループ リーダーボードを実装する

(1) タスクの提案

(2) 関係する知識のポイント

1. データセットとデータフレーム

2. 窓関数

(3) タスクを完了する

1. データファイルを準備する

2. 新しい Maven プロジェクトを作成する

3. ソースプログラムのディレクトリを変更する

4. 関連する依存関係を追加し、ソース プログラム ディレクトリを設定します。

5. ログプロパティファイルの作成

6. HDFS構成ファイルの作成

7. グループリーダーボードのシングルトンオブジェクトを作成します

8. プログラムを実行し、結果を表示します。

4. SparkSQL を使用して毎日の新規ユーザーをカウントする

(1) タスクの提案

(2) 実現アイデア

(3) タスクを完了する

1. データファイルを準備する

2. 新しい Maven プロジェクトを作成する

4. 関連する依存関係を追加し、ソース プログラム ディレクトリを設定します。

5. ログプロパティファイルの作成

6. HDFS構成ファイルの作成

7. 統計を作成し、ユーザー シングルトン オブジェクトを追加します

8. プログラムを実行し、結果を表示します。

9. Spark Shell でコードを実行する


0. この講義の学習目標

  1. Spark SQL を使用して単語頻度統計を実現する
  2. Spark SQL を使用して合計スコアと平均スコアを計算する
  3. Spark SQL を使用してグループ リーダーボードを実装する
  4. Spark SQL を使用して毎日の新規ユーザーをカウントする

1. Spark  SQL を使用して単語頻度統計を実現する

(1) タスクの提案

  • 単語頻度統計は分散コンピューティングを学ぶための入門プログラムで、MapReduceなど多くの実装方法がありますが、Sparkが提供するRDD演算子を利用するとより簡単に単語頻度統計を実現できます。このタスクでは、SparkSQL を使用して単語頻度統計を取得する必要があります。
  • ワードファイル
hello scala world
hello spark world
scala is very concise
spark is very powerful
let us learn scala and spark
we can learn them well
  • 単語頻度統計
    ここに画像の説明を挿入

(2) 課題の達成

1. データファイルを準備する

  • ディレクトリに/home作成されるwords.txt
    ここに画像の説明を挿入
  • Word ファイルを HDFS の指定されたディレクトリにアップロードします
    ここに画像の説明を挿入

2.Maven プロジェクトを作成する

  • Maven プロジェクトの作成 - SparkSQLWordCount
    ここに画像の説明を挿入
  • [完了]ボタンをクリックします
    ここに画像の説明を挿入

3. ソースプログラムのディレクトリを変更する

  • ディレクトリをディレクトリjava変更しますscala
    ここに画像の説明を挿入

4. 依存関係を追加し、ソース プログラム ディレクトリを設定します。

  • 依存関係を追加し、ファイルpom.xml内にソース プログラム ディレクトリを設定します。
    ここに画像の説明を挿入
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>net.huawei.sql</groupId>
    <artifactId>SparkSQLWordCount</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>2.12.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.12</artifactId>
            <version>3.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_2.12</artifactId>
            <version>3.1.3</version>
        </dependency>
    </dependencies>
    <build>
        <sourceDirectory>src/main/scala</sourceDirectory>
    </build>
</project>

5. ログプロパティファイルの作成

  • ディレクトリにファイルresourcesを作成するlog4j.properties
    ここに画像の説明を挿入
log4j.rootLogger=ERROR, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spark.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

6. HDFS構成ファイルの作成

  • ディレクトリにファイルresourcesを作成するhdfs-site.xml
    ここに画像の説明を挿入
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property>
        <description>only config in clients</description>
        <name>dfs.client.use.datanode.hostname</name>
        <value>true</value>
    </property>
</configuration>

7. 単語頻度統計シングルトン オブジェクトを作成する

  • パッケージを作成し、net.huawei.sqlパッケージ内にWordCountシングルトン オブジェクトを作成します
    ここに画像の説明を挿入
package net.huawei.sql

import org.apache.spark.sql.{Dataset, SparkSession}

/**
 * 功能:利用Spark SQL实现词频统计
 * 作者:华卫
 * 日期:2023年05月25日
 */
object WordCount {
  def main(args: Array[String]): Unit = {
    // 创建或得到SparkSession
    val spark = SparkSession.builder()
      .appName("SparkSQLWordCount")
      .master("local[*]")
      .getOrCreate()
    // 读取HDFS上的单词文件
    val lines: Dataset[String] = spark.read.textFile("hdfs://master:9000/wordcount/input/words.txt")
    // 显示数据集lines内容
    lines.show()
    // 导入Spark会话对象的隐式转换
    import spark.implicits._
    // 将数据集中的数据按空格切分并合并
    val words: Dataset[String] = lines.flatMap(_.split(" "))
    // 显示数据集words内容
    words.show()
    // 将数据集默认列名由value改为word,并转换成数据帧
    val df = words.withColumnRenamed("value", "word").toDF()
    // 显示数据帧内容
    df.show()
    // 基于数据帧创建临时视图
    df.createTempView("v_words")
    // 执行SQL分组查询,实现词频统计
    val wc = spark.sql(
      """
        | select word, count(*) as count
        |    from v_words group by word
        |    order by count desc
        |""".stripMargin)
    // 显示词频统计结果
    wc.show()
    // 关闭会话
    spark.close()
  }
}

8. プログラムを開始して結果を表示します。

  • WordCountシングルトンオブジェクトを実行する
    ここに画像の説明を挿入

9. 単語頻度統計データ変換フローチャート

  • テキスト ファイルはデータセットに変換され、次にデータ フレームに変換され、最後にテーブル クエリに基づいて結果のデータ フレームが取得されます。
    ここに画像の説明を挿入

2. Spark SQL を使用して合計スコアと平均スコアを計算します

(1) タスクの提案

  • python.txt、spark.txt、django.txt などの複数科目のスコアシートは、各学生の 3 つの科目の合計スコアと平均スコアを計算します。

  • Python スコア表 - python.txt

1 张三丰 89
2 李孟达 95
3 唐雨涵 92
4 王晓云 93
5 张晓琳 88
6 佟湘玉 88
7 杨文达 66
8 陈燕文 98
  • スパークスコアテーブル- spark.txt
1 张三丰 67
2 李孟达 78
3 唐雨涵 89
4 王晓云 75
5 张晓琳 93
6 佟湘玉 70
7 杨文达 87
8 陈燕文 90
  • ジャンゴの転写 - django.txt
1 张三丰 88
2 李孟达 93
3 唐雨涵 97
4 王晓云 87
5 张晓琳 79
6 佟湘玉 89
7 杨文达 93
8 陈燕文 95
  • 期待される出力
1 张三丰 244 81.33
2 李孟达 266 88.67
3 唐雨涵 278 92.67
4 王晓云 255 85.00
5 张晓琳 260 86.67
6 佟湘玉 247 82.33
7 杨文达 246 82.00
8 陈燕文 283 94.33

(2) タスクを完了する

1. データファイルを準備する

  • master仮想マシン上に 3 つのグレード ファイルを作成する
    ここに画像の説明を挿入
  • 3 つの成績ファイルの内容を表示する
    ここに画像の説明を挿入
  • 3 つのグレードのファイルをHDFS の/calsumavg/inputディレクトリにアップロードします
    ここに画像の説明を挿入

2. 新しい Maven プロジェクトを作成する

  • プロジェクト情報の設定(プロジェクト名、保存場所、グループ番号、プロジェクト番号)
    ここに画像の説明を挿入

  • [完了]ボタンをクリックします
    ここに画像の説明を挿入

3. ソースプログラムのディレクトリを変更する

  • ディレクトリをディレクトリjava変更しますscala
    ここに画像の説明を挿入

4. 関連する依存関係を追加し、ソース プログラム ディレクトリを設定します。

  • 依存関係を追加し、ファイルpom.xml内にソース プログラム ディレクトリを設定します。
    ここに画像の説明を挿入
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>net.huawei.sql</groupId>
    <artifactId>CalculateSumAvg</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>2.12.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.12</artifactId>
            <version>3.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_2.12</artifactId>
            <version>3.1.3</version>
        </dependency>
    </dependencies>
    <build>
        <sourceDirectory>src/main/scala</sourceDirectory>
    </build>
</project>

5. ログプロパティファイルの作成

  • resourcesログプロパティファイル を作成します -log4j.properties
    ここに画像の説明を挿入
log4j.rootLogger=ERROR, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spark.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

6. HDFS構成ファイルの作成

  • ディレクトリにファイルresourcesを作成するhdfs-site.xml
    ここに画像の説明を挿入
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property>
        <description>only config in clients</description>
        <name>dfs.client.use.datanode.hostname</name>
        <value>true</value>
    </property>
</configuration>

7. 合計スコアと平均スコアを計算するためのシングルトン オブジェクトを作成します。

  • パッケージ内にシングルトン オブジェクトnet.huawei.sqlを作成するCalculateSumAverage
    ここに画像の説明を挿入
package net.huawei.sql

import org.apache.spark.sql.{Dataset, SparkSession}

/**
 * 功能:利用Spark SQL计算总分与平均分
 * 作者:华卫
 * 日期:2023年05月25日
 */
object CalculateSumAverage {
  def main(args: Array[String]): Unit = {
    // 创建或得到Spark会话对象
    val spark = SparkSession.builder()
      .appName("CalculateSumAverage")
      .master("local[*]")
      .getOrCreate()
    // 读取HDFS上的成绩文件
    val lines: Dataset[String] = spark.read.textFile("hdfs://master:9000/calsumavg/input")
    // 导入隐式转换
    import spark.implicits._
    // 创建成绩数据集
    val gradeDS: Dataset[Grade] = lines.map(
      line => {
        val fields = line.split(" ")
        val id = fields(0).toInt
        val name = fields(1)
        val score = fields(2).toInt
        Grade(id, name, score)
      })
    // 将数据集转换成数据帧
    val df = gradeDS.toDF();
    // 基于数据帧创建临时表
    df.createOrReplaceTempView("t_grade")
    // 查询临时表,计算总分与平均分
    val result = spark.sql(
      """
        |select first(id) as id, name, sum(score) as sum,
        |       cast(avg(score) as decimal(5, 2)) as average
        |   from t_grade
        |   group by name
        |   order by id
        |""".stripMargin
    )

    // 按照指定格式输出总分与平均分
    result.collect.foreach(row => println(row(0) + " " + row(1) + " " + row (2) + " " + row(3)))

    // 关闭Spark会话
    spark.close()
  }

  // 定义成绩样例类
  case class Grade(id: Int, name: String, score: Int)
}

8. プログラムを実行し、結果を表示します。

  • CalculateSumAvgシングルトンオブジェクトを実行する
    ここに画像の説明を挿入

3. Spark SQL を使用してグループ リーダーボードを実装する

(1) タスクの提案

  • グループ化による上位 N の検索は、ビッグ データの分野では一般的な要件です。主にデータの特定の列に従ってグループ化され、次に指定された列に従ってグループ化された各データを並べ替えて、最終的にデータの上位 N 行を取得します。各グループ。
  • 生徒の成績データのセットがあります
张三丰 90
李孟达 85
张三丰 87
王晓云 93
李孟达 65
张三丰 76
王晓云 78
李孟达 60
张三丰 94
王晓云 97
李孟达 88
张三丰 80
王晓云 88
李孟达 82
王晓云 98
  • 同じ生徒に複数の成績があるため、各生徒の最高得点を持つ最初の 3 つの成績と、予想される出力結果を計算する必要があります。
张三丰:94
张三丰:90
张三丰:87
李孟达:88
李孟达:85
李孟达:82
王晓云:98
王晓云:97
王晓云:93
  • データシートt_grade
    ここに画像の説明を挿入
  • クエリを実行する
    ここに画像の説明を挿入
SELECT * FROM t_grade tg 
   WHERE (SELECT COUNT(*) FROM t_grade 
	           WHERE tg.name = t_grade.name 
						    AND score >= tg.score						 		
	        ) <= 3 ORDER BY name, score DESC;    

(2) 関係する知識のポイント

1. データセットとデータフレーム

2. 窓関数

(1) ウィンドウ機能の概要

  • Spark 1.5.xこのバージョン以降、ウィンドウ関数はSpark SQLDataFrameに導入されましたrow_number()。その中でより一般的に使用されるウィンドウ関数は、この関数の機能は、テーブル内のフィールドに従ってグループ化し、テーブル内のフィールドに従って並べ替えることです。実際、ソート順に従って、グループにシーケンス番号が の各レコードに追加され、シーケンス番号の各グループが先頭から始まり1、グループ化に使用できますtopN

(2) 窓関数の形式

  • ROW_NUMBER() OVER (PARTITION BY  field1 ORDER BY  field2 DESC) ランク
  • 上位 3 を見つけるためのグループ化の SQL ステートメント
    ここに画像の説明を挿入

(3) タスクを完了する

1. データファイルを準備する

  • ディレクトリ/homeに成績ファイルを作成するgrades.txt
    ここに画像の説明を挿入
  • grades.txtHDFS にアップロードされる/topn/inputディレクトリ
    ここに画像の説明を挿入

2. 新しい Maven プロジェクトを作成する

  • プロジェクト情報の設定(プロジェクト名、保存場所、グループ番号、プロジェクト番号)
    ここに画像の説明を挿入

  • [完了]ボタンをクリックします
    ここに画像の説明を挿入

3. ソースプログラムのディレクトリを変更する

  • ディレクトリをディレクトリjava変更しますscala
    ここに画像の説明を挿入

4. 関連する依存関係を追加し、ソース プログラム ディレクトリを設定します。

  • 依存関係を追加し、ファイルpom.xml内にソース プログラム ディレクトリを設定します。
    ここに画像の説明を挿入
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>net.huawei.sql</groupId>
    <artifactId>SparkSQLGradeTopN</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>2.12.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.12</artifactId>
            <version>3.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_2.12</artifactId>
            <version>3.1.3</version>
        </dependency>
    </dependencies>
    <build>
        <sourceDirectory>src/main/scala</sourceDirectory>
    </build>
</project>

5. ログプロパティファイルの作成

  • ディレクトリにファイルresourcesを作成するlog4j.properties
    ここに画像の説明を挿入
log4j.rootLogger=ERROR, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spark.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

6. HDFS構成ファイルの作成

  • ディレクトリにファイルresourcesを作成するhdfs-site.xml
    ここに画像の説明を挿入
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property>
        <description>only config in clients</description>
        <name>dfs.client.use.datanode.hostname</name>
        <value>true</value>
    </property>
</configuration>

7. グループリーダーボードのシングルトンオブジェクトを作成します

  • パッケージ内にシングルトン オブジェクトnet.huawei.sqlを作成するGradeTopN
    ここに画像の説明を挿入
package net.huawei.sql

import org.apache.spark.sql.{Dataset, SparkSession}

/**
 * 功能:利用Spark SQL实现分组排行榜
 * 作者:华卫
 * 日期:2022年06月15日
 */
object GradeTopNBySQL {
  def main(args: Array[String]): Unit = {
    // 创建或得到Spark会话对象
    val spark = SparkSession.builder()
      .appName("GradeTopNBySQL")
      .master("local[*]")
      .getOrCreate()
    // 读取HDFS上的成绩文件
    val lines: Dataset[String] = spark.read.textFile("hdfs://master:9000/input/grades.txt")
    // 导入隐式转换
    import spark.implicits._
    // 创建成绩数据集
    val gradeDS: Dataset[Grade] = lines.map(
      line => { val fields = line.split(" ")
        val name = fields(0)
        val score = fields(1).toInt
        Grade(name, score)
      })
    // 将数据集转换成数据帧
    val df = gradeDS.toDF()
    // 基于数据帧创建临时表
    df.createOrReplaceTempView("t_grade")
    // 查询临时表,实现分组排行榜
    val top3 = spark.sql(
      """
        |SELECT name, score FROM
        |    (SELECT name, score, row_number() OVER (PARTITION BY name ORDER BY score DESC) rank from t_grade) t
        |    WHERE t.rank <= 3
        |""".stripMargin
    )   

    // 按指定格式输出分组排行榜
    top3.foreach(row => println(row(0) + ": " + row(1)))

    // 关闭Spark会话
    spark.close()
  }

  // 定义成绩样例类
  case class Grade(name: String, score: Int)
}

8. プログラムを実行し、結果を表示します。

  • GradeTopNシングルトンオブジェクトを実行する
    ここに画像の説明を挿入

4. SparkSQL を使用して毎日の新規ユーザーをカウントする

(1) タスクの提案

  • ユーザーのアクセス履歴データとして、1列目はWebサイトにアクセスした日付、2列目はユーザー名であることがわかっています。
2023-05-01,mike
2023-05-01,alice
2023-05-01,brown
2023-05-02,mike
2023-05-02,alice
2023-05-02,green
2023-05-03,alice
2023-05-03,smith
2023-05-03,brian
2023-05-01 マイク アリス 茶色
2023-05-02 マイク アリス
2023-05-03 アリス スミス ブライアン
  • 次に、上記のデータに基づいて毎日追加される新規ユーザーの数をカウントし、統計結果を期待する必要があります。
2023-05-01新增用户数:3
2023-05-02新增用户数:1
2023-05-03新增用户数:2
  • 1
  • 2
  • 3
  • つまり、2023 年 5 月 1 日に 3 人の新しいユーザー (それぞれマイク、アリス、ブラウン)、2023 年 5 月 2 日に 1 人の新しいユーザー (緑)、2023 年 5 月に 2 人の新しいユーザーが追加されました。 03 (それぞれスミスとブライアン)。

(2) 実現アイデア

  • 転置索引方式、ユーザー名をキーワード、アクセス日を文書IDとすると、ユーザー名とアクセス日のマッピング関係は下図のようになります。
2023-05-01 2023-05-02 2023-05-3
マイク
アリス
茶色
スミス
ブライアン
  • 同一のユーザーが複数の訪問日に該当する場合、最も小さい日付がユーザーの登録日、つまり新規の日付となり、それ以外の日付は繰り返しの訪問日となりカウントされません。したがって、各ユーザーは、ユーザーが訪問する最小の日付のみを計算する必要があります次の図に示すように、各ユーザーの訪問の最小日付を最初の列に移動します。最初の列は有効なデータです。最初の列の各日付の出現数のみがカウントされ、これが新規ユーザーの数となります。対応する日付。
1列目 2列目 3列目
マイク 2023-05-01 2023-05-02
アリス 2023-05-01 2022-01-02 2022-01-03
茶色 2023-05-01
2023-05-02
スミス 2023-05-03
ブライアン 2023-05-03

(3) タスクを完了する

1. データファイルを準備する

  • ディレクトリにファイル/homeを作成するusers.txt
    ここに画像の説明を挿入
  • /newusers/inputまずディレクトリを作成し、そのディレクトリにユーザー ファイルをアップロードします。
    ここに画像の説明を挿入

2. 新しい Maven プロジェクトを作成する

  • プロジェクト情報の設定(プロジェクト名、保存場所、グループ番号、プロジェクト番号)
    ここに画像の説明を挿入
  • [完了]ボタンをクリックします
    ここに画像の説明を挿入
  • ディレクトリをディレクトリjava変更しますscala
    ここに画像の説明を挿入

4. 関連する依存関係を追加し、ソース プログラム ディレクトリを設定します。

  • 依存関係を追加し、ファイルpom.xml内にソース プログラム ディレクトリを設定します。
    ここに画像の説明を挿入
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>net.huawei.sql</groupId>
    <artifactId>SparkSQLCountNewUsers</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>2.12.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.12</artifactId>
            <version>3.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_2.12</artifactId>
            <version>3.1.3</version>
        </dependency>
    </dependencies>
    <build>
        <sourceDirectory>src/main/scala</sourceDirectory>
    </build>
</project>

5. ログプロパティファイルの作成

  • ディレクトリにファイルresourcesを作成するlog4j.properties
    ここに画像の説明を挿入
log4j.rootLogger=ERROR, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spark.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

6. HDFS構成ファイルの作成

  • ディレクトリにファイルresourcesを作成するhdfs-site.xml
    ここに画像の説明を挿入
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property>
        <description>only config in clients</description>
        <name>dfs.client.use.datanode.hostname</name>
        <value>true</value>
    </property>
</configuration>

7. 統計を作成し、ユーザー シングルトン オブジェクトを追加します

  • パッケージを作成し、net.huawei.sqlパッケージ内にCountNewUsersシングルトン オブジェクトを作成します
    ここに画像の説明を挿入
package net.huawei.sql

import org.apache.spark.sql.{Dataset, SparkSession}

/**
 * 功能:使用SparkSQL统计新增用户
 * 作者:华卫
 * 日期:2023年05月25日
 */
object CountNewUsers {
  def main(args: Array[String]): Unit = {
    def main(args: Array[String]): Unit = {
      // 创建或得到Spark会话对象
      val spark = SparkSession.builder()
        .appName("CountNewUsers")
        .master("local[*]")
        .getOrCreate()
      // 读取HDFS上的用户文件
      val ds: Dataset[String] = spark.read.textFile("hdfs://master:9000/newusers/input/users.txt")
      // 导入隐式转换
      import spark.implicits._
      // 创建用户数据集
      val userDS: Dataset[User] = ds.map(
        line => {
          val fields = line.split(",")
          val date = fields(0)
          val name = fields(1)
          User(date, name)
        }
      )
      //将数据转换成数据帧
      val df = userDS.toDF()
      // 创建临时表
      df.createOrReplaceTempView("t_user")
      // 统计每日新增用户
      val result = spark.sql(
        """
          |select date, count(name) as count from
          |   (select min(date) as date, name from t_user group by name)
          |group by date
          |""".stripMargin
      )
      // 输出统计结果
      result.foreach(row => println(row(0) + "新增用户数:" + row(1)))
      // 关闭Spark会话
      spark.close()
    }
  }

  //编写User样例类
  case class User(date: String, name: String)
}

8. プログラムを実行し、結果を表示します。

  • CountNewUsers シングルトンオブジェクトを実行する
    ここに画像の説明を挿入
  • 統計が表示されないのは奇妙です

9. Spark Shell でコードを実行する

  • 次のコードを実行して結果を表示します
    ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_61324603/article/details/131250927