๐ป ๋ก์ปฌ ๋งฅ๋ถ์์ Spark ์คํํ๊ธฐ - 1ํธ: Local Mode
Databricks Certification ์ทจ๋์ ๋ชฉํ๋ก Apache Spark๋ฅผ โ์ ๋๋กโ ๊ณต๋ถํด๋ณด๊ณ ์์ต๋๋ค. ํ์ฌ์์ Databricks Unity Catalog๋ฅผ ๋์ ํ๋ ค๊ณ ๋ถํฌํ๊ณ ์๋๋ฐ์. Spark์ ์ข ์นํด์ง ์ ์์๊น์? ๐ ์ ์ฒด ํฌ์คํธ๋ Development - Spark์์ ํ์ธํด์ค ์ ์์ต๋๋ค.
์ ๊ธฐ๋ฅผ ๋ฐฐ์ธ ๋์ ์ฒซ ๊ฑธ์์ ์ ๊ธฐ๋ฅผ ์ฌ๋ ๊ฒ(์.!?), ์๋ก์ด ์ธ์ด๋ฅผ ๋ฐฐ์ธ ๋๋ ์ธ์ด๋ฅผ ์ธํ ํ๋ ๊ฒ๋ถํฐ ํ๋ฏ์ด. Spark๋ ๋ก์ปฌ์ ์ธํ ์ ํด๋ณด๋ฉด์ ๋ฐฐ์ฐ๋๊ฒ ๋ง์ ๊ฑฐ๋ผ๊ณ ์๊ฐํ๋ค. ๋ณธ์ธ์ ํ์ฌ์์ Databricks๋ฅผ ์ฌ์ฉํด์ ๊ทธ๋์ Spark๋ฅผ ํ๋ฒ๋ ์ง์ ์ธํ ํด๋ณธ ์ ์ด ์์๋คโฆ! Databricks๊ฐ ์ฐธ ํธ๋ฆฌํ๊ธด ํ๋ฐ, ๊ทผ๋ณธ ์๋ฆฌ๋ฅผ ๋ชจ๋ฅด๊ณ ์ฐ๋ค๋ณด๋ ๋ชจ๋์ฑ ์์์ ๋ญ๊ฐ๋ฅผ ์์์ฌ๋ฆฌ๋ ๋๋์ ๋จ์น ์ ์์๋ค. ๊ทธ๋์ ์์ํ๊ฒ ๋ Spark ๊ณต๋ถโฆ!
์ง๊ธ๊น์ง ๋ง์ ๊ฒ๋ค์ ์๋ก ์ตํ๊ณ ๋ฐฐ์ ์ง๋งโฆ!? ์๋ก์ด ๊ฑธ ๋ฐฐ์ฐ๋ ๊ฑธ ๋ ํ๋ค๊ณ ๊ดด๋ก์ ๋ค. ์ฒ์์ ์ด๋ ต๊ฒ ์ง๋ง ๊ณง ์ต์ํด์ง๊ฒ ์ง ๋ญ~~ ์ํผ ์ผ๋จ ๋ก์ปฌ์ pyspark
๋ฅผ ์ค์นํด์ Spark๋ฅผ ๋๋ ค๋ณด์!!
Install Spark
Spark๋ฅผ ์ค์นํ๋ ๋ฐฉ๋ฒ์ ์ฌ๋ฌ ๋ฐฉ๋ฒ์ด ์๊ฒ ์ผ๋, ์ฌ๊ธฐ์๋ pip3 install pyspark
๋ฅผ ์ค์นํด ์ฌ์ฉํ๋ค. pyspark
์์ pip package ๋ฟ๋ง ์๋๋ผ ๊ฐ์ข
Spark CLI๋ค์ด ๋ชจ๋ ๋ค์ด์๋ค. ๋ง์ฝ, pyspark
๋ฐฉ์์ ํ๊ณ ์ถ์ง ์๋ค๋ฉด, ์๋์ ๊ฐ์ด Spark CLI๋ง ์ค์นํด์ ์ฌ์ฉํด๋ณผ ์๋ ์๋ค.
$ brew install apache-spark
Just Install PySpark
# venv ์ธํ
$ python3 -m venv venv
$ source venv/bin/activate
# pyspark ์ค์น
$ pip3 install pyspark==3.5.2
pyspark
CLI
$ pyspark
Python 3.12.4 (main, Jun 6 2024, 18:26:44) [Clang 15.0.0 (clang-1500.3.9.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
24/08/18 17:06:43 WARN Utils: Your hostname, Seokyunui-MacBookPro.local resolves to a loopback address: 127.0.0.1; using 192.168.0.21 instead (on interface en0)
24/08/18 17:06:43 WARN Utils: Set SPARK_LOCAL_IP if you need to bind to another address
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
24/08/18 17:06:43 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/__ / .__/\_,_/_/ /_/\_\ version 3.5.2
/_/
Using Python version 3.12.4 (main, Jun 6 2024 18:26:44)
Spark context Web UI available at http://192.168.0.21:4040
Spark context available as 'sc' (master = local[*], app id = local-1723968404162).
SparkSession available as 'spark'.
>>>
์์ ์ถ๋ ฅ์์ ์ฃผ๋ชฉํ ๋ถ๋ถ์ด ์๋๋ฐ,
Spark context Web UI available at
http://192.168.0.21:4040
Spark context available assc
(master = local[*], app id = local-1723968404162).
SparkSession available asspark
.
http://localhoost:4040/jobs/
์ ๋ค์ด๊ฐ๋ณด๋ฉด, ์๋ ๊ฒ Spark UI๊ฐ ๋จ๋ ๊ฑธ ๋ณผ ์ ์๋ค.
ํด๋น ์ฝ์์์ Spark Context์ Spark Session์ ์ ๊ทผํ๋ ค๋ฉด ๊ฐ๊ฐ spark
์ sc
๋ก ์ ๊ทผํ๋ฉด ๋๋ค. (์ฐธ๊ณ ๋ก Databricks๋ ๋ง์ฐฌ๊ฐ์ง๋ก ํด๋ฌ์คํฐ๋ฅผ ๋ถ์ด๋ฉด spark
, sc
๋ณ์๊ฐ ํญ์ ์กด์ฌํ๋ค.)
>>> spark
<pyspark.sql.session.SparkSession object at 0x10cc3b6b0>
>>> sc
<SparkContext master=local[*] appName=PySparkShell>
Spark Context์์ master=local[*]
๋ก ๋์ด ์๋ ๋ถ๋ถ์ 2๊ฐ์ง ์๋ฏธ๋ฅผ ๋ด๊ณ ์๋๋ฐ,
local
: Spark ์ดํ๋ฆฌ์ผ์ด์ ์ด ๋ก์ปฌ ๋ชจ๋์์ ์คํ๋จ. ๋ก์ปฌ ๋ชจ๋์์ ํด๋ฌ์คํฐ๊ฐ ํ์ํ์ง ์์ผ๋ฉฐ, ๋จ์ผ ๋จธ์ ์์ ๋ชจ๋ ์์ ์ด ์ํ๋จ.[*]
: ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ ์ฝ์ด๋ฅผ ์๋ฏธ. ์ปดํจํฐ์ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ ์ฝ์ด๋ฅผ ์ฐ๊ฒ ๋ค๋ ์๋ฏธ์.
๋ง์ฝ ์ฝ์ด ๊ฐฏ์๋ฅผ ์ง์ ํ๊ณ ์ถ๋ค๋ฉด, local[4]
์ ๊ฐ์ด ์ ์ผ๋ฉด ๋๋ค๊ณ ํ๋ค.
import pyspark
import pyspark
ํด์ pyspark ์ฝ๋๋ฅผ ์คํํ๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ค. ์์ฃผ ๊ฐ๋จํ pyspark ์ฝ๋๋ฅผ ์คํํด๋ณด์. SparkSession๊ณผ SparkContext๋ ํน๋ณํ ์ด์ ๊ฐ ์๋ค๋ฉด, ๋ชจ๋ spark
์ sc
๋ก ์ด๋ฆ์ ์ง์ ํ๊ฒ ๋ค.
from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
print(spark)
sc = spark.sparkContext
print(sc)
rdd = sc.parallelize(range(10000))
cnt = rdd.count()
print(cnt)
---
<pyspark.sql.session.SparkSession object at 0x105bbe3c0>
<SparkContext master=local[*] appName=pyspark-shell>
10000
์ด๋, ๋ง์ง๋ง์ time.sleep(60 * 60 * 2)
๋ฅผ ์ถ๊ฐ ํด๋๋ฉด, Spark UI๋ฅผ ํ์ธํ ์ ์๋ค. ์ฃผ์๋ ์ด์ ๊ณผ ๋๊ฐ์ด http://localhoost:4040/jobs/
์ด๋ค.
์คํ ํ๋ ๊ฒ๋ค์ด Spark Jobs๋ค๋ก ๋ง๋ค์ด์ ธ์ ์ ๋์จ๋ค!!
Spark Local Mode๋?
์ง๊ธ๊น์ง ๋ก์ปฌ์์ pyspark
๋ฅผ ์ค์นํด ์คํํ ๋ฐฉ๋ฒ์ Spark๋ฅผ Local Mode๋ก ์ฌ์ฉํ ๊ฒ์ด๋ค. Spark๋ฅผ ์คํํ๋ ๋ฐฉ๋ฒ์ ํฌ๊ฒ โLocal Modeโ์ โCluster Modeโ๋ก ๋๋๋ค. ์ฝ๊ฒ ์๊ฐํ๋ฉด ๋จ์ผ ๋จธ์ ์ด๋ ๋๋ผ์ด๋ฒ-์์ปค๋ก ๊ตฌ์ฑ๋ ํด๋ฌ์คํฐ๋ก ๋๋ฆฌ๋์ ์ฐจ์ด.
- Local Mode (์ง๊ธ๊น์ง ํ ๊ฒ)
- Cluster Mode (์ธ์ ๊ฐ ๋ค๋ฃฐ ์์ )
- Client Deploy Mode
- Cluster Deploy Mode
์ํผ ์ง๊ธ๊น์ง ์ฐ๋ฆฌ๊ฐ ์คํํ ๋ฐฉ์์ Local Mode๋ผ๋ ๊ฒ! ์ด ๋ชจ๋๋ ๋จ์ผ ๋จธ์ ์์ ๋ชจ๋ ๊ฒ์ ์คํํ๋ค. ๊ทธ๋๋ Diver์ Executor๋ ๊ฐ๊ฐ 1๊ฐ์ฉ ๋ฌ๋ค.
spark-submit
spark-submit
์ ํตํด Spark ๋จธ์ ์ python ์ฝ๋๋ฅผ ์คํํ๊ฒ ๋ง๋ค ์ ์๋ค. Local Mode์์ spark-submit
์ ํด๋ณด์.
$ spark-submit \
--master "local[2]" \
./hello-spark.py
---
...
24/08/22 01:15:54 INFO TaskSchedulerImpl: Adding task set 0.0 with 2 tasks resource profile 0
24/08/22 01:15:54 INFO TaskSetManager: Starting task 0.0 in stage 0.0 (TID 0) (172.30.1.16, executor driver, partition 0, PROCESS_LOCAL, 8979 bytes)
24/08/22 01:15:54 INFO TaskSetManager: Starting task 1.0 in stage 0.0 (TID 1) (172.30.1.16, executor driver, partition 1, PROCESS_LOCAL, 8979 bytes)
24/08/22 01:15:54 INFO Executor: Running task 0.0 in stage 0.0 (TID 0)
24/08/22 01:15:54 INFO Executor: Running task 1.0 in stage 0.0 (TID 1)
24/08/22 01:15:55 INFO PythonRunner: Times: total = 329, boot = 285, init = 44, finish = 0
24/08/22 01:15:55 INFO PythonRunner: Times: total = 329, boot = 283, init = 46, finish = 0
24/08/22 01:15:55 INFO Executor: Finished task 1.0 in stage 0.0 (TID 1). 1324 bytes result sent to driver
24/08/22 01:15:55 INFO Executor: Finished task 0.0 in stage 0.0 (TID 0). 1324 bytes result sent to driver
24/08/22 01:15:55 INFO TaskSetManager: Finished task 0.0 in stage 0.0 (TID 0) in 390 ms on 172.30.1.16 (executor driver) (1/2)
24/08/22 01:15:55 INFO TaskSetManager: Finished task 1.0 in stage 0.0 (TID 1) in 389 ms on 172.30.1.16 (executor driver) (2/2)
24/08/22 01:15:55 INFO TaskSchedulerImpl: Removed TaskSet 0.0, whose tasks have all completed, from pool
24/08/22 01:15:55 INFO PythonAccumulatorV2: Connected to AccumulatorServer at host: 127.0.0.1 port: 51645
24/08/22 01:15:55 INFO DAGScheduler: ResultStage 0 (count at /Users/seokyunha/xxxx/hello-spark.py:10) finished in 0.832 s
24/08/22 01:15:55 INFO DAGScheduler: Job 0 is finished. Cancelling potential speculative or zombie tasks for this job
24/08/22 01:15:55 INFO TaskSchedulerImpl: Killing all running tasks in stage 0: Stage finished
24/08/22 01:15:55 INFO DAGScheduler: Job 0 finished: count at /Users/seokyunha/xxxx/hello-spark.py:10, took 0.848853 s
10000
์์ง ๋ก๊ทธ ์ฝ๋ ๋ฒ์ ์ ๋ชจ๋ฅด๊ฒ ๋ค. ๋์ค์ ์ฐพ์๋ณผ ๊ฒ!!
๋ง๋ฌด๋ฆฌ
์ฌ๊ธฐ๊น์ง๊ฐ ๋จ์ผ ๋จธ์ ์์ Spark ์์ ์ ์คํํ๋ Local Mode ์๋ค. ํฌ์คํธ๋ฅผ ๋๋์ด, 2ํธ์์๋ ๋ค์ค ๋จธ์ ๊ตฌ์กฐ์ธ Cluster Mode์์ Spark ์์ ์ ์คํํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด์!!
๐ ๋ก์ปฌ ๋งฅ๋ถ์์ Spark ์คํํ๊ธฐ - 2ํธ: Cluster Mode