Làm thế nào để tạo người dùng với việc sử dụng RAM hạn chế?


44

Vậy là tôi có RAM 4 GB + trao đổi 4GB. Tôi muốn tạo một người dùng với ram và trao đổi hạn chế: RAM 3 GB và trao đổi 1 GB. Là điều như vậy có thể? Có thể khởi động các ứng dụng có RAM hạn chế và trao đổi với chúng mà không cần tạo một người dùng riêng (và không cài đặt bất kỳ ứng dụng đặc biệt nào - chỉ có cấu hình máy chủ Debian / CentOS mặc định và không sử dụng sudo)?

Cập nhật:

Vì vậy, tôi đã mở terminall và gõ vào lệnh ulimit : ulimit -v 1000000nó sẽ giống như 976,6Mbgiới hạn. Tiếp theo tôi gọi ulimit -avà thấy giới hạn đó là "bật". Sau đó, tôi bắt đầu một số tập lệnh bash biên dịch và khởi động ứng dụng của mình nohup, một tập lệnh dài nohup ./cloud-updater-linux.sh >& /dev/null & ... nhưng sau một thời gian tôi thấy:

nhập mô tả hình ảnh ở đây

(sẽ ổn nếu không áp dụng giới hạn nào - nó đã tải xuống một số lib lớn và bắt đầu biên dịch nó.)

Nhưng tôi nghĩ rằng tôi đã áp dụng các giới hạn cho trình bao và tất cả các quy trình được khởi chạy với / từ nó với ulimit -v 1000000? Tôi đã làm gì sai? Làm thế nào để tạo một thiết bị đầu cuối và tất cả các quy trình phụ mà nó khởi chạy bị hạn chế về việc sử dụng ram?


1
Bạn không thể đặt giới hạn bộ nhớ cho toàn bộ người dùng, chỉ trên mỗi quy trình. Và bạn không thể phân biệt giữa RAM và sử dụng trao đổi. Nếu bạn muốn kiểm soát tốt hơn, hãy chạy các quy trình của người dùng trong một máy ảo.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles khá chắc chắn rằng các máy ảo chỉ sử dụng các nhóm và không gian tên hoặc các dẫn xuất của
RapidWebs

@RapidWebs không họ không. Họ chỉ mô phỏng lượng RAM được xác định trước và hệ điều hành khách sau đó quyết định cách phân bổ nó cho các quy trình.
Ruslan

Các thùng chứa (không phải máy ảo) sử dụng các nhóm, để hạn chế sử dụng bộ nhớ. Hạn chế bộ nhớ ảo không phải là một ý tưởng tốt; Một tiến trình có thể sử dụng nhiều bộ nhớ ảo, nhưng chỉ có thể sử dụng một ít RAM. Ví dụ, hệ thống của tôi có 34359738367 kB bộ nhớ ảo được phân bổ, nhưng ram ít hơn nhiều.
ctrl-alt-delor

Câu trả lời:


64

ulimitđược làm cho điều này. Bạn có thể thiết lập mặc định cho ulimitmỗi người dùng hoặc theo từng nhóm

/etc/security/limits.conf

ulimit -v KBYTESđặt kích thước bộ nhớ ảo tối đa. Tôi không nghĩ rằng bạn có thể cung cấp một lượng trao đổi tối đa. Đó chỉ là giới hạn về dung lượng bộ nhớ ảo mà người dùng có thể sử dụng.

Vì vậy, bạn limits.confsẽ có dòng (tối đa 4Gbộ nhớ)

luser  hard  as   4000000

CẬP NHẬT - Cgroup

Các giới hạn áp đặt bởi ulimitlimits.conflà trên mỗi quá trình. Tôi chắc chắn không rõ ràng về điểm đó.

Nếu bạn muốn giới hạn tổng dung lượng bộ nhớ mà người dùng sử dụng (đó là những gì bạn đã hỏi). Bạn muốn sử dụng cgroups .

Trong /etc/cgconfig.conf:

group memlimit {
    memory {
        memory.limit_in_bytes = 4294967296;
    }
}

Điều này tạo ra một cgroupgiới hạn bộ nhớ tối đa là 4GiB.

Trong /etc/cgrules.conf:

luser   memory   memlimit/

Điều này sẽ khiến tất cả các quy trình được chạy bởi luserđược chạy bên trong các memlimitnhóm được tạo trong cgconfig.conf.


điều đó có thể giải quyết được useraddkhông?
myWallJSON

4
@myWallJSON Không trực tiếp, nhưng bạn có thể ngay lập tức thêm nó vào giới hạn. Thông tin hoặc bạn có thể thiết lập một nhóm với các giới hạn nhất định trong giới hạn.
tưởng

1
Thật tuyệt vời! Tôi không biết bạn có thể làm điều này! Câu trả lời tuyệt vời +1
Yanick Girouard

1
@utopiabound: Đã cập nhật Q của tôi với một số dữ liệu tôi đã cố gắng sử dụng ulimit.
myWallJSON

1
@ f.ardelian Nâng cấp kernel. Đây là một bài viết về cách làm điều đó!
Daniel C. Sobral

4

Bạn không thể giới hạn mức sử dụng bộ nhớ ở cấp độ người dùng, ulimit có thể làm điều đó nhưng với một quy trình duy nhất.

Ngay cả khi sử dụng giới hạn cho mỗi người dùng /etc/security/limits.conf, người dùng có thể sử dụng tất cả bộ nhớ bằng cách chạy nhiều quy trình.

Nếu bạn thực sự muốn giới hạn tài nguyên, bạn cần sử dụng một công cụ quản lý tài nguyên, như RCapd được sử dụng bởi các dự án và khu vực thuộc Solaris.

Có một thứ dường như cung cấp các tính năng tương tự trên Linux mà bạn có thể điều tra: cgroups .


Chà, tôi cho rằng việc đặt giới hạn cho trình đăng nhập của người dùng hoặc một cái gì đó tương tự có thể được hiểu là "đặt giới hạn cho người dùng", vì tất cả các quy trình sẽ kế thừa từ trình bao đó?
Amn

1
@amn Nó sẽ không. Một người dùng có thể chỉ cần mở một vỏ đăng nhập mới để khắc phục giới hạn đó.
jlliagre

Phải, điều đó làm mất hiệu lực giả định của tôi.
Amn

3

cgroupslà cách đúng đắn để làm điều này, như các câu trả lời khác đã chỉ ra. Thật không may, không có giải pháp hoàn hảo cho vấn đề này, vì chúng ta sẽ đi vào bên dưới. Có một loạt các cách khác nhau để đặt giới hạn sử dụng bộ nhớ cgroup. Làm thế nào một người đi về việc làm cho phiên đăng nhập của người dùng tự động là một phần của một nhóm khác nhau tùy theo hệ thống. Red Hat có một số công cụ, và systemd cũng vậy .

memory.memsw.limit_in_bytesmemory.limit_in_bytesđặt giới hạn bao gồm và không bao gồm trao đổi, tương ứng. Nhược điểm memory.limit_in_byteslà nó đếm các tập tin được lưu trong bộ nhớ cache của nhân thay mặt cho các tiến trình trong nhóm so với hạn ngạch của nhóm. Ít bộ nhớ đệm hơn có nghĩa là truy cập nhiều đĩa hơn, do đó bạn có khả năng từ bỏ một số hiệu suất nếu hệ thống có sẵn một số bộ nhớ.

Mặt khác, memory.soft_limit_in_bytescho phép nhóm này vượt quá hạn ngạch, nhưng nếu kẻ giết OOM hạt nhân được gọi thì những nhóm đó vượt quá hạn ngạch của họ sẽ bị giết trước, theo logic. Tuy nhiên, nhược điểm của điều đó là có những tình huống cần một số bộ nhớ ngay lập tức và không có thời gian để kẻ giết người OOM tìm kiếm các quy trình để giết, trong trường hợp đó có thể thất bại trước các quy trình của người dùng vượt quá giới hạn bị giết

ulimittuy nhiên, hoàn toàn là công cụ sai cho việc này. ulimit đặt giới hạn cho việc sử dụng bộ nhớ ảo, gần như chắc chắn không phải là điều bạn muốn. Nhiều ứng dụng trong thế giới thực sử dụng bộ nhớ ảo nhiều hơn nhiều so với bộ nhớ vật lý. Hầu hết các thời gian chạy được thu gom rác (Java, Go) hoạt động theo cách này để tránh phân mảnh. Một chương trình "hello world" tầm thường trong C, nếu được biên dịch với trình khử trùng địa chỉ, có thể sử dụng 20TB bộ nhớ ảo. Phân bổ không dựa vào sbrk, chẳng hạn như jemalloc (là cấp phát mặc định cho Rust) hoặc tcmalloc, cũng sẽ có mức sử dụng bộ nhớ ảo vượt quá mức sử dụng vật lý của họ. Để hiệu quả, nhiều công cụ sẽ tập tin mmap, làm tăng mức sử dụng ảo nhưng không nhất thiết phải sử dụng vật lý. Tất cả các quy trình Chrome của tôi đều sử dụng 2TB bộ nhớ ảo. Tôi đang sử dụng máy tính xách tay với 8GB bộ nhớ vật lý. Bất kỳ cách nào người ta cố gắng thiết lập hạn ngạch bộ nhớ ảo ở đây đều sẽ phá vỡ Chrome, buộc Chrome phải vô hiệu hóa một số tính năng bảo mật dựa trên việc phân bổ (nhưng không sử dụng) số lượng lớn bộ nhớ ảo hoặc hoàn toàn không hiệu quả trong việc ngăn người dùng lạm dụng hệ thống .

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.