Courses
Apache Spark là một công cụ phân tích hợp nhất cho kỹ thuật dữ liệu, khoa học dữ liệu và machine learning ở quy mô lớn. Nó có thể được sử dụng với Python, SQL, R, Java hoặc Scala. Spark ban đầu được khởi xướng tại Đại học California, Berkeley vào năm 2009 và sau đó được đóng góp cho Apache Software Foundation vào năm 2013. Hiện nay nó là “công cụ được sử dụng rộng rãi nhất cho điện toán có khả năng mở rộng,” với hàng nghìn tin tuyển dụng yêu cầu công nghệ này. Là một kỹ năng được đánh giá cao trong thế giới kỹ thuật dữ liệu, dưới đây là các câu hỏi phỏng vấn để hỗ trợ quá trình tìm việc của bạn hoặc tìm kiếm nhân tài có kinh nghiệm với Spark. Các câu trả lời mã sẽ được cung cấp bằng Python.
Câu hỏi phỏng vấn Spark cơ bản
Những câu hỏi này bao quát một số khái niệm nền tảng của Spark và phù hợp với những người chỉ có kinh nghiệm cơ bản. Nếu bạn cần ôn lại, khóa học Giới thiệu về Spark SQL trong Python của chúng tôi là nơi lý tưởng để bắt đầu.
1. Apache Spark là gì và vì sao nó được dùng trong xử lý dữ liệu?
Câu hỏi này đánh giá hiểu biết tổng quát của ứng viên về Apache Spark và vai trò của nó trong hệ sinh thái dữ liệu lớn.
Trả lời:
Apache Spark là hệ thống điện toán phân tán mã nguồn mở, cung cấp giao diện để lập trình toàn bộ cụm với khả năng song song dữ liệu ngầm định và chịu lỗi. Nó được dùng cho xử lý dữ liệu quy mô lớn nhờ tốc độ và dễ sử dụng so với MapReduce truyền thống.
Tính năng chính:
- Tính toán trong bộ nhớ: Lưu dữ liệu trong bộ nhớ để xử lý nhanh hơn.
- Khả năng mở rộng: Có thể xử lý dữ liệu ở mức petabyte bằng cụm máy.
- Dễ sử dụng: Cung cấp API trong Java, Scala, Python và R.
- Công cụ phân tích hợp nhất: Hỗ trợ SQL, dữ liệu streaming, machine learning và xử lý đồ thị.
2. Giải thích khái niệm Resilient Distributed Datasets (RDDs)
Câu hỏi này kiểm tra bạn về các khái niệm nền tảng của Apache Spark. Hãy chắc chắn bạn hiểu một trong những thành phần cốt lõi khiến Spark mạnh mẽ.
Resilient Distributed Datasets (RDDs) là khối xây dựng cơ bản của Apache Spark. Chúng đại diện cho một tập hợp đối tượng bất biến, phân tán, có thể được vận hành song song trên toàn cụm. Dưới đây là giải thích về các đặc điểm và khái niệm chính liên quan đến RDD:
- Bất biến: RDD là bất biến, nghĩa là sau khi tạo, nội dung của chúng không thể bị sửa đổi. Bạn chỉ có thể biến đổi RDD bằng cách áp dụng các phép biến đổi để tạo ra RDD mới. Tính bất biến này đơn giản hóa khả năng chịu lỗi và cho phép mô hình đánh giá lười của Spark.
- Phân tán: RDD được phân tán trên nhiều nút trong cụm, cho phép Spark thực hiện các thao tác song song trên chúng. Mỗi RDD được chia thành nhiều phân vùng, và các phân vùng này có thể được xử lý độc lập trên các nút khác nhau.
- Chịu lỗi: “Resilient” trong RDD biểu thị khả năng chịu lỗi. Spark đảm bảo tính bền bỉ bằng cách theo dõi phả hệ (lineage) của mỗi RDD. Nếu một phân vùng của RDD bị mất do lỗi nút, Spark có thể tính toán lại phân vùng đó bằng thông tin phả hệ và các phép biến đổi đã áp dụng lên dữ liệu gốc.
- Tập dữ liệu: RDD là biểu diễn phân tán của dữ liệu, nghĩa là chúng có thể chứa bất kỳ loại dữ liệu nào, bao gồm dữ liệu có cấu trúc hoặc phi cấu trúc. Spark cung cấp API ở nhiều ngôn ngữ (như Scala, Java, Python và R) để làm việc với RDD, giúp linh hoạt cho nhiều trường hợp sử dụng và loại dữ liệu khác nhau.
- Đánh giá lười: RDD hỗ trợ đánh giá lười, nghĩa là các phép biến đổi trên RDD không được thực thi ngay lập tức. Thay vào đó, Spark xây dựng một đồ thị có hướng phi chu kỳ (DAG) của các phép biến đổi để định nghĩa tính toán nhưng trì hoãn thực thi cho đến khi một hành động được kích hoạt. Sự tối ưu này cho phép Spark tối ưu kế hoạch thực thi và cải thiện hiệu năng.
3. YARN là gì?
YARN là trình quản lý container phân tán, quản lý tài nguyên trong Hadoop. Spark có thể sử dụng YARN khi chạy trên các cụm Hadoop để quản lý tài nguyên hiệu quả hơn. Một trong những thành phần quan trọng của YARN là khả năng phân bổ tài nguyên hiệu quả trên toàn cụm, lập lịch công việc hiệu quả và chịu lỗi khi xảy ra sự cố nút. Đây là một trong nhiều thành phần làm cho Spark trở thành công cụ mạnh mẽ.
4. Sự khác nhau giữa các phép biến đổi map và flatMap trong RDD của Spark là gì?
Câu hỏi này giúp xác định liệu bạn hiểu các loại phép biến đổi khác nhau trong RDD (Resilient Distributed Datasets) của Spark hay không.
Trả lời:
.map(): Biến đổi mỗi phần tử của RDD thành đúng một phần tử mới. Kết quả là một RDD có cùng số phần tử như RDD đầu vào..flatMap(): Biến đổi mỗi phần tử của RDD thành không, một hoặc nhiều phần tử mới. Kết quả là một RDD có số phần tử có thể khác với RDD đầu vào.
# Example of map
rdd = spark.sparkContext.parallelize([1, 2, 3])
mapped_rdd = rdd.map(lambda x: x * 2)
print(mapped_rdd.collect()) # Output: [2, 4, 6]
# Example of flatMap
flat_mapped_rdd = rdd.flatMap(lambda x: [x, x * 2])
print(flat_mapped_rdd.collect()) # Output: [1, 2, 2, 4, 3, 6]
Đoạn mã này minh họa sự khác biệt giữa map và flatMap bằng cách biến đổi một RDD số nguyên.
5. Bạn sử dụng Spark SQL để truy vấn dữ liệu từ DataFrame như thế nào?
Câu hỏi này kiểm tra khả năng sử dụng Spark SQL để truy vấn dữ liệu, điều thiết yếu cho các tác vụ phân tích dữ liệu.
Trả lời:
# Register the DataFrame as a SQL temporary view
df.createOrReplaceTempView("table")
# Execute SQL query
result = spark.sql("SELECT column1, SUM(column2) FROM table GROUP BY column1")
# Show the results
result.show()
Đoạn mã này minh họa cách tạo một view tạm từ DataFrame và dùng Spark SQL để thực hiện truy vấn group-by.
Câu hỏi phỏng vấn Spark trung cấp
Dành cho những người đã nắm vững căn bản và áp dụng trong công việc, các câu hỏi này có thể phổ biến hơn:
6. Giải thích khái niệm đánh giá lười (lazy evaluation) trong Spark và vì sao quan trọng
Câu hỏi này đánh giá hiểu biết của ứng viên về một trong các nguyên lý cốt lõi của Spark, rất quan trọng để tối ưu hiệu năng.
Trả lời:
Đánh giá lười nghĩa là Spark không thực thi ngay các phép biến đổi khi được gọi. Thay vào đó, nó xây dựng một kế hoạch thực thi logic. Các phép biến đổi chỉ được thực thi khi một hành động (như collect hoặc count) được gọi, kích hoạt tính toán thực sự.
Đánh giá lười quan trọng vì hai lý do:
- Cho phép Spark tối ưu toàn bộ luồng xử lý dữ liệu trước khi thực thi, kết hợp các thao tác để giảm thiểu việc xáo trộn dữ liệu.
- Giảm số lần quét dữ liệu, cải thiện hiệu năng.
7. Bạn lưu trữ (persist) dữ liệu trong Spark như thế nào và các mức lưu trữ có sẵn là gì?
Câu hỏi này kiểm tra kiến thức về lưu trữ dữ liệu trong Spark, quan trọng cho tối ưu hiệu năng và các thuật toán lặp.
Trả lời:
Dữ liệu có thể được lưu trữ trong Spark bằng phương thức .persist() hoặc .cache(). .cache() là cách viết tắt của .persist() với mức lưu trữ mặc định.
Các mức lưu trữ:
- MEMORY_ONLY: Lưu RDD dưới dạng đối tượng Java đã giải tuần tự trong JVM. Nếu RDD không vừa bộ nhớ, một số phân vùng sẽ không được cache.
- MEMORY_AND_DISK: Lưu RDD dưới dạng đối tượng Java đã giải tuần tự trong bộ nhớ. Nếu không vừa bộ nhớ, các phân vùng sẽ được lưu trên đĩa.
- MEMORY_ONLY_SER: Lưu RDD dưới dạng đối tượng Java đã tuần tự trong JVM. Điều này giảm mức sử dụng bộ nhớ nhưng tăng chi phí CPU cho (de)serialization.
- MEMORY_AND_DISK_SER: Tương tự MEMORY_AND_DISK nhưng lưu đối tượng đã tuần tự.
- DISK_ONLY: Chỉ lưu các phân vùng RDD trên đĩa.
rdd = spark.sparkContext.parallelize([1, 2, 3, 4, 5])
rdd.persist(storageLevel=StorageLevel.MEMORY_AND_DISK)
8. Bạn xử lý dữ liệu bị lệch (skewed) trong Spark như thế nào?
Câu hỏi này đánh giá hiểu biết về hiện tượng lệch dữ liệu và cách quản lý, điều then chốt để đảm bảo xử lý dữ liệu hiệu quả.
Trả lời:
Lệch dữ liệu xảy ra khi một số phân vùng có lượng dữ liệu nhiều hơn đáng kể so với các phân vùng khác, dẫn đến nút thắt hiệu năng. Chiến lược xử lý bao gồm:
- Salting: Thêm khóa ngẫu nhiên vào dữ liệu để phân phối đều hơn qua các phân vùng.
- Repartitioning: Tăng số phân vùng để phân phối dữ liệu đồng đều hơn.
- Biến broadcast: Phát tán một tập dữ liệu nhỏ đến tất cả các nút để tránh shuffle các tập dữ liệu lớn.
from pyspark.sql.functions import monotonically_increasing_id, col
# Example of salting
df = df.withColumn("salt", monotonically_increasing_id() % 10)
df = df.withColumn("new_key", col("original_key") + col("salt"))
9. Giải thích sự khác nhau giữa các phép biến đổi hẹp (narrow) và rộng (wide) trong Spark
Câu hỏi này kiểm tra hiểu biết của ứng viên về mô hình thực thi của Spark và ảnh hưởng của các loại phép biến đổi khác nhau đến hiệu năng.
Trả lời:
- Biến đổi hẹp (Narrow Transformations): Các thao tác mà mỗi phân vùng đầu vào đóng góp chính xác cho một phân vùng đầu ra. Ví dụ gồm
.map(),.filter()và.union(). Chúng thường nhanh hơn vì không cần shuffle dữ liệu. - Biến đổi rộng (Wide Transformations): Các thao tác mà mỗi phân vùng đầu vào có thể đóng góp vào nhiều phân vùng đầu ra. Ví dụ gồm
.groupByKey(),.reduceByKey()và.join(). Chúng yêu cầu shuffle dữ liệu qua mạng, có thể tốn thời gian.
# Narrow transformation example
rdd1 = rdd.map(lambda x: x * 2)
# Wide transformation example
rdd2 = rdd.groupByKey()
10. Spark Streaming trong xử lý dữ liệu thời gian thực
Spark vượt trội khi streaming dữ liệu thời gian thực từ các nguồn như Apache Kafka hoặc Amazon Kinesis vì nó có khả năng mở rộng và chịu lỗi. Điều này được thực hiện thông qua phần mở rộng Spark Streaming. Nó tương tác với các nguồn dữ liệu bên ngoài bằng các input DStream, đại diện cho dòng dữ liệu liên tục từ các nguồn này.
Spark Streaming đảm bảo khả năng chịu lỗi và tính nhất quán dữ liệu thông qua các kỹ thuật như checkpointing và write-ahead logs. Checkpointing định kỳ lưu trạng thái của ứng dụng streaming vào lưu trữ bền vững (ví dụ: HDFS) để phục hồi khi có sự cố, trong khi write-ahead logs cung cấp khả năng chịu lỗi cho dữ liệu nhận từ nguồn bên ngoài.
Câu hỏi phỏng vấn Spark nâng cao
Những câu hỏi này dành cho người dùng có nhiều kinh nghiệm thực hành với Spark, đặc biệt ở các chủ đề chuyên sâu hơn. Nếu cần ôn lại, hãy xem hướng dẫn Spark Machine Learning.
11. Thảo luận cách Spark có thể được sử dụng cho machine learning
Câu hỏi này kiểm tra hiểu biết của người phỏng vấn về môi trường của Spark và thư viện MLlib.
Thư viện MLlib của Spark cung cấp bộ công cụ và thuật toán phong phú để thực hiện các tác vụ machine learning ở quy mô lớn. Về kỹ thuật trích chọn đặc trưng và tiền xử lý cho các tập dữ liệu lớn, MLlib cung cấp nhiều kỹ thuật và tối ưu hóa nâng cao:
- Biến đổi và lựa chọn đặc trưng: MLlib cung cấp nhiều kỹ thuật biến đổi đặc trưng như scaling, normalization, binarization và vector hóa (ví dụ: one-hot encoding). Ngoài ra, nó còn cung cấp phương pháp lựa chọn đặc trưng, gồm lọc theo tương quan, thông tin thu được hoặc kiểm định thống kê, cũng như các kỹ thuật nâng cao như Phân tích Thành phần Chính (PCA) để giảm chiều dữ liệu.
- Xử lý biến phân loại: MLlib có công cụ xử lý hiệu quả biến phân loại, như StringIndexer để chuyển đổi biến phân loại sang dạng số và OneHotEncoder để chuyển thành vector nhị phân. Các biến đổi này được tối ưu để thực thi song song trên các cụm Spark phân tán.
- Pipeline API: Pipeline API của Spark cho phép người dùng xâu chuỗi nhiều giai đoạn trích chọn đặc trưng và mô hình hóa vào một quy trình làm việc duy nhất. Điều này giúp tạo các pipeline biến đổi đặc trưng phức tạp đồng thời đảm bảo tính nhất quán và khả năng tái lập giữa các tập dữ liệu và tác vụ học máy khác nhau.
- Transformer và Estimator tùy chỉnh: MLlib cho phép định nghĩa các transformer và estimator đặc trưng tùy chỉnh bằng DataFrame API của Spark. Điều này cho phép tích hợp các kỹ thuật trích chọn đặc trưng theo miền hoặc thư viện bên thứ ba vào pipeline ML của Spark, mở rộng tính năng và tính linh hoạt.
12. Giải thích cách Spark tích hợp với các hệ thống lưu trữ bên ngoài như Apache Hadoop HDFS và Apache Cassandra. Lợi ích của việc tận dụng các tích hợp này trong một pipeline dữ liệu dựa trên Spark là gì?
Điều này kiểm tra xem người dùng có hiểu chức năng nền tảng của các hệ thống dựa trên Spark và cách Spark làm việc với HDFS và Apache Cassandra hay không. Quan trọng là hiểu cả cách truy xuất dữ liệu bằng mã và cách dữ liệu di chuyển trong toàn hệ thống.
- Kết nối Hadoop HDFS: Spark tích hợp với các hệ thống lưu trữ bên ngoài như Apache Hadoop HDFS và Apache Cassandra thông qua các connector hoặc thư viện được thiết kế riêng cho từng hệ thống. Ví dụ, tích hợp HDFS là tính năng gốc của Spark, cho phép Spark đọc/ghi dữ liệu trực tiếp từ/đến HDFS bằng các API Hadoop InputFormat và OutputFormat.
- Kết nối Apache Cassandra: Lợi ích của việc tận dụng các tích hợp này bao gồm hiệu năng được cải thiện nhờ tính cục bộ dữ liệu (đối với HDFS), đơn giản hóa truy cập và thao tác dữ liệu, và khả năng tương thích với hạ tầng dữ liệu hiện có. Ngoài ra, Spark có thể tận dụng tính phân tán của các hệ thống lưu trữ này để xử lý song song, cho phép xử lý dữ liệu có khả năng mở rộng.
13. Giải thích khái niệm biến broadcast trong Spark
Biến broadcast trong Spark là các biến chỉ đọc, được cache và cung cấp cho tất cả các nút công nhân trong một ứng dụng Spark phân tán. Chúng được dùng để phân phối hiệu quả các tập dữ liệu hoặc giá trị lớn, chỉ đọc tới các nút công nhân, từ đó giảm chi phí mạng và cải thiện hiệu năng tác vụ.
Biến broadcast được tuần tự hóa và gửi đến mỗi nút công nhân chỉ một lần, tại đó chúng được cache trong bộ nhớ và tái sử dụng qua nhiều tác vụ. Điều này loại bỏ nhu cầu gửi biến theo từng tác vụ, giảm chi phí truyền dữ liệu, đặc biệt với tập dữ liệu lớn.
- Cách sử dụng: Biến broadcast thường được dùng khi cần chia sẻ một tập dữ liệu hoặc giá trị lớn qua nhiều tác vụ hoặc giai đoạn tính toán. Ví dụ, trong các phép join mà một DataFrame hoặc RDD nhỏ hơn đáng kể so với cái còn lại, broadcast DataFrame/RDD nhỏ có thể giảm đáng kể lượng dữ liệu shuffle qua mạng trong phép join.
- Kịch bản có lợi:
- Phép join: Broadcast các tập dữ liệu nhỏ cho phép join có thể cải thiện lớn hiệu năng bằng cách giảm lưu lượng mạng và tăng tốc thực thi tác vụ.
- Bảng tra cứu: Broadcast các bảng tra cứu hoặc dictionary nhỏ dùng để làm giàu hoặc lọc có thể tăng hiệu năng bằng cách tránh truyền dữ liệu lặp lại.
- Machine learning: Broadcast vector đặc trưng hoặc tham số mô hình đến các nút công nhân trong quá trình huấn luyện phân tán có thể đẩy nhanh quá trình, đặc biệt khi vector/ tham số tương đối nhỏ so với tập dữ liệu.
- Thách thức:
- Chi phí bộ nhớ: Broadcast biến lớn có thể tiêu tốn nhiều bộ nhớ trên các nút công nhân, có thể dẫn đến lỗi thiếu bộ nhớ nếu không quản lý cẩn thận.
- Tắc nghẽn mạng: Broadcast biến lớn cũng có thể gây tắc nghẽn mạng trong giai đoạn broadcast ban đầu, đặc biệt ở các cụm lớn với băng thông hạn chế.
- Dữ liệu động: Biến broadcast là bất biến sau khi phát, nên không phù hợp cho các tình huống cần cập nhật dữ liệu được broadcast trong quá trình chạy job Spark.
14. Bạn tối ưu một job Spark bằng partitioning và coalescing như thế nào?
Câu hỏi này đánh giá khả năng tối ưu các job Spark, một kỹ năng then chốt để cải thiện hiệu năng và hiệu quả. Thông qua tinh chỉnh hiệu năng Spark, chúng ta có thể tận dụng khung phân tán của Spark bằng partitioning và coalescing, vốn quản lý phân bổ tải công việc trên cụm để thực hiện các thao tác dữ liệu nhanh hơn.
Trả lời:
- Partitioning: Kiểm soát số phân vùng trong RDD hoặc DataFrame. Dùng
.repartition()để tăng hoặc phân phối đều các phân vùng. Thao tác này tốn kém tính toán hơn và chỉ nên dùng khi cần chia đều dữ liệu để cân bằng xử lý. - Coalescing: Giảm số phân vùng mà không thực hiện shuffle toàn phần, hiệu quả hơn so với repartition khi giảm số phân vùng. Thực hiện bằng
.coalesce().
# Increasing partitions (full shuffle)
df_repartitioned = df.repartition(10)
# Reducing partitions (no full shuffle)
df_coalesced = df.coalesce(2)
Lưu ý một câu hỏi tiếp theo có thể đề cập khi nào các thao tác này hữu ích nhất. Hãy nêu rằng chúng hiệu quả hơn khi làm việc với tập dữ liệu lớn, và không nên lãng phí tài nguyên tính toán trên các tập dữ liệu nhỏ.
15. Giải thích khả năng tương tác của Spark với các định dạng tuần tự hóa dữ liệu
Chuyên gia dữ liệu sẽ tương tác với nhiều định dạng dữ liệu khác nhau. Mỗi định dạng có đánh đổi riêng. Hãy đảm bảo bạn có thể giải thích cách Spark tương tác nói chung với các định dạng này và nêu các cân nhắc hiệu năng ở mức cao cũng như cân nhắc cho hệ sinh thái rộng hơn.
- Hỗ trợ định dạng tuần tự hóa dữ liệu: Spark tương tác với các định dạng như Avro, Parquet hoặc ORC thông qua hỗ trợ sẵn có hoặc thư viện bên thứ ba. Các định dạng này có ưu điểm như nén hiệu quả, lưu trữ dạng cột và tiến hóa schema, phù hợp cho xử lý và lưu trữ dữ liệu trong các pipeline dựa trên Spark.
- Tối ưu đọc dữ liệu: Spark tối ưu thao tác đọc/ghi với các định dạng này bằng cách sử dụng reader/writer chuyên biệt, tận dụng cấu trúc nội tại và kỹ thuật nén của chúng. Ví dụ, Parquet và ORC dùng lưu trữ dạng cột để tối thiểu hóa I/O và cải thiện hiệu năng truy vấn.
- Đánh đổi định dạng dữ liệu: Các đánh đổi bao gồm hiệu quả lưu trữ (ví dụ: tỷ lệ nén), hiệu năng (ví dụ: thông lượng đọc/ghi) và khả năng tương thích với công cụ xử lý dữ liệu khác. Việc chọn định dạng phù hợp phụ thuộc vào đặc điểm dữ liệu, mẫu truy vấn và yêu cầu tích hợp trong pipeline dữ liệu.
Câu hỏi phỏng vấn Spark về mã hóa
Những câu hỏi mã hóa này tập trung vào việc sử dụng PySpark để tương tác với môi trường Spark.
16. Tìm N từ xuất hiện nhiều nhất trong một tệp văn bản lớn
Câu hỏi này kiểm tra khả năng tương tác với Spark và hiểu biết về cách dùng mapping trong chính Spark.
from pyspark import SparkContext
# create your spark context
sc = SparkContext("local", "WordCount")
# import a text file from a local path
lines = sc.textFile("path/to/your/text/file.txt")
# split and map the words
# then reduce by using the words as keys and add to the count
word_counts = lines.flatMap(lambda line: line.split(" ")) \
.map(lambda word: (word, 1)) \
.reduceByKey(lambda a, b: a + b)
# order the words and take only the top N frequent words
top_n_words = word_counts.takeOrdered(N, key=lambda x: -x[1])
print(top_n_words)
17. Tính trung bình các giá trị trong một RDD cho trước
Câu hỏi này là cách hay để thể hiện ai đó biết cách tạo một RDD đơn giản và thao tác nó. Tính trung bình các giá trị là nhiệm vụ rất phổ biến với chuyên gia dữ liệu và điều quan trọng là bạn hiểu cách đưa dữ liệu vào ngữ cảnh Spark.
from pyspark import SparkContext
# Create sparkContext and name it “Average”
sc = SparkContext("local", "Average")
# Generate Spark RDD
data = sc.parallelize([1, 2, 3, 4, 5])
# Sum the RDD, count the number of values in RDD
total_sum = data.sum()
count = data.count()
# divide sum by count to get average
average = total_sum / count
print("Average:", average)
18. Thực hiện left outer join giữa hai RDD
Thực hiện các tác vụ thao tác và biến đổi dữ liệu như join là thành phần then chốt của SparkSQL. Điều này cho phép kết hợp dữ liệu từ các nguồn khác nhau để phân tích.
from pyspark import SparkContext
# Create SparkContext
sc = SparkContext("local", "LeftOuterJoin")
# Create two RDDs with tuples sharing keys
rdd1 = sc.parallelize([(1, 'a'), (2, 'b'), (3, 'c')])
rdd2 = sc.parallelize([(1, 'x'), (2, 'y')])
# Use the .leftOuterJoin() method to join the first rdd to the second rdd
joined_rdd = rdd1.leftOuterJoin(rdd2)
# Use the .collect() method to show the rdd
print(joined_rdd.collect())
19. Đọc dữ liệu từ Kafka, thực hiện biến đổi, rồi ghi kết quả vào HDFS
Điều này kiểm tra khả năng đưa dữ liệu từ nguồn bên ngoài vào và hiểu biết cách Spark kết nối với nguồn dữ liệu bên ngoài. Tập trung vào các khái niệm chung, như cần import các tiện ích/phần mở rộng cho một luồng dữ liệu cụ thể thay vì ghi nhớ chính xác từng dòng mã. Lưu ý với SparkContext, chúng tôi đặt appname (KafkaWordCount) như tham số tùy chọn, nhưng hữu ích vì giúp các tiến trình rõ ràng.
# Import the sparkcontext, additionally import streaming context and Kafka
from pyspark import SparkContext
from pyspark.streaming import StreamingContext
from pyspark.streaming.kafka import KafkaUtils
# Create context
sc = SparkContext("local", "KafkaWordCount")
# Use streaming context to bring in data at 10 second intervals
ssc = StreamingContext(sc, 10) # 10-second batch interval
# Use Kafka param dictionary in order to connect to the stream using the streaming context, the topic of interest, and the parameters
kafka_params = {"metadata.broker.list": "broker1:9092,broker2:9092"}
kafka_stream = KafkaUtils.createDirectStream(ssc, ["topic"], kafka_params)
# save the results of this stream to lines
# perform MapReduce in order to generate dictionary and count by keys
lines = kafka_stream.map(lambda x: x[1])
word_counts = lines.flatMap(lambda line: line.split(" ")) \
.map(lambda word: (word, 1)) \
.reduceByKey(lambda a, b: a + b)
# save to external file
word_counts.saveAsTextFiles("hdfs://path/to/save")
# start context until you terminate
ssc.start()
ssc.awaitTermination()
20. Bạn thực hiện các phép biến đổi và hành động cơ bản trên một Spark DataFrame như thế nào?
Câu hỏi này đánh giá hiểu biết của ứng viên về các thao tác DataFrame trong Spark.
Transformations là các thao tác trên DataFrame trả về một DataFrame mới, như select, filter và groupBy. Actions là các thao tác kích hoạt tính toán và trả về kết quả, như show, count và collect.
Đoạn mã sau cho thấy chọn cột, lọc dòng và thực hiện tổng hợp theo nhóm.
# Select specific columns
selected_df = df.select("column1", "column2")
# Filter rows based on a condition
filtered_df = df.filter(df["column1"] > 100)
# Group by a column and perform aggregation
grouped_df = df.groupBy("column2").agg({"column1": "sum"})
# Show the results
selected_df.show()
filtered_df.show()
grouped_df.show()
Kết luận
Nắm vững những câu hỏi phỏng vấn này là bước đầu tuyệt vời để trở thành một chuyên gia dữ liệu. Spark là hạ tầng phổ biến được nhiều tổ chức sử dụng để xử lý pipeline dữ liệu lớn. Hiểu lợi ích và thách thức của Spark sẽ giúp bạn nổi bật như một chuyên gia dữ liệu am hiểu. Đây mới chỉ là khởi đầu! Trải nghiệm thực hành với Spark là cách học tốt nhất.
Bạn có thể bắt đầu với các khóa học và hướng dẫn PySpark sau trên DataCamp:
Câu hỏi thường gặp về phỏng vấn Spark
Tôi bắt đầu với Spark như thế nào nếu tôi mới với các công nghệ dữ liệu lớn?
Khám phá các khóa học của Datacamp như Giới thiệu về PySpark, Giới thiệu về Spark SQL trong Python và Big Data với PySpark để bắt đầu.
Một số trường hợp sử dụng phổ biến của Spark trong ứng dụng thực tế là gì?
Spark được dùng cho pipeline ETL, khám phá dữ liệu, phân tích thời gian thực, machine learning và kho dữ liệu. Có kiến thức về Spark giúp bạn ứng tuyển ở nhiều ngành.
Spark so với các khung xử lý dữ liệu lớn khác như Hadoop MapReduce như thế nào?
Spark giữ kết quả trong bộ nhớ nhiều nhất có thể, trong khi MapReduce ghi kết quả trung gian xuống đĩa. Tuy nhiên, Spark có thể sử dụng hạ tầng Hadoop như YARN cho quản lý tài nguyên nên chúng thường được dùng cùng nhau.
Spark có phù hợp với các tác vụ xử lý dữ liệu quy mô nhỏ hay chỉ dành cho dữ liệu lớn?
Có. Spark được thiết kế để mở rộng dựa trên nhu cầu xử lý dữ liệu. Một số tính năng tối ưu hiệu năng của Spark có thể lãng phí tài nguyên trên các tập dữ liệu nhỏ, vì vậy bạn có thể cần điều chỉnh pipeline cho phù hợp.
Tôi có thể dùng Spark với các ngôn ngữ khác ngoài Python không?
Có. Spark có thể sử dụng với Scala, Java, R và SQL.
Tôi là một nhà khoa học dữ liệu có kinh nghiệm về phân tích không gian, học máy và đường ống dữ liệu. Tôi đã làm việc với GCP, Hadoop, Hive, Snowflake, Airflow và các quy trình khoa học/kỹ thuật dữ liệu khác.
