twemproxy(트웸프록시)에 대한 예시이다.

redis나 memcached 프로토콜을 지원하며, consistent hashing을 지원하는 툴로서, 많이 사용하고 있다. 



트웸프록시 tar 압축 파일을 다운받으려면, https://github.com/twitter/twemproxy에 방문하여 “To build twemproxy from distribution tarball”를 찾은 후, distribution tarball 링크를 클릭하면 tar 압축 파일을 구글 드라이브로 볼 수 있다. 구글 드라이브에서 다운받을 수 있는 tar 압축 파일을 다운받는다.


$ tar -zxf nutcracker-0.4.1.tar.gz

$ cd nutcracker-0.4.1

$ ./configure

$ make


트웸프록시의 binary인 nutcracker이 정상적으로 실행되는지 확인한다.


$ ./src/nutcracker --help

This is nutcracker-0.4.1


Usage: nutcracker [-?hVdDt] [-v verbosity level] [-o output file]

                  [-c conf file] [-s stats port] [-a stats addr]

                  [-i stats interval] [-p pid file] [-m mbuf size]


Options:

  -h, --help             : this help

  -V, --version          : show version and exit

  -t, --test-conf        : test configuration for syntax errors and exit

  -d, --daemonize        : run as a daemon

  -D, --describe-stats   : print stats description and exit

  -v, --verbose=N        : set logging level (default: 5, min: 0, max: 11)

  -o, --output=S         : set logging file (default: stderr)

  -c, --conf-file=S      : set configuration file (default: conf/nutcracker.yml)

  -s, --stats-port=N     : set stats monitoring port (default: 22222)

  -a, --stats-addr=S     : set stats monitoring ip (default: 0.0.0.0)

  -i, --stats-interval=N : set stats aggregation interval in msec (default: 30000 msec)

  -p, --pid-file=S       : set pid file (default: off)

  -m, --mbuf-size=N      : set size of mbuf chunk in bytes (default: 16384 bytes)



설정 파일은 conf/nutcracker.yml이고, 야믈(yaml) 파일이다.


$ cat conf/nutcracker.yml

alpha:

  listen: 127.0.0.1:22121

  hash: fnv1a_64

  distribution: ketama

  auto_eject_hosts: true

  redis: true

  server_retry_timeout: 2000

  server_failure_limit: 1

  servers:

   - 127.0.0.1:6379:1


beta:

  listen: 127.0.0.1:22122

  hash: fnv1a_64

  hash_tag: "{}"

  distribution: ketama

  auto_eject_hosts: false

  timeout: 400

  redis: true

  servers:

   - 127.0.0.1:6380:1 server1

   - 127.0.0.1:6381:1 server2

   - 127.0.0.1:6382:1 server3

   - 127.0.0.1:6383:1 server4


gamma:

  listen: 127.0.0.1:22123

  hash: fnv1a_64

  distribution: ketama

  timeout: 400

  backlog: 1024

  preconnect: true

  auto_eject_hosts: true

  server_retry_timeout: 2000

  server_failure_limit: 3

  servers:

   - 127.0.0.1:11212:1

   - 127.0.0.1:11213:1


delta:

  listen: 127.0.0.1:22124

  hash: fnv1a_64

  distribution: ketama

  timeout: 100

  auto_eject_hosts: true

  server_retry_timeout: 2000

  server_failure_limit: 1

  servers:

   - 127.0.0.1:11214:1

   - 127.0.0.1:11215:1

   - 127.0.0.1:11216:1

   - 127.0.0.1:11217:1

   - 127.0.0.1:11218:1

   - 127.0.0.1:11219:1

   - 127.0.0.1:11220:1

   - 127.0.0.1:11221:1

   - 127.0.0.1:11222:1

   - 127.0.0.1:11223:1


omega:

  listen: /tmp/gamma

  hash: hsieh

  distribution: ketama

  auto_eject_hosts: false

  servers:

   - 127.0.0.1:11214:100000

   - 127.0.0.1:11215:1


distribution: ketama는 consistent hashing을 쓰겠다는 의미이다.

설정은 alpha부터 omega까지 있다. 다중 레디스를 쓰는지에 대한 설정을 가진다. 분산방법, timeout 등 설정이 있다.


설정 파일이 정상인지 체크하려면 -t를 추가한다.


$ ./src/nutcracker -t -c conf/nutcracker.yml

nutcracker: configuration file 'conf/nutcracker.yml' syntax is ok



만약 아래 에러가 발생해도 이슈는 없다. 디폴트로 22121 포트이다.

nc_connection.c:374 recv on sd 6 failed: Connection refused

nc_connection.c:374 recv on sd 7 failed: Connection refused


데몬으로 실행하려면 -d를 커맨드 라인에 추가한다.

그리고, pid 파일이나 로그 파일도 지정할 수 있다. 




이제, alpha 버전인 기준으로 6379 포트만 띄운 redis만 테스트해본다.



창 하나를 띄워 redis 데몬을 실행한다.

127.0.0.1:6379> monitor

OK



nutcracker의 22121 포트로 데이터를 보낸다.


$ redis-cli -p 22121 set key value

OK



이미 띄워놓은 MONITOR 창에서 정상적으로 결과를 확인한다.


1455010283.355070 [0 127.0.0.1:55737] "set" "key" "value"




다음은 redis 인스턴스를 여러 대를 잘 처리하는지 살펴본다.


레디스 서버를 3 개의 포트로 띄운다. flushdb로 깔끔히 데이터를 정리한다.


$ ./src/redis-server --port 6379 --daemonize yes

$ ./src/redis-server --port 6380 --daemonize yes

$ ./src/redis-server --port 6381 --daemonize yes



conf/nutcracker.yml 파일에서 alpha 설정 밑에 6380과 6381을 추가한 후 재시작한다.


$ vi conf/nutcracker.yml 

alpha:

  listen: 127.0.0.1:22121

  hash: fnv1a_64

  distribution: ketama

  auto_eject_hosts: true

  redis: true

  server_retry_timeout: 2000

  server_failure_limit: 1

  servers:

   - 127.0.0.1:6379:1

   - 127.0.0.1:6380:1

   - 127.0.0.1:6381:1

...
$ ./src/nutcracker  -c conf/nutcracker.yml



트웸프록시 설정이 제대로 되었는지 확인한다.

$ telnet 127.0.0.1 22222 2> /dev/null | tail -n 1 | jq '.'

{


  "alpha": {

    "client_eof": 0,

    "client_err": 0,

    "client_connections": 0,

    "server_ejects": 0,

    "forward_error": 0,

    "fragments": 0,

    "127.0.0.1:6379": {

      "server_eof": 0,

      "server_err": 0,

      "server_timedout": 0,

      "server_connections": 0,

      "server_ejected_at": 0,

      "requests": 0,

      "request_bytes": 0,

      "responses": 0,

      "response_bytes": 0,

      "in_queue": 0,

      "in_queue_bytes": 0,

      "out_queue": 0,

      "out_queue_bytes": 0

    },

    "127.0.0.1:6380": {

      "server_eof": 0,

      "server_err": 0,

      "server_timedout": 0,

      "server_connections": 0,

      "server_ejected_at": 0,

      "requests": 0,

      "request_bytes": 0,

      "responses": 0,

      "response_bytes": 0,

      "in_queue": 0,

      "in_queue_bytes": 0,

      "out_queue": 0,

      "out_queue_bytes": 0

    },

    "127.0.0.1:6381": {

      "server_eof": 0,

      "server_err": 0,

      "server_timedout": 0,

      "server_connections": 0,

      "server_ejected_at": 0,

      "requests": 0,

      "request_bytes": 0,

      "responses": 0,

      "response_bytes": 0,

      "in_queue": 0,

      "in_queue_bytes": 0,

      "out_queue": 0,

      "out_queue_bytes": 0

    }

  },





트웸프록시 포트로 데이터를 저장해본다.

$ redis-cli -p 22121 set key value

$ redis-cli -p 22121 set key1 value

$ redis-cli -p 22121 set key2 value

$ redis-cli -p 22121 set akey yvalue


결과는 다음과 같다.


6379 포트 위의 레디스


127.0.0.1:6379>

127.0.0.1:6379> keys *

(empty list or set)

127.0.0.1:6379> monitor

OK

1455030738.382162 [0 127.0.0.1:56016] "set" "akey" "yvalue"




6380 포트 위의 레디스


127.0.0.1:6380> keys *

(empty list or set)

127.0.0.1:6380> monitor

OK





6381 포트 위의 레디스


127.0.0.1:6381> keys *

(empty list or set)

127.0.0.1:6381> monitor

OK

1455030017.397192 [0 127.0.0.1:55987] "set" "key" "value"

1455030688.255451 [0 127.0.0.1:55987] "set" "key1" "value"

1455030690.631344 [0 127.0.0.1:55987] "set" "key2" "value"



제대로 읽기도 잘한다.

$ redis-cli -p 22121 get key2

"value"



트웸프록시를 통해 다양하게 저장한다.

트웸프록시가 SPOF 가 될 수 있으니, L4나 HA_PROXY를 이용해서 여러 대의 트웸프록시를 바인딩할 수 있다.



참고로, info 커맨드를 이용하면 연결이 종료된다.


$ redis-cli -p 22121 info

Error: Server closed the connection





twemproxy의 해싱 알고리즘은 다양하다. libmemcached가 사실상 consistent hashing의 대표적인 알고리즘이므로 crc32로 써도 무관하다.


hash: The name of the hash function. Possible values are:

  • one_at_a_time
  • md5
  • crc16
  • crc32 (crc32 implementation compatible with libmemcached)
  • crc32a (correct crc32 implementation as per the spec)
  • fnv1_64
  • fnv1a_64
  • fnv1_32
  • fnv1a_32
  • hsieh
  • murmur
  • jenkins


그리고, 배포방식은 3가지가 존재한다.


distribution: The key distribution mode. Possible values are:

  • ketama
  • modula
  • random



자세한 내용은 아래를 참조한다.

https://github.com/twitter/twemproxy

https://github.com/twitter/twemproxy/blob/master/notes/recommendation.md




'Redis' 카테고리의 다른 글

[redis] 3.0에 있는 redis cluster 실행해보기  (0) 2016.02.15
[redis] AOF (append-only-file)  (0) 2016.02.10
[redis] RDB  (1) 2016.02.09
[펌] redis의 persistence에 대한 내용  (0) 2016.02.09
[펌] stunnel과 redis 설정  (0) 2016.01.28
Posted by '김용환'
,