티스토리 뷰

IT/개발

Redis HA

K.Nero 2018. 4. 5. 09:37

Single 로 사용하던 세션서버 용도의 Redis 를 노드를 늘릴 수 있는 기회가 생겨서 어떤 구성을 적용할 지 고민을 하게 되었다. 이상적인 구조는 Master 하나와 2대 이상의 Slave 그리고 3대 이상의 Sentinel 이지만 현재의 서버가 부족하여 2대로 구성을 해야 했다.

처음 생각했던 것은 Master 1, Slave 1 구성하고 Replication 을 사용하고 Slave 의 read only 를 사용하지 않는 것이었다. 마스터 장애 시 slave 에 쓸 수 있고 장애가 복구되면 다시 master 를 사용하려는 목적이었다.

하지만 slave 의 데이터가 master 로 가지 않는 단점이 있어서 slave 의 사용 시간이 늘어날 수록 복구 후 손실되는 데이터가 많아지는 단점을 갖고 있었다. (master 의 데이터를 동기화 하기 때문에 slave 에게만 있는 데이터는 master 가 복구된 후 모두 사라진다.)

그래서 생각한 것이 위 구성에서 Sentinel 1 를 더 구성하는 것이었다. 그럼 클라이어트에서 장애 감지 후 Slave 에 데이터를 쓰는 동안 Sentinel 이 장애를 감지하고 slave 를 master 로 승격시켜주게 되고 데이터가 손실되지 않기 때문이다.

아래 설명 중 slave only 를 비활성화 해주는 이유는 master 가 죽게 되면 잠깐 동안이라도 데이터를 쓰기 위해서인다. (개발한 redis connectino pool 이 장애를 감지해서 다른 서버를 사용하게 된다.)

Master 설치
특별히 해줄 것은 없지만 장애 후 slave 가 될 경우를 대비해서 redis.conf 의 slave-read-only 를 no 로 변경해 준다. 위 설명 중 slave 의 read only 를 비활성화하는 이유와 같다.
실행 : ./src/redis-server ./redis.conf

Slave 설치
redis.conf 의 slaveof <masterip> <msaterport> 에 master node 의 ip port 를 설정해 준다. 그리고 master 에서 했던 것과 같이 slave-read-only 설정을 no 로 변경해준다.
실행 : ./src/redis-server ./redis.conf

Sentinel 설치
sentinel을 위한 설정파일은 sentinel.conf 로 별도로 있다.

1. sentinel monitor <master-name> <ip> <redis-port> <quorum> 에 master node의 정보를 적어준다. 기본은 mymaster 로 되어 있다.

master-name : 이름을 지정해 줄 수 있는데 나중에 클라이언트에서 master 의 정보를 sentinel 을 통해서 가져올 때 사용할 수 있다.

quorum : sentinel 들이 투표를 통해서 master 의 교체가 필요하다고 판단하는데 사용되는 투표수를 지정하는 것이다. 보통은 sentinel 수 - 1 을 설정하지만 여기서는 sentinel 이 하나이므로 1로 설정한다. (혼자 판단한다!)

2. protected-mode 설정을 no 로 해준다. 내부망에서만 사용하는 것이고 클라이언트(redis 를 사용하는 application)에서 master 의 정보를 가져올 때 쉽게 가져올 수 있다.

3. sentinel down-after-milliseconds mymaster 60000 master 가 죽었다고 판단하는데 사용하는 시간으로 지금 설정은 1분동안 응답이 없으면 죽었다고 판단한다. mymaster 는 위에 <master-name> 에 적은 이름이다.

클라이언트에서 master 정보 가져오기

Jedis jedis = new Jedis("127.0.0.1", 26379) // setinel 정보
System.out.println(jedis.sentinelGetMasterAddrByName("mymaster"));
결과 : ["127.0.0.1", 6379] //배열이 반환되며 0:ip, 1:port 정보이다.

FailOver 가 가능한 jedis pool 만들기

Jedis 는 JedisPool 이라는 커넥션 풀을 이미 제공해 주고 있다. 이를 사용하여 master, slave 모두 관리 할 수 있도록 한다.

Map<Address, JedisPool> pools = new LinkedHashMap<>();
Address masterAddress;

그리고 항상 master를 사용한다.

Jedis jedis = pools.get(masterAddress).getResource();

만약 장애 발생시 slave 에서 가져온다.

그리고 별도의 HealthChecker 가 주기적으로 master 의 주소를 sentinel 에게서 가져와 masterAddress 의 정보를 변경해 준다.

'IT > 개발' 카테고리의 다른 글

객체지향 이란  (0) 2018.06.10
레거시에 Solr 적용하기  (0) 2018.05.22
Github 에 개인 maven repository 생성하기  (0) 2018.02.14
Garbage Collection  (0) 2017.02.04
Object class  (0) 2017.02.01
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
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
글 보관함