simDev1234
심플하고 차분하게
simDev1234
전체 방문자
오늘
어제
  • 분류 전체보기
    • Computer Science
      • Basic Math
      • Data Structure
      • Algorithm
      • Database
      • OS
    • Language
      • Java
      • Kotlin
      • SQL
    • Framework
      • Spring
      • Orm&Mapper
      • 프로젝트로 스프링 이해하기
      • 스프링 라이브러리
    • Infra
      • Cloud
      • Docker
      • Redis
      • AWS, Azure
      • Device
    • Etc
      • CleanCoding
    • Git,Github

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 컨트롤러
  • 자바메모리구조
  • 자바프로그램
  • 404
  • null
  • 참조타입
  • 스프링
  • JVM메모리구조
  • 참조변수
  • controllerTest
  • 자바
  • scanner #next() #nextLine()
  • 자바프로그래밍

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
simDev1234
Infra/Docker

[Docker] Proxy Layer 구성하기

[Docker] Proxy Layer 구성하기
Infra/Docker

[Docker] Proxy Layer 구성하기

2024. 1. 8. 23:37

 

1. Proxy Layer란 

- Proxy Layer : 대리층

- ProxySQL : C++로 짜여진 오픈 소스 Proxy 프로그램으로 총 4개의 database schema를 가지며, Proxy를 컨트롤하고 모니터링할 수 있게 한다.
- Proxy Layer를 두는 이유 : 

앞서서 Orchestra 설정을 해두면 Master(db001)이 샷다운 되더라도 Slave(db002)이 자동으로 Master로 승격되어 고가용성, 곧 시스템이 지속될 수 있도록 할 수 있었다. 하지만, Application 입장에서는, Application의 자체 설정에 따라 기존의 Master(db001)을 계속해서 바라볼 수 있다. 이를 해결하기 위해 중간층인 Proxy Layer를 둘 수 있는데, MySql은 Proxy 프로그램으로 ProxySQL을 사용할 수 있다.

Ex. Spring Boot application-yml에서 Master를 db001로 설정해둔 경우 
--> db001이 샷다운 되고 db002이 자동으로 Master가 되어도
--> Spring Boot는 여전히 db001를 Master로 인식하고 있다.

출처:https://dkswnkk.tistory.com/729

 

2. Docker로 Proxy SQL 생성하기

[1] proxy 디렉토리 생성 및 권한 부여

- ProxySQL 컨테이너도 MySQL 컨테이너와 마찬가지로 호스트 볼륨에 컨테이너 파일이 마운트될 수 있게 해줘야한다.

- 따라서, data 정보가 담길 data 디렉토리와 설정 정보가 담길 conf 티렉토리를 호스트에 생성해준다.

mkdir -p db/proxysql/data db/proxysql/conf
chmod 777 db/proxysql/data db/proxysql/conf
cd db/proxysql/conf

 

[2] proxysql.cnf 생성 후 권한을 644로 부여

- conf 디렉토리에서 proxysql 설정 파일을 만들어준다.

- mysql의 경우 my.cnf로 설정을 작성한다면, proxysql은 proxysql.cnf로 설정을 작성한다.

vi proxysql.cnf
chmod 644 proxysql.cnf

 

datadir="/var/lib/proxysql"
admin_variables=
{
    admin_credentials="admin:admin;radmin:radmin"
    mysql_ifaces="0.0.0.0:6032"
}
mysql_variables=
{
    threads=4
    max_connections=2048
    default_query_delay=0
    default_query_timeout=36000000
    have_compress=true
    poll_timeout=2000
    interfaces="0.0.0.0:6033"
    default_schema="information_schema"
    stacksize=1048576
    server_version="5.5.30"
    connect_timeout_server=3000
    monitor_username="monitor"
    monitor_password="monitor"
    monitor_history=600000
    monitor_connect_interval=60000
    monitor_ping_interval=10000
    monitor_read_only_interval=1500
    monitor_read_only_timeout=500
    ping_interval_server_msec=120000
    ping_timeout_server=500
    commands_stats=true
    sessions_sort=true
    connect_retries_on_failure=10
}

 

[3] docker로 ProxySql 생성

- proxysql 이름을 가지며 호스트명은 proxysql이고, proxysql을 네트워크 alias로 하여 브릿지를 연결한다.

- 호스트 16032 port에서 컨테이너의 6033 port로 연결되며, 

- [1]에서 생성한 호스트의 data, conf로 proxysql의 data파일들과 conf 파일을 영속적으로 연결해준다.

docker run -it --name proxysql -h proxysql \
--net mybridge --net-alias=proxysql \
-p 16032:6032 -p 16033:6033 \
-v /home/opc/db/proxysql/data:/var/lib/proxysql \
-v /home/opc/db/proxysql/conf/proxysql.cnf:/etc/proxysql.cnf \
-d proxysql/proxysql

- Docker 생성 확인 

docker ps --format "table {{.ID}}\t{{.Names}}\{{.Status}}"


[4] ProxySQL 접속(호스트에서 접속하는 것으로, 이 경우 호스트에 mysql 있어야함)

- 여기서 살짝 헤맸는데, 호스트에서 ProxySQL에 직접적으로 접속하기 위해서는 먼저 호스트 OS안에 mysql이 별도로 설치가 되어 있어야 한다. (나는 없었어서 아래 명령어가 에러가 남..)

- MySQL을 설치하고, 아래 명령어를 입력하면 ProxySQL에 접속이 가능하다.

mysql -h127.0.0.1 -P16032 -uradmin -pradmin --prompt "ProxySQL Admin>"

 

3. Proxy Layer 테스트해보기

[1] 먼저 Master 컨테이너 db001에서 테스트 데이버테이스와, 어플리케이션용 user, proxysql용 모니터링 user를 생성한다.

docker exec -it -uroot db001 /bin/bash
mysql -uroot -p

mysql > create user 'appuser'@'%' identified by 'apppass';
mysql > create database testdb default character set utf8;
mysql > grant select, insert, update, delete on testdb.* to 'appuser'@'%'

mysql > create user 'monitor'@'%' identified by 'monitor';
mysql > grant REPLICATION CLIENT on *.* to 'monitor'@'%';

mysql > flush privileges;

 

[2] proxy에서 hostgroup에 db 서버 정보 입력

- proxysql에서 현재 상태와 맞게 쓰기그룹, 읽기 그룹을 형성하고,
 쓰기그룹/읽기그룹을 나누는 기준을 global의 " read_only "로 잡아둔다. (Slave는 global=read_only임)

mysql -h127.0.0.1 -P16032 -uradmin -pradmin --prompt "ProxySQL Admin>"
# 쓰기 그룹(10)
INSERT INTO mysql_servers(hostgroup_id, hostname, port)
VALUES(10, 'db001', 3306);
# 읽기 그룹(20)
INSERT INTO mysql_servers(hostgroup_id, hostname, port)
VALUES(20, 'db001', 3306);
INSERT INTO mysql_servers(hostgroup_id, hostname, port)
VALUES(20, 'db002', 3306);
INSERT INTO mysql_servers(hostgroup_id, hostname, port)
VALUES(20, 'db003', 3306);
# 호스트 그룹 설정
# VALUES(쓰기,읽기,쓰기/읽기 구분 기준, '')
INSERT INTO mysql_replication_hostgroups 
VALUES(10, 20, 'read_only', '');
# 로드
LOAD MYSQL SERVERS TO RUNTIME;
# 설정 영구적인 저장
SAVE MYSQL SERVERS TO DISK;


[3] proxy에서 어플리케이션 user 정보 입력

- Application에서 user:appuser, password:apppass로 ProxySQL에 접속을 요청하면, 

- ProxySQL은 아래에서 설정한 default_hostgroup=10번그룹과 연결을 시도한다.

- 10번은 쓰기그룹이며 Master를 의미하는데, 이는 시스템 상황에 따라 db001 또는 db002로 변경될 수 있다.
  (이때, 구분 기준은 앞서 말했듯 read_only=응/아니 를 기준으로 한다.)

INSERT INTO mysql_users(username, password, default_hostgroup, transaction_persistent)
VALUES('appuser', 'apppass', 10, 0);

LOAD MYSQL USERS TO RUNTIME;

SAVE MYSQL USERS TO DISK;


[4] proxy에서 쿼리 룰 정보 입력 

- 각 호스트 그룹별로 쿼리룰을 설정해준다.

- 기본적으로 모든 쿼리는 [3]에서 설정한 default_hostgroup 인 10번으로 가도록 되어 있는데, 

  아래와 같이 쿼리룰을 설정하면 Select/Update시에 10번으로, Select시에 20번으로 가게된다.

- **쿼리룰 순서가 중요. 반드시 순서대로 해주어야 한다.

INSERT INTO mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup)
VALUES(1, 1, '^SELECT.*FOR UPDATE$', 10);

INSERT INTO mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup)
VALUES(2, 1, '^SELECT', 20);

LOAD MYSQL QUERY RULES TO RUNTIME;

SAVE MYSQL QUERY RULES TO DISK;


[5] 호스트 os 에서 연결  테스트 쉘스크립트 실행

vi app_test_conn.sh
sh app_test_conn.sh

- app_test_conn.sh : hostip주소는 hostname -i로 확인할 수 있는 공인 ip주소를 작성해줘야한다.

# !/bin/bash
while true;
do

  mysql -uappuser -papppass -h{hostip 주소} -P16033 -N -e "select@@hostname,now()" 2>&1| grep -v "Warning"

  sleep 1

done

 

[5] 호스트 os 에서 insert 테스트 쉘스크립트 실행

vi app_test_insert.sh
sh app_test_insert.sh
#!/bin/bash

while true;
do
    mysql -uappuser -papppass -h{{공인ip}} -P16033 -N -e "INSERT INTO testdb.insert_test VALUES ('$(hostname)', NOW())" 2>&1 | grep -v "Warning"
    sleep 1
done

 

[6] 장애 테스트 만들기

세 개의 shell를 연 상태에서 아래와 같이 작업을 수행한다.

(1) sh app_test_insert.sh 로 insert를 지속적으로 실행한다.

(2) slave인 db002에서 읽기를 계속해서 해준다.

(3) docker stop db001로 master db를 stop 시킨다.

그리고 결과를 확인하면, db001에서 insert를 하다가, db002에서 insert를 하는 걸 볼 수 있다.

 

[출처] 인프런 - 따라하며 배우는 MySQL on Docker

[참고]

https://notemusic.tistory.com/55

https://dkswnkk.tistory.com/729

'Infra > Docker' 카테고리의 다른 글

[Docker] Prometheus와 Grafana를 통해 실시간 로그 확인  (1) 2024.01.09
[Docker] Orchestra를 통해 High Availability(HA) 구축하기  (1) 2024.01.08
[Docker] 브리지를 통해 컨테이너 통신  (1) 2024.01.08
[Docker] Master-Slave Replication 구성  (0) 2023.12.31
[Docker] 호스트OS에 log, config 연결 (+my.cnf)  (1) 2023.12.29
    'Infra/Docker' 카테고리의 다른 글
    • [Docker] Prometheus와 Grafana를 통해 실시간 로그 확인
    • [Docker] Orchestra를 통해 High Availability(HA) 구축하기
    • [Docker] 브리지를 통해 컨테이너 통신
    • [Docker] Master-Slave Replication 구성
    simDev1234
    simDev1234
    TIL용 블로그. * 저작권 이슈가 있는 부분이 있다면 댓글 부탁드립니다.

    티스토리툴바

    단축키

    내 블로그

    내 블로그 - 관리자 홈 전환
    Q
    Q
    새 글 쓰기
    W
    W

    블로그 게시글

    글 수정 (권한 있는 경우)
    E
    E
    댓글 영역으로 이동
    C
    C

    모든 영역

    이 페이지의 URL 복사
    S
    S
    맨 위로 이동
    T
    T
    티스토리 홈 이동
    H
    H
    단축키 안내
    Shift + /
    ⇧ + /

    * 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.