Giới hạn các quá trình không vượt quá 10% mức sử dụng CPU


32

Tôi vận hành một hệ thống Linux có rất nhiều người dùng nhưng đôi khi xảy ra lạm dụng; trong đó người dùng có thể chạy một tiến trình duy nhất sử dụng tới hơn 80% CPU / Bộ nhớ.

Vì vậy, có cách nào để ngăn chặn điều này xảy ra bằng cách giới hạn lượng sử dụng CPU mà một quá trình có thể sử dụng (chẳng hạn đến 10%)? Tôi biết cpulimit, nhưng không may áp dụng giới hạn cho các quy trình tôi hướng dẫn để giới hạn (ví dụ: các quy trình đơn lẻ). Vì vậy, câu hỏi của tôi là, làm thế nào tôi có thể áp dụng giới hạn cho tất cả các quy trình và quy trình đang chạy sẽ được chạy trong tương lai mà không cần cung cấp id / path của họ chẳng hạn?


Bạn đang gặp vấn đề về hiệu suất? hay đó chỉ là những con số làm phiền bạn?
ctrl-alt-delor

@richard Vấn đề về hiệu năng, vì vậy đó là lý do tại sao tôi cố gắng giết / giới hạn / chấm dứt các quá trình dường như đang sử dụng nhiều CPU, nhưng tôi đã làm như vậy bằng cách viết một tập lệnh bash. Đây cũng là một máy ảo nếu điều đó có ích
Giovanni Mounir

2
Hãy cẩn thận với việc tiêu diệt các quy trình có thể là 100% trong thời gian rất ngắn, cả các quy trình hệ thống. Xem xét cpulimitkết hợp với kịch bản tìm kiếm của bạn. Có chính sách và khuyến nghị sử dụng cpulimit, sau đó tìm kiếm trên 10% và sau đó giới hạn ở mức 5% (vì vậy người dùng được khuyến khích sử dụng cpulimit). Đồng thời đảm bảo rằng bạn có thể phát hiện nhiều quy trình thêm tối đa 10% cho một người dùng.
ctrl-alt-delor

@richard Cảm ơn Richard vì tất cả những bình luận khá hữu ích này! Họ đã giúp tôi rất nhiều! Đề xuất sử dụng của bạn cpulimitlà cách tốt hơn so với việc giết quá trình vì nó có thể được người dùng khởi động lại sau này (như được nêu trong một trong những bình luận của bạn). Cảm ơn bạn!
Giovanni Mounir

Câu trả lời:


20

Mặc dù nó có thể là một sự lạm dụng cho bộ nhớ, nhưng nó không phải là CPU: khi CPU không hoạt động, một quá trình đang chạy (bằng cách "chạy", tôi có nghĩa là quá trình không chờ I / O hoặc một cái gì khác) sẽ diễn ra 100% thời gian CPU theo mặc định. Và không có lý do để thực thi một giới hạn.

Bây giờ, bạn có thể thiết lập các ưu tiên nhờ nice. Nếu bạn muốn chúng áp dụng cho tất cả các quy trình cho một người dùng nhất định, bạn chỉ cần đảm bảo rằng vỏ đăng nhập của anh ta được chạy với nice: các tiến trình con sẽ kế thừa nicegiá trị. Điều này phụ thuộc vào cách người dùng đăng nhập. Xem ưu tiên đăng nhập ssh (đẹp) chẳng hạn.

Ngoài ra, bạn có thể thiết lập máy ảo. Thật vậy, việc đặt giới hạn cho mỗi quy trình không có ý nghĩa gì vì người dùng có thể bắt đầu nhiều quy trình, lạm dụng hệ thống. Với một máy ảo, tất cả các giới hạn sẽ là toàn cầu đối với máy ảo.

Một giải pháp khác là đặt /etc/security/limits.confgiới hạn; xem trang giới hạn. thông tin (5). Chẳng hạn, bạn có thể đặt thời gian CPU tối đa cho mỗi lần đăng nhập và / hoặc số lượng quy trình tối đa cho mỗi lần đăng nhập. Bạn cũng có thể đặt maxloginsthành 1 cho mỗi người dùng.


1
@GiovanniMounir Ý tôi là: một máy ảo cho mỗi người dùng.
vinc17

1
Tôi thấy, nhưng thật không may, điều này sẽ tiêu tốn tài nguyên và không thực sự hữu ích cho mục đích của tôi, vì người dùng có thể yêu cầu sử dụng một số gói phát triển chung và tôi sẽ không cài đặt nó trên mỗi máy mới; Tôi nghĩ tốt hơn là cứ để nó như vậy và thực hiện giám sát tự động bằng một tập lệnh bash.
Giovanni Mounir

1
@GiovanniMounir Bạn có thể chia sẻ phân vùng giữa một số máy ảo.
vinc17

@GiovanniMounir Bạn có thể sử dụng LXC hoặc Docker để giảm chi phí ảo hóa xuống gần như bằng không. Ngoài ra "thích" không phải là một lý do mạnh mẽ. Ví dụ: tôi sẽ đi cùng với giải pháp của bạn nếu bạn đang quản lý máy chủ PHP được chia sẻ vì thực hiện LXC hoặc Máy ảo sẽ yêu cầu viết lại phần mềm được cấp phép $ 15 / $ 5 quá mức cần thiết.
Pooyan Khosravi

sự hiểu biết của tôi là tốt đẹp chỉ đặt CPU tương đối so với các quá trình khác. Nếu không có quá trình nào khác đang sử dụng CPU, thì quá trình của bạn sẽ sử dụng CPU 100%, không giới hạn ở mức 10%.
johny tại sao

25

đẹp / đổi mới

nice là một công cụ tuyệt vời để tinh chỉnh 'một lần' cho một hệ thống.

 nice COMMAND

cpulimit

cpulimit nếu bạn cần chạy một công việc chuyên sâu về CPU và có thời gian CPU miễn phí là điều cần thiết cho khả năng đáp ứng của hệ thống.

cpulimit -l 50 COMMAND

nhóm

cgroups áp dụng các giới hạn cho một tập hợp các quy trình, thay vì chỉ một

cgcreate -g cpu:/cpulimited
cgset -r cpu.shares=512 cpulimited
cgexec -g cpu:cpulimited COMMAND_1
cgexec -g cpu:cpulimited COMMAND_2
cgexec -g cpu:cpulimited COMMAND_3

Tài nguyên

http://blog.scoutapp.com/articles/2014/11/04/restricting- Process-cpu-usage-USE-nice-cpulimit-and-cgroups


5
Đối với những người đang tìm cách đặt giới hạn cứng cho việc sử dụng CPU, ngay cả khi không có quá trình nào khác đang chạy, hãy xem cpu.cfs_quota_ustham số (xem hướng dẫn )
Diego

các nhóm dễ sử dụng hơn nhờ các chỉ thị systemd ... tạo một đơn vị hoặc hệ thống hoặc người dùng cho mục đích đó là lựa chọn tốt nhất
Yves Martin

cho một quá trình hoạt động, ví dụ:sudo cgclassify -g cpu:cpulimited 2315444
Sức mạnh Bảo Bình

1
sự hiểu biết của tôi là tốt đẹp chỉ đặt CPU tương đối so với các quá trình khác. Nếu không có quá trình nào khác đang sử dụng CPU, thì quá trình của bạn sẽ sử dụng CPU 100%, không giới hạn ở mức 10%.
johny tại sao

10

Bạn đã nhìn vào cgroups? Có một số thông tin trên Arch Wiki về họ. Đọc phần về cpu.shares, có vẻ như nó đang làm những gì bạn cần và chúng có thể hoạt động ở cấp độ người dùng, do đó bạn có thể giới hạn tất cả các quy trình người dùng cùng một lúc.


Cgroup là con đường để đi, mặc dù. Tôi cũng chạy (nhiều) máy chủ dùng chung và chúng tôi sử dụng các nhóm để giới hạn số lượng lõi tối đa mà toàn bộ phiên đăng nhập có thể sử dụng. Bằng cách này, nếu người tiếp tục bắt đầu các quy trình mới, mỗi người sẽ có một lát nhỏ hơn. Tương tự cho việc sử dụng bộ nhớ. Bạn có thể có người dùng tự động đưa vào một nhóm với pam_cgroups và dịch vụ cgrulesengd. Bạn có thể sử dụng 'mẫu' trong tệp cgconfig để đặt từng người dùng vào nhóm riêng của họ. cgrulesengd hoạt động giống như tập lệnh của bạn, ngoại trừ thay vì giết các tiến trình, nó chỉ đảm bảo mỗi tiến trình nằm trong nhóm đúng.
jsbillings

Ngay cả khi bạn không sử dụng các nhóm để hạn chế sử dụng tài nguyên, bạn có thể sử dụng nó để đánh giá số lượng tài nguyên mà một cá nhân đang sử dụng, bằng cách xem tệp 'stat' cho mỗi tài nguyên, sau đó sử dụng thông tin đó cho tập lệnh 5 phút của bạn.
jsbillings

3

Đối với bộ nhớ, những gì bạn đang tìm kiếm là ulimit -v. Lưu ý rằng ulimitđược kế thừa bởi các tiến trình con, vì vậy nếu bạn áp dụng nó vào vỏ đăng nhập của người dùng tại thời điểm đăng nhập, nó sẽ áp dụng cho tất cả các quy trình của anh ta.

Nếu tất cả người dùng của bạn sử dụng bashlàm vỏ đăng nhập, việc đặt dòng sau vào /etc/profilesẽ khiến tất cả các quy trình người dùng có giới hạn cứng là 1 gigabyte (chính xác hơn là một triệu kilobyte):

ulimit -vH 1000000

Tùy chọn này Hđảm bảo rằng đó là một giới hạn cứng, nghĩa là, người dùng không thể thiết lập lại nó sau đó. Tất nhiên người dùng vẫn có thể lấp đầy bộ nhớ bằng cách bắt đầu đủ nhiều quá trình cùng một lúc.

Đối với các shell khác, bạn sẽ phải tìm hiểu các tệp khởi tạo nào chúng đọc thay thế (và lệnh nào khác thay vì ulimitchúng sử dụng).

Đối với CPU, những gì bạn muốn dường như không có ý nghĩa đối với tôi. Điều gì sẽ là việc sử dụng cho phép 90% CPU không được sử dụng khi chỉ có một tiến trình đang chạy? Tôi nghĩ những gì bạn thực sự muốn là nice(và có thể ionice). Lưu ý rằng, như ulimit, nicecác giá trị được kế thừa bởi các tiến trình con, do đó, áp dụng nó vào vỏ đăng nhập tại thời điểm đăng nhập là đủ. Tôi đoán điều đó cũng áp dụng cho ionicenhưng tôi không chắc chắn.


Cảm ơn đề nghị bộ nhớ! Có bất kỳ cơ hội nào bạn có thể chỉ cho tôi một ví dụ để áp dụng điều này cho shell đăng nhập của người dùng tại thời điểm đăng nhập không? Tôi không thực sự chắc chắn làm thế nào để làm điều này. Tôi cũng xin lỗi vì không đủ rõ ràng; những gì tôi đang cố gắng không cho phép bất kỳ quá trình nào sử dụng hơn 10% CPU. Vì vậy, bạn có nghĩ rằng nicesẽ đủ tốt để làm điều này? Nếu vậy, bạn có nghĩ rằng bạn có thể chỉ cho tôi một ví dụ để đạt được điều này?
Giovanni Mounir

Tôi vẫn không có ý định giữ cho CPU không hoạt động 90% khi chỉ có một tiến trình đang chạy.
celtschk

1
Nếu hiện tại có ít hơn 10 tiến trình đang chạy đồng thời (và bằng cách chạy tôi có nghĩa là thực sự đang chạy, không chỉ chờ đầu vào của người dùng hoặc I / O của đĩa), thì hầu như đảm bảo rằng một trong số chúng sẽ có hơn 10% CPU. Nếu không, CPU sẽ gần như không hoạt động. Và nếu bạn chỉ giết bất kỳ quy trình nào vượt quá 10%, tôi chắc chắn bạn sẽ có nhiều người dùng muốn giết bạn. Hoặc ít nhất, sẽ cố gắng để bạn được thay thế bởi một người có manh mối về ý nghĩa của những con số đó, bởi vì bạn dường như không.
celtschk

Trái ngược với nhận xét của @celtschk, nếu có từ 11 quy trình trở lên đang chạy (ràng buộc cpu), thì chúng sẽ ở mức dưới 9,09%. Vì vậy, nếu tôi là người dùng hệ thống cấm sử dụng cpu trên 10%, tôi có thể chạy 11 quy trình trở lên và ẩn dưới radar.
ctrl-alt-delor

@richard Bạn nói đúng, có lẽ sẽ tốt hơn nếu tập lệnh sẽ tổng hợp tổng bộ nhớ / CPU được sử dụng bởi người dùng và sau đó chấm dứt tất cả các quy trình của người dùng này khi tỷ lệ phần trăm đạt đến một mức cụ thể (do đó cũng sẽ đăng nhập anh ta ra)
Giovanni Mounir

3

Vì bạn đang nói rằng cpulimit sẽ không được thực tế trong trường hợp của bạn, sau đó tôi đề nghị bạn nhìn vào thoải mái , renice , và taskset , có thể đến gần với những gì bạn muốn đạt được, mặc dù taskset cho phép để thiết lập CPU ái lực của một quá trình, vì vậy nó có thể không hữu ích ngay lập tức trong trường hợp của bạn.


1
nicerenice? Thật tuyệt! Tôi đã xem các trang hướng dẫn của họ, nhưng tôi vẫn không nghĩ họ có thể giúp với điều này vì bạn vẫn phải đặt ID quy trình. Tuy nhiên, nếu bạn có thể cho tôi một ví dụ liên quan đến các gói này để áp dụng giới hạn cho tất cả các quy trình đang chạy / quy trình trong tương lai sẽ rất tuyệt vời!
Giovanni Mounir

1

Vì thẻ của bạn có centos, bạn có thể sử dụng systemd.

Ví dụ: nếu bạn muốn giới hạn người dùng với ID của 1234:

sudo systemctl edit --force user-1234.slice

Sau đó nhập và lưu này:

[Slice] CPUQuota=10%

Lần tới khi người dùng đăng nhập, nó sẽ ảnh hưởng.

Trang Man: systemctl, systemd.slice, systemd.resource-control...


0

Nếu bạn muốn giới hạn các quy trình đã được bắt đầu, bạn sẽ phải thực hiện từng bước một bằng PID, nhưng bạn có thể có một tập lệnh bó để làm điều đó như quy trình dưới đây:

#!/bin/bash
LIMIT_PIDS=$(pgrep tesseract)   # PIDs in queue replace tesseract with your name
echo $LIMIT_PIDS
for i in $LIMIT_PIDS
do
    cpulimit -p $i -l 10 -z &   # to 10 percent processes
done

Trong trường hợp của tôi pypdfocrkhởi động sự tham lam tesseract.

Ngoài ra trong một số trường hợp, CPU của bạn khá tốt, bạn chỉ có thể sử dụng renicenhư thế này:

watch -n5 'pidof tesseract | xargs -L1 sudo renice +19'
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.