시냅스

Spring WebFlux 에서 ProxySQL 을 사용할 때 문제점 본문

Java, Spring

Spring WebFlux 에서 ProxySQL 을 사용할 때 문제점

ted k 2024. 2. 7. 22:41

ProxySQL

ProxySQL 은 MySQL의 proxy middleware 입니다.

로드 밸런싱과 쿼리 라우팅, Read-Write split, 캐싱 등의 기능을 제공하며 고성능, 고가용성을 위해 사용됩니다.

 

서비스에서 HA를 위해 사용하던 기존 Galera Cluster + HAproxy 에서 MHA + ProxySQL 로 Migration 을 진행 중이었습니다.

이때 WAS 는 Spring WebFlux 를 사용하고 있는데요.

이 글에서는 왜 WebFlux 와 함께 ProxySQL 을 사용하지 못했는지에 대해 설명하겠습니다.

 

 

문제 상황

WebFlux 에서는 connection validation failed 에러가 발생했고, ProxySQL 은 아래와 같은 에러가 지속해서 발생하였습니다.

MySQL_Session.cpp:149:kill_query_thread(): [WARNING] KILL CONNECTION 76231 on server-2.example.net:3306
MySQL_Session.cpp:3364:handler___status_NONE_or_default(): [ERROR] Unexpected packet from client 10.222.10.5 . Session_status: 6 , client_status: 10682367 Disconnecting it

 

mysql 의 general log 에서도 connection 이 kill 되는 쿼리가 실행되고 있었습니다.

다만 kill 되는 쿼리 이전의 쿼리들의 문법에는 이상이 없었으므로 의아하였습니다.

그리고 아래와 같은 글을 발견하였습니다.

 

https://github.com/sysown/proxysql/issues/3880

 

Client disconnect with no apparent reason during transaction, kill_query_thread(), COMMIT never issued · Issue #3880 · sysown/

Hi Team, Description: Application is apache Druid, we are trying to remove mysql-router component (used only on RW port) and start using ProxySQL. Publishing segments on the metadata storage (maria...

github.com

 

주된 내용은 아직 ProxySQL에서 batch statement 를 지원하지 않는다는 것이었습니다.

그러므로 client 에서 insert 쿼리를 보내고 서버로부터 ok 응답 이전에 추가적인 쿼리를 전송하는 것이 문제라는 것이었습니다.

MySQL 프로토콜은 위와 같은 방식을 허용하지만 proxySQL 은 OK sign 이후에 실행할 수 있다는 것입니다.

실제로 서비스에서도 관련된 포트에 tcpdump를 수행했고, 비슷한 현상을 발견하였습니다.

 

R2DBC

 

WebFlux 에서는 RDB Driver로 R2DBC를 사용합니다.

RDB에 Non-Blocking 으로 Reactive Programming Model 에 기반한 데이터베이스 접근 방식을 제공합니다.

따라서 쿼리를 독립적인 작업(Data Stream)으로 간주하며 각 작업이 완료될 때까지 기다리지 않고 다음 작업을 실행합니다.

이때 문제가 발생합니다.

 

위에서 살펴보았듯 ProxySQL 은 batch statement 를 사용하지 못하므로 한 세션에는 insert 이후 순차적인 쿼리 실행이 필요합니다.

따라서 리액티브하게 쿼리를 실행할 때에는, 특히 Mono.zip 과 같이 insert 와 함께 쿼리를 동시에 실행할 때에는 문제가 됩니다.

MySQL 서버의 OK 사인이 떨어지기 전에 또 다른 쿼리가 실행되었기 때문입니다.

 

따라서 아쉽지만 ProxySQL 이 batch statement 를 지원하기 전에는 적합하지 않다고 판단하였습니다.

여전히 서비스에서는 MHA 를 사용하고 있으므로 failover 자체는 VIP 를 사용한 방법(KeepAlived)으로 수행하고,

Read / Write split 은 애플리케이션 내에서 처리할 예정입니다.

ProxySQL 관련된 업데이트가 있다면 다시 작성할 수 있도록 하겠습니다.

 

 

끝!

 

 

참고

https://r2dbc.io/

 

R2DBC

R2DBC 0.8.1.RELEASE: A standard API for reactive programming using SQL databases.

r2dbc.io

 

Comments