Giới hạn kích thước bộ đệm bộ đệm trong Linux


25

Có cách nào để nói với nhân Linux chỉ sử dụng một tỷ lệ bộ nhớ nhất định cho bộ đệm bộ đệm không? Tôi biết /proc/sys/vm/drop_cachescó thể được sử dụng để xóa bộ nhớ cache tạm thời, nhưng có bất kỳ cài đặt cố định nào ngăn nó phát triển lên hơn 50% bộ nhớ chính không?

Lý do tôi muốn làm điều này là vì tôi có một máy chủ chạy Ceph OSD liên tục phục vụ dữ liệu từ đĩa và quản lý để sử dụng toàn bộ bộ nhớ vật lý làm bộ đệm bộ đệm trong vài giờ. Đồng thời, tôi cần chạy các ứng dụng sẽ phân bổ một lượng lớn (vài 10 GB GB) bộ nhớ vật lý. Trái với suy nghĩ phổ biến (xem lời khuyên đưa ra gần như tất cả các câu hỏi liên quan đến bộ đệm bộ đệm), việc tự động giải phóng bộ nhớ bằng cách loại bỏ các mục bộ nhớ cache sạch không phải là ngay lập tức: bắt đầu ứng dụng của tôi có thể mất đến một phút khi bộ đệm bộ đệm đầy ( *), trong khi sau khi xóa bộ đệm (sử dụng echo 3 > /proc/sys/vm/drop_caches), cùng một ứng dụng bắt đầu gần như ngay lập tức.

(*) Trong thời gian khởi động này, ứng dụng bị lỗi trong bộ nhớ mới nhưng dành 100% thời gian cho kernel, theo Vtune trong một chức năng được gọi pageblock_pfn_to_page. Chức năng này dường như có liên quan đến việc nén bộ nhớ cần thiết để tìm các trang lớn, điều này khiến tôi tin rằng thực sự sự phân mảnh là vấn đề.


1
Có một cái gì đó gọi là phân tầng bộ đệm. ceph osd pool set {cacheptool docs.ceph.com/docs/master/rados/operations/cache-tiering
Michael D.

2
Vì vấn đề này rõ ràng chỉ ảnh hưởng đến việc khởi động các ứng dụng cần nhiều bộ nhớ, nên có thể bạn có thể khởi động ứng dụng thông qua một tập lệnh xóa bộ nhớ cache trước khi thực sự khởi động chúng. Có lẽ điều này khởi động chúng nhanh hơn trong khi vẫn để quản lý bộ đệm vào kernel trong khi chúng đang chạy.
Bình minh

Câu trả lời:


14

Nếu bạn không muốn một giới hạn tuyệt đối mà chỉ cần nhấn kernel để xả bộ đệm nhanh hơn, bạn nên xem xét vm.vfs_cache_pressure

Biến này kiểm soát xu hướng của kernel để lấy lại bộ nhớ được sử dụng để lưu trữ bộ đệm của VFS, so với pagecache và trao đổi. Việc tăng giá trị này làm tăng tốc độ lấy lại bộ đệm VFS.

Phạm vi từ 0 đến 200. Di chuyển về phía 200 để có áp suất cao hơn. Mặc định được đặt ở 100. Bạn cũng có thể phân tích việc sử dụng bộ nhớ của mình bằng slabtoplệnh. Trong trường hợp của bạn, giá trị dentry*_inode_cachephải cao.

Nếu bạn muốn một giới hạn tuyệt đối, bạn nên tìm kiếm cgroups. Đặt máy chủ Ceph OSD trong một nhóm và giới hạn bộ nhớ tối đa có thể sử dụng bằng cách đặt memory.limit_in_bytestham số cho nhóm đó.

memory.memsw.limit_in_bytesđặt số tiền tối đa cho tổng bộ nhớ và sử dụng trao đổi. Nếu không có đơn vị nào được chỉ định, giá trị được hiểu là byte. Tuy nhiên, có thể sử dụng hậu tố để biểu thị các đơn vị lớn hơn - k hoặc K cho kilobyte, m hoặc M cho Megabyte và g hoặc G cho Gigabyte.

Tài liệu tham khảo:

[1] - Điều chỉnh hạt nhân GlusterFS Linux

[2] - Hướng dẫn quản lý tài nguyên của RHEL 6


1
Một nhóm với limit_in_bytestập hợp dường như để làm điều đó. Cảm ơn!
Wim

4
Tôi nghĩ rằng vfs_cache_pressurechỉ xóa bộ nhớ cache và inode, và không có gì để làm với bộ đệm bộ đệm.
kawing-chiu

Tăng vfs_cache_pressureở trên 100có thể giúp ích trong trường hợp bạn không có đủ RAM cho khối lượng công việc của mình. Nó sẽ làm giảm việc sử dụng RAM nhưng sẽ khiến hiệu năng I / O kém hơn nói chung.
Mikko Rantalainen

3

Tôi không biết về A% nhưng, Bạn có thể đặt giới hạn thời gian để nó giảm xuống sau x số phút.

Đầu tiên trong một thiết bị đầu cuối

sync && echo 3 | sudo tee /proc/sys/vm/drop_caches

Để xóa bộ nhớ cache hiện tại.

Đặt nó là cron-job Nhấn Alt-F2, gõ gksudo gedit /etc/crontab, sau đó Thêm dòng này ở gần cuối.

 */15 *    * * *   root    sync && echo 3 > /proc/sys/vm/drop_caches

Điều này làm sạch cứ sau 15 phút. Bạn có thể đặt thành 1 hoặc 5 phút nếu bạn thực sự muốn bằng cách thay đổi tham số đầu tiên thành * hoặc * / 5 thay vì * / 15

Để xem RAM miễn phí của bạn, ngoại trừ bộ đệm:

free -m | sed -n -e '3p' | grep -Po "\d+$

Tôi cảm thấy ở đây một chút dư thừa. Theo như tôi biết, 3 > drop_cachesbao gồm hành vi củasync
andras.tim

1
@ andras.tim no - đồng bộ ghi các trang bẩn vào đĩa, 3 đến drop_caches chỉ lấy lại / giải phóng bộ nhớ được sử dụng bởi các trang sạch và bộ nhớ cache khác. bạn không phải chạy đồng bộ nhưng nếu bạn làm thế, nhiều bộ nhớ sẽ sạch hơn thay vì bẩn và nhiều bộ nhớ sẽ được giải phóng khi bạn thả bộ nhớ cache
Daniel S. Sterling

2

Tôi nghĩ linh cảm của bạn ở cuối câu hỏi của bạn đang đi đúng hướng. Tôi nghi ngờ một trong hai trang di chuyển phân bổ bộ nhớ nhận biết A, NUMA giữa các CPU hoặc B, nhiều khả năng là mã chống phân mảnh của các vòng đệm trong suốt đang cố gắng tìm các vùng liền kề, liên kết.

Ôm và ôm trong suốt đã được xác định cho cả hai cải tiến hiệu suất được đánh dấu trên khối lượng công việc nhất định và chịu trách nhiệm tiêu thụ một lượng lớn thời gian CPU mà không mang lại nhiều lợi ích.

Sẽ hữu ích để biết hạt nhân nào bạn đang chạy, nội dung của / Proc / meminfo (hoặc ít nhất là các giá trị HugePages_ *.), Và, nếu có thể, nhiều hơn trong số các tham chiếu trang trình bày hồ sơ vtune profiler pageblock_pfn_to_page ().

Ngoài ra, nếu bạn thưởng thức dự đoán của mình, hãy thử tắt chức năng chống phân mảnh hugepage với:

echo 'never'> / sys / kernel / mm / suốt_hugepage / defrag

(nó có thể là cái này thay vào đó, tùy thuộc vào kernel của bạn :)

echo 'never'> / sys / kernel / mm / redhat_transparent_hugepage / defrag

Cuối cùng, ứng dụng này có sử dụng nhiều hàng chục hợp đồng ram mà bạn đã viết không? Ngôn ngữ nào?

Vì bạn đã sử dụng thuật ngữ "lỗi trong các trang bộ nhớ", tôi đoán bạn đã đủ quen thuộc với thiết kế vận hành và bộ nhớ ảo. Tôi đấu tranh để hình dung một tình huống / ứng dụng sẽ bị lỗi rất nghiêm trọng đến mức không đọc được nhiều I / O - hầu như luôn luôn từ bộ đệm bộ đệm mà bạn đang cố gắng hạn chế.

(Nếu bạn tò mò, hãy xem các cờ mmap (2) như MAP_ANONYMOUS và MAP_POPULATE và mincore (2) có thể được sử dụng để xem trang ảo nào thực sự có trang vật lý được ánh xạ.)

Chúc may mắn!


2

Nếu Ceph OSD là một quy trình riêng biệt, bạn có thể sử dụng các nhóm để kiểm soát tài nguyên được sử dụng theo quy trình:

Tạo một nhóm có tên như nhóm1 với giới hạn bộ nhớ (ví dụ: 50 GB, các giới hạn khác như CPU ​​được hỗ trợ, ví dụ CPU cũng được đề cập):

cgcreate -g memory,cpu:group1

cgset -r memory.limit_in_bytes=$((50*1024*1024*1024)) group1

Sau đó, nếu ứng dụng của bạn đang chạy, hãy đưa ứng dụng vào nhóm này:

cgclassify -g memory,cpu:group1 $(pidof your_app_name)

Hoặc thực thi ứng dụng của bạn trong nhóm này:

cgexec -g memory,cpu:group1 your_app_name

0

điều chỉnh là một trình nền điều chỉnh hệ thống thích ứng động điều chỉnh các cài đặt hệ thống một cách linh hoạt tùy thuộc vào cách sử dụng.

 $ man tuned

Xem các tài liệu liên quan và các tập tin cấu hình.

 /etc/tuned
 /etc/tuned/*.conf
 /usr/share/doc/tuned-2.4.1
 /usr/share/doc/tuned-2.4.1/TIPS.txt

This parameter may be useful for you.

** Set flushing to once per 5 minutes
** echo "3000" > /proc/sys/vm/dirty_writeback_centisecs

Thông tin bổ sung

Lệnh đồng bộ sẽ xóa bộ đệm, tức là buộc tất cả dữ liệu chưa được ghi vào đĩa và có thể được sử dụng khi người ta muốn chắc chắn rằng mọi thứ đều được ghi an toàn. Trong các hệ thống UNIX truyền thống, có một chương trình gọi là cập nhật đang chạy trong nền đồng bộ hóa cứ sau 30 giây, do đó thường không cần thiết phải sử dụng đồng bộ hóa. Linux có một trình nền bổ sung, bdflush , đồng bộ hóa không hoàn hảo hơn thường xuyên hơn để tránh bị đóng băng đột ngột do I / O đĩa nặng mà đôi khi đồng bộ hóa gây ra.

Trong Linux, bdflush được bắt đầu bằng cách cập nhật. Thường không có lý do để lo lắng về điều đó, nhưng nếu bdflush chết vì một lý do nào đó, kernel sẽ cảnh báo về điều này và bạn nên bắt đầu bằng tay ( / sbin / update ).


1
Đây không phải chỉ dành cho các mục bẩn? Tôi không nghĩ đó là vấn đề trên hệ thống của mình vì tất cả đều sạch - sự chậm trễ không phải là viết lại các trang bẩn mà là phân mảnh không gian còn lại bằng cách xóa các trang sạch.
Wim

Vâng, đây là cho các trang bẩn, tôi nghĩ bạn cũng có thể khắc phục các sự cố hiệu suất khác bằng cách đặt điều chỉnh sang chế độ động.
Ijaz Ahmad Khan

"Kể từ Linux 2.6, cuộc gọi hệ thống [bdflush] không được chấp nhận và không làm gì cả. Nó có khả năng biến mất hoàn toàn trong một bản phát hành kernel trong tương lai. Ngày nay, tác vụ được thực hiện bởi bdflush () được xử lý bởi luồng pdflush kernel." man7.org/linux/man-pages/man2/bdflush.2.html
sourcejedi
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.