[linux] SVN command

svn co –no-auth-cache –config-option servers:global:http-proxy-host=10.10.10.10 –config-option servers:global:http-proxy-port=3128 –username 아이디 –password 암호 http://svn.bbunbro.com/static/ /bbunbro/data/static/

설명

–no-auth-cache : 암호 인증 관련 크레덴셜을 저장하지 않음

— config-option : ~/.subversion/config 지정하는 옵션, 위에서는 proxy 이용한 svn 접속을 뜻함

–username, –password : svn 접속 주소

[linux] Nginx performance tuning

user  nobody;
# no need for more workers in the proxy mode
worker_processes  2;
error_log  /var/log/nginx/error.log info;
worker_rlimit_nofile 20480;
events {
worker_connections 8120; # increase for busier servers
use epoll; # you should use epoll here for Linux kernels 2.6.x
}
http {
server_name_in_redirect off;
server_names_hash_max_size 10240;
server_names_hash_bucket_size 1024;
include    mime.types;
default_type  application/octet-stream;
server_tokens off;
disable_symlinks if_not_owner;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 3;
gzip on;
gzip_vary on;
gzip_disable “MSIE [1-6]\.”;
gzip_proxied any;
gzip_http_version 1.1;
gzip_min_length  1000;
gzip_comp_level  3;
gzip_buffers  16 8k;
# You can remove image/png image/x-icon image/gif image/jpeg if you have slow CPU
gzip_types    text/plain text/xml text/css application/x-javascript application/xml image/png image/x-icon image/gif image/jpeg application/xml+rss text/javascript application/atom+xml;
ignore_invalid_headers on;
client_header_timeout  120m;
client_body_timeout 120m;
send_timeout         90m;
reset_timedout_connection on;
connection_pool_size  256;
client_header_buffer_size 256k;
large_client_header_buffers 4 256k;
client_max_body_size 1024M;
client_body_buffer_size 128k;
request_pool_size  32k;
output_buffers   4 32k;
postpone_output  1460;
proxy_temp_path  /tmp/nginx_proxy/;
client_body_in_file_only on;
log_format bytes_log “$msec $bytes_sent .”;
include “/etc/nginx/vhosts/*”;
include /etc/nginx/naxsi_core.rules;
#limit_zone limit_per_ip $binary_remote_addr 5m;
#limit_conn_zone limit_per_ip $binary_remote_addr 10m;
#limit_conn_zone limit_per_ip $binary_remote_addr zone=limit_per_ip:10m;
limit_req_zone $binary_remote_addr zone=allips:5m rate=200r/s;
limit_req zone=allips burst=200 nodelay;
limit_conn_zone $binary_remote_addr zone=addr:10m;
}

 

원본 위치 <http://www.phpfoxcamp.com/topic/6025-first-byte-time-is-too-long-on-my-nginx-server/>

[linux] CURL 을 이용한 서버 접속 속도 체크

[root@10.10.10.10 ~]# curl -o /dev/null -w “Connect: %{time_connect} TTFB: %{time_starttransfer} Total time: %{time_total} \n” -s https://internal-test.bbunbro.com
Connect: 0.002 TTFB: 0.069 Total time: 0.069

외부는 그냥 webpagetest.org 에서 테스트 하시오. 좋습니다.

참고 :
(로컬 호스트 톰켓 http listener 체크)
[root@10.10.10.10 ~]# curl -o /dev/null -w “Connect: %{time_connect} TTFB: %{time_starttransfer} Total time: %{time_total} \n” -s http://127.0.0.1:8080/www
Connect: 0.000 TTFB: 0.026 Total time: 0.026

A friendly formatter for curl requests to help with debugging.
Raw (디버깅을 위한 스니프 포멧 생성 후 테스트 하는 법)
sniff.txt
\n
============= HOST: ==========\n
\n
local_ip: %{local_ip}\n
local_port: %{local_port}\n
remote_ip: %{remote_ip}\n
remote_port: %{remote_port}\n
\n
======= CONNECTION: ==========\n
\n
http_code: %{http_code}\n
http_connect: %{http_connect}\n
num_connects: %{num_connects}\n
num_redirects: %{num_redirects}\n
redirect_url: %{redirect_url}\n
\n
============= FILE: ==========\n
\n
content_type: %{content_type}\n
filename_effective: %{filename_effective}\n
ftp_entry_path: %{ftp_entry_path}\n
size_download: %{size_download}\n
size_header: %{size_header}\n
size_request: %{size_request}\n
size_upload: %{size_upload}\n
speed_download: %{speed_download}\n
speed_upload: %{speed_upload}\n
ssl_verify_result: %{ssl_verify_result}\n
url_effective: %{url_effective}\n
\n
=== TIME BREAKDOWN: ==========\n
\n
time_appconnect: %{time_appconnect}\n
time_connect: %{time_connect}\n
time_namelookup: %{time_namelookup}\n
time_pretransfer: %{time_pretransfer}\n
time_redirect: %{time_redirect}\n
time_starttransfer: %{time_starttransfer}\n
———-\n
time_total: %{time_total}\n
\n

Steps to Use:
#1. Make a file named sniff.txt and paste the contents of this gist into it
#2. Make an alias in your .bash_profile or .zshrc ( or whatever you use ) that looks like this ( make sure to source .bash_profile the file afterwards ):
alias sniff=’curl -w “@/path/to/sniff.txt” -o /dev/null -s ‘
#3. Now you can use your alias to get some fun data back:
sniff https://api.twitter.com/1.1/search/tweets.json?q=@mrmidi
You will get a response that looks like this:
============= HOST: ==========
local_ip: 192.168.0.67
local_port: 49469
remote_ip: 199.16.156.231
remote_port: 443
======= CONNECTION: ==========
http_code: 400
http_connect: 000
num_connects: 1
num_redirects: 0
redirect_url:
============= FILE: ==========
content_type: application/json; charset=utf-8
filename_effective: /dev/null
ftp_entry_path:
size_download: 62
size_header: 380
size_request: 110
size_upload: 0
speed_download: 57.000
speed_upload: 0.000
ssl_verify_result: 0
url_effective: https://api.twitter.com/1.1/search/tweets.json?q=mrmidi
=== TIME BREAKDOWN: ==========
time_appconnect: 0.724
time_connect: 0.566
time_namelookup: 0.526
time_pretransfer: 0.724
time_redirect: 0.000
time_starttransfer: 1.078
———-
time_total: 1.078

[linux] bandwidth 측정 도구 iperf

iperf 소스를 다운받아 ./configure && make && make install  을 진행하거나, package를 다운받아서 설치한다.

 

http://pkgs.repoforge.org/iperf/ 에서 다운받아 쎈트에는 rpm -ivh로 설치함, 우분투는 apt-get install iperf

 

서버에서는 다음과 같이 실행

iperf -s

 

디폴트로 5001 tcp 포트가 오픈되며, acl등을 막지 않으면 클라이언트에서 다음과 같이 테스트한다.

 

iperf -c SERVER_IP

 

 

약간의 시간이 지연된 후 데이터전송 대역폭의 측정값이 노출된다.

 

추가로 다음과 같은 옵션이 가능

 

-t : 데이터를 보내는 시간 (기본 10초)

-i : 밴드위스를 쪼개는 옵션 ( -t 50으로 50초 동안 데이터를 보낸다는 가정하에 -i 5 옵션은 5번으로 끊어 나눠서 보내면서 테스트 한다.

-r : 양방향 테스트

-p : 페러럴 클라이언트 쓰레드 실행

[linux] memcache 스크랩

개요

  • memcached 는 이름 그대로 메모리를 사용해 캐시서비스를 제공해주는 데몬이다. memcache 라는 이름의 라이브러리가 많은데, 여기서 설명하는 건 ‘데몬’이다.
  • memcached 는 LiveJournal을 개발한 Brad Fitzpatrick 이 개발했다. 유투브나 아마존, 위키피디아, 소스포지, 트위터 등 많은 대형 사이트에서 사용되고 있는 데몬이다.
  • memcached 운용시 시스템의 메모리 상황를 모니터링 해, 스왑과 락이 일어나지 않도록 해야한다. memcached는 스왑이 일어나지 않을 정도로 메모리는 여유있다는 가정하에 개발되었다고 한다. 메모리가 부족해 스왑이 일어나 메모리에 저장했던 컨텐츠가 스왑 디스크에 저장되면, 심각한 속도 저하가 있을 것이다.
  • memcached 는 메모리에 데이터를 캐시하는 데몬이며, 아래와 같은 사용은 지양해야 한다.
    • 파일의 캐시로 사용하지 말 것. 단순한 파일 캐시는 OS상에서 제공해준다. memcached는 파일을 읽고 가공한 것을 캐시해야 한다.
    • 데이터베이스 쿼리 결과의 캐시로 사용하지 말 것. 위와 비슷한 이유다. 요즘 나오는 대부분의 상용 DBMS는 쿼리결과를 캐시해주기 때문에 이중으로 캐시할 필요 없다.

설치

  • libevent
    memcached 설치에는 libevent 라이브러리가 필요하다. 이 라이브러리는 이벤트(예를 들어 시그널이나 타입아웃)가 발생했을 때 콜백 함수를 쉽게 호출할 수 있도록 도와주는 라이브러리다.
    libevent
    root@wl ~/src # wget –no-check-certificate https://github.com/downloads/libevent/libevent/libevent-2.0.20-stable.tar.gz
    root@wl ~/src # tar xvfz libevent-2.0.20-stable.tar.gz
    root@wl ~/src # cd libevent-2.0.20-stable
    root@wl ~/src/libevent-2.0.20-stable # ./configure CFLAGS=”-I/usr/local/ssl/include” CPPFLAGS=”-I/usr/local/ssl/include”
    root@wl ~/src/libevent-2.0.20-stable # make
    root@wl ~/src/libevent-2.0.20-stable # make install
  • memcached
    root@wl ~/src # wget http://memcached.googlecode.com/files/memcached-1.4.15.tar.gz
    root@wl ~/src # tar xvfz memcached-1.4.15.tar.gz
    root@wl ~/src # cd memcached-1.4.15
    root@wl ~/src/memcached-1.4.15 # ./configure –enable-dtrace
    root@wl ~/src/memcached-1.4.15 # make
    root@wl ~/src/memcached-1.4.15 # make install
  • libMemcached
    • memcached 는 TCP로 데몬에 접속해 메시지를 주고 받는 방법으로 사용한다. 따라서 라이브러리를 제공하지 않고 memcached 프로토콜 스펙만 제공해준다. 이를 래핑해 사용하기 쉽도록 만든 라이브러리가 libmemcached 이다.
    • libMemcached 는 현재 Solaris Studio 12.3 으로 컴파일 되지 않는다. (#pragma once 미지원) 솔라리스에 번들된 GCC컴파일러로도 안된다. 필자의 경우 GCC 4.6.2 를 사용했다. GCC 4.6.2를 설치하려면 윈디하나의 솔라나라: GCC (작성중)를 참고하자. 이 문서의 내용을 진행함에 있어 libMemcached 라이브러리는 컴파일하지 않아도 된다.
    • libMemcached
      root@wl ~/src # wget –no-check-certificate https://launchpad.net/libmemcached/1.0/1.0.10/+download/libmemcached-1.0.10.tar.gz
      root@wl ~/src # tar xvfz libmemcached-1.0.10.tar.gz
      root@wl ~/src # cd libmemcached-1.0.10
      root@wl ~/src/libmemcached-1.0.10 # ./configure –with-memcached –disable-64bit –enable-umem


      Configuration summary for libmemcached version 1.0.5

      * Installation prefix:       /usr/local
      * System type:               pc-solaris2.10
      * Host CPU:                  i386
      * C Compiler:                gcc (GCC) 4.6.2
      * Assertions enabled:        yes
      * Debug enabled:             no
      * Warnings as failure:       no


      root@wl ~/src/libmemcached-1.0.5 # /usr/sfw/bin/gmake
      root@wl ~/src/libmemcached-1.0.5 # /usr/sfw/bin/gmake install

실행

  • memcached 설정 및 실행
    • 데몬을 띄울 포트번호와 사용할 최대 메모리 양을 정한다. 기본 포트는 11211 번이며, 사용할 최대 메모리는 64MB이 기본 값이다.
    • memcached 는 별도의 설정 파일을 제공하지 않는다.
      root@wl ~ # memcached -h 1)
      memcached 1.4.15

      -l <addr>     바인드할 주소
      -p <num>      TCP 포트 번호 (기본값: 11211)
      -U <num>      UDP 포트 번호 (기본값: 11211, 0 인경우 사용안함)
      -s <file>     UNIX 소켓 경로 (네트워크 지원 안함)
      -d            데몬으로 실행
      -u <username> 전환할 사용자 이름(루트로 실행시)
      -m <num>      최대 메모리(MB단위, 기본값: 64)
      -M            데이터 저장시 메모리가 부족할 경우 오류를 반환(기본값은 오래된 데이터를 삭제)
      -c <num>      최대 접속 개수 (기본값: 1024)
      -P <file>     PID 파일 저장 위치. -d 옵션 사용시 사용
      -f <factor>   증가 팩터값. (기본값: 1.25)
      -n <bytes>    키+값+플래그를 저장할 최소 단위(기본값: 48)
      -L            large memory pages 사용(가능한경우)
      -t <num>      사용할 쓰레드 개수 (기본값: 4)
      -v            로그 보임
      -vv           자세한 로그 보임
      -vvv          매우 자세한 로그 보임

      1) 도움말. 중요하다고 생각되는건 번역했다. 대형 사이트의 경우 도움말을 참조해 메모리관련 옵션 최적화를 반드시 수행해야 한다.

      아래 커맨드는 windy 사용자의 권한을 사용하고, 64MB 메모리를 사용하고, 큰 페이지를 사용하며, 127.0.0.1만 바인드(외부 접속 불가)하는 데몬을 띄운다. PID 파일은 /tmp/memcached.pid 에 있다.
      root@wl ~ # memcached -u windy -d -m 64 -l 127.0.0.1 -p 11211 -L -P /tmp/memcached.pid

      memcached 는 kill 을 사용해 종료하면 된다.
      root@wl ~ # kill `cat /tmp/memcached.pid`

  • memcached 프로토콜 예제
    memcached 의 프로토콜은 두가지다. 바이너리 프로토콜과 아스키 프로토콜이 그것인데, 아스키 프로토콜은 telnet 등을 사용해 아래와 같이 이용할 수 있다. 부하가 많이 걸리는 곳에서는 바이너리 프로토콜이 아스키 프로토콜에 비해 성능이 ‘약간’ 좋은 것으로 알려져있다.
    root@wl ~ # telnet localhost 11211
    Trying 127.0.0.1…
    Connected to localhost.
    Escape character is ‘^]’.
    stats settings 1)
    STAT maxbytes 67108864
    STAT maxconns 1024
    STAT tcpport 11211
    STAT udpport 11211
    STAT inter NULL
    STAT verbosity 0
    STAT oldest 0
    STAT evictions on
    STAT domain_socket NULL
    STAT umask 700
    STAT growth_factor 1.25
    STAT chunk_size 48
    STAT num_threads 4
    STAT num_threads_per_udp 4
    STAT stat_key_prefix :
    STAT detail_enabled no
    STAT reqs_per_event 20
    STAT cas_enabled yes
    STAT tcp_backlog 1024
    STAT binding_protocol auto-negotiate
    STAT auth_enabled_sasl no
    STAT item_size_max 1048576
    STAT maxconns_fast no
    STAT hashpower_init 0
    END
    set mykey 0 100 2
    hi
    2)
    STORED
    get mykey 3)
    VALUE mykey 0 2
    hi
    END
    Ctrl+]
    telnet> Ctrl+D
    Connection to localhost closed.
    root@wl ~ #

    1) 세팅 확인
    2) 데이터 저장
    3) 데이터 추출

  • 기본 튜닝
    TCP 스펙상 접속을 끊은 후 TIME_WAIT 대기 시간이 발생한다. 30~240초로 설정할 수 있는데, 대부분의 운영체제에서는 240초가 기본값이다. 하지만 이 값은 memcached 를 운용하는 환경에서는 너무 길다. 트래픽이 많은 곳에서 memcached 와 빈번하게 통신하다 보면, TIME_WAIT가 수만개 이상 발생하는 경우가 있고, 이로인해 memcached 에 접속이 안되는 현상이 발생하는 경우가 있기 때문이다. (어느 정도까지 문제 없는지는 운영체제마다, 설정마다 다르다) 따라서 각 운영체제 마다 이를 줄여주는 옵션이 있다. memcached 를 실행한 서버에서 아래와 같이 30초로 세팅한다. 참고로 TCP표준은 최소 60초 이상을 권장한다.

    • 솔라리스
      root@wl ~ # ndd -set /dev/tcp tcp_time_wait_interval 30000
      root@wl ~ # export EVENT_NOEVPORT=1
    • 리눅스
      root@wll ~ # vi /etc/sysctl.conf
      net.ipv4.ip_local_port_range = 16384 65534
      net.ipv4.tcp_fin_timeout = 30
      net.ipv4.tcp_tw_reuse = 1
      root@wll ~ # sysctl -p
    • 윈도
      C:\>edit tcptimewait.reg
      [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]
      “TcpTimedWaitDelay”=dword:0000001e
      C:\>regedit /S tcptimewait.reg
  • memcached 와 DTrace
    현재 지원되는 프로바이더와 프로브는 아래와 같다. (아래 예제를 따라하기 전에 먼저 memcached 데몬을 실행해야 한다)
    root@wl ~ # dtrace -l -m memcached
    ID   PROVIDER            MODULE                          FUNCTION NAME
    2752 memcached16537         memcached                      assoc_delete assoc-delete
    2753 memcached16537         memcached                        assoc_find assoc-find
    2754 memcached16537         memcached                      assoc_insert assoc-insert
    2755 memcached16537         memcached               complete_update_bin command-add
    2756 memcached16537         memcached              complete_nread_ascii command-add
    2757 memcached16537         memcached               complete_update_bin command-append
    2758 memcached16537         memcached              complete_nread_ascii command-append
    2759 memcached16537         memcached              complete_nread_ascii command-cas
    2760 memcached16537         memcached                      do_add_delta command-decr
    2761 memcached16537         memcached            process_delete_command command-delete
    2762 memcached16537         memcached                process_bin_delete command-delete
    2763 memcached16537         memcached               process_get_command command-get
    2764 memcached16537         memcached                   process_bin_get command-get
    2765 memcached16537         memcached                      do_add_delta command-incr
    2766 memcached16537         memcached               complete_update_bin command-prepend
    2767 memcached16537         memcached              complete_nread_ascii command-prepend
    2768 memcached16537         memcached               complete_update_bin command-replace
    2769 memcached16537         memcached              complete_nread_ascii command-replace
    2770 memcached16537         memcached               complete_update_bin command-set
    2771 memcached16537         memcached              complete_nread_ascii command-set
    2772 memcached16537         memcached                 process_bin_touch command-touch
    2773 memcached16537         memcached                          conn_new conn-allocate
    2774 memcached16537         memcached                          conn_new conn-create
    2775 memcached16537         memcached                         conn_free conn-destroy
    2776 memcached16537         memcached                 dispatch_conn_new conn-dispatch
    2777 memcached16537         memcached                        conn_close conn-release
    2778 memcached16537         memcached                      do_item_link item-link
    2779 memcached16537         memcached                    do_item_remove item-remove
    2780 memcached16537         memcached                   do_item_replace item-replace
    2781 memcached16537         memcached             do_item_unlink_nolock item-unlink
    2782 memcached16537         memcached                    do_item_unlink item-unlink
    2783 memcached16537         memcached                    do_item_update item-update
    2784 memcached16537         memcached                    conn_set_state process-command-end
    2785 memcached16537         memcached                   process_command process-command-start
    2786 memcached16537         memcached              dispatch_bin_command process-command-start
    2787 memcached16537         memcached                    do_slabs_alloc slabs-allocate
    2788 memcached16537         memcached                    do_slabs_alloc slabs-allocate-failed
    2789 memcached16537         memcached                     do_slabs_free slabs-free
    2790 memcached16537         memcached                  do_slabs_newslab slabs-slabclass-allocate
    2791 memcached16537         memcached                  do_slabs_newslab slabs-slabclass-allocate-failed

    아래와 같이 memcached_watch.d 스크립트를 작성해 DTrace 를 실행하고 위의 프로토콜 예제를 다시 따라하면 [command-set fired]가 출력될 것이다. Ctrl+C를 눌러 종료한다.
    root@wl ~ # cat memcached_watch.d
    /* TO RUN: dtrace -s memcached_watch.d -p `pgrep -x memcached` -q */
    dtrace:::BEGIN
    {
    printf(“Hit Ctrl-C to end.\n”);
    }
    memcached*:::command-set
    {
    printf(“command-set fired\n”);
    }
    root@wl ~ # dtrace -s memcached_watch.d -p `pgrep -x memcached` -q
    Hit Ctrl-C to end.
    command-set fired
    ^C

JAVA/JSP

memcache.java  다운로드 (717 바이트)

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

package test;

 

import java.io.IOException;

import java.net.InetSocketAddress;

import java.util.HashMap;

 

import net.spy.memcached.MemcachedClient;

 

/**

* Memcached Sample.

* WindyHana’s Solanara – Memcached http://www.solanara.net/solanara/memcached

* java test.MemcachedSample

*/

public class MemcachedSample {

/**

* 테스트 함수

* @param args

*/

@SuppressWarnings(“unused”)

public static void main(String[] args) {

MemcachedClient c;

try {

c = new MemcachedClient(new InetSocketAddress(“localhost”, 11211));

c.set(“someKey”, 3600, new HashMap<String, Object>());

Object myObjeckt = c.get(“someKey”);

c.delete(“someKey2”);

} catch (IOException e) {

e.printStackTrace();

}

}

}

PHP

PHP에서 memcached 를 사용하기 위한 모듈은 두가지를 제공한다. PECL:memcachePECL:memcached 가 그것인데, 두가지 모두 memcached 에 접속해 사용한다. 단지 PECL:memcache는 memcached 에 직접 접속하는 PHP 모듈이고, PECL:memcached 는 libMemcached 를 통해 memcached 에 접속하는 모듈이라는 점이 다르다. PHP에서의 사용 방법이나 지원 함수도 조금씩 다르므로 매뉴얼을 확인하자.

  • PECL:memcache 를 설치하기 위해서는 autoconf 가 필요하다. 윈디하나의 솔라나라: Autotools – autoconf를 참고해 autoconf 를 설치하자.
  • PECL:memcache 설치 및 설정
    root@wl ~/src # mkdir phpmemcache
    root@wl ~/src # cd phpmemcache
    root@wl ~/src/phpmemcache # /usr/local/php/bin/pecl download memcache
    root@wl ~/src/phpmemcache # tar xvf memcache-2.2.7.tgz
    root@wl ~/src/phpmemcache # cd memcache-2.2.7
    root@wl ~/src/phpmemcache/memcache-2.2.7 # /usr/local/php/bin/phpize
    root@wl ~/src/phpmemcache/memcache-2.2.7 # CFLAGS=”-xc99″ ./configure -with-php-config=/usr/local/php/bin/php-config
    root@wl ~/src/phpmemcache/memcache-2.2.7 # make
    root@wl ~/src/phpmemcache/memcache-2.2.7 # cp memcache.php /usr/local/php/lib/php
    root@wl ~/src/phpmemcache/memcache-2.2.7 # cp ./modules/memcache.so /usr/local/php/lib/php/extensions

    php.ini 를 수정해야 한다. 윈디하나의 솔라나라: SAMP의 [PHP 설정]를 참조해 extension_dir 을 설정하고 아래와 같이 extension 을 추가해야 한다.
    root@wl ~ # vi /usr/local/php/lib/php.ini
    extension=memcache.so

  • memcached 세션 설정
    PHP의 세션 핸들러로 memcached 를 설정할 수 있으며, 저장 경로로 두개 이상의 memcached 데몬을 사용할 수 있다. php 세션을 위한 memcached 의 키값은 [memc.sess.key] 형식으로 정해진다.
    root@wl ~ # vi /usr/local/php/lib/php.ini
    session.save_handler = memcache
    session.save_path = “127.0.0.1:11211”
  • PHP – memcache 테스트
memcache.phps  다운로드 (534 바이트)

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

<?php session_start(); ?>

<pre>

<?php

$presessdata = @$_SESSION[“data”];

$_SESSION[“data”] = @$_SESSION[“data”] + 1;

 

$memcache = new Memcache;

$memcache->connect(“localhost”, 11211);

print_r($memcache->getStats());

 

$items = array(

‘key1’ => ‘value1’,

‘key2’ => ‘value2’,

‘key3’ => ‘value3’

);

foreach ($items as $k => $v) {

$memcache->set($k, $v);

}

var_dump($memcache->get(array(‘key1’, ‘key3’)));

var_dump($memcache->get(‘key2’));

var_dump($memcache->get(‘key4’));

?>

SESSION: <?php echo $_SESSION[“data”]; ?>

</pre>

아래와 유사하게 출력되어야 한다.

Array
(
[pid] => 16700
[uptime] => 425530
[time] => 1333412724
[version] => 1.4.15
[libevent] => 2.0.20-stable
[pointer_size] => 32
[rusage_user] => 6.387770
[rusage_system] => 4.913250
[curr_connections] => 5
[total_connections] => 57
[connection_structures] => 7
[reserved_fds] => 20
[cmd_get] => 148
[cmd_set] => 45
[cmd_flush] => 0
[cmd_touch] => 0
[get_hits] => 100
[get_misses] => 48
[delete_misses] => 6
[delete_hits] => 0
[incr_misses] => 0
[incr_hits] => 0
[decr_misses] => 0
[decr_hits] => 0
[cas_misses] => 0
[cas_hits] => 0
[cas_badval] => 0
[touch_hits] => 0
[touch_misses] => 0
[auth_cmds] => 0
[auth_errors] => 0
[bytes_read] => 66307
[bytes_written] => 36315
[limit_maxbytes] => 67108864
[accepting_conns] => 1
[listen_disabled_num] => 0
[threads] => 4
[conn_yields] => 0
[hash_power_level] => 16
[hash_bytes] => 262144
[hash_is_expanding] => 0
[expired_unfetched] => 0
[evicted_unfetched] => 0
[bytes] => 27437
[curr_items] => 20
[total_items] => 45
[evictions] => 0
[reclaimed] => 0
)
array(2) {
[“key1”]=>
string(6) “value1”
[“key3”]=>
string(6) “value3”
}
string(6) “value2”
bool(false)
SESSION: 1

  • igbinary
    • php serializer중 하나다. PHP의 표준 serializer 보다 메모리를 덜 소비하고, 성능도 더 좋다. libmemcached 와 PECL:memcached 를 설치해야 memcached 와 함께 사용할 수 있다.
    • PECL: igbinary
      root@wl ~/src # /usr/local/php/bin/pecl download igbinary
      root@wl ~/src # tar xvfz igbinary-1.1.1.tgz
      root@wl ~/src # cd igbinary-1.1.1
      root@wl ~/src/igbinary-1.1.1 # /usr/local/php/bin/phpize
      root@wl ~/src/igbinary-1.1.1 # CFLAGS=”-xc99″ ./configure –with-php-config=/usr/local/php/bin/php-config
      root@wl ~/src/igbinary-1.1.1 # make
      root@wl ~/src/igbinary-1.1.1 # cp ./modules/igbinary.so /usr/local/php/lib/php/extensions
      root@wl ~/src/igbinary-1.1.1 # vi /usr/local/php/lib/php.ini
      extension=igbinary.so
      session.serialize_handler=igbinary
      ;apc.serializer=igbinary

 

출처 – http://www.solanara.net/solanara/memcached

 

원본 위치 <http://linuxism.tistory.com/984>

[linux] redis sentinel

Redis Sentinel

Redis 본가 프로젝트로 개발되고있는 Redis 서버의 사활 감시 / 알림 및 자동 페일 오버 기능을 제공하는 관리 서버 (redis-sentinel)입니다. v2.4.16 또는 2.6.0-rc6 이상 버전에서 사용할 수 있습니다. 공식 문서를 참고로하면서 동작 확인을합니다.

  • 환경 : CentOS 5.9 (x86_64), Redis 2.6.10

구성

여기에서는 두 호스트에서 Slave를 2 프로세스 Sentinel 3 프로세스 구성 봅니다.

  • Master db0 : 6379
  • Slave db0 : 6380, db1 : 6379
  • Sentinel db0 : 26379, db0 : 23680, db1 : 26379

설정

/etc/redis/sentinel.conf

# port <sentinel-port>
port 26379
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster db0 6379 2
# sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down after milliseconds mymaster 5000
# sentinel failover-timeout <master-name> <milliseconds>
sentinel failover timeout mymaster 900000
# sentinel can-failover <master-name> <yes | no>
sentinel can failover mymaster yes
# sentinel parallel-syncs <master-name> <numslaves>
sentinel parallel syncs mymaster 1

각 설정 항목 표하고 있습니다. Sentinel 의한 클러스터 모니터는 이른바 Quorum 기반 투표의 방식을 취합니다. 여러 Sentinel이 Master를 감시하고 그중 임계 값보다 많은 Sentinel이 Master 다운을 감지하면 장애 조치 프로세스를 시작합니다.

설정 항목 개요
monitor Master 호스트와 포트 및 상태가 ** ODOWN (objectively down) **로 전환하기위한 정족수 (quorum)
down-after-milliseconds Master / Slave 다운 감지 후 상태가 ** SDOWN (subjectively down) **로 전환 될 때까지의 시간 (ms)
failover-timeout 장애 처리 시간 (ms)
can-failover 장애 조치가 실행하거나 (yes / no)
parallel-syncs Slave를 Master로 승격시킨 후, 몇 개의 Slave와 동기화하거나

Sentinel은 Master와 Slave 모두의 사활 감시를 해줍니다 만, 상태가 ODOWN로 전환하는 것은 Master만이므로주의하십시오. can-failover를 no로하고 시작한 Sentinel 과정은 장애 조치 자체는 실시하지 않고 (다른 Sentinel에 맡길) 자신은 다운 탐지 및 투표 처리 만합니다.

시작

Sentinel 시작 전에 복제가 작동하는지 확인해야합니다.

redis-cli

redis db0 : 6379> info replication
# Replication
role : master
connected_slaves : 1
slave0 : db0, 6380, online
slave1 : db1, 6379, online

계속 3 개의 Sentinel 프로세스를 시작합니다.

redis-sentinel

$ redis sentinel / etc / redis / sentinel. conf
## 또는 redis-server sentinel 모드로 부팅
$ redis server / etc / redis / sentinel. conf sentinel

로그에서 각 Slave 및 Sentinel와 연결 한 것을 확인할 수 있습니다.

[19069] 14 May 16 : 30 : 31.909 * + slave slave db1 : 6379 db1 6379 @ mymaster db0 6379
[19069] 14 May 16 : 30 : 31.909 * + slave slave db0 : 6380 db0 6380 @ mymaster db0 6379
[19069] 14 May 16 : 30 : 38.320 * + sentinel sentinel db0 : 26380 db0 26380 @ mymaster db0 6379
[19069] 14 May 16 : 30 : 39.655 * + sentinel sentinel db1 : 26379 db1 26379 @ mymaster db0 6379

또한 Sentinel 시작 후 INFO 명령 Sentinel 관련 정보를 확인할 수 있습니다.

redis-cli

redis db0 : 26379> info sentinel
# Sentinel
sentinel_masters : 1
sentinel_tilt : 0
sentinel_running_scripts : 0
sentinel_scripts_queue_length : 0
master0 : name = mymaster, status = ok, address = db0 : 6379, slaves = 2, sentinels = 3

Sentinel 과정 자체 모니터링은 아래 항목을 보도록하면 좋을까 생각합니다.

장애 조치 동작 확인을 위해 여기에서 Master를 떨어 뜨립니다.

redis-cli

redis db0 : 6379> shutdown

로그에서 장애 조치 진행 상황을 확인할 수 있습니다.

[19069] 14 May 16 : 30 : 51.170 # + sdown master mymaster db0 6379
[19069] 14 May 16 : 30 : 52.386 # + odown master mymaster db0 6379 #quorum 2/2
[19069] 14 May 16 : 30 : 52.386 # + failover-triggered master mymaster db0 6379
[19069] 14 May 16 : 30 : 52.386 # + failover-state-wait-start master mymaster db0 6379 #starting in 13910 milliseconds
[19069] 14 May 16 : 31 : 06.379 # + failover-state-select-slave master mymaster db0 6379
[19069] 14 May 16 : 31 : 06.480 # + selected-slave slave db1 : 6379 db1 6379 @ mymaster db0 6379
[19069] 14 May 16 : 31 : 06.480 * + failover-state-send-slaveof-noone slave db1 : 6379 db1 6379 @ mymaster db0 6379
[19069] 14 May 16 : 31 : 06.583 * + failover-state-wait-promotion slave db1 : 6379 db1 6379 @ mymaster db0 6379
[19069] 14 May 16 : 31 : 06.901 # + promoted-slave slave db1 : 6379 db1 6379 @ mymaster db0 6379
[19069] 14 May 16 : 31 : 06.902 # + failover-state-reconf-slaves master mymaster db0 6379
[19069] 14 May 16 : 31 : 06.991 * + slave-reconf-sent slave db0 : 6380 db0 6380 @ mymaster db0 6379
[19069] 14 May 16 : 31 : 07.294 * + slave-reconf-inprog slave db0 : 6380 db0 6380 @ mymaster db0 6379
[19069] 14 May 16 : 31 : 08.316 * + slave-reconf-done slave db0 : 6380 db0 6380 @ mymaster db0 6379
[19069] 14 May 16 : 31 : 08.417 # + failover-end master mymaster db0 6379
[19069] 14 May 16 : 31 : 08.417 # + switch-master mymaster db0 6379 db1 6379
[19069] 14 May 16 : 31 : 08.548 * + slave slave db0 : 6380 db0 6380 @ mymaster db1 6379
[19069] 14 May 16 : 31 : 09.068 * + sentinel sentinel db0 : 26380 db0 26380 @ mymaster db1 6379
[19069] 14 May 16 : 31 : 12.258 * + sentinel sentinel db1 : 26379 db1 26379 @ mymaster db1 6379

Sentinel이 Master 다운을 감지하면 상태가 SDOWN에 quorum 파라미터에서 지정한 수의 SDOWN이 맞춰지면 다음은 ODOWN로 전환 후 장애 조치 프로세스가 시작됩니다.

마지막으로 새로운 Master와 Slave에서 제대로 실행되는지 확인합니다.

redis-cli

redis db1 : 6379> info replication
# Replication
role : master
connected_slaves : 1
slave0 : db0, 6380, online

이상 Sentinel 페일 오버 기능이 작동 확인까지 시도했습니다.

Sentinel API

Sentinel 몇 가지 API를 제공하고 있기 때문에 쉽게 소개하고 싶습니다.

redis-cli

## SENTINEL masters
# 감시 대상의 Master 정보 확인
redis 127.0 0.1 : 26379> sentinel masters
1) 1) “name”
2) “mymaster”
3) “ip”
4) “127.0.0.1”
5) “port”
6) “6379”
7) “runid”
8) “b3b31e6c6d1fbb0cec5d179fd666ce00ea103746”
9) “flags”
10) “master”
11) “pending-commands”
12) “0”
13) “last-ok-ping-reply”
14) “568”
15) “last-ping-reply”
16) “568”
17) “info-refresh”
18) “9745”
19) “num-slaves”
20) “1”
21) “num-other-sentinels”
22) “1”
23) “quorum”
24) “2”

## SENTINEL slaves <master name>
# Slave 정보 확인
redis 127.0 0.1 : 26379> sentinel slaves mymaster
1) 1) “name”
2) “127.0.0.1:6380”
3) “ip”
4) “127.0.0.1”
5) “port”
6) “6380”
7) “runid”
8) “17c0f7e7e4d2af0f5f6140ea0ceb0d82d0010aed”
9) “flags”
10) “s_down, slave, disconnected”
11) “pending-commands”
12) “0”
13) “last-ok-ping-reply”
14) “709377”
15) “last-ping-reply”
16) “709377”
17) “s-down-time”
18) “704333”
19) “info-refresh”
20) “712808”
21) “master-link-down-time”
22) “0”
23) “master-link-status”
24) “ok”
25) “master-host”
26) “127.0.0.1”
27) “master-port”
28) “6379”
29) “slave-priority”
30) “100”

## SENTINEL is-master-down-by-addr <ip> <port>
# Master의 사활 확인
redis 127.0 0.1 : 26379> sentinel is – master down by addr 127.0 0.1 6379
1) (integer) 0 ## 0 : UP 1 : DOWN
2) “397dec99760d5d30043941fe4c1c35ba99e99ebf”## Sentinel (subjective leader) run_id

## SENTINEL get-master-addr-by-name <master name>
# Master IP, Port를 확인
redis 127.0 0.1 : 26379> sentinel get master addr by name mymaster
1) “127.0.0.1”
2) “6379”

## SENTINEL reset
# Sentinel의 현재 상태를 재설정 (장애 조치 중에라도)
redis 127.0 0.1 : 26379> sentinel reset mymaster
(integer) 1

Sentinel 관련 관리 도구를 만들 때이 Sentinel API를 지원하는 클라이언트 라이브러리를 사용하면 쉽게 아닐까 생각합니다.

이하, 장애 복구 프로세스의 거동에 관한 부분을 픽업하여 소개합니다.

승격 Slave의 선택

당연 합니다만 Slave로 성공적으로 실행하는 프로세스가 적용됩니다. 세세한 조건을 생략하고 싹둑 말하면, Master와의 연결이 안정하고 (다운 타임이 적은) Sentinel에서 PING / INFO 명령에 최근 5000ms 이내에 응답하는 Slave가 대상이됩니다 (자세한 내용은 공식 문서와 src / sentinel.c 참조).

대상이되는 Slave가 여러 개있는 경우 slave_priority 값이 작은 Slave를 선택합니다.

redis-cli

redis db0 : 6380> info replication
# Replication
role : slave
master_host : 127.0 0.1
master_port : 6379
master_link_status : up
master_last_io_seconds_ago : 0
master_sync_in_progress : 0
slave_priority : 100 ## <-이 값
slave_read_only : 1
connected_slaves : 0

같은 slave_priority의 Slave가 있으면 run_id 작은 Slave를 선택합니다.

redis-cli

redis db0 : 6380> info
# Server
redis_version : 2.6. 10
redis_git_sha1 : 00000000
redis_git_dirty : 0
redis_mode : standalone
os : Linux 2.6 18194.26 1. el5 x86_64
arch_bits : 64
multiplexing_api : epoll
gcc_version : 4.1. 2
process_id : 17468
run_id : 17 c0f7e7e4d2af0f5f6140ea0ceb0d82d0010aed ## <-이 값
tcp_port : 6380
uptime_in_seconds : 1738
uptime_in_days : 0
lru_clock : 538965

2013/06 현재는 slave_priority을 변경할 API는 공개되지 않은 것이므로 단순히 run_id 젊은 Slave가 선택되게됩니다. Slave 선택 알고리즘은 향후 변경 될 수도있을 것입니다.

Sentinels / Slaves 자동 감지

Sentinel 설정에 Slave의 목록을 갖게 할 필요가없는 것은 Sentinel이 Pub / Sub 의한 정보 공유를하고 있기 때문입니다. 중간에 다른 Sentinel와 Slave를 온라인으로 추가해도 다른 Sentinel 그 정보는 전해집니다.

redis-cli

## Sentinel “__sentinel __ : hello”채널을 이용하고있다
redis db0 : 6379> subscribe __sentinel__ : hello
Reading messages (press Ctrl C to quit)
1) “subscribe”
2) “__sentinel __ : hello”
3) (integer) 1
1) “message”
2) “__sentinel __ : hello”
3) “127.0.0.1:26380:77887a367e1c76ee9dc15f67a2fb3dc49bb00bf4:1”
1) “message”
2) “__sentinel __ : hello”
3) “127.0.0.1:26379:3a92da7269b69fa1dcce5915068c4af6e8caf161:1”
1) “message”
2) “__sentinel __ : hello”
3) “127.0.0.1:26380:77887a367e1c76ee9dc15f67a2fb3dc49bb00bf4:1”
1) “message”
2) “__sentinel __ : hello”
3) “127.0.0.1:26379:3a92da7269b69fa1dcce5915068c4af6e8caf161:1”

메시지의 내용은 host : port : run_id : can-failover가있어 __ sentinel __ : hello 채널에 5 초마다 publish 모든 Sentinel은이 채널을 subscribe하여 정보 공유하고 있습니다.

[linux] kernel parameter Swappiness 스왑 공간 사용 비중

Reference

 

http://forums.gentoo.org/viewtopic.php?t=175419

  1. Swappiness (2.6 kernels)

Since 2.6, there has been a way to tune how much Linux favors swapping out to disk compared to shrinking the caches when memory gets full.

 

ghoti adds:

When an application needs memory and all the RAM is fully occupied, the kernel has two ways to free some memory at its disposal: it can either reduce the disk cache in the RAM by eliminating the oldest data or it may swap some less used portions (pages) of programs out to the swap partition on disk.

It is not easy to predict which method would be more efficient.

The kernel makes a choice by roughly guessing the effectiveness of the two methods at a given instant, based on the recent history of activity.

 

Before the 2.6 kernels, the user had no possible means to influence the calculations and there could happen situations where the kernel often made the wrong choice, leading to thrashing and slow performance. The addition of swappiness in 2.6 changes this.

 

원본 위치 <http://knight76.tistory.com/1549>

 

 

# sysctl vm.swappiness   (또는 cat /proc/sys/vm/swappiness 으로 확인 가능)

vm.swappiness = 60

 

 

Swap

Linux 시스템에서는 다양한 용도로 스왑을 사용한다. 일반적으로 부족한 메모리를 보충하기 위한 용도로만 알려져 있지만 아래와 같은 용도로 활용이 되고 있다.

  • 메모리를 많이 사용하는 프로그램을 위해 (가장 일반적인 용도)
  • Hibernation (메모리의 내용을 디스크에 저장해 두기 위한 용도)

일반 노트북이나 랩탑에서 Hibernation을 하기 위해서는 시스템의 메모리 크기보다 큰 스왑 공간이 반드시 필요하다. 메모리의 정보를 모두 디스크에 담아야 하기 때문이다.

  • 예측에서 벗어난 메모리 공간을 사용하는 프로그램에 대비하기 위한 경우
  • 메모리의 효율을 높이기 위해서

스왑 영역은 일반적으로 디스크에 존재하기 때문에 메모리에 비교할 수 없을 정도로 성능이 떨어지지만 이러한 스왑 영역이 메모리 사용 효율을 높일 수 있다. 프로세스가 데이터를 읽어들일 때 메모리에 저장하여 읽게 되고 이러한 작업이 빈번하게 발생할 경우 메모리에 캐시하여 응답속도를 높이는 형태로 동작한다.

즉, 메모리에 캐시할 수 있는 공간이 많으면 많을 수록 효율을 높일 수 있는데 스왑 영역은 프로세스가 예약한 메모리 공간 중에서 사용되지 않는 혹은 당장 필요하지 않는 부분을 저장하여 메모리가 캐시 역할을 할 수 있는 공간을 더 확보 할 수 있도록 한다.

메모리가 많은데도 Swap을 사용합니다

자주 문의 받는 내용 중 하나이다. 분명 시스템의 RAM은 여유가 있음에도 스왑으로 할당해 둔 공간에 데이터를 쓰는 경우가 종종 있다. 사실 크게 문제되지는 않지만 스왑 영역과 데이터를 자주 주고 받게 된다면 디스크 I/O의 성능에 전체 시스템의 성능이 영향을 받는 경우가 있다.

Linux가 메모리가 많음에도 불구하고 스왑공간을 사용하는 이유는 스왑 사용여부를 결정하는 값의 계산식에서 비롯되는데 Linux Kernel의 mm/vmscan.c에는 아래와 같은 코드가 있다.

swap_tendency = mapped_ratio / 2 + distress + sc->swappiness;

스왑을 사용하려는 경향(tendency)을 계산하는데 있어서 mapped_ratio와 distress 그리고 swappiness라는 변수가 영햐을 미친다.

먼저, mapped_ratio는 아래와 같이 계산되는데

mapped_ratio = ((global_page_state(NR_FILE_MAPPED) +
global_page_state(NR_ANON_PAGES)) * 100) / vm_total_pages;

쉽게 말해서 전체 메모리 중에서 프로세스가 사용하고 있는(Mapped) 메모리의 크기에 대한 비율(% 값)이다.

두 번째로 distress 변수는 아래와 같이 표현되며

distress = 100 >> min(zone->prev_priority, priority);

페이지(메모리 저장구조 단위)를 얼마나 많이 스캔하게 될 건지를 뜻한다. 일반적으로 값은 0이며 100에 가까울 수록 스캔해야하는 양이 많아져서 시스템에 문제가 있다는 뜻이다. (커널 코드 주석에서는 Great Trouble이라고 표현되어 있다)

그리고 swappiness 값은 사용자가 직접 수정할 수 있는 변수로 /proc/sys/vm/swappiness에서 확인 할 수 있으며 기본 값은 60이다.

첫 번째 확인했던 수식을 다시금 정리하면 일반적인 경우에 distress는 0이고 swappiness는 60이기 때문에 아래와 같이 표현 된다.

swap_tendency = mapped_ratio / 2 + 0 + 60;

만약, 4GB 메모리를 가진 시스템에서 3GB를 사용 중이라고 가정하면

swap_tendency = (3GB / 4GB * 100) / 2 + 0 + 60 = 97.5

97.5이기 때문에 바로 스왑이 일어나지는 않는다. (100이상이면 발생한다)

swappiness 값에 따른 영향

실질적으로 사용자가 변경할 수 있는 값은 swappiness 변수 이기 때문에 이 값에 따른 스왑이 발생하는 시점을 유추해 볼 필요가 있을 것이다.

먼저 기본 값인 60일 경우에는 언제 스왑이 발생할지 계산해 보기위해서는 swap_tendency가 100이 되는 시점을 찾으면 되는데

100 = mapped_ratio / 2 + distress + swappiness
mapped_ratio = (100 – distress – swappiness) * 2
mapped_ratio = (100 – 0 – 60) * 2 = 80

즉, 80% 이상의 메모리를 사용하게 되면 스왑이 발생하게 될 것을 예측 할 수 있다. 다만 distress 0인 상황에서라는 전제조건이 필요하다.

만약, swappiness 값을 10으로 설정하고 distress가 0이면 mapped_ratio는 200%이기 때문에 스왑이 발생하는 경우의 조건이 성립하지 않지만 distress가 50이면 80%로 계산된다.

그래서

앞의 예제와 같이 distress 값은 유동적이기 때문에 결과적으로 swappiness 값의 설정이 절대적인 결과를 얻는 값으로 사용될 수 없지만 0에 가까울 수록 가급적 스왑을 하지 않으려 할 것이고 100에 가까울 수록 스왑을 하도록 설정할 수 있다는 부분은 어렵지 않게 알 수 있다.

추가적으로

자주 질문 받던 내용을 정리하기 위해 다시금 리눅스 소스코드를 열어보았다가 발견한 사실로 위에서 언급한 계산 식이 vmscan.c 코드에서 사라졌다.

몇 개의 버전을 더 받아서 확인해 본 결과 CentOS 5.7/RHEL 5.7의 2.6.18-274 커널에는 존재하지만 kernel.org에서 내려받은 2.6.35.13과 3.4 커널 코드에는 존재하지 않았다.

즉, 메모리 관리 기법에 대한 변화로 인해서 해당 코드는 삭제 된 것으로 추측된다. (2.6.20 커널의 패치 파일에서는 수식 변경이 발견되었고 그 뒤 버전에서는 아예 사라졌다) 변경된 내용에 대한 내용까지 조사해서 정리하면 좋겠지만 이 문서를 작성하면서 고려하지 않았던 내용이기 때문에 이 부분은 나중으로 미루려고 한다.

다만, 최신 커널 문서에서도 여전히 swappiness 값은 0 100사이에서 동일한 의미로 설명되고 있기 때문에 설정 값에 대한 내부 처리 부분의 변경은 다시 확인해야겠지만 당장 설정하는데 별다른 문제는 없당

[기타] 레디스 커멘드라인 사용 꿀팁

Redis-cli

 

SCAN 0 COUNT 100 MATCH *

# 100개 제한 읽어오기. Keys * 보다 효율적임..

 

DEBUG OBJECT 키

# 해당 정보의 사이즈 lru , expire 정보등을 읽어옴

 

SETEX 키 시간 키밸류

# expire time을 걸어 아이템을 set 한다.

# setex hong 60 sungho 라고 입력하면, 60초간 hong이라는 키가 저장된다.

 

 

SLOWLOG GET

# get 으로 시작하는 카운트 중 시간이 오개걸리는 값을 반환한다..

# 일반적으로 겟 명령어에서 슬로우 로그가 발생하는 경우 해당 키값의 데이터가 용량이 가장 큰 (메모리를 많이 잡아먹는) 키 값이다..

# 레디스 운영 시 OOM redis Out Of Memory 같은 경우, 해당 키 또는 리스트의 값이 너무 큰 (보통 팝 과정 없이  잘못 쌓이는 push LIST에서 발생한다. )

# GET , RESET, LEN  등을 확인 할 수 있다.

 

Lpush, Lpop, Rpush , Rpop

# push 는 데이터를 입력하며, Left, Right로 데이터를 입력한다.

# pop 은 데이터를 읽는 개념이 아닌, 가져간다는 표현으로 pop을 통해 꺼내어진 데이터는 해당 데이터테이블에서 삭제된다.

# Lrange 명령을 통해서 대상이 지정된 범위의 리스트를 읽어온다. 0 은 시작점을 의미하고, -1 은 리스트의 끝 (오른쪽 마지막) 을 의미하므로, 모든 리스트에 저장된 데이터를 확인 할 때 사용한다.

# 모든 리스트에서 데이터를 꺼내어 쓰면, 데이터가 없다는 의미의 nil 을 표시한다.

# 예시 )

Rpush hong A B C

 

LRANGE hong 0 -1

“A”

“B”

“C”

 

Rpop hong

“C”

 

Rpop hong

“B”

 

Rpop hong

“A”

 

Rpop hong

(nil)

 

 

Redis-cli -h HOSTNAME –stat

# 레디스의 key count, memory Usage, clinet, blocked, requests, connections 정보를 알려줌..

 

Redis-cli -h HOSTNAME -c ‘keys hong*” | xargs redis-cli -h HOSTNAME DEL

# hong으로 시작하는 모든 키를 검색하여, 한번에 지우는 방법..

[python] boto모듈을 이용해 s3 backup (upload)

from boto.s3.connection import S3Connection

# S3 account

AWS_ACCESS_KEY_ID = ‘엑세스키’

AWS_ACCESS_KEY_SECRET = ‘시크릿키’

# make connection

conn = S3Connection(AWS_ACCESS_KEY_ID, AWS_ACCESS_KEY_SECRET)

# backup target BUCKET

bucket_name = ‘버킷명’

bucket = conn.get_bucket(bucket_name)

# BACKUP DIR and target DIR

backup_dir =’/backup/로컬백업폴더’

target_dir = ‘버킷하위디렉터리명’

# TIME setting to target

import time

utime = time.strftime(‘%Y-%m-%d’)

dest_dir = target_dir+’/’+utime

# search FUNCTION DEF

import os.path, os

def find(inputdir):

return [os.path.join(path, file)

for (path, dirs, files) in os.walk(inputdir)

for file in files]

# Search

listfile=find(backup_dir)

# upload

from boto.s3.key import Key

for list in listfile:

#print(list)

uploadkey = dest_dir+list

print(‘upload files to ‘+bucket_name+’ bucket\n’+’dir = ‘+uploadkey+’\n’)

k = Key(bucket)

k.key = uploadkey

k.set_contents_from_filename(list)

print ‘upload FILES finish’

# END

[protocol] HTTP 1.1 status code

HTTP 1.1 status codes [TOP]

100 : Continue

101 : Switching protocols

200 : OK, 에러없이 전송 성공

201 : Created, POST 명령 실행 및 성공

202 : Accepted, 서버가 클라이언트 명령을 받음

203 : Non-authoritative information, 서버가 클라이언트 요구 중 일부만 전송

204 : No content, 클라언트 요구을 처리했으나 전송할 데이터가 없음

205 : Reset content

206 : Partial content

300 : Multiple choices, 최근에 옮겨진 데이터를 요청

301 : Moved permanently, 요구한 데이터를 변경된 임시 URL에서 찾았음

302 : Moved temporarily, 요구한 데이터가 변경된 URL에 있음을 명시

303 : See other, 요구한 데이터를 변경하지 않았기 때문에 문제가 있음

304 : Not modified

305 : Use proxy

400 : Bad request, 클라이언트의 잘못된 요청으로 처리할 수 없음

401 : Unauthorized, 클라이언트의 인증 실패

402 : Payment required, 예약됨

403 : Forbidden, 접근이 거부된 문서를 요청함

404 : Not found, 문서를 찾을 수 없음

405 : Method not allowed, 리소스를 허용안함

406 : Not acceptable, 허용할 수 없음

407 : Proxy authentication required, 프록시 인증 필요

408 : Request timeout, 요청시간이 지남

409 : Conflict

410 : Gone, 영구적으로 사용할 수 없음

411 : Length required

412 : Precondition failed, 전체조건 실패

413 : Request entity too large,

414 : Request-URI too long, URL이 너무 김

415 : Unsupported media type

500 : Internal server error, 내부서버 오류(잘못된 스크립트 실행시)

501 : Not implemented, 클라이언트에서 서버가 수행할 수 없는 행동을 요구함

502 : Bad gateway, 서버의 과부하 상태

503 : Service unavailable, 외부 서비스가 죽었거나 현재 멈춤 상태

504 : Gateway timeout

505 : HTTP version not supported