Apache Spark: Số lượng lõi so với số lượng người thi hành


192

Tôi đang cố gắng tìm hiểu mối quan hệ của số lượng lõi và số lượng nhân viên thực thi khi chạy một công việc Spark trên YARN.

Môi trường thử nghiệm như sau:

  • Số nút dữ liệu: 3
  • Thông số máy nút dữ liệu:
    • CPU: Core i7-4790 (# lõi: 4, # của luồng: 8)
    • RAM: 32GB (8GB x 4)
    • Ổ cứng: 8TB (2TB x 4)
  • Mạng: 1Gb

  • Phiên bản Spark: 1.0.0

  • Phiên bản Hadoop: 2.4.0 (Hortonworks HDP 2.1)

  • Luồng công việc Spark: sc.textFile -> bộ lọc -> bản đồ -> bộ lọc -> mapToPair -> lessByKey -> map -> saveAsTextFile

  • Dữ liệu đầu vào

    • Loại: tệp văn bản duy nhất
    • Dung lượng: 165GB
    • Số dòng: 454,568,833
  • Đầu ra

    • Số dòng sau bộ lọc thứ hai: 310.640.717
    • Số dòng của tệp kết quả: 99.848.268
    • Kích thước của tệp kết quả: 41GB

Công việc được chạy với các cấu hình sau:

  1. --master yarn-client --executor-memory 19G --executor-cores 7 --num-executors 3 (người thực thi trên mỗi nút dữ liệu, sử dụng nhiều như lõi)

  2. --master yarn-client --executor-memory 19G --executor-cores 4 --num-executors 3 (Số lõi giảm)

  3. --master yarn-client --executor-memory 4G --executor-cores 2 --num-executors 12 (ít cốt lõi hơn, thực thi nhiều hơn)

Thời gian đã qua:

  1. 50 phút 15 giây

  2. 55 phút 48 giây

  3. 31 phút 23 giây

Thật ngạc nhiên, (3) nhanh hơn nhiều.
Tôi nghĩ rằng (1) sẽ nhanh hơn, vì sẽ có ít giao tiếp giữa các nhà điều hành khi xáo trộn.
Mặc dù số lõi của (1) nhỏ hơn (3), nhưng số lõi #of không phải là yếu tố chính vì 2) đã hoạt động tốt.

(Phần tiếp theo đã được thêm vào sau câu trả lời của pwilmot.)

Để biết thông tin, chụp màn hình hiệu suất màn hình như sau:

  • Tóm tắt nút dữ liệu Ganglia cho (1) - công việc bắt đầu lúc 04:37.

Tóm tắt nút dữ liệu Ganglia cho (1)

  • Tóm tắt nút dữ liệu Ganglia cho (3) - công việc bắt đầu lúc 19:47. Hãy bỏ qua biểu đồ trước thời gian đó.

Tóm tắt nút dữ liệu Ganglia cho (3)

Biểu đồ chia thành 2 phần:

  • Thứ nhất: từ bắt đầu đến giảmByKey: CPU chuyên sâu, không có hoạt động mạng
  • Thứ hai: sau khi giảmByKey: CPU giảm, I / O mạng được thực hiện.

Như biểu đồ cho thấy, (1) có thể sử dụng nhiều năng lượng CPU như đã được cung cấp. Vì vậy, nó có thể không phải là vấn đề về số lượng của các chủ đề.

Làm thế nào để giải thích kết quả này?


2
Bây giờ tôi đang nghi ngờ GC ... Trên thực tế, trên Spark UI, tổng thời gian dành cho GC dài hơn 1) so với 2).
zeodtr

Tại sao bạn không thử 3) với 19G? Có thể việc giới hạn các nhân viên trên 4G làm giảm hiệu ứng NUMA mà một số ppl có tại chỗ? tức là 4G của bạn được đặt trên một trong 2 lõi được phân bổ cho quy trình làm việc của bạn và do đó sẽ giảm tốc độ i / o, dẫn đến hiệu suất tổng thể tốt hơn. Mặt khác, tôi nghĩ rằng một câu hỏi chính là: có bao nhiêu lõi / luồng có thể sử dụng một trình thực thi duy nhất trên một công nhân? (Người ta chỉ có thể chỉ định tổng số lõi cho một công nhân, không phải ở mức độ chi tiết của người thi hành)
Bacon

4
Btw Tôi vừa kiểm tra mã tại core / src / main / scala / org / apache / spark / triển khai / worker / ExecutorRunner.scala và có vẻ như 1 thực thi = 1 luồng của công nhân.
Thịt xông khói

hơi muộn nhưng đây là một bài đăng trên cloudera về chủ đề này: blog.cloudera.com/blog/2015/03/ mẹo
Orelus

1
Bằng cách này, tôi thấy thông tin này trong một Cloudera trượt boong slideshare.net/cloudera/... , giải thích một chút về việc lập decission trong chấp hành viên, lõi và bộ nhớ
Manish Sahni

Câu trả lời:


58

Để hy vọng làm cho tất cả những điều này cụ thể hơn một chút, đây là một ví dụ hoạt động về việc định cấu hình ứng dụng Spark để sử dụng càng nhiều cụm càng tốt: Hãy tưởng tượng một cụm có sáu nút chạy NodeManager, mỗi nút được trang bị 16 lõi và 64GB bộ nhớ . Các dung lượng của NodeManager, Sợi.nodemanager.resource.memory-mb và Sợi.nodemanager.resource.cpu-vcores, có lẽ nên được đặt thành 63 * 1024 = 64512 (megabyte) và 15 tương ứng. Chúng tôi tránh phân bổ 100% tài nguyên cho các thùng chứa YARN vì nút cần một số tài nguyên để chạy trình nền OS và Hadoop. Trong trường hợp này, chúng tôi để lại một gigabyte và lõi cho các quy trình hệ thống này. Cloudera Manager giúp bằng cách hạch toán những thứ này và tự động định cấu hình các thuộc tính YARN này.

Sự thúc đẩy đầu tiên có khả năng sẽ là sử dụng --num-execors 6 --executor-core 15 --executor-memory 63G . Tuy nhiên, đây là cách tiếp cận sai vì:

63GB + chi phí bộ nhớ thực thi sẽ không phù hợp với dung lượng 63GB của NodeManager. Bậc thầy ứng dụng sẽ chiếm một lõi trên một trong các nút, nghĩa là sẽ không có chỗ cho người thi hành 15 lõi trên nút đó. 15 lõi cho mỗi người thi hành có thể dẫn đến thông lượng I / O HDFS xấu.

Một lựa chọn tốt hơn sẽ là sử dụng --num-execors 17 --executor-core 5 --executor-memory 19G . Tại sao?

Cấu hình này dẫn đến ba người thực thi trên tất cả các nút ngoại trừ một nút có AM, sẽ có hai người thực thi. --executor-memory được dẫn xuất là (63/3 người thực thi trên mỗi nút) = 21. 21 * 0.07 = 1.47. 21 - 1.47 ~ 19.

Lời giải thích được đưa ra trong một bài viết trên blog của Cloudera, Cách thực hiện: Điều chỉnh công việc Spark Apache của bạn (Phần 2) .


1
"Cấu hình này dẫn đến ba người thực thi trên tất cả các nút ngoại trừ một nút có AM, sẽ có hai người thực thi.". Điều này có nghĩa gì với "--executor-core 5"?
derek

Nó có nghĩa là mỗi thực thi sử dụng 5 lõi. Mỗi nút có 3 bộ thực thi, do đó sử dụng 15 lõi, ngoại trừ một trong số các nút cũng sẽ chạy ứng dụng chính cho công việc, do đó chỉ có thể lưu trữ 2 bộ thực thi, tức là 10 lõi được sử dụng làm bộ thực thi.
Davos

Giải thích rõ ràng - xin lưu ý rằng điều này áp dụng cho yarn.scheduler.capacity.resource-calculatorngười khuyết tật, đó là mặc định. Điều này là do mặc định nó lên lịch theo Bộ nhớ chứ không phải bởi CPU.
YoYo

1
Nhiều người thực thi có thể dẫn đến thông lượng I / O HDFS xấu. Vì vậy, nếu tôi hoàn toàn không sử dụng HDFS, trong trường hợp đó tôi có thể sử dụng nhiều hơn 5 lõi cho mỗi người thi hành không?
Darshan

Tôi mặc dù ứng dụng chủ chạy trên mỗi nút. Ở trên, có nghĩa là sẽ chỉ có 1 Application Master để điều hành công việc. Đúng không?
Roshan Fernando

15

Khi bạn chạy ứng dụng tia lửa của mình trên đỉnh HDFS, theo Sandy Ryza

Tôi đã nhận thấy rằng máy khách HDFS gặp sự cố với hàng tấn luồng đồng thời. Một dự đoán sơ bộ là nhiều nhất năm nhiệm vụ cho mỗi người thực thi có thể đạt được thông lượng ghi đầy đủ, vì vậy thật tốt khi giữ số lượng lõi trên mỗi người thực thi dưới con số đó.

Vì vậy, tôi tin rằng cấu hình đầu tiên của bạn chậm hơn so với thứ ba là do thông lượng I / O HDFS xấu


11

Bản thân tôi chưa chơi với các cài đặt này nên đây chỉ là suy đoán nhưng nếu chúng tôi nghĩ vấn đề này là lõi và luồng bình thường trong hệ thống phân tán thì trong cụm của bạn, bạn có thể sử dụng tối đa 12 lõi (máy 4 * 3) và 24 luồng (8 * 3 máy). Trong hai ví dụ đầu tiên của bạn, bạn đang cung cấp cho công việc của mình một số lượng lõi (không gian tính toán tiềm năng) nhưng số lượng luồng (công việc) để chạy trên các lõi đó bị hạn chế đến mức bạn không thể sử dụng nhiều năng lực xử lý được phân bổ và do đó công việc chậm hơn mặc dù có nhiều tài nguyên tính toán được phân bổ hơn.

bạn đề cập rằng mối quan tâm của bạn là trong bước xáo trộn - trong khi thật tốt để hạn chế chi phí trong bước xáo trộn, điều quan trọng hơn nhiều là sử dụng sự song song của cụm. Hãy suy nghĩ về trường hợp cực đoan - một chương trình luồng đơn với không xáo trộn.


Cảm ơn câu trả lời của bạn. Nhưng tôi nghi ngờ rằng số lượng chủ đề không phải là vấn đề chính. Tôi đã thêm tính năng chụp màn hình theo dõi. Như biểu đồ cho thấy, 1) có thể sử dụng nhiều năng lượng CPU như đã được cung cấp.
zeodtr

1
@zeodtr pwilmot là chính xác - bạn cần 2-4 nhiệm vụ TỐI THIỂU để tận dụng hết tiềm năng của lõi. Đặt nó là thế này - Tôi thường sử dụng ít nhất 1000 phân vùng cho cụm 80 lõi của mình.
samthebest

@samthebest Điều tôi muốn biết là lý do của sự khác biệt hiệu suất giữa 1) và 3). Khi tôi xem Spark UI, cả hai đều chạy 21 nhiệm vụ song song trong phần 2. (tại sao 21 thay vì 24 trong trường hợp 3) hiện chưa rõ) Nhưng, các tác vụ cho 3) chỉ chạy nhanh hơn.
zeodtr

10

Câu trả lời ngắn gọn : Tôi nghĩ tgbaggio là đúng. Bạn đạt giới hạn thông lượng HDFS trên người thi hành.

Tôi nghĩ rằng câu trả lời ở đây có thể đơn giản hơn một chút so với một số khuyến nghị ở đây.

Manh mối cho tôi là trong biểu đồ mạng cụm. Đối với chạy 1, mức sử dụng ổn định ở mức ~ 50 M byte / s. Đối với chạy 3, mức sử dụng ổn định được nhân đôi, khoảng 100 M byte / s.

Từ bài đăng trên blog cloudera được chia sẻ bởi DzOrd , bạn có thể thấy trích dẫn quan trọng này:

Tôi đã nhận thấy rằng máy khách HDFS gặp sự cố với hàng tấn luồng đồng thời. Một dự đoán sơ bộ là nhiều nhất năm nhiệm vụ cho mỗi người thực thi có thể đạt được thông lượng ghi đầy đủ, vì vậy thật tốt khi giữ số lượng lõi trên mỗi người thực thi dưới con số đó.

Vì vậy, hãy thực hiện một vài tính toán để xem hiệu suất mà chúng tôi mong đợi nếu điều đó là đúng.


Chạy 1: 19 GB, 7 lõi, 3 người thực thi

  • 3 người thực hiện x 7 chủ đề = 21 chủ đề
  • với 7 lõi ​​cho mỗi người thi hành, chúng tôi hy vọng IO bị giới hạn ở HDFS (tối đa là ~ 5 lõi)
  • thông lượng hiệu quả ~ = 3 người thực hiện x 5 luồng = 15 luồng

Chạy 3: 4 GB, 2 nhân, 12 người thi hành

  • 2 người thực hiện x 12 luồng = 24 luồng
  • 2 lõi cho mỗi người thi hành, vì vậy thông lượng hdfs là ok
  • thông lượng hiệu quả ~ = 12 người thực hiện x 2 luồng = 24 luồng

Nếu công việc bị giới hạn 100% bởi đồng thời (số lượng chủ đề). Chúng tôi hy vọng thời gian chạy hoàn toàn tương quan nghịch với số lượng luồng.

ratio_num_threads = nthread_job1 / nthread_job3 = 15/24 = 0.625
inv_ratio_runtime = 1/(duration_job1 / duration_job3) = 1/(50/31) = 31/50 = 0.62

Vì vậy ratio_num_threads ~= inv_ratio_runtime, và có vẻ như chúng tôi bị hạn chế mạng.

Hiệu ứng tương tự này giải thích sự khác biệt giữa Run 1 và Run 2.


Chạy 2: 19 GB, 4 lõi, 3 người thực thi

  • 3 người thực hiện x 4 chủ đề = 12 chủ đề
  • với 4 lõi cho mỗi người thi hành, ok IO đến HDFS
  • thông lượng hiệu quả ~ = 3 người thực hiện x 4 luồng = 12 luồng

So sánh số lượng chủ đề hiệu quả và thời gian chạy:

ratio_num_threads = nthread_job2 / nthread_job1 = 12/15 = 0.8
inv_ratio_runtime = 1/(duration_job2 / duration_job1) = 1/(55/50) = 50/55 = 0.91

Nó không hoàn hảo như so sánh trước, nhưng chúng ta vẫn thấy hiệu suất giảm tương tự khi chúng ta mất chủ đề.

Bây giờ cho bit cuối cùng: tại sao chúng ta có hiệu suất tốt hơn với nhiều chủ đề hơn, đặc biệt. nhiều luồng hơn số lượng CPU?

Một tốt giải thích về sự khác biệt giữa lý song song (những gì chúng ta có được bằng cách chia lưu dữ liệu lên nhiều CPU) và đồng thời (những gì chúng ta nhận được khi chúng ta sử dụng nhiều chủ đề để làm việc trên một CPU duy nhất) được cung cấp trong bài viết tuyệt vời này bởi Rob Pike: Concurrency không song song .

Lời giải thích ngắn gọn là nếu một công việc Spark tương tác với hệ thống tệp hoặc mạng, CPU sẽ dành nhiều thời gian chờ đợi để giao tiếp với các giao diện đó và không mất nhiều thời gian thực sự "làm việc". Bằng cách cho các CPU đó hoạt động nhiều hơn 1 nhiệm vụ cùng một lúc, chúng sẽ tốn ít thời gian chờ đợi hơn và nhiều thời gian hơn để làm việc, và bạn thấy hiệu suất tốt hơn.


1
Giải thích thú vị và thuyết phục, tôi tự hỏi nếu bạn đưa ra dự đoán của mình rằng người thực thi có giới hạn 5 nhiệm vụ để đạt được thông lượng tối đa.
Đạt Nguyễn

Vì vậy, số 5 không phải là thứ tôi nghĩ ra: Tôi chỉ nhận thấy các dấu hiệu tắc nghẽn IO và đã đi tìm nơi những nút thắt đó có thể đến từ đâu.
turtlemonvh

8

Từ các tài nguyên tuyệt vời có sẵn tại trang gói Sparklyr của RStudio :

ĐỊNH NGH SPA SPARK :

Có thể hữu ích khi cung cấp một số định nghĩa đơn giản cho danh pháp Spark:

Nút : Một máy chủ

Worker Node : Một máy chủ là một phần của cụm và có sẵn để chạy các công việc Spark

Master Node : Máy chủ điều phối các nút Worker.

Executor : Một loại máy ảo bên trong một nút. Một nút có thể có nhiều Executor.

Driver Node : Node khởi tạo phiên Spark. Thông thường, đây sẽ là máy chủ nơi Sparklyr được đặt.

Driver (Executor) : Driver Node cũng sẽ hiển thị trong danh sách Executor.



1

Có một vấn đề nhỏ trong hai cấu hình đầu tiên tôi nghĩ. Các khái niệm về chủ đề và lõi như sau. Khái niệm về luồng là nếu các lõi là lý tưởng thì sử dụng lõi đó để xử lý dữ liệu. Vì vậy, bộ nhớ không được sử dụng đầy đủ trong hai trường hợp đầu tiên. Nếu bạn muốn đánh dấu băng ghế ví dụ này, hãy chọn các máy có hơn 10 lõi trên mỗi máy. Sau đó làm điểm đánh dấu.

Nhưng không cung cấp nhiều hơn 5 lõi cho mỗi người thực thi, sẽ có cổ chai về hiệu suất i / o.

Vì vậy, các máy tốt nhất để thực hiện đánh dấu băng ghế này có thể là các nút dữ liệu có 10 lõi.

Thông số kỹ thuật của nút máy dữ liệu: CPU: Core i7-4790 (# lõi: 10, # của luồng: 20) RAM: 32GB (8GB x 4) HDD: 8TB (2TB x 4)


0

Tôi nghĩ một trong những lý do chính là địa phương. Kích thước tệp đầu vào của bạn là 165G, các khối liên quan đến tệp chắc chắn được phân phối trên nhiều DataNodes, nhiều người thực thi có thể tránh sao chép mạng.

Hãy thử thiết lập số thực thi số khối bằng nhau, tôi nghĩ có thể nhanh hơn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.