Kéo tất cả bộ nhớ hoán đổi của một quá trình ra khỏi trao đổi


8

Làm thế nào một người có thể nhanh chóng rút tất cả bộ nhớ bị hoán đổi của quá trình ra khỏi trao đổi mà không ghi vào đĩa?

Bối cảnh về vấn đề này là tầm thường, vì vấn đề mang tính hệ thống đòi hỏi câu hỏi đang được xử lý bởi các bên khác. Tuy nhiên, ngay bây giờ, tôi có một vấn đề là tôi thường xuyên phải giải phóng không gian trao đổi trên một nút OpenVZ trong khi tải và chờ IO là cực kỳ cao.

Việc hoán đổi thường được tiêu thụ chủ yếu bởi một số ít các quy trình MySQL và clamd chạy trên các container riêng lẻ. Khởi động lại các dịch vụ này giải phóng trao đổi và giải quyết vấn đề trên nút, nhưng không mong muốn vì những lý do rõ ràng.

Tôi đang tìm cách để nhanh chóng giải phóng trao đổi khỏi các quy trình đó trong khi nút bị quá tải và cần một cái gì đó nhanh hơn phương thức hiện tại của tôi:

unswap(){ [[ $1 && $(ls /proc/$1/maps) ]]  && ((gcore -o /tmp/deleteme $1 &>/dev/null; rm -fv /tmp/deleteme.$1)&) 2>/dev/null  || echo "must provide valid pid";};unswap

Kết xuất lõi này buộc tất cả ram phải được truy cập và do đó thực hiện công việc rút nó ra khỏi trao đổi, nhưng tôi vẫn chưa tìm được cách nào để tránh việc ghi nó vào tập tin. Ngoài ra, có vẻ như quá trình sẽ nhanh hơn nếu tôi có thể cô lập phạm vi địa chỉ hiện đang hoán đổi và chỉ chuyển phần đó thành / dev / null, nhưng tôi vẫn chưa tìm ra cách để làm điều đó.

Đây là một nút rất lớn, vì vậy phương pháp hoán đổi / hoán đổi thông thường rất tốn thời gian và một lần nữa, cấu hình của nút không nằm trong tầm kiểm soát của tôi, vì vậy việc khắc phục nguyên nhân gốc không phải là một phần của câu hỏi này. Tuy nhiên, bất kỳ cái nhìn sâu sắc nào về cách tôi có thể giải phóng một phần đáng kể của trao đổi một cách nhanh chóng mà không giết / khởi động lại bất cứ điều gì sẽ được đánh giá cao.

Môi trường: CentOS 6.7 / OpenVZ

Cập nhật cho bất cứ ai có thể vấp ngã sau này:

Sử dụng đầu vào của Jlong, tôi đã tạo ra chức năng sau:

unswap(){ (awk -F'[ \t-]+' '/^[a-f0-9]*-[a-f0-9]* /{recent="0x"$1" 0x"$2}/Swap:/&&$2>0{print recent}' /proc/$1/smaps | while read astart aend; do gdb --batch --pid $1 -ex "dump memory /dev/null $astart $aend" &>/dev/null; done&)2>/dev/null;};

Nó hơi chậm, nhưng thực hiện chính xác những gì được yêu cầu ở đây. Có lẽ có thể cải thiện tốc độ bằng cách chỉ tìm phạm vi địa chỉ lớn nhất trong trao đổi và bỏ qua các lần lặp cho các khu vực nhỏ tầm thường, nhưng tiền đề là âm thanh.

Ví dụ làm việc:

#Find the process with the highest swap use
[~]# grep VmSwap /proc/*/status 2>/dev/null | sort -nk2 | tail -n1 | while read line; do fp=$(echo $line | cut -d: -f1); echo $line" "$(stat --format="%U" $fp)" "$(grep -oP "(?<=NameS).*" $fp); done | column -t
/proc/6225/status:VmSwap:   230700  kB  root  mysqld

#Dump the swapped address ranges and observe the swap use of the proc over time
[~]# unswap(){ (awk -F'[ t-]+' '/^[a-f0-9]*-[a-f0-9]* /{recent="0x"$1" 0x"$2}/Swap:/&&$2>0{print recent}' /proc/$1/smaps | while read astart aend; do gdb --batch --pid $1 -ex "dump memory /dev/null $astart $aend" &>/dev/null; done&)2>/dev/null;}; unswap 6225; while true; do grep VmSwap /proc/6225/status; sleep 1; done
VmSwap:   230700 kB
VmSwap:   230700 kB
VmSwap:   230676 kB
VmSwap:   229824 kB
VmSwap:   227564 kB
... 36 lines omitted for brevity ... 
VmSwap:     9564 kB
VmSwap:     3212 kB
VmSwap:     1876 kB
VmSwap:       44 kB
VmSwap:        0 kB

Giải pháp cuối cùng cho việc bán phá giá hàng loạt chỉ là những khối lớn của bộ nhớ bị tráo đổi:

unswap(){ (awk -F'[ \t-]+' '/^[a-f0-9]*-[a-f0-9]* /{recent="0x"$1" 0x"$2}/Swap:/&&$2>1000{print recent}' /proc/$1/smaps | while read astart aend; do gdb --batch --pid $1 -ex "dump memory /dev/null $astart $aend" &>/dev/null; done&)2>/dev/null;}; grep VmSwap /proc/*/status 2>/dev/null | sort -nk2 | tail -n20 | cut -d/ -f3 | while read line; do unswap $line; done;echo "Dumps Free(m)"; rcount=10; while [[ $rcount -gt 0 ]]; do rcount=$(ps fauxww | grep "dump memory" | grep -v grep | wc -l); echo "$rcount        $(free -m | awk '/Swap/{print $4}')"; sleep 1; done 

Tôi vẫn chưa xác định liệu phương pháp này có gây rủi ro cho sức khỏe của quy trình hoặc hệ thống hay không, đặc biệt là khi lặp qua nhiều quy trình đồng thời. Nếu bất cứ ai có cái nhìn sâu sắc về bất kỳ hiệu ứng tiềm năng nào có thể có trên các quy trình hoặc hệ thống, xin vui lòng bình luận.


Tôi nghĩ với tôi rằng "giải pháp cuối cùng" có thể khởi chạy một số lượng lớn các gdbtrường hợp song song nếu quá trình được hoán đổi có nhiều đoạn bị tráo đổi. Kịch bản sẽ khởi chạy gdbthể hiện song song cho mỗi đoạn được hoán đổi (lớn) cho 20 quy trình lớn nhất. Tôi nghĩ ít nhất người ta nên thêm | tail -n20vào sau awkkhi chuyển kết quả vào whilevòng lặp để giới hạn các quy trình tương đương tối đa đến 400.
Mikko Rantalainen

Câu trả lời:


8

Bạn có thể đạt được kết quả tương tự bằng cách sử dụng lệnh 'kết xuất bộ nhớ' của GDB và ghi nó vào / dev / null.

Bạn chỉ cần tìm các vùng trong / Proc / $ PID / smaps cần được bỏ qua. ví dụ từ / Proc / $ PID / smaps:

02205000-05222000 rw-p 00000000 00:00 0 
Size:              49268 kB
Rss:               15792 kB
Pss:                9854 kB
Shared_Clean:          0 kB
Shared_Dirty:      11876 kB
Private_Clean:         0 kB
Private_Dirty:      3916 kB
Referenced:          564 kB
Anonymous:         15792 kB
AnonHugePages:         0 kB
Swap:              33276 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB

và sau đó sử dụng chế độ --batch để thực thi lệnh gdb để bạn có thể sử dụng nó trong chức năng của mình:

[root@nunya ~]# swapon -s ; gdb --batch --pid 33795 -ex "dump memory /dev/null 0x02205000 0x05222000" ;swapon -s
Filename                Type        Size    Used    Priority
/dev/sda2                               partition   7811068 7808096 -1

[Thread debugging using libthread_db enabled]

Filename                Type        Size    Used    Priority
/dev/sda2                               partition   7811068 7796012 -1

Ý kiến ​​hay, tôi đã cải thiện nó một chút sau đó, sau đó những người khác đã cải thiện nó nhiều hơn trong những năm qua và nó đã trở thành github.com/wiedemannc/deswappify-auto
kubanchot
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.