본문 바로가기

Linux

시스템 성능향상을 위한 팁!!

출처 : http://www.ubuntu.or.kr/viewtopic.php?p=99854


시스템 성능향상의 대부분은 디스크와메모리와 관련되어 있습니다.
왜냐면 디스크의 접근속도와는 비교할 수 없을 정도로 메모리 접근속도가 빠르기 때문이죠.
그래서 가능하면 디스크대신 메모리에서 작업하는것이 속도향상에 도움이 됩니다.
램디스크, 램드라이브 같은것도 같은 맥락입니다.
메모리와 디스크 사이에서 전환을 지원하는 방식으로는 
디스크캐싱 (자주 접근한 디스크내용을 저장하고, 접근시 저장된 곳에서 먼저 찾는 방식),
스왑핑 (메모리가 부족할때 일정량의 메모리(메모리페이지)를 디스크에 저장하고 메모리를 회수해서 여유 메모리를 늘려주는것),
램디스크/램드라이브 (메모리의 일부분을 고정적으로 할당하여 디스크인양 사용하게 하는것)
등이 있습니다.

이것을 효율적으로 관리하면 속도를 엄청 향상시킬 수 있습니다.
컨셉은 여유메모리(free memory)가 많다는 것은 그만큼 메모리를 낭비하고 있다는 뜻도 됩니다.
최대한 여유메모리를 줄이고, 디스크접근도 줄여서 성능을 향상시키는 것입니다.

1) 스왑핑을 가능한 줄이자.
리눅스 시스템은 항상 일정량의 여유 메모리를 확보하려고 합니다.
그과정에서 여유메모리가 있음에도 스와핑을 하게 되고, 디스크접근이 이루어집니다.
하지만 얼만큼의 여유메모리를 항상 확보해야 될까요? 그건 리눅스시스템으로서도 알 수 없겠죠.
그래서 이것을 지정해줄 필요가 있습니다.

커널에 파라미터를 동적으로 넘겨주기 위한 것으로 sysctl명령과 /etc/sysctl.conf파일이 있습니다.
/etc/sysctl.conf 파일에 다음을 적어주면 재부팅시 적용됩니다.
이 값이 작을수록 스왑핑을 자주 안하게 됩니다.

기본값으로 60으로 설정되어 있지만, 리눅스 문서를 살펴보아도 데스크탑에서 추천하는 값은 10입니다.
더 안정적으로 하고 싶다면 20이면 충분할것입니다.

Code:
vm.swappiness=10


그리고 재부팅없이 적용하려면,
Code:
sysctl -p /etc/sysctl.conf

혹은
Code:
sysctl -w vm.swappiness=10


2) 디스크캐싱을 최대한 활용하자.
캐싱이라는 기법은 여러부분에 사용됩니다.
대부분 네트웍속도에 비해 디스크접근속도가 빠르므로, 전송된 내용을 디스크에 캐싱하기도 하고 (이 방식은 대부분의 웹브라우져가 구현하고 있지요),
메모리가 디스크에 비해 접근이 빠르기 떄문에, 디스크의 일부분을 메모리에 캐싱하기도 합니다.
하지만 디스크를 메모리에 캐싱하였다고 하였을때, 메모리가 부족해지면 어떻게 될까요?
이때 시스템은 디스크의 메모리캐시를 회수하거나, 이것도 여의치 않으면 메모리의 일부분(메모리페이지)를
디스크에 저장하고 해당메모리를 회수하여 응용프로그램에게 메모리를 할당해 주게 됩니다.
요럴때 디스크의 메모리캐시에서 회수하는 정도를 커널에 지정해 줄 수 있습니다. 
Code:
vm.vfs_cache_pressure=50


기본값은 최대값인 100으로 되어 있으며, 가능한한 캐시메모리에서 강탈해갑니다.
이것을 40-100정도 사이에서 조정해 주시면 되는데..
웹서핑을 해보면 대부분은 50정도를 추천하지만, 일부는 40까지 적용한 예도 있고,
또 저의 경우는 80정도가 적당하더군요.

아래는 이것을 테스트하고, 적당한 값을 찾아 볼 수 있게 하는 스크립트입니다.
Code:
#!/usr/bin/sudo /bin/bash
TEST_FILE_SIZE=1024M
TEST_DIR=/usr/share
TEST_VALUES="100 90 80 70 60 50 40"
TEMP_DIR=${1:-$HOME}

echo 3 > /proc/sys/vm/drop_caches
dd if=/dev/zero of=$TEMP_DIR/testfile0 count=1 bs=$TEST_FILE_SIZE

i=1
for v in $TEST_VALUES;
do
   sysctl -w vm.vfs_cache_pressure=$v
   find $TEST_DIR> /dev/null
   cp $TEMP_DIR/testfile0 $TEMP_DIR/testfile$i
   echo "** vm.vfs_cache_pressure=$v **"
        time find $DIR/ > /dev/null
   ((i++))
done

for ((v=0; v<$i; v++));
do
   rm -f $TEMP_DIR/testfile$v
done

실행시 시간이 오래 걸릴 수 있으니,
파일크기와 테스트할 수치들을 좀 줄여서 실행하세요.

3) 스왑핑을 디스크가 아닌 메모리에..
메모리가 부족해서 스와핑하는데..
어째서 메모리에 메모리 내용을 저장하냐구요?
키워드는 압축입니다.
스왑영역에 자동압축알고리즘을 적용하여
메모리를 압축하는것이죠.
스왑영역은 여럿 존재할 수 있기 때문에..
압축으로도 부족할때 스왑파티션이나 스왑파일을 사용하면 되겠죠.
이것을 구현한것으로는 google의 compcache/ramzswap과 zramswap-enabler등이 있구요.
이미 우분투리눅스이미지에는 compcache적용되어 있을 겁니다.
/usr/share/initramfs-tools/hooks에 해당 스크립트가 있고,
update-initramfs나 update-grub명령 등으로 바뀐 내용을 적용할 수 있습니다.
하지만, 이것은 크기를 지정해주어야 하고 효율도 zramswap-enabler보다 떨어집니다.
단지 initramfs환경에서 구동하기 위해서 필요하겠죠. 일단 하드로 부팅한 후에는 zram을 사용하는것이 좋습니다.
설치 방법은
Code:
sudo apt-add-repository ppa:shnatsel/zram && sudo apt-get update
sudo apt-get install zramswap-enabler

따로 설정할 것은 없습니다.
다만 3.2커널을 사용할 경우 문제가 있으니, 수정을 요합니다.
Code:
#/etc/init/zramswap.conf
#.. 생략 ..
#modprobe zram num_devices=$num_cpus
#위의 부분을 아래로 바까주세요. 아마도 커널 파라미터 이름이 변경되었나 봅니다.
modprobe zram num_devices=$num_cpus 2>/dev/null || modprobe zram zram_num_devices=$num_cpus 2>/dev/null
#.. 생략 ..


zramswap을 사용하게 되면 스왑핑이 실제로 디스크로 거의 이루어지지 않게 되어서, 엄청 빨라집니다.

4) 부팅속도를 빠르게 해봅시다.
기본적으로 우분투에 uread-ahead라는 서비스가 있고, 이것은 디스크 정보를 저장해놨다가 부팅시에 미리 읽어들여서,
부팅속도는 떨어지지만 시스템의 전반적인 속도를 향상시키는 기능을 합니다.
그냥 넵두는것이 좋겠군요.

그러면 어떻게 부팅속도를 빠르게 할까요?
하이버네이션 또는 서스펜드를 이용하면 금새 부팅이 가능합니다.
그러나 이 기능을 사용하기 위해서는 스왑핑이 필요하고, 보통 스왑 용량이 메모리 총용량보다 커야 합니다.
그리고 스왑핑을 하기 위해서 용량 만큼의 디스크 접근이 필요합니다.
uswsusp라는 유틸리티를 추천합니다.
이름은 unswap suspend의 약자로서, 스왑을 이용하지 않고, 자체적으로 용량을 설정하고 압축해서 저장하게 됩니다.
소프트웨어 소스는 universe에 속해 있으므로 다음 명령으로 설치하시고,
sudo apt-get install uswsusp

서스펜드 모드로 들어가기 위해서 절전모드키 외에..
s2disk와 s2ram명령을 지원하고 있으며
s2disk는 상태를 저장하고 시스템 전원을 끄게 되고, 리부팅시에 바로 부팅됩니다.
s2ram은 실제 전원은 끄지 않고, 최대 절전 모드로 숨어있다가, 파워버튼을 누르면 짜잔하고 뜨게 되는겁니다.

만약 부팅시 어느부분에서 시간이 걸리는지 알아보려면,
bootchart를 설치해보세요
부팅상황을 분석해서 /var/log/bootchart/*.png파일을 만들어 줍니다.
그러나 이것도 부팅시간을 잡아먹기 때문에.. 그림을 확인한 후 서비스를 자동시작하지 않게 만들어 주는게 좋겠죠.


5) 램디스크의 활용? 
램디스크를 만드는 방법은 부팅시 부팅메뉴에서 'e'키를 눌러 편집모드로 들어간 후
linux xxx.vmlinuz ... 뒷부분에 ram_disk_size=킬로바이트수치
로 변경해주고 부팅하면 램디스크가 사용가능하며,
참고로,
512 MiB=524288 KiB
256 MiB=262144 KiB
128 MiB=131072 KiB
64 MiB=65536 KiB
32 MiB=32768 KiB

/etc/default/grub파일에서
GRUB_CMDLINE_LINUX_DEFAULT= 부분뒷쪽에 ram_disk_size=xxx라고 적어주시고
sudo update-grub 명령을 주시면 다음 부팅때 램디스크가 생성됩니다.

부팅한 후에는 /dev/ram0는 메모리에서 일정량을 점유하는 램디스크 디바이스가 됩니다.
하지만 파일시스템이 없기 때문에 파일시스템을 만들어 주어야 하고, 디바이스이기 떄문에 마운트도 해주어야 합니다.
Code:
#/etc/rc.local
#...생략
mke2fs -m 0 /dev/ram0 2>/dev/null
if [ $? -ne 0 ]; then
    mkdir -p /mnt/rd 2>/dev/null 
    mount /dev/ram0 /mnt/rd
    chown 1000.1000 /mnt/rd
fi


이것은 전통적인 방법의 램디스크 생성법이지만, 약간 다르지만 tmpfs를 이용하여 부팅시 파라미터를 넘겨주지 않아도 간단히 램디스크를 만들 수 있습니다.
Code:
mount -t tmpfs -o size=[tmpfs size] tmpfs [mount point]

또는 /etc/fstab에
tmpfs [mount point] tmpfs size=[tmpfs size] 0 0
로 적어주고 마운트해주면 되는데 사실은 램디스크와는 조금 다릅니다.
공유메모리를 이용하는것이죠.
/dev/shm이것은 공유메모리를 뜻하는 디바이스입니다.

이제까지는 램디스크의 생성법이었구요.
일단 활용하는 방법은 웹브라우져등의 임시파일이나 캐시등을 해당 램디스크 마운트포인트로 설정해 놓으면
저장하고 읽는 과정은 모두 메모리에서 이루어지기 때문에 빠릅니다.
그러고 시스템이 종료되면 다 날아가겠죠?
다만 이것은 메모리의 일부분을 항상 차지하기 때문에.. 너무 크게 지정하거나 메모리가 적은 시스템의 경우는 오히려 좋지 않다고 봅니다.


저는 개인적으로 램디스크를 추천하지 않으며 오히려 앞서의 방법들을 이용해서 캐시메모리를 최대한 활용할 것을 추천합니다.


다만 램디스크가 정말 필요할 경우는..
리눅스ISO파일을 하드에 저장하고,
Code:
#/boot/grub/custom.cfg
menuentry "Boot to RAMDISK from Ubuntu ISO " {
insmod ext2
insmod fat
insmod ntfs
insmod loopback
set isofile=/ubuntu.iso
search -s isodev -f $isofile
loopback lo $isodev$isofile
linux (lo)/casper/vmlinuz boot=casper toram iso-scan/filename=$isofile quiet splash
initrd (lo)/casper/initrd.lz
}

로 편집 저장하고 부팅하면..
ISO내용을 몽땅 메모리에 복사하고, 디스크를 언마운트해서 포멧이 가능하게 하는 경우입니다.

'Linux' 카테고리의 다른 글

[Linux/Unix]디스크 쿼타(Disk Quota)  (0) 2012.07.20
Linux Performance Metrics  (0) 2012.07.05
SAR in Ubuntu  (0) 2012.06.22
crontab  (0) 2012.06.21
리눅스용 텍스트 브라우저 W3m 사용기  (0) 2012.06.15