๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
BackEnd๐ŸŒฑ/DB & SQL

[Docker MySQL] Proxy Layer ๊ตฌ์ถ•ํ•˜๊ธฐ

by ์•ˆ์ฃผํ˜• 2023. 11. 12.

๊ฐœ์š”

์ด์ „ ๊ฒŒ์‹œ๊ธ€ [Docker MySQL] Orchestrator๋ฅผ ์ด์šฉํ•œ High Availability(HA) ๊ตฌ์ถ•ํ•˜๊ธฐ์—์„œ ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์— ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„๋ฅผ ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„๋กœ ์Šน๊ฒฉ์‹œํ‚ค๋Š” ๊ณผ์ •์„ ์ž๋™ํ™”ํ•˜๋Š” Orchestrator๋ฅผ ํ™œ์šฉํ•œ ๊ณ ๊ฐ€์šฉ์„ฑ(High Availability, HA) ๊ตฌ์„ฑ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์˜ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ž๋™์œผ๋กœ ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์— ๋™๊ธฐํ™”๋˜๊ฒŒ ๋˜๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์˜ ๋ถ€ํ•˜๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๋ถ„์‚ฐ์‹œํ‚ฌ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ, HA ๊ตฌ์„ฑ๋งŒ์œผ๋กœ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ DB ์„œ๋ฒ„ ์‚ฌ์ด์˜ ๋™๊ธฐํ™” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ค์ • ์ •๋ณด์—๋Š” ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ•œ db001์ด ๋งˆ์Šคํ„ฐ DB๋กœ ์„ค์ •๋˜์–ด ์žˆ๋‹ค๋ฉด, db001์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒจ db002๊ฐ€ ์ƒˆ๋กœ์šด ๋งˆ์Šคํ„ฐ๊ฐ€ ๋˜์—ˆ์„ ๋•Œ์—๋„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๊ณ„์† db001์„ ๋ฐ”๋ผ๋ณด๋„๋ก ์„ค์ •๋˜์–ด ์žˆ๊ณ , db001์— ์ ‘์†ํ•˜๋ ค๊ณ  ๊ณ„์† ์‹œ๋„ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ ๊ฒŒ์‹œ๊ธ€์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ DB ์„œ๋ฒ„ ์‚ฌ์ด์— ํ”„๋ก์‹œ ์—ญํ• ์„ ํ•ด์ฃผ๋Š” ๋ ˆ์ด์–ด๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ค์ • ๋ณ€๊ฒฝ์ด๋‚˜ ์žฌ์‹œ์ž‘ ์—†์ด ์ž๋™์œผ๋กœ ๋ณ€๊ฒฝ๋œ ๋งˆ์Šคํ„ฐ DB๋กœ ์—ฐ๊ฒฐํ•˜๊ณ , READ์™€ WRITE ์š”์ฒญ์— ๋”ฐ๋ผ ๋ถ„์‚ฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

Proxy Layrer ๊ตฌ์„ฑ

๋””๋ ‰ํ† ๋ฆฌ ๋ฐ ํŒŒ์ผ ์„ค์ •

๋จผ์ € proxySQL์„ ๊ตฌ์„ฑํ•  ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. 

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

๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ ํ™•์ธ

์ง€๊ธˆ๊นŒ์ง€ ์ด์ „ ๋‚ด์šฉ๋“ค ๊ทธ๋Œ€๋กœ ์ž˜ ๋”ฐ๋ผ์™”๋‹ค๋ฉด, ์œ„์™€ ๊ฐ™์ด ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ๊ตฌ์„ฑ๋˜์—ˆ์„ ๊ฒ๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ, /db/proxysql/conf ๋””๋ ‰ํ† ๋ฆฌ์— cnf ํ˜•์‹์˜ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ , ์„ค์ • ๋‚ด์šฉ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, /db/proxysql/conf/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
}

์—ฌ๊ธฐ์„œ ProxySQL์˜ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ, ๊ด€๋ฆฌ์ž ๊ณ„์ • ์ •๋ณด, MySQL ์ธํ„ฐํŽ˜์ด์Šค ๋ฐ ํฌํŠธ ์„ค์ • ๋“ฑ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์•„๋ž˜์˜ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด proxysql.cnf์˜ ๊ถŒํ•œ์„ 644๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

chmod 644 proxysql.cnf

๊ฐ ์„ค์ • ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์‚ดํŽด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • datadir="/var/lib/proxysql": ProxySQL์˜ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •
  • admin_variables: ๊ด€๋ฆฌ์ž ๊ณ„์ •์— ๋Œ€ํ•œ ์„ค์ •์„ ์ง€์ •ํ•˜๋Š” ์„น์…˜
  • admin_credentials="admin:admin;radmin:radmin": ๊ด€๋ฆฌ์ž ๊ณ„์ •์˜ ์‚ฌ์šฉ์ž ์ด๋ฆ„๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์„ค์ •. ์—ฌ๊ธฐ์„œ๋Š” "admin" ์‚ฌ์šฉ์ž์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ "admin"์œผ๋กœ ์„ค์ •ํ•˜๊ณ , "radmin" ์‚ฌ์šฉ์ž์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ "radmin"์œผ๋กœ ์„ค์ •ํ•จ
  • mysql_ifaces="0.0.0.0:6032": ProxySQL ๊ด€๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค์˜ IP ์ฃผ์†Œ์™€ ํฌํŠธ๋ฅผ ์„ค์ •. ์—ฌ๊ธฐ์„œ๋Š” ๋ชจ๋“  IP ์ฃผ์†Œ์—์„œ 6032 ํฌํŠธ๋กœ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•จ
  • mysql_variables: MySQL ์„œ๋ฒ„์— ๋Œ€ํ•œ ์„ค์ •์„ ์ง€์ •ํ•˜๋Š” ์„น์…˜
  • threads=4: ProxySQL์—์„œ ์‚ฌ์šฉํ•  ์“ฐ๋ ˆ๋“œ ์ˆ˜
  • max_connections=2048: ProxySQL์—์„œ ํ—ˆ์šฉํ•  ์ตœ๋Œ€ ๋™์‹œ ์ ‘์† ์ˆ˜
  • default_query_delay=0: ์ฟผ๋ฆฌ ์‹คํ–‰์— ๋Œ€ํ•œ ๋”œ๋ ˆ์ด๋ฅผ ์„ค์ •.
  • default_query_timeout=36000000: ์ฟผ๋ฆฌ ์‹คํ–‰์— ๋Œ€ํ•œ ํƒ€์ž„์•„์›ƒ ์‹œ๊ฐ„์„ ์„ค์ •(๋ฐ€๋ฆฌ ์ดˆ)
  • have_compress=true: ์••์ถ•์„ ์ง€์›ํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์„ค์ •
  • poll_timeout=2000: ProxySQL์ด ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ํด๋งํ•˜๋Š” ์ฃผ๊ธฐ๋ฅผ ์„ค์ •(๋ฐ€๋ฆฌ ์ดˆ)
  • interfaces="0.0.0.0:6033": ProxySQL์˜ MySQL ์ธํ„ฐํŽ˜์ด์Šค์˜ IP ์ฃผ์†Œ์™€ ํฌํŠธ๋ฅผ ์„ค์ •. ์—ฌ๊ธฐ์„œ๋Š” ๋ชจ๋“  IP ์ฃผ์†Œ์—์„œ 6033 ํฌํŠธ๋กœ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•จ
  • default_schema="information_schema": ๊ธฐ๋ณธ ์Šคํ‚ค๋งˆ๋ฅผ ์„ค์ •
  • stacksize=1048576: ProxySQL์˜ ์Šคํƒ ํฌ๊ธฐ๋ฅผ ์„ค์ •
  • server_version="5.5.30": ProxySQL์ด ์‚ฌ์šฉํ•  MySQL ์„œ๋ฒ„์˜ ๋ฒ„์ „์„ ์„ค์ •
  • connect_timeout_server=3000: MySQL ์„œ๋ฒ„์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ ํƒ€์ž„์•„์›ƒ ์‹œ๊ฐ„์„ ์„ค์ •(๋ฐ€๋ฆฌ ์ดˆ)
  • monitor_username="monitor": Monitor ์œ ์ €์˜ ์‚ฌ์šฉ์ž ์ด๋ฆ„์„ ์„ค์ •
  • monitor_password="monitor": Monitor ์œ ์ €์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์„ค์ •
  • monitor_history=600000: Monitor ์œ ์ €์˜ ์ด๋ ฅ์„ ์ €์žฅํ•˜๋Š” ์‹œ๊ฐ„์„ ์„ค์ •(๋ฐ€๋ฆฌ ์ดˆ)
  • monitor_connect_interval=60000: Monitor ์œ ์ €๊ฐ€ MySQL ์„œ๋ฒ„์™€์˜ ์—ฐ๊ฒฐ์„ ํ™•์ธํ•˜๋Š” ์ฃผ๊ธฐ๋ฅผ ์„ค์ •(๋ฐ€๋ฆฌ ์ดˆ)
  • monitor_ping_interval=10000: Monitor ์œ ์ €๊ฐ€ MySQL ์„œ๋ฒ„์— ํ•‘์„ ๋ณด๋‚ด๋Š” ์ฃผ๊ธฐ๋ฅผ ์„ค์ •(๋ฐ€๋ฆฌ ์ดˆ)
  • monitor_read_only_interval=1500: Monitor ์œ ์ €๊ฐ€ ์ฝ๊ธฐ ์ „์šฉ ๋ชจ๋“œ๋กœ ์ „ํ™˜ํ•˜๋Š” ์ฃผ๊ธฐ๋ฅผ ์„ค์ •(๋ฐ€๋ฆฌ ์ดˆ)
  • monitor_read_only_timeout=500: Monitor ์œ ์ €๊ฐ€ ์ฝ๊ธฐ ์ „์šฉ ๋ชจ๋“œ๋กœ ์ „ํ™˜๋˜๊ธฐ๊นŒ์ง€์˜ ํƒ€์ž„์•„์›ƒ ์‹œ๊ฐ„์„ ์„ค์ •(๋ฐ€๋ฆฌ ์ดˆ)
  • ping_interval_server_msec=120000: MySQL ์„œ๋ฒ„์— ๋Œ€ํ•œ ํ•‘์„ ๋ณด๋‚ด๋Š” ์ฃผ๊ธฐ๋ฅผ ์„ค์ •(๋ฐ€๋ฆฌ ์ดˆ)
  • ping_timeout_server=500: MySQL ์„œ๋ฒ„์— ๋Œ€ํ•œ ํ•‘ ์‘๋‹ต์˜ ํƒ€์ž„์•„์›ƒ ์‹œ๊ฐ„์„ ์„ค์ •(๋ฐ€๋ฆฌ ์ดˆ)
  • commands_stats=true: ์ฟผ๋ฆฌ ์‹คํ–‰์— ๋Œ€ํ•œ ํ†ต๊ณ„ ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™”
  • sessions_sort=true: ์„ธ์…˜์„ ์ •๋ ฌํ•˜์—ฌ ๊ฐ€์žฅ ๋ถ€ํ•˜๊ฐ€ ์ ์€ ์„œ๋ฒ„์— ์šฐ์„ ์ ์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋„๋ก ํ•จ
  • connect_retries_on_failure=10: MySQL ์„œ๋ฒ„์— ์—ฐ๊ฒฐ ์‹œ๋„ ์ค‘ ์‹คํŒจํ•  ๊ฒฝ์šฐ ์žฌ์‹œ๋„ ํšŸ์ˆ˜๋ฅผ ์„ค์ •

์œ„์˜ ์„ค์ •์„ ํ†ตํ•ด ProxySQL์€ MySQL ์„œ๋ฒ„์™€์˜ ์—ฐ๊ฒฐ ๋ฐ ๊ด€๋ฆฌ๋ฅผ ๋‹ด๋‹นํ•˜๋ฉฐ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ ‘์† ์ •๋ณด๋ฅผ ๋™์ ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ๋ณ€๊ฒฝ๋œ ๋งˆ์Šคํ„ฐ DB๋กœ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

 

ProxySQL ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰

ProxySQL ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

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

๊ทธ๋ฆฌ๊ณ  docker ps ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ProxySQL ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰ ์ค‘์ธ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

docker ps ํ™•์ธ

 

 

ProxySQL ๊ด€๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค ์ ‘์† ํ™•์ธ

ProxySQL ๊ด€๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค์— ์ ‘์†ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” MySQL ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ProxySQL์—๋Š” MySQL ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋‚ด์žฅ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ProxySQL ์ปจํ…Œ์ด๋„ˆ์— ์ ‘์†ํ•œ ํ›„์— ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ ‘์†์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์€ ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” -P ์˜ต์…˜์€ ๋Œ€๋ฌธ์ž๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์†Œ๋ฌธ์ž๋กœ ์ž‘์„ฑํ•˜๋ฉด ์ ‘์†์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

docker exec -it proxysql mysql -h 127.0.0.1 -P 6032 -u radmin -pradmin

์œ„ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด proxysql ์ปจํ…Œ์ด๋„ˆ์— ์ ‘์†ํ•˜์—ฌ MySQL ํด๋ผ์ด์–ธํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ณ , 127.0.0.1 ์ฃผ์†Œ์™€ 6032 ํฌํŠธ๋ฅผ ํ†ตํ•ด ProxySQL ๊ด€๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค์— ์ ‘์†ํ•ฉ๋‹ˆ๋‹ค. proxysql.cnf์— ๋ช…์‹œํ–ˆ๋˜ radmin ์‚ฌ์šฉ์ž๋กœ ์ ‘์†ํ•˜๋ฉฐ, ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” radmin์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ProxySQL ๊ด€๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค์— ์ •์ƒ์ ์œผ๋กœ ์ ‘์†ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ๊ตฌ์„ฑ

ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉํ•  ์œ ์ €์™€ ProxySQL์šฉ ๋ชจ๋‹ˆํ„ฐ๋ง ์œ ์ €๋ฅผ ์ƒ์„ฑํ•œ ํ›„, ProxySQL ํ˜ธ์ŠคํŠธ ๊ทธ๋ฃน์— DB ์„œ๋ฒ„ ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•˜์—ฌ ์ฟผ๋ฆฌ๋ฅผ ๋ถ„์‚ฐ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ƒ์„ฑ

docker exec -it -uroot db001 /bin/bash

mysql -uroot -p

CREATE DATABASE testdb DEFAULT CHARACTER SET utf8;

USE testdb;

CREATE TABLE insert_test(
    hostname VARCHAR(5) NOT NULL,
    insert_time DATETIME NOT NULL
);

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉํ•  ์œ ์ € ์ƒ์„ฑ

CREATE USER appuser@'%' IDENTIFIED BY 'apppass';

GRANT SELECT, INSERT, UPDATE, DELETE ON testdb.* TO appuser@'%';

FLUSH PRIVILEGES;

ProxySQL์šฉ ๋ชจ๋‹ˆํ„ฐ๋ง ์œ ์ € ์ƒ์„ฑ

CREATE USER 'monitor'@'%' IDENTIFIED BY 'monitor';

GRANT REPLICATION CLIENT ON *.* TO 'monitor'@'%';

FLUSH PRIVILEGES;

ProxySQL ํ˜ธ์ŠคํŠธ ๊ทธ๋ฃน์— DB ์„œ๋ฒ„ ์ •๋ณด ์ž…๋ ฅ

-- Write ํ˜ธ์ŠคํŠธ ๊ทธ๋ฃน์— db001 ์„œ๋ฒ„ ์ •๋ณด ์ž…๋ ฅ
INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (10, 'db001', 3306);

-- Read ํ˜ธ์ŠคํŠธ ๊ทธ๋ฃน์— db001, db002, db003 ์„œ๋ฒ„ ์ •๋ณด ์ž…๋ ฅ
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);

-- Replication ๊ด€๋ จ ์„ค์ •
INSERT INTO mysql_replication_hostgroups VALUES (10, 20, 'read_only', '');

-- ๋ณ€๊ฒฝ๋œ ์„ค์ •์„ ์ ์šฉ
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;

์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์œ ์ € ์ •๋ณด ์ž…๋ ฅ

-- ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์œ ์ € ์ •๋ณด ์ž…๋ ฅ
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;

์ฟผ๋ฆฌ ๋ฃฐ ์ •๋ณด ์ž…๋ ฅ

-- ์ฟผ๋ฆฌ ๋ฃฐ ์ •๋ณด ์ž…๋ ฅ
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;

์œ„์™€ ๊ฐ™์€ ์ˆœ์„œ๋กœ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ฉด, ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์ด ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ProxySQL์„ ํ†ตํ•ด ์ฟผ๋ฆฌ๊ฐ€ ๋ถ„์‚ฐ๋˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฐ˜๋“œ์‹œ ์œ„์˜ ์ˆœ์„œ๋Œ€๋กœ ์ž‘์—…์„ ์ง„ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ProxySQL์˜ ์„ค์ • ๊ฐ’์ด ์ œ๋Œ€๋กœ ๋“ค์–ด๊ฐ”๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์•„๋ž˜์˜ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด mysql_servers, mysql_users, mysql_query_rules ํ…Œ์ด๋ธ”์—์„œ ๊ฐ’์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

SELECT * FROM mysql_servers;
SELECT * FROM mysql_users;
SELECT rule_id, active, match_pattern, destination_hostgroup, apply FROM mysql_query_rules;

mysql_servers
mysql_users
mysql_query_rules

Connect ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ ์ž‘์„ฑ(app_test_conn.sh)

#!/bin/bash
while true;
do
  mysql -uappuser -papppass -h{docker_host:ip} -P16033 -N -e "SELECT @@hostname, NOW()" 2>&1 | grep -v "Warning"
  sleep 1
done

Insert ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ ์ž‘์„ฑ(app_test_insert.sh)

#!/bin/bash
for i in {1..30};
do
  mysql -uappuser -papppass -h{docker_host:ip} -P16033 -N -e "INSERT INTO testdb.insert_test SELECT @@hostname,now()" 2>&1| grep -v "Warning"
  sleep 1
done

์œ„ ์Šคํฌ๋ฆฝํŠธ๋“ค์€ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค. app_test_conn.sh๋Š” ํ”„๋ก์‹œ ํฌํŠธ(16033)๋ฅผ ํ†ตํ•ด ProxySQL์— ์ ‘์†ํ•˜์—ฌ SELECT ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ , ์ˆ˜ํ–‰ํ•œ ์ปจํ…Œ์ด๋„ˆ์˜ ํ˜ธ์ŠคํŠธ๋„ค์ž„๊ณผ ํ˜„์žฌ ์‹œ๊ฐ„์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. app_test_insert.sh๋Š” ํ”„๋ก์‹œ ํฌํŠธ๋ฅผ ํ†ตํ•ด ProxySQL์— ์ ‘์†ํ•˜์—ฌ 30๋ฒˆ์˜ INSERT ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

{docker_host:ip} ๋ถ€๋ถ„์—๋Š” ๋ณธ์ธ์˜ ๋„์ปค ํ˜ธ์ŠคํŠธ IP๋ฅผ ์ ์–ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

 

ํ…Œ์ŠคํŠธ ํ™•์ธ

app_test_conn.sh ์‹คํ–‰ ๊ฒฐ๊ณผ

sh app_test_conn.sh

์œ„ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ app_test_conn.sh ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด, 3๋Œ€์˜ MySQL ์„œ๋ฒ„์—์„œ ์ž‘์—…์ด ๋ถ„์‚ฐ๋˜์–ด ์ฒ˜๋ฆฌ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ๊ฐ์˜ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ์—๋Š” ํ˜ธ์ŠคํŠธ๋„ค์ž„๊ณผ ํ˜„์žฌ ์‹œ๊ฐ„์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

๋ถ„์‚ฐ๋˜์–ด์„œ ์ฒ˜๋ฆฌ๋˜๋Š” ๊ฒƒ ํ™•์ธ

app_test_insert.sh ์‹คํ–‰ ๊ฒฐ๊ณผ

sh app_test_insert.sh

์œ„ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ app_test_insert.sh ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ณ , db001์— ์ ‘์†ํ•˜์—ฌ ํ…Œ์ด๋ธ”์„ ์กฐํšŒํ•ด ๋ณด๋ฉด ๋ชจ๋“  INSERT ์ฟผ๋ฆฌ๊ฐ€ db001์„ ํ†ตํ•ด์„œ๋งŒ ์ˆ˜ํ–‰๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ProxySQL์ด ์„ค์ •๋œ ๋Œ€๋กœ Write ํ˜ธ์ŠคํŠธ ๊ทธ๋ฃน(db001)์œผ๋กœ ๋ชจ๋“  ์“ฐ๊ธฐ ์ž‘์—…์„ ์ „๋‹ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

db001์„ ํ†ตํ•ด์„œ๋งŒ write๋œ ๊ฒƒ์„ ํ™•์ธ

์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด app_test_conn.sh์—์„œ๋Š” ์ฟผ๋ฆฌ๊ฐ€ 3๋Œ€์˜ MySQL ์„œ๋ฒ„๋กœ ๋ถ„์‚ฐ๋˜์–ด ์ฒ˜๋ฆฌ๋˜๊ณ , app_test_insert.sh์—์„œ๋Š” ๋ชจ๋“  INSERT ์ฟผ๋ฆฌ๊ฐ€ db001์„ ํ†ตํ•ด์„œ๋งŒ ์ˆ˜ํ–‰๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ProxySQL์„ ํ†ตํ•ด ์ฟผ๋ฆฌ๊ฐ€ ์ ์ ˆํ•˜๊ฒŒ ๋ถ„์‚ฐ๋˜๋Š” ํ™˜๊ฒฝ์ด ๊ตฌ์„ฑ๋˜์—ˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

 

 

Fail Over Test

Failover ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์‹œ๋ฎฌ๋ ˆ์ด์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. insert_test ํ…Œ์ด๋ธ” ๋ฐ์ดํ„ฐ ์ดˆ๊ธฐํ™”
  2. app_test_insert.sh ์‹คํ–‰
  3. app_test_insert.sh ์‹คํ–‰ ๋„์ค‘ db001 ์ปจํ…Œ์ด๋„ˆ ์ธ์œ„์ ์œผ๋กœ ์ค‘๋‹จ(Failover ์ƒํ™ฉ ์—ฐ์ถœ)
  4. select ์ฟผ๋ฆฌ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌ๋˜๋Š”์ง€ ํ™•์ธ

ProxySQL Failover แ„แ…ฆแ„‰แ…ณแ„แ…ณ

์œ„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ํ…Œ์ŠคํŠธ๋ฅผ ๋ณด๋ฉด db001์—์„œ๋งŒ INSERT๊ฐ€ ๋˜๋‹ค๊ฐ€ db001์ด ์ค‘๋‹จ๋œ ์ดํ›„์—๋Š” db002๋กœ๋ถ€ํ„ฐ INSERT๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ProxySQL์„ ํ†ตํ•ด Failover๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ๋™์ผํ•œ ์ ‘์† ์ •๋ณด๋ฅผ ์œ ์ง€ํ•˜๊ณ  ๊ณ„์†ํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

Failover ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ProxySQL์ด ์ ์ ˆํžˆ ๋™์ž‘ํ•˜์—ฌ Master ์„œ๋ฒ„๊ฐ€ ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

์ •๋ฆฌ

์—ฌ๊ธฐ๊นŒ์ง€ Proxy Layer ๊ตฌ์ถ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ DB ์„œ๋ฒ„ ์‚ฌ์ด์— ํ”„๋ก์‹œ ์—ญํ• ์„ ํ•ด์ฃผ๋Š” ๋ ˆ์ด์–ด๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ ‘์† ๊ด€๋ฆฌ, ๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ, ์žฅ์•  ๋ณต๊ตฌ ๋“ฑ์„ ๋ณด๋‹ค ํšจ๊ณผ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ProxySQL์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘์†๊ณผ ์ฟผ๋ฆฌ ๋ถ„์‚ฐ์„ ๊ด€๋ฆฌํ•˜๊ณ , Failover ์ƒํ™ฉ์—์„œ๋„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ค‘๋‹จ๋˜์ง€ ์•Š๊ณ  ์ž‘๋™ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

์ด์ „๊ธ€

  1. [Docker MySQL] Master-Slave Replication(๋ณต์ œ) ๊ตฌ์ถ•ํ•˜๊ธฐ
  2. [Docker MySQL] Orchestrator๋ฅผ ์ด์šฉํ•œ High Availability(HA) ๊ตฌ์ถ•ํ•˜๊ธฐ

์ฐธ๊ณ 

https://www.inflearn.com/course/mysql-docker/dashboard

๋Œ“๊ธ€