sentinel_data_structure
Redis SENTINEL Data Structure
레디스 센티널 교육 신청 |
레디스 정기점검/기술지원 Redis Technical Support |
레디스 엔터프라이즈 서버 Redis Enterprise Server |
---|
Redis SENTINEL Data Structure
센티널 데이터 구조를 설명한다.
센티널 데이터 구조 개요
- sentinelState: 센티널 정보, 센티널 인스턴스 당 1개
- sentinelRedisInstance(Master): 센티널이 모니터링하는 마스터 정보, 마스터 개수 만큼 생성
- sentinels: 마스터를 모니터링하는 다른 센티널 정보(sentinelRedisInstance와 같은 구조체), 다른 센티널 개수 만큼 생성
- slaves: 마스터를 바라보는 슬레이브 정보(sentinelRedisInstance와 같은 구조체), 슬레이브 개수 만큼 생성
- master: 슬레이브일때 마스터를 가리키는 포인터(sentinelRedisInstance와 같은 구조체)
- promoted_slave: 마스터 다운 시 새 마스터가 될 슬레이브 포인터(sentinelRedisInstance와 같은 구조체)
No | Data Type | Name | 설명 | Default |
---|---|---|---|---|
1 | char | myid[40+1] | 센티널 ID(40자) | memset(0) |
2 | uint64_t | current_epoch | 현재 epoch, 센티널 리더 선출할때 마다 1씩 증가함 | 0 |
3 | dict | *masters | 센티널이 모니터링하고 있는 마스터들의 정보, distionary 구조체로 관리함 | dictCreate() |
4 | int | tilt | 틸트모드는 센티널이 비정상일때 설정된다. 운영체제의 시간이 뒤로 갔거나, 센티널이 2초 동안 아무 동작을 하지 못했으면 틸트모드로 진입하고, 30초 후에 정상으로 돌아온다. | 0 |
5 | mstime_t | tilt_start_time | 틸트모드 시작 시각, 이 시각을 체크해서 30초가 지났으면 정상모드로 돌아온다. | 0 |
6 | mstime_t | previous_time | 틸트모드 확인이 끝나면 현재 시각이 세팅된다. 틸트모드 확인이 시작될때 현재 시각에서 previous_time을 뺀 값이 0보다 작거나 2초를 초과하면 틸트모드가 된다. | mstime() |
7 | int | running_scripts | 현재 실행 중인 스크립트(파일)의 수이다. 스크립트는 notification_script 또는 client_reconfig_script이다. sentinel pending-scripts 명령 참조 | 0 |
8 | list | *scripts_queue | 실행 대기 중 또는 실행 중인 스크립트 개수이다. 센티널은 경고 이벤트(sentinelEvent(warning))가 발생하면 실행할 스크립트를 이 큐(리스트)에 넣고 하나씩 실행한다. 실행이 완료되면 큐에서 제거된다. | listCreate() |
9 | char | *announce_ip | IP addr that is gossiped to other sentinels if not NULL. | NULL |
10 | int | announce_port | Port that is gossiped to other sentinels if non zero. | 0 |
11 | unsigned long | simfailure_flags | 센티널은 장애조치 중간에 시뮬레이션용으로 센티널을 다운시킬 수 있다. 다운 시점은 리더 선출 직후 또는 슬레이브를 마스터로 승격시킨 직후 2가지인데, 이중 하나를 설정할 수 있다. 이것은 시뮬레이션(테스트) 용도로 사용된다. 명령 sentinel simfailure_failure 참조 | 0 |
No | Data Type | Name | 설명 | Default |
---|---|---|---|---|
1 | int | flags; | 인스턴스의 상태를 나타내는 플레그로 비트로 관리되어 여러가지 상태를 나타낼 수 있다. 상태에 대한 자세한 정보는 아래 FLAGS를 참조 | |
2 | char | *name | 마스터일때는 모니터링할 때 설정한 이름, 슬레이브일때는 IP:Port, 센티널일때는 runid | |
3 | char | *runid | 마스터, 슬레이브, 센티널 모두 runid | NULL |
4 | uint64_t | config_epoch; | Configuration epoch. | 0 |
5 | sentinelAddr | *addr | IP, Port | |
6 | instanceLink | *link | instanceLink를 가리킨다. default: createInstanceLink() | |
7 | mstime_t | last_pub_time | 마지막 publish 시각 | mstime() |
8 | mstime_t | last_hello_time; | Pub/Sub를 통해서 마지막 hello 메시지를 받은 시각 | mstime() |
9 | mstime_t | down_after_period | 이 시간동안 레디스 서버로 부터 응답이 없으면 주관적 다운을 인지한다. 설정파일(sentinel.conf)에 있는 down-after-milliseconds 시간이 들어간다. | 30000ms |
10 | mstime_t | s_down_since_time | 주관적 다운을 인지한 시각 | 0 |
11 | mstime_t | o_down_since_time | 객관적 다운을 판정한 시각 | 0 |
12 | mstime_t | last_master_ down_reply_time |
객관적 다운을 확인하기 위해서 또는 센티널 리더를 선출할때
sentinel is-master-down-by-addr 명령을 다른 센티널에게 보내는데,
그 응답이 온 시각을 기록한다. 이 명령(is-master-down..)을 1초마다 실행하기위해서 이 시각을 체크한다. 이 시각을 기준으로 5초 초과하여 응답이 없으면 오래된 정보로 간주하여 MASTER_DOWN 플레그를 지우고 leader를 삭제한다. | mstime() |
13 | mstime_t | info_refresh | 마스터 또는 슬레이브의 정보를 얻기위해 INFO 명령을 보내고, 받아서 처리한 시각. 센티널은 평상시 10초마다 보내고, 이상이 발생하면 1초마다 보내는데, 이 시각을 기준으로 계산한다. | 0 |
14 | sds | info | INFO 명령의 결과를 여기에 담아 놓는다. | NULL |
15 | char | *auth_pass | 마스터, 슬레이브가 password를 가지고 있을 때 여기에 설정한다. | NULL |
역할(role) 정보 | ||||
16 | int | role_reported | 변경된 역할(master/slave)을 확인하는데 사용된다.
flags는 현재 역할이고 role_reported가 새 역할이다. 센티널은 마스터 또는 슬레이브에 INFO 명령을 보내서 정보를 받는다. role 필드에 있는 정보를 여기에 등록한다. | |
17 | mstime_t | role_reported_time | 역할(role)이 변경되었을 경우 변경된 시각이 세팅된다. | mstime() |
마스터일 때 | ||||
18 | dict | *sentinels | 이 마스터를 모니터링하고 있는 다른 센티널들의 정보. Dict으로 구성되고, sentinelRedisInstance 구조체를 가리킨다. | dictCreate() |
19 | dict | *slaves | 이 마스터를 바라보는 슬레이브들의 정보. Dict으로 구성되고, sentinelRedisInstance 구조체를 가리킨다. | dictCreate() |
20 | unsigned int | quorum | 이 마스터의 쿼럼값이다. 객관적 다운을 판정하는 기준이다. | quorum |
21 | int | parallel_syncs | 장애조치 과정에서 새 마스터에 대해서 여러 슬레이브에 slaveof 명령을 수행하는데 동시에 수행할 명령의 수를 정한다. | 1 |
슬레이브일 때 | ||||
22 | struct sentinel RedisInstance | *master | 마스터 포인터 | master |
23 | char | *slave_master_host | 마스터 IP (INFO) | NULL |
24 | int | slave_master_port | 마스터 Port (INFO) | 0 |
25 | int | slave_master_ link_status | 마스터 연결 여부(UP/DOWN) (INFO) | 1 |
26 | int | slave_priority | 이 값이 적은 슬레이브가 마스터로 선정된다. INFO 명령으로 얻은 정보를 여기에 넣는다. | 100 |
27 | unsigned long long | slave_repl_offset | Slave replication offset. | 0 |
28 | mstime_t | master_link_ down_time |
슬레이브가 마스터와 오랫동안 끊겨있으면 마스터로 선정될 수 없다. (down-after-milliseconds * 10) INFO 명령으로 얻은 master_link_down_since_seconds 정보를 여기에 넣는다. | 0 |
29 | mstime_t | slave_reconf_ sent_time | slaveof | 0 |
30 | mstime_t | slave_conf_ change_time | 슬레이브의 마스터 주소(IP,Port)가 변경되었을 때 세팅된다. | mstime() |
장애조치(failover) 정보 | ||||
31 | char | *leader | 센티널이 투표한 리더 센티널의 runid | NULL |
32 | uint64_t | leader_epoch | Epoch of the 'leader' field. | 0 |
33 | uint64_t | failover_epoch | Epoch of the currently started failover. | 0 |
34 | int | failover_state | 자세한 정보는 아래 FAILOVER_STATE를 참조 | 0 |
35 | mstime_t | failover_state_ change_time | failover_state가 변경될 때 마다 기록된다. 이 시각으로 각 단계마다 시간초과를 체크한다. | 0 |
36 | mstime_t | failover_start_time | 장애조치 시작 시각, 다른 센티널에게 투표했으면 투표한 시각이 들어가고, 다른 센티널에게 투표하지 않았고 자신이 객관적 다운을 판정했으면 장애조치 시작 시각이 들어간다. 이 시각을 기준으로 10초 동안 리더가 선출되지 않으면 시간초과가 발생하고 장애조치가 다시 시작된다. | 0 |
37 | mstime_t | failover_timeout | failover_timeout은 장애조치 시작부터 끝까지가 아니고, 각 단계마다의 소요시간을 체크해서 시간초과여부를 판정한다. | 180000 |
38 | mstime_t | failover_delay_logged | failover_start_time과 비교해서 "Next failover delay" 로그를 남기는데 이용된다. | 0 |
39 | struct sentinel RedisInstance | *promoted_slave; | 새 마스터로 선정된 슬레이브 | NULL |
스크립트(scripts) | ||||
40 | char | *notification_script | 경고 이벤트가 발생하면 여기 설정한 파일을 실행해서
관리자에게 이메일 또는 SMS로 알린다. sentinel notification(알림) 참조 | NULL |
41 | char | *client_reconfig_script | 장애조치가 완료되면 이 파일을 실행해서 예전 마스터 주소(IP, Port)와 새 마스터 주소를 알린다. | NULL |
InstanceLink 데이터 구조
센티널(레디스) 버전 3.2.0에서 InstanceLink 구조체가 새로 생겼다.
이것은 sentinelRedisInstance 구조체에서 연결(connection)정보를 분리해 낸 것이다.
그럼 이제부터 왜 연결(connection)정보를 분리했는지 알아보자.
이해를 돕기위해 센티널 5대(X1~5), 마스터 3대(M1~3)를 모니터링하는 상황을 가정해서 설명한다.
위 그림은 센티널 버전 3.0.x에서 센티널 X1이 마스터 3대와 다른 센티널 4대의 정보를 가지고 있는 것을 표시했다.
센티널은 다른 센티널의 정보를 자신이 모니터링하고 있는 마스터 단위로 가지고 있다.
센티널 X1은
M1을 같이 모니터링하는 센티널 X2 정보를 M1->x2로 가지고 있고,
M2를 같이 모니터링하는 센티널 X2 정보를 M2->x2로 또 가지고 있고,
M3를 같이 모니터링하는 센티널 X2 정보를 M3->x2로 또 가지고 있다.
X3, X4, X5도 마찬가지로 세 개씩 가지고 있다.
이렇게 분리된 정보를 각각 가지고 있으면 센티널 X2가 살아있는지 확인하기 위해서
M1->x2를 통해서 ping을 X2에게 보내고 ping을 보낸 시각, pong을 받은 시각 등을 관리한다.
M2->x2는 이미 M1->x2를 통해서 X2가 살아있는지 확인했어도 정보가 공유되지 않으므로 같은 작업을 반복한다.
M3->x3도 마찬가지이다.
이런 문제를 해결하기 위해서 버전 3.2.0에서는 센티널 연결정보를 아래 그럼과 같이 별로 구조체로 분리했다.
위 그림이 좀 복잡해진 것처럼 보이기도 하지만, X2 연결정보를 담당하는 L2를 만들어서
M1->x2, M2->x2, M3->x3가 공유하는 것이다.
그럼 ping을 보내는 횟수 등이 훨씬 줄어들게 된다.
이는 모니터링하는 마스터의 개수가 많을수록 효과가 더 있다.
100개의 마스터를 모니터링한다면 400개의 연결정보가 있어야 했는데,
이제는 4개만 있으면 된다.
이 구조는 센티널 뿐만이 아니라 마스터, 슬레이브에도 같이 적용된다.
마스터, 슬레이브는 연결정보가 하나만 있으면 되기 때문에 연결정보 분리의 효과가 없다.
이것은 센티널을 위한 것이다.
No | Data Type | Name | 설명 | Default |
---|---|---|---|---|
1 | int | refcount | 이 연결정보를 공유하는 개수. 위 그림에서 보면 L2로 들어도는 화살표의 개수이다. 마스터, 슬레이브는 항상 1이다. | 1 |
2 | int | disconnected | 일반적인 기준으로 15초를 초과해서 응답이 없으면 1로 세팅한다. 1은 연결이 끊긴것이다. | 1 |
3 | int | pending_commands | 센티널은 레디스 서버에 보내는 명령을 항상 비동기(async)로 실행한다.
명령을 실행할 때마다 1 증가시키고, 응답이 오면 1 감소시킨다.
현재 몇 개의 명령이 응답을 대기중인지 기록하는 필드이다. 주기적으로 보내는 PING, INFO, PUBLISH 명령은 최대 99개 까지 대기할 수 있다. 100개 이상이면 이 명령들을 더 이상 실행하지 않는다. 장애조치 같은 다른 명령은 이런 제한이 없다. | 0 |
4 | redisAsyncContext | *cc | Hiredis context for commands. | NULL |
5 | redisAsyncContext | *pc | Hiredis context for Pub / Sub. | NULL |
6 | mstime_t | cc_conn_time | cc connection time. | 0 |
7 | mstime_t | pc_conn_time | pc connection time. | 0 |
8 | mstime_t | pc_last_activity | Last time we received any message. | 0 |
9 | mstime_t | last_avail_time | 마지막 Pong을 받은 시각, 연결이 끊긴 상태(disconnected == 1)에서는 이 시각을 기준으로 계산해서 down_after_period를 초과했으면 주관적 다운으로 인지한다. | mstime() |
10 | mstime_t | act_ping_time |
연결중인 상태(disconnected == 0)에서는 이 시간을 기준으로 계산해서
down_after_period를 초과했으면 주관적 다운으로 인지한다. 이 필드가 0인 상태에서 Ping을 보내면 보낸 시각을 세팅하고, Pong을 받으면 0으로 세팅한다. 이전 Ping에 대한 Pong이 없는 상태(0이 아닌 상태)에서 Ping을 보낼때는 보낸 시각을 세팅하지 않는다. | mstime() |
11 | mstime_t | last_ping_time | 마지막 Ping을 보낸 시각, 이 필드와 last_pong_time으로 계산해서 1초에 한 번씩 Ping을 보낸다. | 0 |
12 | mstime_t | last_pong_time | 마지막 pong을 받은 시각, Ping을 보내는 기준과 disconnected 필드를 1로 세팅하는데 사용된다. | mstime() |
13 | mstime_t | last_reconn_time | 연결이 끊긴 상태에서 마지막 연결 시도 시각, 연결 성공 여부와 관계없이 세팅된다. | 0 |
sentinelScriptJob 데이터 구조
이것은 위에서 언급한 notification_script와 client_reconfig_script를 관리하는 구조체이다.
이 스크립트가 큐에 대기하거나 실행중일때 여기에 관리된다.
알림에 대한 전반적인 내용은
sentinel notification(알림)을 참조하세요.
No | Data Type | Name | 설명 | Default |
---|---|---|---|---|
1 | int | flags | 현재 실행중(running)인지 대기중인지 나타낸다. | |
2 | int | retry_num | 스크립트를 실행했으나 60초가 지나도 끝나지 않으면 시간초과로 중지된다. 이후에 다시 실행된다. 이 필드는 재 시도 횟수를 기록한다. 10번까지 시도할 수 있다. | |
3 | char | **argv | notification_script의 인수는 이벤트 명, 이벤트 설명이고, client_reconfig_script의 인수는 master-name, 역할(reader, observer), 상태(현재는 start)로 고정, old-master ip, old-master port, new-master ip, new-master port | |
4 | mstime_t | start_time; | 대기중일때는 0, 실행하면 실행시작 시각이 들어간다. 재시도하면 재시도 시작 시각(미래 시각)이 들어간다. | |
5 | pid_t | pid | 실행하면 자식 프로세스 ID가 들어간다. |
FLAGS
마스터, 슬레이브, 센티널의 상태를 나타낸다.
- SRI_MASTER (1<<0) : 마스터일 때
- SRI_SLAVE (1<<1) : 슬레이브일 때
- SRI_SENTINEL (1<<2) : 센티널일 때
- SRI_S_DOWN (1<<3) : 주관적 다운(마스터, 슬레이브, 센티널에 모두 해당)
- SRI_O_DOWN (1<<4) : 객관적 다운(특정 마스터를 주관적 다운으로 인지한 센티널 수가 쿼럼값 이상이면 객관적 다운으로 판정), 이것은 마스터에만 해당한다.
- SRI_MASTER_DOWN (1<<5) : 센티널이 다른 센티널에게 마스터 다운 여부를 문의했을 때 다운되었다고 응답이 오면 master-down으로 표시한다. 이 master-down 개수가 쿼럼값 이상이면 센티널은 해당 마스터를 객과적 다운으로 판정한다. 이것은 센티널에 표시된다.
- SRI_FAILOVER_IN_PROGRESS (1<<6) : 장애조치가 시작되었다. 마스터에 표시.
- SRI_PROMOTED (1<<7) : 새로운 슬레이브가 새 마스터로 승격되었다. 마스터에 표시.
- SRI_RECONF_SENT (1<<8) : 슬레이브에게 새 마스터를 바라보도록 slaveof new-master 명령을 보냈다. 슬레이브에 표시.
- SRI_RECONF_INPROG (1<<9) : 슬레이브가 slaveof new-master 명령을 실행중이다. 슬레이브에 표시.
- SRI_RECONF_DONE (1<<10) : 슬레이브가 slaveof new-paster 명령을 완료했다.
- SRI_FORCE_FAILOVER (1<<11) : sentinel failover 명령 실행으로 장애조치 시작
- SRI_SCRIPT_KILL_SENT (1<<12) : SCRIPT KILL already sent on -BUSY
FAILOVER_STATE
- SENTINEL_FAILOVER_STATE_NONE 0 : 평상(normal) 상태
- SENTINEL_FAILOVER_STATE_WAIT_START 1 : 장애조치 단계에 진입, 센티널 리더를 선출한다.
- SENTINEL_FAILOVER_STATE_SELECT_SLAVE 2 : 리더가 새로운 마스터가 될 슬레이브를 선정한다.
- SENTINEL_FAILOVER_STATE_SEND_SLAVEOF_NOONE 3 : 슬레이브가 새 마스터가 되도록 슬레이브에게 slaveof no one 명령을 보낸다.
- SENTINEL_FAILOVER_STATE_WAIT_PROMOTION 4 : 명령이 완료되기를 기다린다.
- SENTINEL_FAILOVER_STATE_RECONF_SLAVES 5 : 슬레이브들에게 새로운 마스터를 바라보도록 slaveof new-master 명령을 보내다.
- SENTINEL_FAILOVER_STATE_UPDATE_CONFIG 6 : 정보를 업데이트하고 새 마스터를 모니터링한다.
문서 정보
- 이 문서는 2016년 8월에 버전 3.2.2을 기준으로 만들었습니다.
<< Sentinel Introduction | Data Structure | SENTINEL ELECTION OF LEADER >> |
---|
조회수 :