Dữ liệu Spark hiệu quả với Alluxio


Dương Việt Phi
10 tháng trước
Hữu ích 9 Chia sẻ Viết bình luận 0
Đã xem 3596

Giới thiệu

Nhiều tổ chức triển khai Alluxio cùng với Spark để tăng hiệu suất và lợi ích quản lý dữ liệu. Qunar gần đây đã triển khai Alluxio trong sản xuất và công việc phát trực tuyến Spark của họ tăng trung bình 15 lần và lên tới 300 lần trong thời gian cao điểm. Họ nhận thấy rằng một số công việc Spark sẽ chậm lại hoặc không hoàn thành, nhưng với Alluxio, những công việc đó có thể kết thúc nhanh chóng. Trong bài đăng trên blog này, chúng tôi điều tra cách Alluxio giúp Spark hiệu quả hơn. Alluxio tăng hiệu suất của các công việc Spark, giúp các công việc Spark thực hiện dự đoán nhiều hơn và cho phép nhiều công việc Spark chia sẻ cùng một dữ liệu từ bộ nhớ. Trước đây, chúng tôi đã điều tra cách Alluxio được sử dụng cho Spark RDD . Trong bài viết này, chúng tôi điều tra cách sử dụng hiệu quả Spark DataFrames với Alluxio.

Alluxio và Spark Cache

Lưu trữ Spark DataFrames trong bộ nhớ Alluxio rất đơn giản và chỉ yêu cầu lưu DataFrame dưới dạng tệp vào Alluxio. Điều này rất đơn giản với writeAPI Spark DataFrame . DataFrames thường được viết dưới dạng tệp parquet, với df.write.parquet(). Sau khi sàn gỗ được ghi vào Alluxio, nó có thể được đọc từ bộ nhớ bằng cách sử dụng sqlContext.read.parquet().

Để hiểu cách lưu DataFrames vào Alluxio so sánh với việc sử dụng bộ đệm Spark, chúng tôi đã chạy một vài thử nghiệm đơn giản. Chúng tôi đã sử dụng một cá thể Amazon EC2 r3.2xlarge, với bộ nhớ 61 GB và 8 lõi. Chúng tôi đã sử dụng Spark 2.0.0 và Alluxio 1.2.0 với các cấu hình mặc định. Chúng tôi đã chạy cả Spark và Alluxio trong chế độ độc lập trên nút. Đối với thử nghiệm, chúng tôi đã thử các cách khác nhau để lưu trữ Spark DataFrames và lưu DataFrames trong Alluxio và đo xem các kỹ thuật khác nhau ảnh hưởng đến hiệu suất như thế nào. Chúng tôi cũng thay đổi kích thước của dữ liệu để hiển thị kích thước dữ liệu ảnh hưởng đến hiệu suất.

Lưu dữ liệu

Spark DataFrames có thể được "lưu" hoặc "lưu vào bộ nhớ cache" trong bộ nhớ Spark với persist()API. Các persist()API cho phép lưu DataFrame để phương tiện lưu trữ khác nhau. Đối với các thử nghiệm, các mức lưu trữ Spark sau đây được sử dụng:

  • MEMORY_ONLY: lưu trữ các đối tượng Java trong bộ nhớ Spark JVM.
  • MEMORY_ONLY_SER: lưu trữ các đối tượng java được tuần tự hóa trong bộ nhớ Spark JVM.
  • DISK_ONLY: lưu trữ dữ liệu trên đĩa cục bộ.

Dưới đây là ví dụ về cách lưu trữ DataFrame bằng persist()API:

df.persist(MEMORY_ONLY)

Một cách khác để lưu DataFrames vào bộ nhớ là ghi DataFrame dưới dạng tệp trong Alluxio. Spark hỗ trợ viết DataFrames sang một số định dạng tệp khác nhau, nhưng, đối với các thử nghiệm này, chúng tôi viết DataFrames dưới dạng tệp sàn. Dưới đây là một ví dụ về cách ghi DataFrame vào bộ nhớ Alluxio:

df.write.parquet(alluxioFile)

Truy vấn DataFrames đã lưu trong Alluxio

Sau khi DataFrames được lưu, trong Spark hoặc Alluxio, các ứng dụng có thể đọc chúng để tính toán. Trong các thử nghiệm của chúng tôi, chúng tôi đã tạo một DataFrame mẫu với hai cột nổi và tính toán là một tổng trên cả hai cột.

Khi DataFrame được lưu trữ trong Alluxio, để đọc dữ liệu trong Spark cũng đơn giản như đọc tệp từ Alluxio. Dưới đây là một ví dụ về việc đọc DataFrame mẫu của chúng tôi trong Alluxio.

df = sqlContext.read.parquet(alluxioFile)
df.agg(sum("s1"), sum("s2")).show()

Chúng tôi đã thực hiện tổng hợp này trên DataFrame từ các tệp sàn gỗ Alluxio và từ các mức lưu trữ liên tục Spark khác nhau và chúng tôi đã đo thời gian cần thiết cho việc tổng hợp. Hình dưới đây cho thấy thời gian hoàn thành cho các tập hợp.

Hình vẽ cho thấy việc thực hiện tổng hợp trên DataFrame được đọc từ tệp sàn gỗ Alluxio dẫn đến hiệu suất rất dễ đoán và ổn định. Tuy nhiên, khi đọc DataFrames từ bộ đệm Spark, hiệu suất cao đối với kích thước dữ liệu nhỏ, nhưng kích thước dữ liệu lớn hơn làm tổn hại đáng kể đến hiệu suất. Đối với các mức lưu trữ Spark khác nhau, sau khoảng 20 GB dữ liệu đầu vào, tổng hợp chậm lại và tăng đáng kể.

Với bộ nhớ Alluxio, hiệu suất tổng hợp DataFrame chậm hơn một chút so với bộ nhớ Spark cho kích thước dữ liệu nhỏ hơn, nhưng khi kích thước dữ liệu tăng lên, đọc từ hiệu suất Alluxio tốt hơn đáng kể khi nó chia tỷ lệ tuyến tính với kích thước dữ liệu. Vì hiệu năng quy mô tuyến tính, các ứng dụng có thể xử lý kích thước dữ liệu lớn hơn ở tốc độ bộ nhớ với Alluxio.

Chia sẻ dữ liệu lưu trữ dữ liệu lưu trữ dữ liệu với Alluxio

Alluxio cũng cho phép khả năng chia sẻ dữ liệu trong bộ nhớ, thậm chí trên các công việc Spark khác nhau. Sau khi một tệp được ghi vào Alluxio, cùng một tệp đó có thể được chia sẻ qua các công việc, bối cảnh và thậm chí các khung khác nhau, thông qua bộ nhớ của Alluxio. Do đó, nếu một DataFrame trong Alluxio thường xuyên được nhiều ứng dụng truy cập, tất cả các ứng dụng có thể đọc dữ liệu từ tệp Alluxio trong bộ nhớ và không phải tính toán lại hoặc tìm nạp nó từ nguồn bên ngoài.

Để chứng minh các lợi ích chia sẻ trong bộ nhớ của Alluxio, chúng tôi đã tính toán tổng hợp DataFrame trong cùng một môi trường như được mô tả ở trên. Với kích thước dữ liệu 50 GB, chúng tôi đã chạy tổng hợp trong một ứng dụng Spark riêng và đo thời gian cần thiết để thực hiện tính toán. Không có Alluxio, ứng dụng Spark phải đọc dữ liệu từ nguồn, đây là ổ SSD cục bộ trong thử nghiệm này. Tuy nhiên, khi sử dụng Spark với Alluxio, đọc dữ liệu có nghĩa là đọc nó từ bộ nhớ Alluxio. Dưới đây là kết quả của thời gian hoàn thành tổng hợp.

Không có Alluxio, Spark phải đọc lại dữ liệu từ nguồn (SSD cục bộ). Đọc từ Alluxio nhanh hơn vì dữ liệu được đọc từ bộ nhớ. Với Alluxio, tập hợp nhanh hơn 2,5 lần.

Trong thử nghiệm trước, nguồn dữ liệu là SSD cục bộ. Tuy nhiên, nếu nguồn của DataFrame chậm hơn hoặc ít dự đoán hơn, lợi ích của Alluxio có ý nghĩa hơn. Ví dụ, Amazon S3 là một hệ thống phổ biến để lưu trữ lượng lớn dữ liệu. Dưới đây là kết quả khi nguồn của DataFrame là từ Amazon S3.

Hình vẽ cho thấy thời gian hoàn thành tổng hợp trung bình trong 7 lần chạy. Các thanh lỗi trong hình biểu thị phạm vi tối thiểu và tối đa của thời gian hoàn thành. Những kết quả này cho thấy rõ ràng, Alluxio cải thiện đáng kể hiệu suất trung bình của tính toán. Điều này là do với Alluxio, Spark có thể đọc DataFrame trực tiếp từ bộ nhớ Alluxio, thay vì tìm nạp lại dữ liệu từ S3. Trung bình, Alluxio tăng tốc tính toán DataFrame hơn 10 lần.

Vì nguồn dữ liệu là Amazon S3, Spark không có Alluxio phải tìm nạp dữ liệu qua mạng và điều này có thể dẫn đến hiệu suất không thể đoán trước. Hiệu suất không ổn định này được hiển thị từ các thanh lỗi của hình. Không có Alluxio, thời gian hoàn thành công việc Spark rất khác nhau, hơn 1100 giây. Với Alluxio, thời gian hoàn thành chỉ thay đổi trong 10 giây. Alluxio giảm hơn 100 lần không thể đoán trước!

Do mạng S3 không thể đoán trước, Spark chạy chậm nhất mà không có Alluxio có thể mất tới hơn 1700 giây, chậm gần gấp đôi so với mức trung bình. Mặt khác, Spark chạy chậm nhất với Alluxio chậm hơn khoảng 6 giây so với thời gian trung bình. Bằng cách xem xét các hoạt động chậm nhất, Alluxio tăng tốc độ tổng hợp DataFrame hơn 17 lần.

Phần kết luận

Alluxio giúp Spark hiệu quả hơn bằng cách cho phép một số lợi ích. Blog này trình bày cách sử dụng Alluxio với Spark DataFrames và trình bày các đánh giá hiệu suất về lợi ích.

  • Alluxio có thể giữ kích thước dữ liệu lớn hơn trong bộ nhớ để tăng tốc các ứng dụng Spark.
  • Alluxio cho phép chia sẻ dữ liệu trong bộ nhớ.
  • Alluxio cung cấp hiệu suất ổn định và có thể dự đoán.

Để tìm hiểu thêm về cách sử dụng Alluxio cho các công cụ tính toán khác nhau, hãy xem tài liệu Alluxio .

Hữu ích 9 Chia sẻ Viết bình luận 0
Đã xem 3596