2009-02-23 7 views
36

Có cách nào để nói với Linux rằng nó không nên trao đổi bộ nhớ của một quá trình cụ thể với đĩa?Tôi có thể yêu cầu Linux không trao đổi bộ nhớ của một quy trình cụ thể không?

Ứng dụng Java của nó, vì vậy, lý tưởng là tôi hy vọng có cách để thực hiện điều này từ dòng lệnh.

Tôi biết rằng bạn có thể đặt swappiness toàn cầu thành 0, nhưng điều này là khôn ngoan?

+0

Unix được sử dụng để tôn vinh "bit dính" nếu bạn đã thực hiện "chmod + S" trên một ứng dụng, nhưng tôi không nghĩ rằng nó hoạt động nữa. –

+1

Xin lỗi, ý tôi là "chmod + t", nhưng tôi chỉ xem và Linux bỏ qua bit dính. –

+0

http://blogs.msdn.com/b/oldnewthing/archive/2005/06/07/426294.aspx – Hello71

Trả lời

22

Bạn có thể thực hiện việc này thông qua cuộc gọi hệ thống mlockall(2) trong Linux; điều này sẽ làm việc cho toàn bộ quá trình, nhưng hãy đọc về đối số bạn cần phải vượt qua.

Bạn có thực sự cần phải kéo toàn bộ nội dung vào trong lõi không? Nếu đó là một ứng dụng java, bạn có lẽ sẽ khóa toàn bộ JVM trong lõi. Tôi không biết một phương pháp dòng lệnh để làm điều này, nhưng bạn có thể viết một chương trình tầm thường để gọi fork, gọi mlockall, sau đó exec.

Bạn cũng có thể xem liệu một trong các thông báo mẫu truy cập trong số madvise(2) có đáp ứng được nhu cầu của bạn hay không. Tư vấn cho hệ thống con VM về một chiến lược phân trang tốt hơn có thể làm việc tốt hơn nếu nó có thể áp dụng cho bạn.

Lưu ý rằng một thời gian dài trước đây dưới SunOS, có một cơ chế tương tự như madvise được gọi là vadvise(2).

+0

@sanity bạn đã thử cái này chưa? Làm thế nào nó làm việc cho bạn? Tôi đang cân nhắc làm một việc tương tự. –

+6

["Ổ khóa bộ nhớ không được thừa hưởng bởi một đứa trẻ được tạo thông qua ngã ba (2) và được tự động loại bỏ (mở khóa) trong khi thực hiện (2) hoặc khi quá trình chấm dứt."] (Http://www.kernel.org/doc /man-pages/online/pages/man2/mlock.2.html) - cách tiếp cận ngã ba/mlock/exec sẽ không hoạt động – Mat

+0

@Mat có vẻ đúng ... OK ... điều gì đó giống như viết một cái gì đó để gọi qua JNI gọi mlockall là gì? Điều đó bắt đầu cảm thấy khá hackish mặc dù ... –

2

Bạn có thể thực hiện điều đó bởi họ mlock gia đình của các tòa nhà chọc trời. Tôi không chắc chắn, tuy nhiên, nếu bạn có thể làm điều đó cho một quá trình khác nhau.

+0

Tôi sẽ cẩn thận mặc dù tổng số bộ nhớ hệ thống bị khóa. Tôi nghi ngờ rằng bạn có thể hạ gục hệ thống thông qua tấn công nếu bạn không cẩn thận. –

2

Là người dùng siêu bạn có thể 'đẹp' nó ở cấp độ ưu tiên cao nhất -20 và hy vọng điều đó đủ để giữ cho nó không bị hoán đổi. Nó thường là. Số ưu tiên thấp hơn mức độ ưu tiên lên lịch. Người dùng bình thường không thể đẹp lên (tiêu cực)

+3

trừ khi tôi bị nhầm lẫn, điều này sẽ chỉ ảnh hưởng đến thời gian CPU mà quá trình được cấp, chứ không phải xu hướng của nó đối với việc sử dụng bộ nhớ chính. – intuited

+3

@intuited: Tôi tin rằng anh ta có nghĩa là hệ thống con VM cũng sẽ xem xét giá trị 'nice' để quyết định mức độ quan trọng của một quá trình và không trao đổi nó. Âm thanh hợp lý; Tôi không biết nếu Linux thực sự làm điều này, mặc dù. – sleske

+0

'ionice' cũng có thể hữu ích ở đây – fread2281

2

Ngoại trừ trường hợp cực kỳ bất thường, đặt câu hỏi này có nghĩa là bạn đang làm sai (tm).

Nghiêm túc, nếu Linux muốn trao đổi và bạn đang cố gắng giữ cho quy trình của mình trong bộ nhớ thì bạn đang đặt một yêu cầu không hợp lý trên hệ điều hành. Nếu ứng dụng của bạn quan trọng thì 1) mua thêm bộ nhớ, 2) xóa các ứng dụng/trình nền khác khỏi máy hoặc dành máy cho ứng dụng của bạn và/hoặc 3) đầu tư vào hệ thống phụ đĩa thực sự nhanh. Các bước này là hợp lý cho một ứng dụng quan trọng. Nếu bạn không thể biện minh cho họ, thì bạn có thể không thể biện minh cho bộ nhớ dây và cũng đang đói các quá trình khác.

+26

Nếu nó có liên quan mật mã, nó hoàn toàn hợp lý để muốn ở trong ký ức. Ví dụ, gnome-keyring mất một vài bước để giữ các bit quan trọng của chính nó khỏi việc hoán đổi. (Ngoài ra, quan sát hợp lý.) –

+1

Điểm tốt, Paul. Tôi cảm thấy rằng điều này đủ điều kiện như là một tình huống bất thường. – dwc

+2

Nó khá bình thường trong ngành ngân hàng và thẻ thanh toán với tất cả các yêu cầu mã hóa mạnh mẽ. –

1

Tại sao bạn muốn thực hiện việc này?
Nếu bạn đang cố gắng tăng hiệu suất của ứng dụng này thì có thể bạn đang đi sai hướng. Hệ điều hành sẽ trao đổi một quá trình để tăng bộ nhớ cho bộ nhớ cache đĩa - ngay cả khi có RAM miễn phí, hạt nhân biết rõ nhất (actauly các samrt guys đã viết lên lịch biết tốt nhất).
Nếu bạn có một quy trình cần đáp ứng (nó được hoán đổi trong khi không được sử dụng và bạn cần nó khởi động lại nhanh chóng) thì tốt nhất nên ưu tiên cao, mlock hoặc sử dụng hạt nhân thời gian thực có thể hữu ích.

2

Có tồn tại một lớp học của các ứng dụng mà bạn không bao giờ muốn họ để trao đổi . Một lớp như vậy là một cơ sở dữ liệu. Cơ sở dữ liệu sẽ sử dụng bộ nhớ như bộ nhớ cache và bộ đệm cho vùng đĩa của họ, và nó hoàn toàn không có ý nghĩa rằng những bao giờ được đưa vào trao đổi. Bộ nhớ cụ thể có thể chứa một số dữ liệu có liên quan không cần thiết trong một tuần cho đến một ngày khi khách hàng yêu cầu.Nếu không có bộ nhớ đệm/trao đổi, cơ sở dữ liệu đơn giản sẽ tìm thấy các hồ sơ có liên quan trên đĩa, mà sẽ được khá nhanh; nhưng với trao đổi, dịch vụ của bạn có thể đột nhiên mất nhiều thời gian để phản hồi.

mysqld bao gồm mã để sử dụng cuộc gọi hệ điều hành/hệ thống memlock. Trên Linux, kể từ ít nhất 2.6.9, cuộc gọi hệ thống này sẽ hoạt động đối với các quy trình không phải gốc có khả năng CAP_IPC_LOCK[1]. Khi sử dụng memlock(), quá trình vẫn phải hoạt động trong giới hạn của giới hạn LimitMEMLOCK. [2]. Một trong số ít những điều tốt đẹp về số systemd là bạn có thể cấp cho các quy trình mysqld những khả năng này mà không yêu cầu một chương trình đặc biệt. Nếu bạn cũng có thể thiết lập các quảng cáo như bạn mong đợi với ulimit. Dưới đây là một tập tin override cho mysqld mà không được bước cần thiết, trong đó có một vài người khác mà bạn có thể cần cho một quá trình như một cơ sở dữ liệu:

[Service] 
# Prevent mysql from swapping 
CapabilityBoundingSet=CAP_IPC_LOCK 

# Let mysqld lock all memory to core (don't swap) 
LimitMEMLOCK=-1 

# do not kills this process if low on memory 
OOMScoreAdjust=-900 

# Use higher io scheduling 
IOSchedulingClass=realtime  

Type=simple  
ExecStart= 
ExecStart=/usr/sbin/mysqld --memlock $MYSQLD_OPTS 

Note Các mysql cộng đồng tiêu chuẩn hiện tàu với Type=forking và thêm --daemonize trong tùy chọn dịch vụ trên đường dây ExecStart. Điều này vốn kém ổn định hơn so với phương pháp trên.

CẬP NHẬT Tôi không hài lòng với giải pháp này 100%. Sau vài ngày trong thời gian chạy, tôi nhận thấy quá trình này vẫn có số lượng hoán đổi khổng lồ! Kiểm tra /proc/XXXX/smaps, tôi lưu ý những điều sau:

  • Đóng góp lớn nhất của hoán đổi là từ một phân đoạn ngăn xếp! 437 MB và dao động. Điều này trình bày các vấn đề hiệu suất rõ ràng. Nó cũng cho thấy rò rỉ bộ nhớ dựa trên stack.
  • zero Trang bị khóa. Điều này cho biết tùy chọn memlock trong MySQL (hoặc Linux) bị hỏng. Trong trường hợp này, nó sẽ không quan trọng nhiều vì MySQL không thể ngăn chặn ngăn xếp.