Name
Last commit
Last update
..
images 2021-03-05, update2
README.md LVS, PHP DBMS read/write Function 추가

logo

LVS(Linux Virtual Server)를 이용한 DBMS 분산처리

LVS는 Debian 계열(Debian 9 이상/Ubuntu 14 이상) OS에서 검증되었으므로, redhat 계열에서는 해당되지 않는다.

Core Package Lists

  • ipvsadm
  • ldirectord

구성 Package 설치

# apt install ipvsadm ldirectord

Confiure Pre-Requirement

설정 구성 전 다음과 같이 OS에서 사전준비가 필요하다.

# apt install mariadb-client

mariadb-client 패키지는 분산 구성원의 DBMS Alive 상태를 체크하는데 사용된다.

또한 Packet이 LVS를 경유해야하기 때문에 ip_forward Kernel Parameter를 활성화해야 한다.

# cat /etc/sysctl.conf |grep ip_forward
#net.ipv4.ip_forward=1

# sysctl -p

Configure /etc/ha.d/ldirctord.cf

# cat /etc/ha.d/ldirectord.cf
# Global Directives
checktimeout=10
checkinterval=5
#fallback=127.0.0.1:3306
autoreload=yes
logfile="/var/log/ldirectord.log"
#logfile="local0"
quiescent=no

virtual = 180.180.180.143:3306
        real = 180.180.180.211:3306 gate
        real = 180.180.180.216:3306 gate
        checktype = negotiate,connect
        protocol = tcp
        service = mysql
        login = "dbmsmonitor"
        passwd = "패스워드"
        database = "mysql"
        request = "SHOW ENGINE innodb STATUS";
        scheduler = lc
  • Virtual : 서비스될 IP를 지정한다. 참고적으로 반드시 VIP일 필요는 없다.
  • fallback : 하위 웹 서버에 모두 장애가 발생할 경우에 응답할 주소다. 여기서는 80으로 명시했지만, LVS 자체에 웹 서버를 구성해서 응답하도록 포트를 변경할 수도 있다.
  • real : 하위 웹 서버의 IP를 지정한다.
  • service : 분산/체크할 서비스를 명시한다. http, mysql 등의 TCP 기반 서비스가 가능하다.
  • request : 헬스체크 시 하위 웹서버에 요청할 주소 또는 파일 이다.
  • receive : request에서 요청 시 응답받을 값을 지정한다.
  • scheduler : 분산 알고리즘을 지정한다. 라운드로빈(rr), 가중치 라운드로빈(wrr), 최소 커넥션(lc), 가중치 최소커넥션(wlc), 로컬리티베이스 최소커넥션(lblc), 로컬리티베이스 리플리케이션 최소커넥션(lblcr), 수신해시(dh), 송신해시(sh), 최소지연예측(sed), 큐없음(nq)
  • protocol : tcp/udp 를 사용할 수 있다.
  • checktype : 헬스체크의 방식을 지정한다. negotiate(특정 조건을 통해 서비스가 살아있음을 체크하는 방식), connect(단순하게 포트가 살아있는지를 체크하는 방식)의 두 가지가 존재하며, 권장은 두 가지를 모두 지정하는 것(negotiate, connect) 이다.

Client DSR 설정

LB(Load Balancer)의 경우 다음과 같이 두 가지 동작방식이 존재한다.

  • Reverse Proxy
  • DSR(Direct Server Retrun)

홍쓰넷에서는 DSR 방식을 사용하여, Reponse 한다.

설정은 다음과 같이 iptables를 이용하여, 적용한다.

# iptables -t nat -L -v -n |more
Chain PREROUTING (policy ACCEPT 7080 packets, 566K bytes)
 pkts bytes target     prot opt in     out     source               destination
  143  8580 REDIRECT   tcp  --  *      *       0.0.0.0/0            180.180.180.143      tcp dpt:3306

Chain INPUT (policy ACCEPT 6020 packets, 357K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 8 packets, 608 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 8 packets, 608 bytes)
 pkts bytes target     prot opt in     out     source               destination

LVS Status Review

# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  180.180.180.143:3306 wrr
  -> 180.180.180.237:3306         Route   1000   0          45

내부 MariaDB의 Health Check를 수행하는지 ELK를 통해 검증해 본다.

source_overview

PHP DBMS Connection Function

<?php

//readonly 연결 함수 선언
function read_db(){
        $host = "180.180.180.143";
        $user = "유저아이디";
        $pass = "패스워드";
        $database = "디비명";

        $connect = mysqli_connect($host, $user, $pass, $database);
        if (!$connect) {
          $error = mysqli_connect_error();
          $errno = mysqli_connect_errno();
          exit;
        }else{
          mysqli_select_db($connect, $database);
        }

        return $connect;
}

//read/write 연결 함수 선언
function write_db(){
        $host = "180.180.180.250";
        $user = "유저아이디";
        $pass = "패스워드";
        $database = "디비명";

        $connect = mysqli_connect($host, $user, $pass, $database);
        if (!$connect) {
          $error = mysqli_connect_error();
          $errno = mysqli_connect_errno();
          exit;
        }else{
          mysqli_select_db($connect, $database);
        }

        return $connect;
}

?>

PHP Call Pages Usage Example

  • Read Only
<?php
  $query = "SELECT ~";
  $result = mysqli_query(read_db(), $query);
?>
  • Read/Write
<?php
  $query = "INSERT/UPDATE/DELETE ~";
  $result = mysqli_query(write_db(), $query);
?>