Làm thế nào để điều chỉnh số lượng trình thực thi tia lửa, lõi và bộ nhớ trình thực thi?


84

Bạn bắt đầu điều chỉnh các thông số được đề cập ở trên từ đâu. Chúng ta bắt đầu với bộ nhớ trình thực thi và lấy số lượng trình thực thi, hay chúng tôi bắt đầu với lõi và lấy số trình thực thi. Tôi đã theo liên kết . Tuy nhiên đã có một ý tưởng cao cấp, nhưng vẫn không biết bắt đầu như thế nào hoặc từ đâu và đi đến kết luận cuối cùng.

Câu trả lời:


206

Câu trả lời sau bao gồm 3 khía cạnh chính được đề cập trong tiêu đề - số lượng trình thực thi, bộ nhớ trình thực thi và số lõi. Có thể có các thông số khác như bộ nhớ trình điều khiển và những thông số khác mà tôi không đề cập đến khi trả lời này, nhưng tôi muốn bổ sung trong tương lai gần.

Phần cứng Case 1 - 6 nút và mỗi nút 16 lõi, RAM 64 GB

Mỗi trình thực thi là một cá thể JVM. Vì vậy, chúng ta có thể có nhiều người thực thi trong một nút

1 lõi đầu tiên và 1 GB là cần thiết cho OS và Hadoop Daemons, vì vậy có sẵn 15 lõi, RAM 63 GB cho mỗi nút

Bắt đầu với cách chọn số lõi :

Number of cores = Concurrent tasks as executor can run 

So we might think, more concurrent tasks for each executor will give better performance. But research shows that
any application with more than 5 concurrent tasks, would lead to bad show. So stick this to 5.

This number came from the ability of executor and not from how many cores a system has. So the number 5 stays same
even if you have double(32) cores in the CPU.

Số người thi hành:

Coming back to next step, with 5 as cores per executor, and 15 as total available cores in one Node(CPU) - we come to 
3 executors per node.

So with 6 nodes, and 3 executors per node - we get 18 executors. Out of 18 we need 1 executor (java process) for AM in YARN we get 17 executors

This 17 is the number we give to spark using --num-executors while running from spark-submit shell command

Bộ nhớ cho mỗi người thực thi:

From above step, we have 3 executors  per node. And available RAM is 63 GB

So memory for each executor is 63/3 = 21GB. 

However small overhead memory is also needed to determine the full memory request to YARN for each executor.
Formula for that over head is max(384, .07 * spark.executor.memory)

Calculating that overhead - .07 * 21 (Here 21 is calculated as above 63/3)
                            = 1.47

Since 1.47 GB > 384 MB, the over head is 1.47.
Take the above from each 21 above => 21 - 1.47 ~ 19 GB

So executor memory - 19 GB

Số cuối cùng - Người thực thi - 17, Lõi 5, Bộ nhớ người thực thi - 19 GB


Phần cứng Case 2: Cùng 6 nút, 32 lõi, 64 GB

5 giống nhau đối với đồng thời tốt

Số người thực thi cho mỗi nút = 32/5 ~ 6

Vì vậy, tổng số người thực thi = 6 * 6 Nút = 36. Sau đó, số cuối cùng là 36 - 1 cho AM = 35

Bộ nhớ của người thực thi là: 6 người thực thi cho mỗi nút. 63/6 ~ 10. Trên đầu là .07 * 10 = 700 MB. Vì vậy, làm tròn thành 1GB tính trên đầu, chúng tôi nhận được 10-1 = 9 GB

Số cuối cùng - Người thực thi - 35, Lõi 5, Bộ nhớ người thực thi - 9 GB


Trường hợp 3

Các tình huống trên bắt đầu với việc chấp nhận số lượng lõi là cố định và di chuyển đến # trình thực thi và bộ nhớ.

Bây giờ đối với trường hợp đầu tiên, nếu chúng tôi nghĩ rằng chúng tôi không cần 19 GB và chỉ cần 10 GB là đủ, thì sau đây là các con số:

lõi 5 # người thực thi cho mỗi nút = 3

Ở giai đoạn này, điều này sẽ dẫn đến 21 và sau đó là 19 theo phép tính đầu tiên của chúng tôi. Nhưng vì chúng tôi nghĩ rằng 10 là ổn (giả sử ít chi phí), nên chúng tôi không thể chuyển số người thực thi trên mỗi nút thành 6 (như 63/10). Trở thành với 6 người thực thi mỗi nút và 5 lõi, nó giảm xuống 30 lõi cho mỗi nút, khi chúng ta chỉ có 16 lõi. Vì vậy, chúng ta cũng cần thay đổi số lượng lõi cho mỗi trình thực thi.

Vì vậy, tính toán lại,

Phép thuật số 5 đến 3 (bất kỳ số nào nhỏ hơn hoặc bằng 5). Vì vậy, với 3 lõi và 15 lõi khả dụng - chúng tôi nhận được 5 người thực thi trên mỗi nút. Vì vậy (5 * 6 -1) = 29 người thực thi

Vì vậy, bộ nhớ là 63/5 ~ 12. Trên đầu là 12 * .07 = .84 Vì vậy, bộ nhớ thực thi là 12 - 1 GB = 11 GB

Con số cuối cùng là 29 trình thực thi, 3 lõi, bộ nhớ thực thi là 11 GB


Phân bổ động:

Lưu ý: Giới hạn trên cho số lượng người thực thi nếu phân bổ động được bật. Vì vậy, điều này nói rằng ứng dụng spark có thể ăn hết tài nguyên nếu cần. Vì vậy, trong một cụm nơi bạn có các ứng dụng khác đang chạy và chúng cũng cần lõi để chạy các tác vụ, hãy đảm bảo rằng bạn thực hiện điều đó ở cấp độ cụm. Ý tôi là bạn có thể phân bổ số lượng lõi cụ thể cho YARN dựa trên quyền truy cập của người dùng. Vì vậy, bạn có thể tạo spark_user có thể và sau đó cung cấp lõi (tối thiểu / tối đa) cho người dùng đó. Các giới hạn này dành cho việc chia sẻ giữa spark và các ứng dụng khác chạy trên YARN.

spark.dynamicAllocation.enabled - Khi điều này được đặt thành true - Chúng tôi không cần đề cập đến các trình thực thi. Lý do là dưới đây:

Số tham số tĩnh mà chúng tôi cung cấp tại spark-submit là cho toàn bộ thời gian công việc. Tuy nhiên, nếu phân bổ động đi vào hình ảnh, sẽ có các giai đoạn khác nhau như

Bắt đầu bằng gì:

Số lượng trình thực thi ban đầu ( spark.dynamicAllocation.initialExecutor ) để bắt đầu

Bao nhiêu :

Sau đó dựa trên tải (nhiệm vụ đang chờ xử lý) số lượng để yêu cầu. Đây cuối cùng sẽ là những con số mà chúng tôi đưa ra khi gửi spark theo cách tĩnh. Vì vậy, một khi số người thực thi ban đầu được đặt, chúng ta chuyển đến số min ( spark.dynamicAllocation.minExecutor ) và số max ( spark.dynamicAllocation.maxExecutor ).

Khi nào yêu cầu hoặc đưa ra:

Khi nào chúng tôi yêu cầu trình thực thi mới ( spark.dynamicAllocation.schedulerBacklogTimeout ) - Đã có những tác vụ đang chờ xử lý trong khoảng thời gian này. vì vậy yêu cầu. số lượng người thi hành được yêu cầu trong mỗi vòng tăng theo cấp số nhân so với vòng trước. Ví dụ: một ứng dụng sẽ thêm 1 người thực thi trong vòng đầu tiên và sau đó là 2, 4, 8, v.v. trong các vòng tiếp theo. Tại một điểm cụ thể, giá trị tối đa ở trên đi vào hình ảnh

khi nào chúng tôi cho đi một trình thực thi ( spark.dynamicAllocation.executorIdleTimeout ) -

Vui lòng sửa cho tôi nếu tôi bỏ lỡ bất cứ điều gì. Trên đây là hiểu biết của tôi dựa trên blog tôi đã chia sẻ trong câu hỏi và một số tài nguyên trực tuyến. Cảm ơn bạn.

Người giới thiệu:


2
Tôi đã đọc ở đâu đó chỉ có một trình thực thi cho mỗi nút ở chế độ độc lập, bất kỳ ý tưởng nào về điều đó? Tôi không thấy nó được đề cập trong câu trả lời của bạn.
jangorecki

2
Trong một cụm độc lập, theo mặc định, chúng tôi nhận được một trình thực thi cho mỗi nhân viên. Chúng tôi cần chơi với spark.executor.cores và một nhân viên có đủ lõi để có nhiều hơn một trình thực thi.
Ramzy

Tôi thấy nhân viên của mình sử dụng tất cả 32 lõi mà không cần thiết lập spark.executor.cores, vì vậy, nó có thể sử dụng tất cả các lõi có sẵn theo mặc định.
jangorecki

Vâng, mặc định cho các lõi là vô hạn như họ nói. Vì vậy, spark có thể sử dụng tất cả các lõi có sẵn trừ khi bạn chỉ định.
Ramzy

2
@Ramzy Tôi nghĩ cần lưu ý rằng ngay cả với phân bổ động, bạn vẫn nên chỉ định spark.executor.cores để xác định kích thước của từng trình thực thi mà Spark sẽ phân bổ. Mặt khác, bất cứ khi nào Spark phân bổ một trình thực thi mới cho ứng dụng của bạn, nó sẽ phân bổ toàn bộ một nút (nếu có), ngay cả khi tất cả những gì bạn cần chỉ là năm lõi nữa.
Dan Markhasin 19/12/16

6

Ngoài ra, nó phụ thuộc vào trường hợp sử dụng của bạn, một tham số cấu hình quan trọng là:

spark.memory.fraction(Một phần (không gian heap - 300MB) được sử dụng để thực thi và lưu trữ) từ http://spark.apache.org/docs/latest/configuration.html#memory-management .

Nếu bạn không sử dụng bộ nhớ cache / kiên trì, hãy đặt nó thành 0,1 để bạn có tất cả bộ nhớ cho chương trình của mình.

Nếu bạn sử dụng bộ nhớ cache / tồn tại, bạn có thể kiểm tra bộ nhớ được lấy bởi:

sc.getExecutorMemoryStatus.map(a => (a._2._1 - a._2._2)/(1024.0*1024*1024)).sum

Bạn đọc dữ liệu từ HDFS hay từ HTTP?

Một lần nữa, việc điều chỉnh phụ thuộc vào trường hợp sử dụng của bạn.


Bạn có biết lệnh map sẽ như thế nào khi sử dụng pyspark không? Tôi sử dụng sc._jsc.sc (). GetExecutorMemoryStatus () để lấy trạng thái người thi hành, nhưng không thể làm gì với những gì nó trả về ...
Thomas

1
Xin lỗi @Thomas Decaux , nhưng ý bạn là cài đặt spark.memory.storageFraction=0.1? Bởi vì AFAIK spark.memory.fractionquyết định dung lượng bộ nhớ được sử dụng Sparkcho cả quá trình thực thi và lưu trữ (bạn đã đề cập đến điều đó) và chỉ spark.memory.storageFractionbộ nhớ (khả dụng để lưu trữ + thực thi) là miễn nhiễm khỏi việc loại bỏ bộ nhớ cache . Vui lòng xem liên kết này
y2k-shubham

@Thomas Nếu tại ứng dụng của tôi, tôi chỉ có duy nhất (StorageLevel.DISK_ONLY) so với tùy chọn này cũng có thể áp dụng phải không? Nó chỉ ảnh hưởng đến phần bộ nhớ, nhưng không ảnh hưởng đến bất kỳ sự cố tràn đĩa nào?
jk1
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.