4G램 이하에서 Arch linux를 데스크탑으로 쓰기 위한 최적화.

램이 4G라면 적은 건 아니다. 하지만 무거운 프로그램을 돌리려면 부족한 게 사실이다. 이를 해결하려고 Desktop Environment을 바꿔 보았지만 별 효과를 보지 못했다. 그래서 몇 가지 더 손을 본 결과 쓸만한 데스크탑 환경을 구축했다.

가장 큰 효과를 본 것은 스왑 메모리의 설정이었다. SSD에 자주 쓰고 지우면 수명이 단축된다고 하지만, 내 수명이 단축되지 않으려면 스왑을 써야했다. 스왑영역을 잡아주었더니, 버츄어 박스와 IDE 크롬과 파이어폭스를 띄워도 시스템이 멈추지 않는다.

스왑 할당하기

우선 아래 명령어로 할당된 스왑을 확인한다.
sudo swapon -s
free -m

공간이 충분히 남아있는지도 확인한다.
df -h

스왑 파일을 만든다.
sudo fallocate -l 4G /swapfile

root 유저만 읽고 쓰도록 스왑 파일의 권한을 설정한다.
sudo chmod 600 /swapfile

스왑 파일이 잘 만들어 졌는지 확인한다.
ls -lh /swapfile

스왑 영역을 할당한다.
sudo mkswap /swapfile

스왑 영역을 활성화한다.
sudo swapon /swapfile

아래 명령어로 할당된 스왑을 확인한다.
sudo swapon -s
free -m

/etc/fstab 파일에 스왑 설정을 추가한다.
/swapfile none swap sw 0 0

/etc/sysctl.conf 파일에 다음을 추가한다.
vm.swappiness=10
vm.vfs_cache_pressure = 50

스왑 영역을 지울 땐 아래 명령어를 쓰면 된다.
swapoff -a
rm -f /swapfile

gnome-pty-helper 비활성화

사용자가 얼마나 많은 터미널을 열었나 기록하는 헬퍼로 데스크톱 환경에서는 필요가 없다.

chmod 644 /usr/lib/vte/gnome-pty-helper
chmod 644 /usr/lib64/vte/gnome-pty-helper
chmod 644 /lib64/vte/gnome-pty-helper
chmod 644 /lib/vte/gnome-pty-helper

Core dump 비활성화

코어 덤프가 디버깅엔 유용하지만 평소에는 성능에 저하를 가져오므로 비활성화 한다.
/etc/sysctl.conf 파일에 다음을 추가한다.
fs.suid_dumpable = 0

SSD trim 기능 켜기

sudo pacman -S util-linux
sudo systemctl enable fstrim.timer

윈도우 메니저의 변경이 도움이 될 수도 있다.
가벼운 윈도우 메니져가 많다. FVWM과 ICEWM이 가벼운 편이었지만, 보기가 너무 안좋아서 지워버렸다. OpenBox는 좋은 모습을 보여주지만 XFCE의 기본 WM인 XFWM(14M)보다 두배가 넘는 메모리(31M)를 사용한다. 그래도 여전히 가벼운 편이니 취향에 따라 OpenBox로 윈도우메니져를 바꿔 보는 것도 괜찮겠다.

xfce 윈도우 메니저 변경하기

설정 파일을 가져온다.

cp /etc/xdg/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml

~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml 파일을 열어 xfwm4를 openbox로 변경한다.

<value type="string" value="xfwm4"/>to
<value type="string" value="window_manager_executable"/>

오픈박스용 설정 설치

pacman -S obconf

단축키가 제대로 동작하지 않으면 vi .config/openbox/rc.xml 에서 사용하지 않는 단축키를 제거한다.

지금 사용하는 윈도우 메니저 보기

pacman -S wmctrl
wmctrl -m

가볍고 쓸만한 앱을 찾다가 보조 터미널로 좋은 tilda와 자원 점유율을 보여주는 htop을 설치했다.

pacman -S tilda
pacman -S htop


혹시 이 환경에서도 시스템이 불안정한 일이 자주 발생한다면 쓰는 자주 프로그램을 가벼운 걸로 바꾸어 보는 것도 괜찮을 것 같다. 예를 들면 이메일 클라이언트를 썬더버드에서 Trojita나 Geary등으로 바꾸는 것이다. 하지만 설정을 다시 하기는 귀찮으니 우선은 이대로 써야겠다.


문제 해결

키보드 단축키가 작동하지 않을 때

로그아웃 하고 tty1(ctrl+alt+F1)에서 로그인 하여 rm -rf ~/.cache/sessions/* 로 세션 캐쉬를 삭제한다.

Failed to fork (Resource temporarily unavailable) 오류가 날 때

/etc/sysctl.conf 파일에 다음을 추가한다.
fs.file-max = 204708

QT5에서 한글 입력이 안될 때

yaourt -S uim-qt5 --force

SHELL의 변경 (zsh)

pacman -S zsh
zsh /usr/share/zsh/functions/Newuser/zsh-newuser-install -f
chsh -s $(which zsh)
echo $SHELL

재부팅 하지 않고 sysctl 적용

sudo sysctl -p /etc/sysctl.d/99-sysctl.conf

그 밖에 읽어볼 만한 자료.

SSD 최적화

베터리를 오래가게 돕는 도구

실행중인 프로세스가 어떻게 자원을 사용할 지 제어하는 데몬



by


Tags : , , , , , ,

  • 재미있게 읽으셨나요?
    방랑자의 이야기.
    월풍도원에선 기부를 받습니다.

joinedload를 사용한 SQLAlchemy 쿼리 최적화


SQLAlchemy는 파이썬(Python)용 Object Relational Mapper다.
ORM(Object Relational Mapper)은 객체(Object)와 관계형 데이터베이스(RDB - Relational Database)의 데이터 타입을 연결해 주는데,
이게 나오기 전엔 개발을 어떻게 했었나 싶을 정도로 아주 편리하다.

사용법도 간단해서 짧은 코드로 쿼리를 날리면 모델 하나를 딱 불러온다.
Model.get(model_id)
정말 좋다.
아무런 문제가 없었다.
적어도 외부 DB를 사용해 시험해 보기 전엔 그랬다.
외부 DB는 요청을 보내고 받는 시간이 길다.
헌데 SQLALCHEMY에서 자동으로 만들어 주는 쿼리를 쓰면, 너무 많은 요청을 보내게 된다.
그렇다면 성능을 향상하기 위해선?
요청 수를 줄이면 된다.

예제 모델-'SQLAlchemy Query Optimization. 쿼리 최적화'

예제의 product테이블은 여러 테이블과 연결되어 있는데,
쿼리를 날려 product와 관련된 테이블의 정보를 모두 불러와야 한다.
Sqlalchemy의 기본 쿼리 설정은 select로 연관된 table을 독립된 SELECT쿼리로 호출하지만,
응답시간이 느린 외부 DB를 쓴다면, 이를 join해서 쿼리 개수를 줄이면 된다.

sqlalchemy에서 join은 어떻게 하는가?

모델을 생성할 때 lazy='joined'를 써서 관련 테이블을 부를 때 join하는 방법과,
joinedload를 이용한 join 방법이 있다.
모델 생성 시 lazy를 사용해 join한 경우, 모델 호출 시마다 join이 되므로,
예제에선 필요한 상황에만 쿼리를 join하는, joinedload를 사용했다.

joinedload 간략 사용 방법

Model.query.options(db.joinedload(Model.relatedModel).all()

SQLAlchemy 쿼리 최적화 방법

  • 1..1 관계는 innerjoin한다.
    db.joinedload(Seller, innerjoin=True)
  • 1..n 관계는 innerjoin하지 않는다.
    db.joinedload(Tags)
  • 1..n 관계에서 관계가 깊다면, subqueryload를 써서 관련 테이블을 불러오고,
    그에 대해 joinedload를 해준다.
    db.subqueryload(Colors),
    db.joinedload(Colors, Inventory)
SQLAlchemy Query Optimization. 쿼리 최적화

위 방법을 써서 Call 개수를 25% 줄였다.
보통 Call이 29~30개가 나오다가, 22로 줄었으니, 약 7.5개 준 것이다.
Call당 시간이 얼마나 걸리냐에 따라 시간 단축이 가능한데,
테스트 환경에서 0.08초 정도 걸렸으므로 약 0.6초(0.08 * 7.5) 의 시간을 단축했다.
이건 데이터베이스의 응답 지연이 얼마나 되느냐에 따라 더 큰 차이를 보인다.
물론 로컬 db에서는 percall시간이 아주 짧으므로(테스트 환경에선 0.001초) 이런 최적화 차이를 체감하지 못한다.

참조

http://docs.sqlalchemy.org/en/rel09/orm/relationships.html
http://docs.sqlalchemy.org/en/rel09/orm/loading.html
http://stackoverflow.com/questions/6935809/how-to-use-joinedload-contains-eager-for-query-enabled-relationships-lazy-dyna
http://invenio-software.org/wiki/Tools/SQLAlchemy/Performance



by


Tags : , , , , , ,

  • 재미있게 읽으셨나요?
    방랑자의 이야기.
    월풍도원에선 기부를 받습니다.

파이썬 Flask에서 RequireJS Optimizer를 이용한 static폴더 최적화.

자바스크립트MVC를 이용할 경우 자바스크립트와 뷰 템플릿때문에 static폴더가 무겁습니다.
파일의 공백을 모두 제거하여 용량을 줄이면 좀 가벼워 지지요.
허나 파일 공백을 없애면 가독성이 떨어집니다.
난감한 상황이 발생해요.
길이 1m짜리 한줄코드를 고치고 기능 추가하는건 어렵잖아요?
변경이 빈번하게 일어나는 static 폴더.
개발 편의와 성능 두마리 토끼를 잡을 좋은 수가 없을까요?
RequireJS를 이용해 자바스크립트를 관리하신다면 방법이 있습니다!

우선 노드JS(http://nodejs.org)를 설치합니다.

RequireJS Optimizer를 설치합니다.

npm install -g requirejs

3. r.js를 다운로드 받습니다.(http://requirejs.org/docs/release/2.1.8/r.js)

4. 예제에서 사용할 어플리케이션 디렉토리 구조는 다음과 같습니다.

/build
  - r.js
  - build.js
/application
  __init__.py
  /static
    /views
      template.ejs
    /js
      app.js
      /vendor
        jquery-1.10.1.min.js
        bootstrap.min

application/init.py

from flask import Flask
app = Flask(__name__)
# static 폴더 경로를 지정해 줍니다. debug일땐 ‘static’폴더로 경로를 설정하고 나머지는 ‘static-build’를 경로로 잡습니다.
app.static_folder = 'static-build'
if app.debug:
        app.static_folder = 'static'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

application/static/js/app.js

자바스크립트 어플리케이션 파일입니다.
requirejs의 기본 설정을 담고 있습니다.

require.config({
    "baseUrl": "/static/js",
    "paths": {
        "jquery": [
            "//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min",
            "vendor/jquery-1.10.1.min"
        ],
        "jquery.bootstrap": [
            "//netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/js/bootstrap.min",
            "vendor/bootstrap.min"
        ],
    },
    shim: {
        "jquery.bootstrap": {
            deps: ["jquery"],
            exports: '$.fn.bootstrap'
        },
        enforceDefine: true
    }
});

requirejs(['jquery','jquery.bootstrap'],
    function ($) {
    // 어플리케이션 코드 
    }
);

/build/build.js

RequireJS용 build파일입니다.

{
    appDir: '../application/static',
    baseUrl: 'js/vendor',
    mainConfigFile: '../application/static/js/app.js',
    paths: {
        "jquery": "jquery-1.10.1.min",
        "jquery.bootstrap": "bootstrap.min",
    },
    dir: '../application/static-build',
    optimize: "uglify2",
    optimizeCss: "standard.keepLines",
    removeCombined: true, // combine된 파일은 남겨두지 않습니다.
    preserveLicenseComments: false,
    modules: [
        {
            name: '../app'
        }
    ]
}

프로젝트 루트 페이지에서 다음을 실행합니다.

JS/CSS파일을 최적화 하여 application/static-build 폴더에 저장합니다.
node ./build/r.js -o ./build/build.js

단 이는 js와 css만 최적화를 해 주기 때문에 Ejs 템플릿도 용량을 줄이려면 아래 커맨드를 이용하면 됩니다.
find ./application/static-build/views -name '*.ejs' -exec sed -i '/^\s∗\/\//d' {} \;
find ./application/static-build/views -name '*.ejs' -exec sed -i 's/^[ \t]*//g; s/[ \t]*$//g;' {} \;
find ./application/static-build/views -name '*.ejs' -exec sed -i ':a;N;$!ba;s/\n/ /g' {} \;

쉘 스크립트를 작성해 한번에 실행하면 간편합니다.

optimizer.sh

#!/bin/sh
cd './build'
node ./r.js -o build.js
cd '../application/static-build/views'
find . -name '*.ejs' -exec sed -i '/^\s∗\/\//d' {} \;
find . -name '*.ejs' -exec sed -i 's/^[ \t]*//g; s/[ \t]*$//g;' {} \;
find . -name '*.ejs' -exec sed -i ':a;N;$!ba;s/\n/ /g' {} \;

참고 자료



by


Tags : , , , , , , ,

  • 재미있게 읽으셨나요?
    방랑자의 이야기.
    월풍도원에선 기부를 받습니다.