[additional] Active StandBy 전환 간 Dangling Connection 수명주기 확인하기
Closed this issue · 4 comments
연관 챕터
조사 내용
Active StandBy 전환 간 Dangling Connection 이슈 재현하기 위한 TF
- Amazon RDS Active - StandBy 구성
- SpringBoot + JPA 이용하여 Dangling Connection 수명주기 관찰해 보기
- Breakpoint를 걸던
- 관련 텔레메트리를 정의하던
@caffeine-library/readers-release-everything
해당 TF에서 필요한 작업 내역입니다.
어플리케이션
스프링 어플리케이션
- JDBC 연결 100개 가량 물고 대기
- DB 전환 수행
- COMMIT 명령 날려보기
- 오류 관측: 간단하게 로그 파일 까는 걸로 생각중
😞 아니 그냥 단순히 MySQL Client로 검증해 보는 걸로 해 보겠습니다.
인프라
RDS MySQL Multi-AZ 구성
-
퍼블릭 서브넷에 놓아 저희 로컬에서 접근합니다.
-
페일오버 DB 전환은 통상 60-120초 뒤 완료된다고 알려져 있습니다.
-
전환 완료된 후 기존 연결로 요청을 시도, 오류를 확인합시다.
참고하기
댕글댕글 커넥션에 대한 우려를 AWS 공식문서 역시 얘기해 주고 있군요 👍🏻
DB와 클라 간 세션이 원활히 종결되지 않았을 수 있기에,
수동 페일오버(리부팅) 전에 트랜잭션을 멈추기 바란다.
클라우드 비용 신경쓰지 마시고 구체적인 구현 방안 의견이나
공수 나누실 분 있다면(?) 적극 협력해주시면 더욱 좋습니다.
PoC결과 공유
- 일시: 24/01/24 11:48 ~ 11:52
- 클라이언트: MySQL Workbench
- 데이터베이스: Amazon RDS for MySQL Multi-AZ
사전 세팅
dangle.USER
테이블에 열 하나 (Jaebin Joo)만 준비
DR 전환 테스트
USE dangle;
SET AUTOCOMMIT=0;
INSERT INTO USER(name) VALUES ('Jaebin Joo 2');
-- DR 전환 완료후
COMMIT;
SELECT * FROM USER;
- (Jaebin Joo 2) 열을 새로 추가하되 커밋은 넣지 않았습니다.
- AWS 콘솔에서 RDS DR을 수행하고 헬스가 뜰 때까지 약 2분 대기했습니다.
- 이제 커밋을 시도했습니다. 워크벤치 상에서 로딩 아이콘이 생긴 후 어떠한 응답 반응이 없었습니다!
- 한 번 더 커밋을 시도했으며, 조회 쿼리도 한 차례 넣었습니다. 여전히 응답 반응이 없었습니다.
- 그러나 잠시 후 뒤 요청이 처리되었다는 로그가 뜨고, 응답이 들어왔습니다.
- 조회로 긁은 결과에는 (Jaebin Joo 2)가 없네요.
결국 빨간 박스 내 3개 쿼리는 DR DB와 맺어진 뒤늦은 연결로 수행된 것입니다!
이상으로 짧은 PoC 결과 보고드렸습니다.
Dive deep 1
DR 전환 후 보낸 쿼리는 수십초가 지나 결국엔 들어갔습니다..?
✔️ 워크벤치에 연결 재시도 로직이 있다고 유추하게 되었습니다. 이 로직을 증명할 수 있을까요?
✔️ 여러분들은 첫 시도에서 Abort 하는 걸 바라시나요? 아니면 재시도 하기를 바라시나요?
- 정확히 30초(read connection timeout)가 지나서 쿼리를 성공했다면요. 연결 타임아웃 이벤트가 발생했다는 확증이 섭니다.
- 또, 정상 응답 로그가 찍혔으니 DR DB와 연결되었다고도 확증 가능합니다.
MySQL은 쿼리 중 서버가 날라간 현상을 별도 문서로 남겨두어 이런 가이드를 남겼습니다.
You can also get these errors if you send a query to the server that is incorrect or too large. If mysqld receives a packet that is too large or out of order, it assumes that something has gone wrong with the client and closes the connection.
서버에게 부정확하거나, 너무 큰 쿼리를 보내면 해당 오류를 만날 수 있다. mysql가 크거나 처리할 수 없는 쿼리를 받으면, 클라이언트에 이상이 생긴 걸로 알고 연결을 닫는다.
그러니까 DR DB는 기존 연결이 보낸 COMMIT 명령을 이상하게 여겨 쳐냈을 겁니다.
그러므로 워크벤치가 연결 재수립 로직을 구현하고 있는지 알아보기 위해서
✔️ read_conn_timeout에 의한 연결 재시도 확인
✔️ conn timeout에 의한 연결 재시도 확인
첫 번째 사항은 아까전 PoC에서 이미 증명됐구요.
다음 PoC에서는 아래 내용을 진행합니다.
- conn keep-alive 20초 / conn timeout 0초 / read conn timeout 30초로 구성하기
- 30초(read conn timeout) 보다 빨리 쿼리 성공 로그가 발생하는지 봅니다.
keep-alive 도중 연결 실패를 확인한 워크벤치가 연결을 재수립 했다는 증거입니다.
Dive deep 2
RDS 페일오버 시 IP가 변경 될까요?
- RDS 연결은 DNS 네임으로 참조합니다.
- DNS 주소 해결 시 반환되는 IP 주소가 바뀌는 거면, 사실 저희는 책이 소개한 가상 고정 IP DR과는 다른 상황에서 PoC를 진행한 것입니다.
✔️ 우리의 상황이 책과 동일한 것인지도 확인해 보아요.
Nect action item
- conn keep-alive를 20초, conn timeout을 0초, read conn timeout을 30초 구성하고 DR DB에게 30초 보다 작은 시간 내로 쿼리가 도달하는지 확인합니다. (Workbench 연결 재시도 로직 존재 여부를 이중 검증)
- DR 전환 후 바라보는 IP가 변하는지 nslookup으로 확인합니다. (책과 동일 상황인지를 검증)
Dove Deep PoC 결과 공유
- 일시: 24/01/14 20:00 ~ 20:06
- 클라이언트: MySQL Workbench
- 데이터베이스: Amazon RDS for MySQL Multi-AZ
✔️ conn timeout에 의한 연결 재시도 확인
1. conn keep-alive를 20초
2. conn timeout을 0초
3. read conn timeout을 30초 구성
4. COMMIT 라인 실행 시 DR DB에게 30초 보다 작은 시간 내로 쿼리가 도달하는 지 확인
이 가정은 참이었습니다.
Workbench는 timeout 이벤트가 발생하면 연결 수립을 재시도 합니다.
✔️ 우리의 상황의 책과 동일한 것인지도 확인
1. DR 전환 후 바라보는 IP가 변하는지 nslookup으로 확인합니다.
네 IP가 변화합니다. 그러므로
RDS DR 직후 연결 이슈가 있으면, DNS 해결 이슈 + 댕글링 연결 이슈를 모두 고려해 보아야 합니다.
(끝.)