Bài 0 · Nền tảng

Spark là gì? Engine, Spark SQL & so với pandas

Bài này trả lời thẳng những câu hỏi hay gây bối rối nhất khi mới học: Spark là engine hay là ngôn ngữ, hay là database? Spark SQL nằm ở đâu trong bức tranh và chạy nó ở chỗ nào? Và DataFrame của Spark khác gì DataFrame của pandas mà bạn đã quen? Hiểu xong bài này, 6 bài sau chỉ còn là thực hành.

⚙️
Spark là một "động cơ" xử lý dữ liệu
Không phải ngôn ngữ, không phải database

Câu trả lời ngắn gọn: Spark là một compute engine (động cơ tính toán) phân tán. Hãy nghĩ tới động cơ của một chiếc xe — bản thân nó không phải chiếc xe, không phải xăng, không phải con đường. Nó là bộ phận biến nhiên liệu thành chuyển động. Spark cũng vậy: nó là bộ phận nhận dữ liệu vào, thực hiện phép tính, trả kết quả ra — và làm điều đó bằng cách chia việc cho nhiều máy chạy song song.

Chỗ gây nhầm lẫn là chữ "engine". Nó không có nghĩa Spark là một kỹ sư (engineer) hay một phần mềm bạn "mở lên bấm nút". Trong ngành phần mềm, "engine" chỉ một lõi xử lý mà thứ khác gọi vào — ví dụ "game engine", "search engine", "database engine". Spark là data processing engine: bạn viết code (hoặc SQL), đưa cho Spark, Spark lo phần tính toán nặng.

Để định vị cho rõ, đây là những thứ Spark hay bị nhầm — và Spark thực chất khác chúng ra sao:

Thứ hay bị nhầm với SparkNó là gìSpark khác ở chỗ
pandasThư viện xử lý dữ liệu chạy trên 1 máy, trong 1 tiến trình Python.Spark chia dữ liệu ra nhiều máy, xử lý song song. Xem so sánh chi tiết ở cuối bài.
MySQL / Oracle / PostgreSQLDatabase — vừa lưu trữ dữ liệu lâu dài vừa truy vấn.Spark không lưu trữ gì cả. Nó đọc dữ liệu từ nơi khác (file, S3, Kafka, DB), tính toán trong RAM, rồi ghi ra. Tắt Spark là dữ liệu biến mất.
SQLMột ngôn ngữ để mô tả truy vấn.Spark là engine thực thi SQL đó. SQL là "yêu cầu", Spark là "người làm".
Hadoop / HDFSHDFS là hệ thống lưu file phân tán; MapReduce là engine đời cũ.Spark là engine thay thế MapReduce (nhanh hơn nhờ tính trong RAM), thường đọc dữ liệu từ HDFS/S3 nhưng không cần Hadoop.
AirflowBộ lập lịch — quyết định job nào chạy lúc mấy giờ, theo thứ tự nào.Airflow ra lệnh "chạy job Spark lúc 2h sáng"; Spark là thứ thực sự làm việc tính toán đó.
Một câu để nhớ: Airflow hẹn giờ → Spark tính toán → database/S3 lưu trữ. Ba vai trò khác nhau, hay đứng cạnh nhau trong một hệ thống data, nhưng không thay thế cho nhau.
🧩
Bên trong Spark có những gì
Spark SQL là một "module", không phải sản phẩm riêng

Nhiều người tưởng "Spark" và "Spark SQL" là hai phần mềm khác nhau. Thực ra Spark SQL là một thư viện nằm bên trong Spark. Toàn bộ Spark được xây trên một lõi chung (Spark Core), và các thư viện chuyên biệt cắm lên trên lõi đó:

Apache Spark │ ├─ Spark Core ← lõi: quản lý task, phân tán, bộ nhớ, RDD │ ├─ Spark SQL ← DataFrame + chạy SQL + Catalyst optimizer ★ bạn dùng nhiều nhất │ ├─ Structured Streaming ← xử lý dữ liệu real-time (Bài 5) │ ├─ MLlib ← machine learning phân tán │ └─ GraphX ← tính toán trên đồ thị

Điểm quan trọng: DataFrame và Spark SQL đều thuộc thư viện Spark SQL. Khi bạn viết df.groupBy(...) hay viết một câu SELECT ... GROUP BY ..., cả hai đều đi qua cùng một bộ tối ưu tên là Catalyst và được dịch ra cùng một kế hoạch thực thi. Đó là lý do trong Spark, viết bằng DataFrame API hay bằng SQL cho ra kết quả và tốc độ y hệt nhau — chỉ khác cú pháp.

Vì sao điều này quan trọng với bạn: nếu bạn đã mạnh SQL (Oracle/MySQL), bạn gần như đã biết dùng Spark rồi. Chỉ cần học cách "đưa" dữ liệu cho Spark, phần truy vấn viết SQL như cũ.
🐍
Bạn "điều khiển" Spark bằng ngôn ngữ nào
PySpark, Scala, Java, R... và SQL

Spark viết bằng Scala (chạy trên JVM), nhưng nó cho bạn nhiều "tay lái" để ra lệnh:

Dù dùng ngôn ngữ nào, engine bên dưới vẫn là một. Python chỉ là lớp vỏ ra lệnh; công việc nặng luôn chạy trong JVM của các executor.
▶️
Vậy tôi CHẠY Spark SQL ở đâu?
Câu hỏi lớn nhất — trả lời đủ mọi cách

Đây là chỗ hay bí. Với MySQL bạn có Workbench, với Oracle có SQL Developer — "mở lên là gõ SQL". Spark thì không có một chỗ cố định như vậy, vì Spark là engine — nó chạy ở bất cứ nơi nào bạn khởi động một SparkSession. Dưới đây là các "cửa" phổ biến để gõ Spark SQL, từ dễ tới production:

Chốt lại "chạy ở đâu": Spark SQL không chạy ở "một nơi" — nó chạy trong chính cụm Spark của bạn (driver điều phối, executor tính). Những cái trên chỉ là các cách khác nhau để đưa câu SQL vào engine đó. Trong khóa này: bạn gõ trong JupyterLab bằng spark.sql().
Đừng nhầm: câu SQL của Spark KHÔNG chạy trong MySQL/Oracle của bạn. Nó chạy trên dữ liệu đã được nạp vào Spark (từ file, DB, Kafka...). Spark có thể đọc từ MySQL, nhưng phép tính diễn ra trong Spark, không phải trong MySQL.
⚖️
Spark DataFrame vs pandas DataFrame
Giống tên, khác bản chất

Cả hai đều là "bảng dữ liệu có cột và dòng", cùng gọi là DataFrame — nên rất dễ tưởng chúng như nhau. Nhưng chúng khác nhau ở bản chất vận hành. Đây là bảng so sánh đầy đủ:

Tiêu chípandas DataFrameSpark DataFrame
Chạy ở đâu1 máy, 1 tiến trình PythonNhiều máy (cụm), nhiều executor song song
Giới hạn dữ liệuPhải vừa RAM của 1 máy (vài GB)Terabyte — chia partition, tràn ra đĩa nếu cần
Thực thiEager — chạy ngay từng dòng lệnhLazy — chỉ chạy khi gặp action (show/count/write)
Tối ưu tự độngKhông — chạy đúng thứ tự bạn viếtCó — Catalyst tối ưu toàn chuỗi trước khi chạy
Mutable?Có — sửa tại chỗ (df["x"]=...)Bất biến — mỗi phép tạo DataFrame mới
Chỉ số (index)Có index dòngKhông có index
Thứ tự dòngĐược giữ nguyênKhông đảm bảo (dữ liệu rải nhiều partition)
Tốc độ với data nhỏRất nhanh (không có overhead)Chậm hơn vì chi phí khởi động/điều phối
Tốc độ với data lớnChậm dần rồi hết RAM → crashCo giãn — thêm máy là chạy tiếp
Chạy SQLKhông trực tiếp (cần thư viện ngoài)Có sẵn spark.sql()

Nhìn code cạnh nhau sẽ rõ hơn. Cùng một việc "thêm cột thành tiền rồi lọc" — cú pháp na ná, nhưng cơ chế bên dưới rất khác:

pandas
import pandas as pd

df = pd.read_csv("sales.csv")
df["amount"] = df["qty"] * df["unit_price"]
df = df[df["qty"] > 0]
# chạy NGAY, kết quả có liền trong RAM
print(df.head())
PySpark
from pyspark.sql import functions as F

df = spark.read.csv("sales.csv", header=True)
df = (df
  .withColumn("amount", F.col("qty")*F.col("unit_price"))
  .filter(F.col("qty") > 0))
# CHƯA chạy gì — tới show() mới thực thi
df.show()

Khác biệt cốt lõi nằm ở dòng cuối: pandas đã tính xong ngay khi bạn gán df["amount"]. PySpark thì mọi thứ còn là "kế hoạch" cho tới khi gọi show() — lúc đó Catalyst mới nhìn cả chuỗi, tối ưu, rồi rải task xuống executor.

Cầu nối giữa hai thế giới — toPandas(): khi dữ liệu Spark đã gom nhỏ (ví dụ kết quả tổng hợp còn vài trăm dòng), bạn có thể result.toPandas() để đưa về pandas mà vẽ biểu đồ (matplotlib/seaborn) hay xử lý tiếp bằng thư viện Python quen thuộc.
summary = spark.sql("SELECT category, SUM(amount) rev FROM sales GROUP BY category")
pdf = summary.toPandas()   # giờ là pandas, nhỏ gọn, vẽ chart thoải mái
pdf.plot.bar(x="category", y="rev")
Bẫy chết máy: đừng gọi toPandas() (hay collect()) trên DataFrame lớn hàng triệu/tỉ dòng. Toàn bộ dữ liệu sẽ bị kéo về RAM của một máy driver — đúng cái giới hạn mà Spark sinh ra để tránh. Chỉ toPandas() sau khi đã lọc/tổng hợp cho nhỏ.
🧭
Khi nào dùng pandas, khi nào dùng Spark
Chọn đúng công cụ cho đúng việc
Chọn pandas khi
  • Dữ liệu vừa RAM một máy (đến vài GB).
  • Phân tích nhanh, thử nghiệm, vẽ chart.
  • Cần hệ sinh thái Python: scikit-learn, matplotlib...
  • Không muốn chi phí dựng cụm cho việc nhỏ.
Chọn Spark khi
  • Dữ liệu lớn hơn RAM một máy (chục GB → TB).
  • ETL định kỳ trên khối lượng lớn (production).
  • Đọc/ghi nhiều nguồn phân tán: S3, HDFS, Kafka, Parquet.
  • Cần streaming real-time (Structured Streaming).
Quy tắc ngón tay cái: data còn mở được bằng Excel/vừa 1 máy → pandas. Data khiến 1 máy nghẹt thở, hoặc là pipeline chạy hằng ngày cho cả công ty → Spark. Và bạn hoàn toàn có thể dùng cả hai: Spark làm nặng, toPandas() phần nhỏ để vẽ.
📌
Chốt lại 5 ý
Nhớ 5 câu này là đủ nền để đi tiếp
Sẵn sàng đi tiếp: giờ bạn đã có bản đồ toàn cảnh. Bài 1 sẽ dựng SparkSession, đọc dữ liệu vào DataFrame và làm rõ cơ chế lazy/action mà bạn vừa gặp ở đây.
← Quay lại
Mục lục Spark