'분류 전체보기'에 해당되는 글 104건

카테고리 없음

./bin/mysqladmin -u root shutdown


[mysqld]

character-set-server=utf8

collation-server=utf8_general_ci


init_connect=SET collation_connection=utf8_general_ci

init_connect=SET NAMES utf8

[client]

default-character-set=utf8

[mysql]

default-character-set=utf8


./bin/mysqld_safe &




PHP

카테고리 없음
doubleval -- 문자열에서 배정도 실수형 값만 리턴한다. floatval()의 별칭
    :: double doubleval(mixed var)
empty -- 변수가 비어있는지 검사합니다. 변수는 선언되어있으나 NULL값이 경우에도 TRUE이다.
    :: boolean empty(mixed var)
floatval -- 변수의 실수값을 얻습니다.
get_defined_vars --  모든 정의된 변수의 배열을 반환합니다.
    :: array get_defined_vars (void)
get_resource_type --  파일핸들,DB연결등의 리소스타입을 리턴한다.
    :: string get_resource_type (resource handle)
gettype -- 변수 형을 문자열로 리턴한다. (주의)값이 할당안된 변수는 NULL을,널스트링(NULL,"")이 할당된것은 string을 리턴한다.
    :: string gettype(mixed var)
import_request_variables -- GET/POST/쿠키 변수를 전역으로 가져옵니다.
intval -- 문자열에서 integer값만 리턴한다.
    :: int intval(mixed var [, int base])
    예) $var1="84 inch"; echo intval($var1) ; => 결과값은 84
is_array -- 변수가 배열인지 확인합니다.
    :: bool is_array(mixed var)
is_bool --  변수가 불린인지 확인합니다.
is_callable --  변수의 내용이 함수처럼 호출할 수 있는지 확인합니다.
is_double -- is_float()의 별칭.
is_float -- 변수가 실수인지 확인합니다.
is_int -- 변수가 정수인지 확인합니다.
is_integer -- is_int()의 별칭.
is_long -- is_int()의 별칭.
is_null --  변수가 NULL인지 확인합니다.
    예) $str1;  $str2="";   => $str1은 TRUE , $str2는 FALSE이다.  
is_numeric --  변수가 수나 수 문자열인지 확인합니다.
is_object -- 변수가 객체인지 확인합니다.
is_real -- is_float()의 별칭.
is_resource --  변수가 자원인지 확인합니다.
is_scalar --  변수가 스칼라인지 확인합니다.
is_string -- 변수가 문자열인지 확인합니다.
isset -- 존재하는 변수인지 확인합니다. 값이 할당되어 있지 않은 변수와 null로 할당한 변수는 false를 리턴한다.
print_r --  변수에 관한 정보를 사람이 읽기 좋게 출력합니다.
serialize --  값의 저장 표현을 생성합니다.
settype -- 변수타입을 강제로 형변환시키고 성공여부를 리턴한다..
strval -- 변수의 문자열값을 얻습니다. 흔히 숫자값을 문자열로 리턴을 한다.
unserialize --  저장 표현에서 PHP 값을 작성합니다.
unset -- 주어진 변수를 제거합니다.
var_dump -- 변수에 관한 정보를 덤프합니다.
var_export -- 변수의 표현을 출력하거나 문자열로 반환합니다.




카테고리 없음

출처 : http://the-earth.tistory.com/entry/Redis-%EB%8C%80%EB%9F%89-insert


Redis로 대량 insert를 하기에는 여러가지 문제점이 있다. 

매번 클라이언드토 요청하는 것은 RTT(Round trip time)때문에 아주 느릴것이다. 

파이프라이닝(pipelining)을 사용할 수도 있겠지만 대량의 insert를 위해서는 수행한 후 그 결과들을 읽으면서 새로운 command들을 write하는 것이 필요하다. 


소수의 client만이 non-blocking I/O를 지원하며 또 모든 client가 최대의 처리량을 달성할 수 있도록 결과들을 효과적으로 파싱하지 못한다. 

이런 이유들 때문에 Redis는 row format으로 Redis protocol을 담은 text file을 import하는 방식을 제공한다. 


예를 들어 10억개의 key들이 'keyN -> ValueN' 형태로 insert되어야한다면 우리는 아래와 같이 Redis protocol 형식을 따르는 파일을 만들면 된다. 

SET Key0 Value0

SET Key1 Value1

...

SET KeyN ValueN

이제 남은것은 이 파일을 Redis에 가능한한 빠르게 보내는 것이다. 예전 방식으로는 아래의 명령어를 통해 netcat으로 보내는 것이었다. 

(cat data.txt; sleep 10) | nc localhost 6379 > /dev/null

하지만 이런 방법은 안전하지 못한데 이유는 netcat이 데이터를 다 보냈는지 모르며 에러 또한 check할 수 없다. 

아직 불안전한 Redis의 branch에서는 pipe mode라고 불리는 새로운 모드의 redis-cli utility를 제공하는데 이 util은 대량의 insert를 위해 만들어졌다. 

pipe mode를 사용해서 아래와 같은 명령어로 실행이 가능하다. 

cat data.txt | redis-cli --pipe

그리고 결과로 아래와 같은 output을 생산한다. 

All data transferred. Waiting for the last reply...

Last reply received from server.

errors: 0, replies: 1000000

redis-cli utility는 또 standard output으로 에러만 출력되도록 해놓았다. 

카테고리 없음

출처 : http://the-earth.tistory.com/182


Redis clustering 튜토리얼페이지 요약

참고 : http://redis.io/topics/cluster-tutorial


이 페이지에서는 Redis cluster의 구성방법을 다룬다.더 자세한 정보는 아래를 참고하자. 

Redis Cluster specification


Redis cluster tutorial

Redis Cluster 101

Redis cluster는 데이터가 자동으로 sharding되어 다수의 Redis 노드로 분산되어 들어가도록 해준다. 

여러가지 Key에 대한 command는 cluster에서 다루지 않는데 이유는 이런 방식을 노드간의 data이동을 필요로하고 부하가 많은 경우에 Redis cluster의 redis 본연의 성능을 보장해 주지 못하게 하기 때문이다. 


Redis Custer는 노드의 fail이나 통신 불능 상태등에 대해 지속적으로 동작할 수 있도록 파티션 간의 어느정도의 가용성을 제공한다. 

그게 뭐냐하면 

  • 여러 노드들에 데이터들을 분리해서 넣을 수 있다. 
  • 부분적인 노드들에서 실패 혹은 통신 불능 상태에서 지속적인 동작을 제공한다. 

Redis Cluster TCP ports


모든 Redis cluster 노드는 두개의 TCP connection을 필요로한다. 기본적인 Redis TCP port는 client를 위한 것이고, (예를 들어 6379), 추가로 10000을 더한 portt는 데이터 port로 쓰인다. (예를 들면 16379)


두번째 port는 Cluster bus로 사용되는데 노드간의 바이너리 커뮤니케이션 채널로 사용된다. Cluster bus는 노드의 실패 detection이나 설정 업데이트, failover authorization 등등에 쓰이게 된다. Client는 당연히 이 port를 사용하면 안된다. 아까 설명한 첫번째 Redis command port를 사용하자. 

그리고 이 두개의 port가 방화벽에서 열려있는지도 체크하자. 안그러면 cluster가 작동하지 않을 수 있다. 


command port와 cluster bus port의 offset은 항상 10000으로 정해져 있다. 

Cluster가 제대로 작동하기 위해서는 다음을 잘 숙지해야한다. 

1. 기본 client communication port (보통 6379)는 cluster에 접근하고자하는 모든 client와 다른 cluster 노드들(Key 이동을 위해)에 의해서 사용된다.

2. cluster bus port (client port + 10000)은 다른 node cluster에게 항상 개방되어 있어야한다. 


Redis Cluster data sharding


Redis Cluster는 consistency hashing을 사용하지 않고 모든 key가 개념적으로 hash slot의 일부인 다른 sharding을 사용한다. 

Redis cluster는 16384개의 hash slot을 사용하고 key modulo 16384를 사용하는 CRC16를 사용해서 hash slot을 계산한다. 


Redis cluster의 모든 노드는 hash slot의 subset이다. 만약 3개의 노드가 있다면 아래와 같이 slot이 나뉘어 질 수 있다. 

  • Node A contains hash slots from 0 to 5500.
  • Node B contains hash slots from 5501 to 11000.
  • Node C contains hash slots from 11001 to 16384.

이 방법은 노드를 더하고 제가하는 것을 쉽게 한다. 예를 들어 D라는 노드가 추가되었다면 A,B,C의 어느정도의 slot을 D에게 할당하면 된다. 비슷하게 노드 A를 제가한다면 단순히 A의 slot을 B나 C로 옮기면된다. 노드 A가 empty가 되면 언제든지 이 노드를 제거할 수 있다. 


hash slot을 이동하는 것이 cluster를 정지할 필요가 없기 때문에 노드를 더하거나 제거하거나 hash slot의 비율을 변경하는 것이 언제고 가능하다. 


Redis Cluster master-slave model


부분적인 노드가 실패나 통신 불능에서도 가용성을 확보하기 위해 Redis cluster에서는 master-slave를 지원한다. 


아까 예로들었던 A,B, C로 구성된 Cluster에서 B가 실패한다면 5501-11000의 slot을 서비스 할 수 없게 된다. 

그러나 slave를 추가해서 A,B,C가 master이고 A1, B1, C1이 slave가 되도록 cluater를 구성한다면 B1은 B를 replication하게 B의 장애시에 B1가 elaction(투표)를 통해 새로운 master로 선출된다. 

하지만 B와 B1이 동시에 fail되면 지속적으로 서비스 할 수 없다. 


Redis Cluster consistency guarantees

Reids Cluster는 strong consistency를 보장하지 않는다. 쉽게 말하면 특정 조건에서 Redis Cluster에 성공적으로 응답을 받은 데이터를 Cluster가 잃어 버릴 수 있다는 뜻이다. 


첫번째 이유는 Redis Cluster가 asynchronous replication을 사용하기 때문이다. 이 말은 write를 할 때 아래와 같은 절차를 따른다는 뜻이다. 

  • Client가 Master B에 데이터를 쓴다. 
  • master B가 Client에 OK라고 대답한다. 
  • Master B가 B1, B2, B3의 replica에 쓰기를 전달한다. 

보시다싶이 B는 B1, B2, B3에서의 확인을 받기 전에 client에 확인 결과를 보낸다. 이유는 저런 확인이 비용이 비싼 잠재적인 패널티가 될 수 있기 때문이다. B가 쓰기를 확인하고 slave에 이를 전달하기 전에 fail일 발생한다면 데이터가 손실 될 수 있다. 


이것은 대다수의 데이터 베이스들이 1초마다 disk로 데이터를 flush하는 경우에서와 마찬가지다. client에 확인 요청을 보내기 전에 disk에 강제로 flush할 수 있지만 이런 방법은 보통 엄청난 성능 저하를 가져온다. 


기본적으로 consistency와 성능간에는 trade off가 있다. 


또 데이터를 잃을 수 있는 다른 시나리오가 있는데 네트워크 파티션이 일어나고 client가 minor한 파티션에 속하게 되었을 때이다. 

예를 들어보자. 6개의 노드가 있는데 A, B, C, A1, B1, C1으로 3개의 master와 3개의 slaver로 구성되었다고 생각하자. 또 Z1이라는 client도 존재한다고 치자. 


만약 네트워크 파티션이 발생하면 A, C, A1, B1, C1과 B, Z1으로 분리될 수 있다. Z1은 B에게 계속 쓸 수 있다. 만약 파티션된 네트워크가 금방 회복 된다면 cluster는 평상시처럼 지속될 것이다. 

하지만 이 시간이 B1이 master로 선출될 수 있는 충분한 시간이라면 Z1이 B에게 썼던 데이터는 잃게 된다. 


이 설정을 node timeout이라 부르는데 Redis cluster 설정에서 에서 매우 중요하다. 


node timeout이 발생하면 master node는 실패되었다고 간주되고 다른 replica들중에 하나로 교체된다. 비슷하게 node timeout이 발생하고 major한 master 노드들을 감지할 수 없다면 이 노드는 에러 상태로 들어가고 쓰기를 받지 않게된다. 




Creating and using a Redis Cluster


Cluster를 생성하기 위해 필요한 것은 몇개의 cluster mode로 동작하고 있는 empty상태의 Redis instance들이다. 이것은 기본적으로 이 Redist instatnce들이 보통의 instance들이 아니라 Cluster에 부합하는 특징과 command들을 사용할 수 있도록 설정된 특별한 모드의 instance들이라는 것이다. 


아래는 최소한의 Redis cluster 설정파일이다. 

port 7000

cluster-enabled yes

cluster-config-file nodes.conf

cluster-node-timeout 5000

appendonly yes

보이는 것 처럼 cluster mode를 enable시키는 것은 cluster-enabled 지시자이다. 모든 instance들은 마찬가지로 파일의 경로를 가지고 있는데 이것은 이 노드의 설정이 어디에 저장되어 있는지를 알리는 것이며 default로 nodes.conf를 사용한다. 

이 파일들은 사람에 의해서 수정되어서는 안되고 단순히 Redis Cluster가 시작될때 cluster에 의해서 생성되고 매 시간 필요시마다 업데이트된다. 


적어도 세게 이상의 master node가 있어야 minimal cluster가 될 수 있다는 점을 숙지해야한다. 당신을 위해 처음에 3개의 master와 3개의 slave로 구성된 cluster를 강력하게 추천한다. 


그러기 위해서는 새 디렉토리에서 아래와 같이 새로운 instance들이 실행될 수 있는 instance port number를 따르는 디렉토리들을  만들djdi gksek. 

mkdir cluster-test

cd cluster-test

mkdir 7000 7001 7002 7003 7004 7005


각각의 7000부터 7005까지의 directory안에 redis.conf 파일을 생성한다. 템플릿으로는 위의 최소한의 example을 사용하며 port를 각 디렉토리 이름에 맞도록 수정해야한다. 

이제 Github의 unsatble branch를 최신으로 컴파일되거나 실행가능한 redis-server를 복사해서 cluster-test디렉토리에 복사한다. 

아래와 같이 모든 insatance를 실행시킨다. 

cd 7000

../redis-server ./redis.conf

아래와 같이 모든 instance에서 다음과 같은 log를 볼 수 있다. 이것은 nodes.conf 파일이 존재하지 않기 때문이며 모든 노드들을 각자 새로운 ID를 자신에게 할당한다. 

[82462] 26 Nov 11:56:55.329 * No cluster configuration found, I'm 97a3a64667477371c4479320d683e4c8db5858b1


이 ID는 cluster안에서 각자의 유일한 이름으로 영원히 사용된다. 모든 노드들은 IP혹은 port가 아닌 ID로 다른 노드들을 기억한다. IP와 port는 바뀔 수 있지만 이 유일한 노드 식별자는 노드의 일생동안 바뀌지 않는다. 이것을 Node ID라고 부른다. 


Creating the cluster


이제 우리는 실행되고 있는 instance들을 가지고 있고, 노드들에게 뭔가 의미있는 설정을 생성해서 cluster에 써줄 필요가 있다. 

redis-trib이라는 utility를 사용해서 하면 되는데, 이것은 새로운 cluster를 생성하거나 shard를 바꾸거나 하는데 쓰인다. 


redis-trib utility는 배포 코드의 src 디렉토리에 위치한다. cluster를 생성하기위해서는 간단히 아래와 같이 하면 된다. 

./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \

127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005


우리가 원하는 것은 새로운 cluster를 생성하는 것이기 때문에 여기서 사용된 command는 create이다. --replica 1이라는 옵션은 우리가 생성되는  모든 master에 대해서 slave를 원한다는 것을 의밓나다. 다른 argument들은 생성하고자 하는 새로운 cluster에 주소 목록이다. 


명백히 우리가 단지 원하는 것은 3개의 master와 3개의 slave를 가진 cluster이다. 


Redis-trib은 설정을 위해 쓰인다. Yes를 typing한다. 그러면 cluster들이 설정되고 join될 것이다. 이것은 instace들이 서로 이야기하면서 시동됨을 의미한다. 

결론적으로 문제가 없다면 우리는 아래와 같은 메시지를 보게 될 것이다. 

[OK] All 16384 slots covered


이것은 적어도 master instance들의 16384개의 slot들이 사용가능하다는 것을 뜻ㅎ나다. 


Playing with the cluster

현재 단계에서 문제는 Redis Cluster에 대한 client 구현이 미비하다는 것이다. 

현재 알려진 구현은 아래와 같다. 


  • redis-rb-cluster is a Ruby implementation written by me (@antirez) as a reference for other languages. It is a simple wrapper around the original redis-rb, implementing the minimal semantics to talk with the cluster efficiently.
  • redis-py-cluster appears to be a port of redis-rb-cluster to Python. Not recently updated (last commit 6 months ago) however it may be a starting point.
  • The popular Predis has support for Redis Cluster, the support was recently updated and is in active development.
  • The most used Java client, Jedis recently added support for Redis Cluster, see the Jedis Cluster section in the project README.
  • The redis-cli utility in the unstable branch of the Redis repository at Github implements a very basic cluster support when started with the -c switch.


쉽게 Redis Cluster를 테스트 해보는 방법은 redis-cli command line 유틸을 사용하는 것이다. 아래는 그 예이다. 


$ redis-cli -c -p 7000

redis 127.0.0.1:7000> set foo bar

-> Redirected to slot [12182] located at 127.0.0.1:7002

OK

redis 127.0.0.1:7002> set hello world

-> Redirected to slot [866] located at 127.0.0.1:7000

OK

redis 127.0.0.1:7000> get foo

-> Redirected to slot [12182] located at 127.0.0.1:7002

"bar"

redis 127.0.0.1:7000> get hello

-> Redirected to slot [866] located at 127.0.0.1:7000

"world"


redis-cli cluster가 제공하는 것은 기본적인 것이어서 항상 Redis Cluster 노드들이 올바를 client로 redirect된다는 것만을 사용한다. 

좀더 좋은 client는 이것보다 더 나은데 hash slot이나 nodes의 주소 정보 map을 caching하여 바로 필요한 node로 연결될 수 있게 한다. map은 cluster의 설정이 변경될 때만 갱신된다. 예를 들면 failover가 일어 났다거나 admin이 노드를 추가 삭제하여 cluster의 형태가 변경되었을 때이다. 


Writing an example app with redis-rb-cluster


좀더 알아보기 전에 Redis cluster가 어떻게 failover, resharding등을 어떻게 하는지 새로운 example 어플리케이션을 통해서 알아보자. 

이를 통해 우리는 Redis cluster가 실제 상황에서 어떻게 행동하는지 보기 위해 example code를 돌려 fail과 resharding을 관찰수 있다. 


이 섹션은 redis-rb-cluster의 기본적인 두개의 example을 설명한다. 첫째는 아래와 같고 redis-rb-cluster 배포본의 example.rb 파일에 있다. 


     1  require './cluster'

     2

     3  startup_nodes = [

     4      {:host => "127.0.0.1", :port => 7000},

     5      {:host => "127.0.0.1", :port => 7001}

     6  ]

     7  rc = RedisCluster.new(startup_nodes,32,:timeout => 0.1)

     8

     9  last = false

    10

    11  while not last

    12      begin

    13          last = rc.get("__last__")

    14          last = 0 if !last

    15      rescue => e

    16          puts "error #{e.to_s}"

    17          sleep 1

    18      end

    19  end

    20

    21  ((last.to_i+1)..1000000000).each{|x|

    22      begin

    23          rc.set("foo#{x}",x)

    24          puts rc.get("foo#{x}")

    25          rc.set("__last__",x)

    26      rescue => e

    27          puts "error #{e.to_s}"

    28      end

    29      sleep 0.1

    30  }


이 프로그램을 돌리면 결과는 아래와 같은 command의 흐름이다. 

  • SET foo0 0
  • SET foo1 1
  • SET foo2 2
  • And so forth...


7번째 줄에서는 각각의 instance에 대해서 32개의 connection과 timeout 0.1초를 설정해 주고 있다. 


위에서 sartup 노드들은 꼭 cluster의 모든 노드일 필요는 없다. 중요한 점은 적어도 하나의 노드는 접근 가능해야한다는 것이다. redis-rb-cluster는  첫번째 노드에 접속할 수 있을때 startup 노드들의 목록을 업데이트한다. 

이제 rc라는 변수에 Redis cluster instance가 저장되었고 우리는 이 object를 통해서 보통의 Redis object instance처럼 Redis를 사용할 수 있다. 


이것이 11~19째줄에 나타나있다. 우리가 프로그램을 재시작했을 때 foo0부터 다시 시작하길 바라지 않기 때문에 우리는 현재의 count도 Redis에 저장한다. 그래서 11~19줄에서는 예전값을 redis로 부터 읽거나 없다면 0으로 할당하도록 디자인되어 있다. 


21~30째 줄에서는 loop를 돌면서 key를 set하거나 에러를 출력한다. 


결과는 아래와 같다. 


ruby ./example.rb

1

2

3

4

5

6

7

8

9

^C (I stopped the program here)



Resharding the cluster


resharding을 해보자. 

resharding은 기본적으로 특정 node들의 hash slot을 다른 노드들의 slot으로 이동하는 것을 뜻한다. cluster를 생성하는 것과 마찬가지로 redis-trip 유틸을 사용하면된다. 


resharding을 진행하게 위해서는 단순히 아래와 같이 하면 된다. 

./redis-trib.rb reshard 127.0.0.1:7000


하나의 노드만 정하면 다른 노드들은 redis-trib이 알아서 찾는다. 

현재의 redis-trip은 5%정도를 옮겨줘와 같은 것은 지원하지 않는다. redis-trip은 아래와 같은 질문으로 어마만큼 resharding하고 싶은지 물어본다. 


How many slots do you want to move (from 1 to 16384)?


우리는 1000개의 hash slot을 resharding해볼 수 있다. 만약 위의 예제에서 sleep을 주지 않는다면 이는 무시하지 못할 양의 key들이다. 

그다음 redis-trib에게 hash slot들을 받게될 resharding target 을 알려주어야한다. 우리는 127.0.0.1:7000인 첫번째 노드를 사용할 것이며 instance의 Node ID를 사용하게 된다. 아래와 같은 command로 원하는 node의 Node ID를 볼 수 잇따. 


$ redis-cli -p 7000 cluster nodes | grep myself

97a3a64667477371c4479320d683e4c8db5858b1 :0 myself,master - 0 0 0 connected 0-5460


이제 어떤 node들에 이 key들이 속할지 알려주어야한다. 우리는 hash slot들을 다른 master node들로 부터 가져오기위해 all이라고 입력할 것이다. 

마지막 conform후에 우리는 선택한 노드로 부터 다른 노드로 이동되는 모든 slot에 대한 메시지를 볼 수있을 것이다. 그리고 이동되는 모든 key마다 .이 출력될것이다. 


resharding이 진행되는 동안 우리는 example program이 영향을 받지 않고 동작함을 확인 할 수 있다. 

resharding이 완료되면 아래 명령어를 통해서 cluster의 health를 check할 수 있다. 


./redis-trib.rb check 127.0.0.1:7000


확인 해보면 127.0.0.1:7000에 더 많은 slot이 할당되어 있음을 확인 할 수 있다. 

카테고리 없음

ulimit는 유저가(쉘, 프로세스)에 대해서 할당할 자원의 한계를 정하는 것으로

다중 프로그램/사용자를 기본으로 하는 리눅스 시스템에서 과부하를 막아주는 설정이다. 


나 같은 경우는 linux서버의 openfile, corefile size를 많이 제어하는데 사용한다. 

그 이유는 분산처리 파일 환경, 또는 디비서버를 운영할 경우 동시에 많은 파일들이 

읽고 쓰고를 해서 openfile error가 생기는것을 막기 위해서 이다. 


기본적으로 hard 설정과 soft 설정이 있는데 

각 설정을 보려면 아래의 명령어로 확인한다. 

 $ ulimit -Ha 

 $ ulimit -Sa

 

(하드 설정 전체 보기 / 소프트 설정 전체 보기)

하드는 해당쉘의 최대값을 뜻한다 하면 되고,  소프트는 현재 설정을 말한다 생각하면 된다.

hard 설정의 경우는 root권한으로만 변경 가능


 

$ ulimit -Sa

core file size          (blocks, -c) 0

data seg size           (kbytes, -d) unlimited

file size               (blocks, -f) unlimited

max locked memory       (kbytes, -l) unlimited

max memory size         (kbytes, -m) unlimited

open files                      (-n) 256

pipe size            (512 bytes, -p) 1

stack size              (kbytes, -s) 8192

cpu time               (seconds, -t) unlimited

max user processes              (-u) 266

virtual memory          (kbytes, -v) unlimited

 

 

/etc/security/limits.conf 에 설정 파일이 있으며 파일을 변경하거나 
*     soft     nofile     65535
*     hard     nofile     65535

ulimit -Sn 10240  <- 이런 식으로 각 설정별 옵션을 사용해서 변경 가능하면 된다.

수정한 내용의 적용은 해당 유저가 새로운 접속을 시도하면 적용된다.


형식은

--limit.conf--

[유저이름] [hard/soft] [설정할 항목] [설정값]

 

ex)

 

mklife hard nofile 320000  => mklife 유저는 한번 접속에 하드세팅으로 32만개 파일까지 열수 있다.

mklife hard nproc 10000   => mklife 유저는 한번 접속에 하드 세팅으로 1만개 프로시져를 생성가능

mklife soft  nproc 10000   => mklife 유저는 한번 접속에 소프트 세팅으로 1만개 프로시져를 생성가능

 

주의) soft설정은 hard설정값을 넘을수 없으므로. 그냥 soft/hard같이 설정해주는 버릇을 들이자.

네트워크 튜닝

echo "4194303"  > /proc/sys/net/core/rmem_default
echo "16777215"  > /proc/sys/net/core/rmem_max
echo "4194303"  > /proc/sys/net/core/wmem_default
echo "16777215 " > /proc/sys/net/core/wmem_max
echo "100000"  > /proc/sys/net/core/netdev_max_backlog
echo "4194303"  > /proc/sys/net/core/optmem_max
echo "1048576   16777216   33554432"  > /proc/sys/net/ipv4/tcp_rmem
echo "1048576   16777216   33554432"  > /proc/sys/net/ipv4/tcp_wmem

TCP TIME_WAIT이 많이 발생하여 문제가 되는 경우

#sysctl -p

cp_time_wait 은 TCP/IP 프로토콜에서 통신채널을 끊을때 (TCP_FIN) 발생하는 시간으로 연결을 완전히 끊기 전에
클라이언트로 부터 받을 데이터를 못 받게 되는 상황에 대비하여 완전히 끊기 전에 기다리는 시간이다.
만일 시스템에 설정된 양보다 대량의 요청이 발생되게 된다면 WAIT 하는 세션들이 필요이상으로 많아질 것이다.

실제 WAIT 중인 세션들은
# netstat -an | grep TIME_WAIT
명령으로 확인할 수 있다.

그럼 OS의 tcp_time_wait 수치를 확인하려면
# cat /proc/sys/net/ipv4/tcp_fin_timeout
60

시간은 초단위이고 기본값은 60이다.  대량의 요청이 발생한다면 10초 정도로 맞춰주는게 권장값이다.
# echo 10 > /proc/sys/net/ipv4/tcp_fin_timeout

명령으로 현재 파라미터 값을 조정할 수 있다.
 
재부팅시에도 이 값을 유지하고 싶다면
/etc/rc.local 등에 위 명령을 넣거나
/etc/sysctl.conf 에
net.ipv4.tcp_fin_timeout = 10
라인을 추가해준다.


client Port range 변경
매우 바쁜 클라이언트 프로그램일 경우 대량의 TIME_WAIT 가 발생해서 할당해야 될 PORT가 부족할 경우 범위를 늘리는것으로
어느정도 개선이 됩니다. 다만 임시적인 방법이지 완전한 문제를 해결 한다고는 볼 수 없다.

/proc/sys/net/ipv4/ip_local_port_range
보통 32768 61000 으로 지정되어 있는데 , 1024 65535 로 변경
#echo "1024 ~ 65535" > /proc/sys/net/ipv4/ip_local_port_range
/etc/sysctl.conf 에
net.ipv4.ip_local_port_range = 1024 65535

tcp_tw_recycle 기본값이 0인데, 1로 할 경우 TIME_WAIT 상태를 빠르게 recycling 하도록 도와준다.
# echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
/etc/sysctl.conf 에
net.ipv4.tcp_tw_recycle= 1 

tcp_tw_reuse 기본값은 0인데, 1로 할 경우 TIME_WAIT 상태의 소켓을 재사용 할 수 있게 해준다.
setsocketopt() 에 SO_REUSEADDR를 사용한 것과 같은 효과
# echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
/etc/sysctl.conf 에
net.ipv4.tcp_tw_reuse
= 1
카테고리 없음

원본 : http://www.mimul.com/pebble/default/2012/05/04/1336102052449.html


NoSQL 관련 기술 중에 하나인 Consistent Hashing의 개념은 1997년에 MIT의 karger가 웹서버의 숫자가 수시로 변경되는 중에 분산 요청을 처리하기 위해 처음 고안했다고 하는데 그 내용을 살펴보고자 한다.
아래의 내용은 'Consistent Hashing' 이라는 아티클을 많이 참조해서 작성했다.

왜 필요한가?

N개의 캐시 시스템(노드)이 있다고 하고 이때 부하 분산에 사용하는 일반적인 방법은 Object o를 hash(o) mod n 번째 캐시 시스템에 저장하는 방식이다. 이런 방식은 캐시 시스템이 추가되거나 제거되기 전까지는 잘 운영된다.
그러나 캐시 시스템이 추가되거나 장애로 제거 되었을 경우, n이 빠뀌게 되면 모든 Object는 새로운 위치에 모두 재할당을 해야하는데 그러기엔 부하 부담이 크다.
이 때 Consistent Hashing 방법을 사용하게 되면 캐시 시스템이 추가되거나 작동이 중단되어도 모든 Object를 할당을 하는 것이 아니라 추가되면 인접한 다른 캐시 시스템에서 적정한 양의 Object 를 받게되고 마찬가지로 제거된다면 남은 캐시 시스템들이 나누는 형태가 되어 일관되게 일부 Object에 대해서 재 할당을 수행하게 된다. 그러므로 기존에 저장된 대부분의 캐시를 사용할 수 있으며 시스템 변동이 히트율에 영향을 미치지 않게 된다.
기본 원리는 Consistent hashing 알고리즘은 Object와 캐시 시스템 둘다 동일한 Hash 함수를 사용해서 해싱하는 것이다. 캐시 시스템은 구간을 정하고 그 구간에는 많은 Object의 해시값을 가지고 있는다. 캐시 시스템이 제거도면 인접한 구간의 캐시 시스템이 제거된 구간을 맞게되고 다른 캐시 시스템은 영향을 받지 않는다.
Performance는 O(log n).

작동 방식은?

Hash 함수는 Object와 캐시 시스템이 일정 구간을 정하게 한다. Java 언어의 예를 보면 Object의 hashCode() 함수는 리턴을 int로 하고 리턴값 int의 구간은 -2^31에서 2^31-1을 가진다. 
다음 그림은 네 개의 Object(1,2,3,4)와 3개의 캐시 시스템(A, B, C)가 링에 배치되어 있다.

 
위의 그림에서 1,4는 캐시 시스템 A에 들어가고 2는 B, 3은 C에 들어 간다. 이때 C가 제거되었다고 가정하면 Object 3은 A에 들어간다. 기타 지원은 변하지 않는다. 다음 그림처럼 캐시 D가 추가되면, 3, 4는 D로 옮긴다. 그리고 1 만 A에 남아있다.

 
이렇게 함으로써 각 캐시 시스템에 할당된 구간의 사이즈에 예외가 발생해도 잘 동작하게 된다. 한가지 고민해야할 점은 무작위로 분포되기 때문에 캐시 시스템 사이의 Object의 분포는 균일하지 않을 수 있다. 이를 위한 해결책으로 '가상 노드'를 사용하는 방법이 있다. 가상 노드는 캐시 시스템의 링안에서 복제하는데 이는 캐시 시스템 하나 추가할때마다 링에 여러개 배치되게 되는 방식이다.
가상 노드의 효과는 다음 그래프와 같은데 10,000개의 Object를 10개의 캐시 시스템으로 시뮬레이션한 결과이다. X축이 캐시 시스템의 복제수가 되고 Y축은 표준 편차.
복제 수가 작은 Object들의 분산도가 언발란스한데 이는 캐시 시스템의 Object수의 평균의 표준 편차가 크기 때문일 것이다. 이 실험에서 복제를 100이나 200으로 했을 경우 합리적인 균형을 실현할 수 있다고 할 수 있었다고 한다. (표준 편차가 평균 5-10% 정도가 적당함)

 
시스템마다 다수의 Virtual Nodes(가상 노드)를 만들어서 로드발란싱을 좋게 한 예는 libketema이다.

구현 방법은?

Consistent Hashing 방법이 효력이 발휘하기 위해서는 해싱 함수가 잘 동작해야하는데 Object의 hashCode로는 부족하고 MD5를 추천한다.

public class ConsistentHash {

  private final HashFunction hashFunction;
  private final int numberOfReplicas;
  private final SortedMap circle =
    new TreeMap();

  public ConsistentHash(HashFunction hashFunction,
    int numberOfReplicas, Collection nodes) {

    this.hashFunction = hashFunction;
    this.numberOfReplicas = numberOfReplicas;

    for (T node : nodes) {
      add(node);
    }
  }

  public void add(T node) {
    for (int i = 0; i < numberOfReplicas; i++) {
      circle.put(hashFunction.hash(node.toString() + i),
        node);
    }
  }

  public void remove(T node) {
    for (int i = 0; i < numberOfReplicas; i++) {
      circle.remove(hashFunction.hash(node.toString() + i));
    }
  }

  public T get(Object key) {
    if (circle.isEmpty()) {
      return null;
    }
    int hash = hashFunction.hash(key);
    if (!circle.containsKey(hash)) {
      SortedMap tailMap =
        circle.tailMap(hash);
      hash = tailMap.isEmpty() ?
             circle.firstKey() : tailMap.firstKey();
    }
    return circle.get(hash);
  } 

}


사용 사례는?

- NoSQL

- 오픈 소스 


[참조 사이트]


카테고리 없음
rpm -Uvh http://mirror.webtatic.com/yum/el6/latest.rpm
yum install php54w php54w-mysql php54w-pear
End


카테고리 없음

CentOS/RHEL: Ulimit And Maximum Number Of Open Files

Sometimes you may want to set limits on some of your system resources(Processes, Files)
But other times, you may want to do the just the opposite - disable those limits or change them to higher limits like I needed to do few days ago.

1. Check what are the limits

Apparently, RedHat set the default max number of open files for users  to 1024 and and not long ago, this was change to 4096.
For some applications/users this is very low and can cause you a lot of problems.

You can check what is the current limit with ulimit using bash shell:
1
ulimit -Hn
This will show you the hard limit of maximum number of files for your user. you can use -S to check the soft limit.
tcsh: using tcsh you can can check this limit with limit descriptors

if you wish to check the max Open file descriptors for the process your user/application running, use the following command: 
1
cat /proc/[Process ID]/limits

To check what is the system limit for number of files descriptors use the following command:

1
cat /proc/sys/fs/file-max

2. Change the limit

lets start by changing the limit for the user mario:
1
vi /etc/security/limits.conf
now change the following lines:
1
2
mario soft nofile 4096
mario hard nofile 20480
save the file and verify the result by using ulimit like we used it in section 1.
If you want to set maximum number of processes use nproc instead of nofile
If you want to set this setting to all users use * instead of specify user name

Now lets change the limit for the entire system:
1
vi /etc/sysctl.conf
and put the line:
1
fs.file-max = 200500

update the system with::
1
sysctl -p

3. List number of open files/allocated file handles

To check the number of files opened on your system, use:
1
lsof | wc -l
You can also check the allocated file descriptors by using: 
1
cat /proc/sys/fs/files-nr
the first field is the number of total allocated files descriptors.
second field is unused file descriptors
and the third field is the maximum file descriptors that can be used


카테고리 없음

MySQL Cluster 

Introduction 

MySQL 클러스터는 분산 컴퓨팅 환경에서 high-availability와 high-redundancy를 채택하였다. MySQL 클러스터는 NDB 클러스터 스토리지 엔진을 사용하여, 클러스터에서 여러 개의 서버가 함께 돌아가도록 한다. MySQL 클러스터가 지원하는 운영 체제는 Linux, Mac OS X, Solaris 등 이다. 더 자세한 정보는 다음 사이트를 참고 하길 바란다. http://www.mysql.com/products/cluster

MySQL Cluster Overview 


MySQL 클러스터는 share-nothing 시스템에서 in-memory 데이터 베이스의 클러스터링을 가능하게 한다. 이러한 아키텍쳐는 특정한 하드웨어 및 소프트웨어를 요구하지 않으므로 비용을 절감할 수 있도록 하며, 각 콤포넌트가 고유 메모리와 디스크를 보유함으로 단일 취약점(single point of failure)을 가지지 않는다.

MySQL 클러스터는 일반 MySQL 서버에 NDB라는 스토리지 엔진을 통합하여, 다음 그림과 같이 MySQL서버, NDB 클러스터의 데이터 노드, MGM 서버가 포함된 컴퓨터와 데이터에 접근하기 위한 어플리케이션 프로그램으로 구성된다.

데이터가 NDB 클러스터 스토리지 엔진에 저장될 때, 테이블은 데이터 노드에 저장된다. 각 테이블은 클러스터의 MySQL 서버에서 직접 접근이 가능하다. 그래서 클러스터의 어떤 정보를 업데이트 하면, 다른 모든 MySQL서버에서 곧바로 확인할 수 있다.

MySQL 클러스터의 데이터 노드에 저장된 데이터는 미러링이 가능하며, 클러스터는 트랜잭션 중단 등 각 노드들의 상태에 대한 핸들링이 가능하다.

MySQL 클러스터의 구성

Basic MySQL Cluster Concepts 


NDB는 높은 가용성과 데이터 지속성을 갖는 인 메모리 스토리지 엔진이다. DB 스토리지 는 failover와 로드 밸런싱 옵션을 설정할 수 있다. MySQL 클러스터는 NDB 스토리지 엔진과 MySQL 서버로 구성되어 있으며, MySQL 클러스터의 클러스터 부분은 MySQL 서버에 독립적이다. MySQL 클러스터의 각 부분은 노드로 간주한다.

"노드"는 일반적으로 컴퓨터를 지칭하지만 MySQL 클러스터에서는 "프로세스"를 말한다.


클러스터 노드에는 세 가지 타입이 있으며, MySQL Cluster를 구성하기 위해 최소한 노드 세 개가 있어야 한다.

  • MGM node : 이 노드는 설정을 포함, 다른 노드를 관리하는 매니저 노드이다. 다른 노드보다 가장 먼저 실행되며 ndb_mgmd 명령으로 실행시킨다.
  • data node : 클러스터의 데이터를 저장하는 노드이다. ndbd 명령으로 실행시킨다.
  • SQL node : 클러스터 데이터에 접근하는 노드이다. MySQL 클러스터에서는 NDB 클러스터 스토리지 엔진을 사용하는 MySQL 서버가 클라이언트 노드이다. mysqld --ndbcluster나 mysqld 명령으로 실행시키는데, 이 때는 my.cnf 에 ndbcluster를 추가한다. 

MGM 노드는 클러스터 컨피그레이션 파일과 로그를 관리한다. 데이터 노드에 이벤트가 발생하면, 데이터 노드는 그에 대한 정보를 매니저 서버로 보내고, 매니저 서버는 클러스터 로그를 기록한다.


Simple Multi-Computer How-To 


다음과 같이 4대의 컴퓨터로 클러스터를 구성하는 것을 가정하고 있다. (4개의 노드로 구성되고, 각각의 노드는 편이성을 위해 IP로 지칭한다.)

아래에서 필요한 컴퓨터는 리눅스가 설치된 인텔 기반 데스크탑 PC이며, 4대 모두 동일한 이더넷 카드(100Mbps나 1기가 비트)가 필요하다.

Node IP Address

Management (MGM) node 192.168.0.10

MySQL server (SQL) node 192.168.0.20

Data (NDBD) node "A" 192.168.0.30

Data (NDBD) node "B" 192.168.0.40


설치 및 사용 시 주의할 점은 MySQL 클러스터는 클러스터 노드 간 커뮤니케이션에 암호화 및 보호 장치가 전혀 없으므로, 웹 상에서 사용하려면 방화벽을 사용하는 등의 보안상의 대책이 필요하다는 것이다.

MySQL Cluster를 사용하기 위해서는 -max 버전을 설치해야 한다. 모든 설치는 root권한으로 진행하며 작업에 필요한 파일은 /usr/local/ 에 저장한다.

1. /etc/passwd 와 /etc/group 파일에서 mysql 그룹과 유저가 있는지 확인한 후 없으면 다 음과 같이 생성한다.
# cd /usr/local
# groupadd mysql
# useradd -g mysql mysql

2. 유저와 그룹 생성 후 압축을 풀고, 심볼릭 링크를 걸어준다.
# tar -xzvf mysql-max-4.1.13-pc-linux-gnu-i686.tar.gz
# ln -s /usr/local/ mysql-max-4.1.13-pc-linux-gnu-i686 mysql

3. mysql 디렉토리로 이동하여 시스템 데이터베이스 생성을 위한 스크립트를 실행시킨다.
# cd mysql
# scripts/mysql_install_db --user=mysql

4. MySQL 서버와 데이터 디렉토리의 퍼미션을 설정한다.
# chown -R root .
# chown -R mysql data
# chgrp -R mysql .

5. 시스템 부팅 시 자동적으로 Mysql을 실행할 수 있도록 설정한다.
# cp support-files/mysql.server /etc/rc.d/init.d/
# chmod +x /etc/rc.d/init.d/mysql.server
# chkconfig --add mysql.server

6. MGM (management) 노드를 별도의 PC에 설치할 경우 mysql 데몬은 설치하지 않아도 무방하다. 위와 같이 설치한 후 MGM 서버는 다음과 같이 설치를 계속한다.
# cd /usr/local/mysql/bin/
# cp ndb_mgm* /usr/local/bin/
# chmod +x ndb_mgm*

7. 각 데이터 노드와 SQL 노드는 MySQL서버 옵션과 connectstring에 대한 정보가 포함된 my.cnf파일이 필요하고, MGM노드는 config.ini 파일이 필요하다. 에디터를 열어 다음과 같이 편집한 후 파일을 저장한다.
# vi /etc/my.cnf 
[MYSQLD]			      # Options for mysqld process:
Ndbcluster			# run NDB engine
ndb-connectstring=192.168.0.10	# location of MGM node

[MYSQL_CLUSTER]		      # Options for ndbd process:
ndb-connectstring=192.168.0.10	# location of MGM node

8. MGM 노드의 설정 파일을 만들기 위해 적당한 디렉토리를 만든 후 에디터를 열어 다음과 같이 편집한다.
 
# mkdir /var/lib/mysql-cluster
# cd /var/lib/mysql-cluster
# vi config.ini

[NDBD DEFAULT]		# Options affecting ndbd processes on all data nodes:
NoOfReplicas=2		# Number of replicas
DataMemory=80M	         # How much memory to allocate for data storage
IndexMemory=18M	         # How much memory to allocate for index storage
                  		# For DataMemory and IndexMemory, we have used the
                  		# default values. Since the "world" database takes up
                  		# only about 500KB, this should be more than enough
                  		# for this example Cluster setup.

[TCP DEFAULT]		# TCP/IP options:
portnumber=2202	         # This the default; however, you can use any
                  		# port that is free for all the hosts in cluster
                  		# Note: In MySQL 5.0, this parameter is deprecated;
                  		# it is recommended that you do not specify the 
                  		# portnumber at all and simply allow the port to be
                  		# allocated automatically

[NDB_MGMD]			# Management process options:
hostname=192.168.0.10		# Hostname or IP address of MGM node
datadir=/var/lib/mysql-cluster	# Directory for MGM node logfiles

[NDBD]				# Options for data node "A":
				# (one [NDBD] section per data node)
hostname=192.168.0.30		# Hostname or IP address
datadir=/usr/local/mysql/data	# Directory for this data node's 
				# datafiles

[NDBD]				# Options for data node "B":
hostname=192.168.0.40		# Hostname or IP address
datadir=/usr/local/mysql/data	# Directory for this data node's 
				# datafiles

[MYSQLD]			         # SQL node options:
hostname=192.168.0.20	         # Hostname or IP address
datadir=/usr/local/mysql/data	# Directory for SQL node's datafiles
				# (additional mysqld connections can be
				# specified for this node for various
				# purposes such as running ndb_restore)

설치와 설정 과정이 끝났다. 이제 실행을 해 보자.

클러스터 노드들은 각각 실행되어야 한다. 실행 순서는 매니지먼트 노드를 가장 먼저 실행할 것을 권한다. 그 다음은 스토리지 노드와 SQL노드 순이다.
1. 매니지먼트 호스트에서 MGM 노드 프로세스를 실행시켜 보자. 컨피그레이션 파일을 찾을 수 있도록 -f 옵션을 주도록 한다.
# ndb_mgmd -f /var/lib/mysql-cluster/config.ini
MGM 노드를 다운시킬 때에는 다음과 같이 하면 된다.
# ndb_mgm -e shutdown

2. 다음으로 데이터 노드 호스트에서 NDBD프로세스를 실행시킨다. --initial 이란 인수는 ndbd를 처음 실행할 때와 컨피그레이션이 바뀐 후 재시작 할 때만 사용한다.
# ndbd --initial

3. SQL 노드는 다음과 같이 mysql.server를 실행시킨다.
# /etc/rc.d/init.d/mysql.server start

4. 이제 모든 노드가 실행되었으니 MGM 노드 클라이언트를 띄워 간단히 테스트를 해보자.

Ndb_mgm명령어를 입력하였을 때 정상적으로 동작하는 모습은 다음과 같이 프롬프트가 떨어지는 모습이다.
# ndb_mgm
-- NDB Cluster -- Management Client --
ndb_mgm> 

5. 이제 show명령어를 사용하여 클러스터의 모든 노드들이 정상적으로 연동되는지 확인을 해 보자. HELP 를 입력하면 다른 명령어들도 확인해 볼 수 있다. 다음과 같이 4개의 노드를 구성하는 것에 성공하였다.
ndb_mgm> show
Connected to Management Server at: 192.168.0.10:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=2    @192.168.0.30  (Version: 4.1.13, Nodegroup: 0, Master)
id=3    @192.168.0.40 (Version: 4.1.13, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @192.168.0.10 (Version: 4.1.13)

[mysqld(API)]   1 node(s)
id=4   (Version: 4.1.13)

ndb_mgm>

MySQL 클러스터의 제한 


MySQL Cluster 4.1.x 버전은 다음과 같은 사용상의 제한점을 지닌다.

  • 트랙잭션 수행 중의 롤백을 지원하지 않으므로, 작업 수행 중에 문제가 발생하였다면, 전체 트랙잭션 이전으로 롤백하여야 한다.
  • 실제 논리적인 메모리의 한계는 없으므로 물리적으로 허용하는 만큼 메모리를 설정하는 것이 가능하다.
  • 컬럼 명의 길이는 31자, 데이터베이스와 테이블 명은 122자까지 길이가 제한된다. 데이터베이스 테이블, 시스템 테이블, BLOB인덱스를 포함한 메타 데이터(속성정보)는 1600개까지만 가능하다.
  • 클러스터에서 생성할 수 있는 테이블 수는 최대 128개이다.
  • 하나의 로우 전체 크기가 8KB가 최대이다(BLOB를 포함하지 않은 경우).
  • 테이블의 Key는 32개가 최대이다.
  • 모든 클러스터의 기종은 동일해야 한다. 기종에 따른 비트저장방식이 다른 경우에 문제가 발생하기 때문이다.
  • 운영 중 스키마 변경이 불가능하다.
  • 운영 중 노드를 추가하거나 삭제할 수 없다.
  • 최대 데이터 노드의 수는 48개이다.
  • 모든 노드는 63개가 최대이다. (SQL node, Data node, 매니저를 포함) 


MySQL Cluster FAQ 


Cluster 와 Replication의 차이

리플리케이션은 비동기화 방식이고, 클러스터는 동기화 방식이다. 따라서 리플리케이션은 일방적으로 데이타를 전달하여 복제를 하지만 클러스터는 동기방식이므로 데이타를 복제한 후 결과를 확인하기 때문에 데이타 누락이 발생하지 않는다. 다만 복제한 결과를 확인해야 하기 때문에 Cluster가 Replication보다는 속도가 느리다. 또한 Replication의 경우 복제된 데이터에 대한 신뢰를 할 수 없다.


Cluster가 사용하는 네트워크 (How do computers in a cluster communicate?)

MySQL 클러스터는 TCP/IP를 통해 서로 통신한다. 최소한 100Mbps의 이더넷을 사용해야 하며 원활한 통신을 위해 gigabit 이더넷을 권고한다. 실제 데이터가 메모리에 존재하여 사용되며 물리적인 측면에서 봤을 때 CPU, 메모리, 각 노드간의 통신을 위한 네트워킹이 주를 이룬다. 이중 가장 속도가 느린 네트워크의 속도를 높임으로써 전체적인 빠른 동작이 가능하도록 해야 한다. 또한, 더욱 빠른 SCI 프로토콜도 지원하며, 이는 특정 하드웨어를 필요로 한다.


클러스터를 구성하기 위해 컴퓨터가 얼마나 필요한가?

최소한 3대가 있어야 클러스터 구성이 가능하나, MGM 노드와 SQL 노드, 스토리지 노드 둘, 이렇게 4 대로 구성하길 권한다. 하나의 노드가 실패했을 때 지속적인 서비스를 하기 위해서 MGM노드는 분리된 컴퓨터에서 실행되어야 한다.


클러스터에서 각 컴퓨터들이 하는 일은?

MySQL 클러스터는 물리적, 논리적으로 구성된다. 컴퓨터는 물리적 요소이며 호스트라고 불리기도 한다. 논리적, 기능적 요소는 노드이다. 노드는 역할에 따라 MGM 노드, data 노드(ndbd), SQL 노드로 나뉜다.


어떤 OS에서 사용할 수 있는가?
MySQL 4.1.12 현재 MySQL 클러스터는 공식적으로 Linux, Mac OS X, Solaris를 지원한다.


MySQL 클러스터가 요구하는 하드웨어 사양은?

NDB가 설치되고 실행되는 모든 플랫폼이면 가능하나, 당연히 빠른 CPU, 높은 메모리에서 더 성능이 좋다(64-bit CPU에서 더 빠르다). 네트워크은 일반 TCP/IP를 지원하면 되고, SCI 를 지원하려면 특정 하드웨어가 요구된다.


MySQL 클러스터가 TCP/IP를 이용한다면 하나 이상의 노드를 인터넷을 통해 다른 곳에서 실행시킬 수 있는가?

가능하다. 하지만 MySQL 클러스터는 어떠한 보안도 제공되지 않으므로, 외부에서 클러스터 데이터 노드나 매니저 노드에 직접 접근하지 못하도록 해야 한다.


클러스터 사용을 위해 새로운 프로그래밍 언어나 쿼리를 배워야 하나?

표준 (My)SQL 쿼리나 명령을 사용하므로 그러지 않아도 된다.


클러스터 사용 시 에러나 경고 메시지는 어디서 찾나 ?
두 가지 방법이 있다. MySQL창에서 SHOW ERRORS나 SHOW WARNINGS로 확인하는 방법과 프롬프트 상태에서 perror --ndb error-code 를 사용하는 방법이 있다.


MySQL Cluster transaction-safe? 어떤 테이블 타입이 클러스터를 지원하나?
MySQL에서 NDB 스토리지 엔진과 생성된 테이블은 트랜잭션을 지원한다. NDB는 클러스터링만 지원하는 MySQL 스토리지 엔진이다.


"NDB" 의 의미는?
"Network Database".


클러스터를 지원하는 MySQL 버전은? 소스를 컴파일 해야 하나?

MySQL-max 4.1.3부터 지원한다. 바이너리 파일은 컴파일을 할 필요가 없다.


RAM은 얼마나 필요한가? 디스크는 사용하지 못하나?

클러스터는 오직 in-memory이며, 모든 테이블 데이터(인덱스 포함)가 RAM에 저장된다. 클러스터에서 필요한 RAM용량은 다음 공식으로 계산한다. (SizeofDatabase * NumberOfReplicas * 1.1 ) / NumberOfDataNodes


ERROR 1114: The table 'my_cluster_table' is full

위와 같은 에러가 발생했을 때는 할당된 메모리가 부족한 경우이다.


FULL TEXT 인덱스를 지원하는가?

현재 지원하지 않는다.


하나의 컴퓨터에서 여러 개의 노드가 돌아가는가?

가능하긴 하지만 권하진 않는다. 각 노드들이 다른 컴퓨터에서 실행되는 것이 더 안정적이다.


클러스터를 재시작하지 않고 노드를 추가할 수 있는가?

할 수 없다. MGM 이나 SQL 노드를 추가하려면 새로 시작해야 한다.


어떻게 기존의 MySQL 데이터베이스를 클러스터로 임포트 하는가?

ENGINE=NDB 나 ENGINE=NDBCLUSTER 옵션을 가진 테이블은 임포트할 수 있다. 또는 ALTER 기능으로 기존의 테이블을 클러스터로 변환 사용할 수 있다.

- ALTER TABLE OLD_TABLE ENGINE=NDBCLUSTER;


Arbitrator란 ?

클러스터에서 한 개 혹은 그 이상의 노드가 실패할 경우, MGM 서버나 다른 노드가 그 노드의 역할을 대신하여 다른 노드들로 하여금 실패한 노드와 같은 노드로 인식하게 하는 기능을 한다. 이런한 역할을 하는 노드를 중재인이라고 한다.


클러스터 shut down시에 어떤 일이 일어나는가?

클러스터 데이터 노드의 메모리에 있던 데이터가 디스크에 쓰여지고, 그 다음에 클러스터가 시작될 때 다시 메모리에 로드된다.


클러스터에서 다른 매니저 노드를 구성하는 것은?

fail-safe에 있어서 도움이 된다. 단지 하나의 MGM 노드 만이 클러스터를 컨트롤 할 수 있지만 MGM 노드 하나를 primary로, 추가의 매니저 노드를 primary MGM 노드가 실패했을 때 인계받도록 하면 된다.


5. MySQL Cluster Glossary 


Cluster

일반적으로 Cluster는 하나의 업무를 수행하기 위해 함께 동작하는 컴퓨터 세트이다. NDB Cluster는 자료저장, 복구, 컴퓨터 간의 분배 관리 등을 시행하기 위해 MySQL을 사용하는 Storge Engine 이다. MySQL Cluster는 in-memory storage를 사용한 shared-noting 아키텍쳐에서 분산된 MySQL DB를 지원하기 위해 NDB엔진을 사용하여 함께 돌아가는 컴퓨터 그룹이다.


Configuration Files

클러스터, 호스트, 노드에 관계된 직접적인 정보를 포함하는 파일이다. 클러스터 시작 시 Cluster의 MGM 노드가 읽어들인다.


Backup

디스크나 다른 Long-term Storage에 저장되는 모든 클러스터 데이타, 트랜젝션, 로그의 완전한 카피를 말한다.


Restore

백업에 저장되는 것과 같이 클러스터에 그 전 상태로 되돌리는 것을 말한다.


CheckPoint

일반적으로 데이타가 디스크에 저장될 때 체크포인트에 도달한다고 말한다. 클러스터에서는 Committed된 트랜잭션을 디스크에 저장하는 시간을 말한다. NDB Storage Engine에는 일관되게 클러스터의 데이타를 보존하기 위해 두 종류의 CheckPoint가 있다. LocalCheckPoint(LCP) : 싱글 노드의 체크포인트. 그러나 클러스터의 모든 노드에서 LCP를 사용한다. LCP는 디스크에 노드의 모든 데이타를 저장하도록 한다(보통 매 몇 분마다). 클러스터 Activity의 노드와 레벨, 다른 요인에 의해 저장되는 데이타의 양은 의존적이다. GlobalCheckPoint(GCP) : GCP는 모든 노드의 트랜잭션이 동기화되고, redo-log가 Disk에 저장될 때 몇 분마다 발생한다.


Cluster Host

MySQL Cluster의 구성 컴퓨터. 클러스터는 물리적 구조와 논리적 구조를 가진다. 물리적으로 클러스터는 Cluster Host라는 컴퓨터의 수로 구성된다.


Node

MySQL Cluster의 논리적, 기능적 요소를 말하며 Cluster Node라고도 한다. MySQL Cluster에서는 node란 용어를 Cluster의 물리적 Component인 Process를 지칭한다. MySQL Cluster가 동작하기 위해 3가지 타입의 노드가 있다.


MGM node - MySQL Cluster에서 다른 노드들의 설정 정보, 노드의 시작과 정지, 네트워크 파티셔닝, 백업과 저장 등을 포함하여 다른 노드들을 관리한다.


SQL node (MySQL Server) - 클러스터의 데이터 노드안에 저장된 데이터를 Serve 하는 MySQL Server 인스턴스. 데이타를 저장, 분배, 업데이트하는 클라이언트는 MySQL Server를 통해 접근 가능하다.


Data node - 이 노드는 실제 데이타를 저장한다. 현재 싱글 클러스터는 총 48개의 데이타 노드를 지원한다.

싱글 머신에 한 개 이상의 노드가 공존할 수도 있고, 한 머신에 완전한 클러스터를 구성하는 것도 가능하다. MySQL 클러스터에서 호스트는 클러스터의 물리적 컴퍼넌트이며, 노드는 논리적 혹은 기능적인 컴퍼넌트, 즉 프로세스라는 것을 잊지 말자.


Node group

데이터 노드의 집합. 노드 그룹 안의 모든 데이터 노드는 같은 데이터(fragment)를 포함한다. 그리고 싱글 그룹의 모든 노드는 다른 호스트에 존재해야 한다.


Node failure

MySQL 클러스터는 클러스터를 구성하는 어느 한 노드의 기능에만 의존적이지 않다. 클러스터는 하나 혹은 몇 개의 노드가 실패해도 계속될 수 있다.


Node restart

실패한 클러스터 노드의 리스타팅 과정.


Initial node restart

노드의 이전의 파일 시스템을 지우고 시작하는 클러스터 노드의 과정. 소프트웨어 향상과 그 밖의 특별한 상황 등에 사용된다.


System crash(or System fail)

클러스터의 상태가 확인되지 않는 등 많은 클러스터 노드가 실패했을 때 일어날 수 있다.


System restart

클러스터의 리스타팅과 디스크 로그 및 체크 포인트로부터 reinstall하는 프로세스를 말한다. 클러스터를 shutdown 한 이후에 일어나는 과정이다.


fragment

데이터베이스 테이블의 한 부분. NDB스토리지 엔진에서 테이블을 나누어 fragments의 수에 따라 저장한다. Fragment는 파티션이라 불리기도 한다. MySQL 클러스터에서 테이블은, 머신과 노드 간의 로드 밸런싱을 용이하게 할 수 있도록 fragment된다.


Replica

NBD 스토리지 엔진에서 각 테이블 프레그먼트는 여분을 포함하여 다른 데이터 노드에 저장된 많은 replica를 갖는다. 현재는 fragment 당 4개 이상의 replica가 가능하다.


Transpoter

노드들 간의 데이터 이동을 제공하는 프로토콜 TCP/IP(local), TCP/IP(remote), SCI, SHM(MySQL 4.1 버전에서 실험적임)


NDB(Network DataBase)

NDB는 MySQL클러스터에서 사용하는 스토리지 엔진을 말 함. NDB 스토리지 엔진은 모든 일반적인 MySQL 컬럼 타입과 SQL문을 지원하며, ACID(DB무결성 보장을 위한 트랜잭션)성질을 가진다.


Shared-nothing architecture

MySQL 클러스터의 이상적인 아키텍쳐. 진정한 Shared-nothing setup 에서 각 노드는 분리된 호스트에서 실행된다. 이러한 배열은 싱글 호스트나 싱글 노드가 아니면 SOF나 시스템 병목현상이 전체적으로 발생할 수 있다는 데 있다.


In-memory storage

각 데이터 노드에 저장된 모든 데이터는 그 노드의 호스트 컴퓨터의 메모리에 유지된다. 클러스터의 각 데이터 노드를 위해, (데이터 노드의 수로 나뉜 replica의 수 * 데이터베이스 사이즈)만큼의 가용 RAM의 양을 확보해 두어야 한다. 그러니까, 데이터베이스가 1기가의 메모리를 차지하고, 4개의 replica와 8개의 노드로 클러스터를 구성하고자 하면, 각 노드당 최소 500MB의 메모리가 필요하다. 그리고 OS와 다른 어플리케이션 프로그램이 쓰는 메모리가 추가로 필요하다.


Table

관계형 데이터베이스에서는 table은 일반적으로 동일하게 구조화된 레코드의 set을 가리킨다. MySQL 클러스터에서 데이터베이스 테이블은 fragment의 set으로써 데이터 노드에 저장되고, 각 fragment는 추가로 데이터 노드에 복제된다. 같은 fragment를 replicate한 데이터 노드의 set이나 fragment의 set을 노드 그룹이라 한다.


Cluster Programs : 명령어들

서버 데몬
  • ndbd : 데이터 노드 데몬
  • ndb_mgmd : MGM서버 데몬
클라이언트 프로그램
  • ndb_mgm : MGM 클라이언트
  • ndb_waiter : 클러스터의 모든 노드들의 상태를 확인할 때 사용
  • ndb_restore : 백업으로부터 클러스터의 데이터를 복구할 때 사용

Contributors 

처음 작성자 : 송은영,f405(ccotti22) f405@naver.com (2006.2.1 15:37)

작성일 : 2005년 8월 10일 수요일

이 문서는 MySQL Cluster 4.0대의 매뉴얼을 번역, 정리한 것으로 틀린 부분을 다소 포함할 수 있으며, 저는 그에 대한 책임을 지지 않겠습니다.

부족하지만 다른 분들도 공부하는데 도움이 되길 바랍니다.

그리고 이 문서를 작성하기 전 참고한 리눅스 및 MySQL 문서들을 작성하신 많은 선배님들에게 감사의 말씀을 드립니다. 그리고 이 경어는 생략하였습니다. 양해의 말씀을...


카테고리 없음
apachectl 은 httpd 데몬을 띄우는 일종의 alias로 작동한다.

apachectl 에서 옵션(-k)가 없을 경우 디폴트 옵션으로 적용한다.

그래서 apachectl start 를 실행하면 내부적으로는 httpd -k start 로 동작한다.

그런데 아래와 같은 오류가 발생한다.

Permission denied: make_sock: could not bind to address [::]:80
Permission denied: make_sock: could not bind to address 0.0.0.0:80
no listening sockets available, shutting down
Unable to open logs
apache 데몬을 root 권한이 아닌 사용자 계정으로 로딩하기 위해서 소유권을 바꿨더니 발생한다.

기본적으로 예약된 포트는 root 권한 이외의 계정으로는 오픈할 수 없기 때문이다.

이럴 때는,

chown root.root httpd
chmod +s httpd


를 해주면, httpd의 권한이 -rwsr-sr-x 로 변경된다.

그리고 freeism(사용자 계정)으로 소유권이 지정된 ( 즉, chown freeism.freeism apachectl )

apachectl 을 통해서 httpd 데몬을 로딩하면,

사용자 계정으로 마치 root 처럼 데몬을 띄워준다.

1 2 3 4 5 ··· 11
블로그 이미지

개발자

우와신난다