Beyond SW 과정 중 Database 프로젝트를 진행했었다.

우리 팀은 동영상 스트리밍 프로젝트를 진행하기 때문에 DB 서버의 성능은 조회 성능과 더불어 생성 성능도 많이 요구된 상황이었다.

그렇기에 우리 팀은 하이브리드 DB 아키텍처를 구상하였다.(Cluster + Replication)

Server Architecture

따라서 SQL 성능을 체크함과 동시에 서버 아키텍처가 제대로 작동하는지 확인하기 위해서 Jmeter + Prometheus + Grafana로 성능을 확인했었다.

트러블 발생

아니 근데 Jmeter로 부하를 가한 후 Grafana로 부하 과정을 보는데, 하나의 MariaDB만 부하를 받고, 나머지는 전혀 부하를 안 받는 현상이 발견되었다.

분명히 Clustering을 진행한 후, Haproxy(Round Robin을 적용한)를 적용하여 분산 시스템을 만들었지만 분산이 전혀 안되고 있는 상황이였다.

계속 부하를 다시 줘도 같은 현상이 발생하자, 다시 DB 시스템을 뜯어 보았지만 Clustering에는 전혀 문제가 없었다.

우리 팀의 결론은 부하가 잘 안되고 있다는 것이였다.

DB 시스템도 정상으로 작동하고 있고, Haproxy를 통해 DB Client로 접근해도 분산이 잘 되어 MariaDB Id가 변경되는 것을 눈으로 확인했었다.

부하 시스템의 함정

그렇게 계속 설정들을 찾아가다보니 Jmeter에서 ThreadPool를 설정했던 것이 팀 안에서 이야기가 나왔다.

그 추론은 다음과 같았다.

  1. Jmeter에서 DB서버에 Connection을 만들고 유지한다.
  2. Connection을 유지하기 때문에 Haproxy를 통과하지 않는다.
  3. 따라서 이 경우에는 부하분산이 적용되지 않는다.

그렇기에 우리 팀은 Jmeter 설정에서 Loop Count를 증가시켜 Connection 유지를 피하고, 부하 분산을 시도했었다.

그 결과, 실제로 Grafana에서 CPU 사용율이 3개의 서버에서 다같이 올라오는 그래프가 그려졌고, 우리의 가정이 맞았다는 사실을 알게 되었다.

느낀점 

이렇게 SQL 성능 테스트 및 DB 성능 테스트를 진행하면서 설계대로 진행이 안되는 경우가 꽤 존재하고, 자료를 쉽게 찾을수도 없는 경우도 많이 생긴다는 것을 이번 프로젝트에서 경험했다.

그런 와중에도 개발자로서 우리가 해야하는 일은 이 트러블이 일어날 수 있는 경우의 수를 생각한 후, 테스트를 통해 검증하는 일이라는 것을 알게 되었다.

 

Index(인덱스)란?

Index 자료구조

인덱스란  DB에서 추가적인 쓰기 작업과 저장 공간을 활용하여 조회 기능의 성능을 향상시키는 자료구조를 의미합니다.

기본적으로 PK는 Index설정이 자동으로 진행된다.

인덱스는 기본적으로 목차와 매우 비슷하다.

우리가 책 안에서 특정 내용을 찾고자 하면 목차를 보고 비슷한 내용들이 적혀있는 페이지로 넘어가서 찾아야 빠른 것 처럼 DB도 또한 비슷한 내용끼리 미리 정렬을 해놓은 후, 그 근처 자료구조로 넘어가서 찾게 된다.

Index의 장단점

Index 장점

  • 조회 성능을 올릴 수 있다.
  • 조회 성능이 대부분 DB 사용을 차지하고 있으므로, 전체적인 서버 부담이 내려간다.

Index 단점

  • 조회를 제외한 Insert, Delete 성능이 감소한다.
  • 인덱스를 관리하기 위한 추가 저장 공간이 필요하다.
  • 인덱스를 잘 못 사용하는 경우 오히려 서버 부담이 증가하고, DB 조회 성능이 떨어진다.

Index 생성 방법

CREATE INDEX [Index 이름] ON [Index 추가할 테이블]([컬럼 이름]);
CREATE INDEX member_index_email ON member(email); # 예시

위 코드처럼 새롭게 Index를 생성하면 된다.

Store Procedure(저장 프로시저)란??

Store Procedure의 동작 방식

SQL도 당연히 컴퓨터가 이해하기 위해서는 컴파일 과정을 거쳐야 한다.

당연히 여기서 성능 이슈가 생긴다. (물론 그렇게 큰 성능 이슈를 만드는 것은 아니다.)

조금이라도 성능을 잡기 위해서는 자주 사용하는 SQL문들은 미리 컴파일을 한 내용을 저장하고 있다가 호출되면 사용하는 것이 성능이 좀 더 올라간다.

즉, 저장 프로시저는 SQL문을 컴파일해서 미리 저장하고 있다가 호출될 때마다 꺼내어 쓰는 방식을 의미한다.

저장 프로시저의 장단점

저장 프로시저 장점

  • DB 서버의 성능을 향상시킬 수 있다.
  • 유지보수 및 재활용 측면에서 좋다.
  • 네트워크 부하를 줄일 수 있다.

저장 프로서지 단점

  • DB서버를 확장하는데 어려움이 있다.
  • 데이터 분석하는데 어려움이 있다.

저장 프로시저를 만들기 위해서는 다음 SQL 문처럼 작성하면 된다.

DELIMITER $$
CREATE PROCEDURE SP_SELECT_MEMBER () # Create Procedure [저장 프로시저 이름]
BEGIN						# 이 사이에 Query문을 작성하면 된다.
	SELECT * FROM member;
END $$
CALL SP_SELECT_MEMBER();

저장 프로시저에 변수를 넣고 싶으면 다음 SQL문처럼 작성하면 된다.

DELIMITER $$
CREATE PROCEDURE SP_SELECT_MEMBER_WITH_WHERE (IN memberIdx INT)
BEGIN
	SELECT * FROM member WHERE idx=memberIdx;
END $$
CALL SP_SELECT_MEMBER_WITH_WHERE(10);

저장 프로시저 구현 사진

반 정규화란??

정규화에 대해서는 다음 글을 참조하자.

https://harmony-raccoon.tistory.com/95

정규화를 진행하면 데이터를 조회하기 위해서 사용되는 SQL 문이 복잡해지고, 성능이 떨어지는 경우가 존재한다.

대표적으로 집계함수를 써야하는 상황들이 그렇다. (ex, 좋아요 등이 존재한다.)

그렇기 때문에 아예 집계함수를 처리한 값을 테이블 컬럼 안에 집어넣어야 SQL 조회 성능이 많이 좋아진다.

반대로 생성이나 삭제 성능은 상대적으로 떨어지게 되지만, 실제 데이터들은 생성, 삭제보다 조회가 많이 일어나기 때문에 이러한 등가 교환은 성능을 향상시킨다.

어떠한 개발 공부를 하던간에 이런 트레이드 오프(Trade-Off)를 생각하며 개발하고, 공부해야 한다.

참고 자료

https://mangkyu.tistory.com/96

 

[Database] 인덱스(index)란?

1. 인덱스(Index)란? [ 인덱스(index)란? ] 인덱스란 추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조이다. 만약 우리가 책에서 원하는 내

mangkyu.tistory.com

https://jaehee1007.tistory.com/131

 

인덱스(Index)의 개념 정리 및 실습을 통해 이해하기

인덱스란?인덱스(Index)란 데이터베이스에서 데이터를 더 빠르게 검색할 수 있게 해주는 자료구조이다.인덱스를 이해하는 가장 쉬운 방법은 책을 떠올리는 것이다. 책에는 '목차'라는 것이 존재

jaehee1007.tistory.com

https://eunsun-zizone-zzang.tistory.com/52

 

[DB/데이터베이스] 저장 프로시저(Stored Procedure)

저장 프로시저(Stored Procedure, SP) 일련의 쿼리를 마치 하나의 함수처럼 실행하기 위한 쿼리문들의 집합 ✔ 즉, 특정 로직의 쿼리를 함수로 만들어 놓은 것 저장프로시저와 함수의 차이 저장 프로

eunsun-zizone-zzang.tistory.com

혹시라도 틀린 내용이 있다면 댓글로 알려주시면 감사하겠습니다!!

Query 성능 측정하기

Query 성능을 측정하는 방법 중 소요 시간을 확인하는 것과 코드 실행 횟수를 측정하는 방식이 존재한다.

이때, SQL에서 자체적으로 소요 시간 및 코드 실행횟수를 알려주는 명령어가 존재한다.

Profile

MySQL(or MariaDB)에서 쿼리가 처리되는 동안 각 단계별 작업에 시간이 얼마나 걸리는지 확인할 수 있는 기능을 제공합니다.

(단, Query Profiling은 MySQL 5.1 이상 버젼에서만 제공하고 있다.)

set profiling = 1;

일단 Profile을 사용하기 위해서 profiling을 사용한다는 명령어를 실행해야 한다.

Mysql Profile 실행

그 후에 하나의 쿼리를 실행한 후, 다음 명령어를 통해 실행 시간을 정확하게 확인해보자.

show profiles;

조회하는 Query문 작성 후 Profile로 확인

만약 하나의 쿼리문이 어떻게 작동했는지 보고 싶다면 QueryID를 활용해서 확인할 수 있다.

show profile for query [QueryID];

show profile for query 명령어를 이용해서 자세하게 쿼리 진행 과정을 확인

Explain

Explain은 MySQL(MariaDB)에서 실행 계획을 알려주는 SQL 문법이다.

explain [Query 내용 작성]

위처럼 SQL을 작성하고 실행하면 다음 사진처럼 나온다.

explain을 통해서 실행계획 출력

  • id : Query의 고유 Id
  • select_type : 쿼리 타입 (simple, primary, subquery 등)
  • table : 접근하는 테이블
  • type : 조인 방식
  • possible_keys : 사용 가능한 인덱스 목록
  • key : 사용한 인덱스
  • key_len : 사용된 인덱스 길이
  • ref : 어떤 속성을 기준으로 인덱스가 사용되었는지 표시
  • rows : 예상 스캔 행의 수
  • Extra : 각종 조건문이 사용되는지 여부를 나타낸다.

참고 자료

https://peterica.tistory.com/177

 

[Mysql] 쿼리튜닝, Query Profiling

ㅁ 개요 ㅇ mysql의 성능향상을 위한 구체적인 지표를 얻을 수 있는 방법을 찾고 있었다. ㅇ profiling을 통해 디비 프로세스의 다양한 성능지표를 확인하여 쿼리 성능을 확인할 수 있다. ㅁ Mysql 버

peterica.tistory.com

https://0soo.tistory.com/235

 

MySQL 실행계획(explain) 정리

MySQL 실행계획 정리 쿼리 튜닝 검토 전, 실행계획(explain)을 보고 실행할 SQL이 DB에서 어떻게 처리될지 파악할 수 있습니다. MySQL 튜닝에서 가장 중요한 것은 쿼리와 스키마 설계인데, 스키마 설계

0soo.tistory.com

https://twinparadox.tistory.com/631

 

MySQL(MariaDB)의 EXPLAIN으로 실행 결과 분석하기

실행 계획이라고 하면, 쿼리가 어떻게 데이터를 불러오는지에 대한 계획을 의미한다. 실행 계획을 통해서 어떤 테이블이 어떤 방식으로 조회됐는지 확인할 수 있다. 조회 쿼리의 인덱스 사용 유

twinparadox.tistory.com

혹시라도 틀린 내용이 있다면 댓글로 알려주시면 감사하겠습니다!!

 

클러스터링에서 일어날 수 있는 상황

클러스터링(Clustering)는 상황이 크게 2가지로 분류된다.

첫번째는 클러스터링의 과반수보다 낮은 수의 컴퓨터가 다운되었거나 새로 합류할 때이고, 두번째는 과분수보다 높은 수의 컴퓨터가 다운되었을 대이다.

첫번째인 경우에는 IST, SST가 작동하여 클러스터링으로 서버를 유지할 수 있고, 두번째 경우는 쿼럼 유지를 실패한 경우이다.

  • Incremental State Transfer(IST) : 클러스터에서 이탈한 컴퓨터가 복귀할 때, 변경된 데이터만 복사받는 방식을 의미한다.
    • State Snapshot Transfer(SST) : 클러스터에 새로운 컴퓨터가 합류할 때, 전체 데이터를 스냅샷(Snap Shot)처럼 복사해서 보내주거나 받는 과정을 의미한다.
  • Quorum(쿼럼) : 몇대 이상의 컴퓨터가 살아있어야 클러스터가 안정성이 유지된다고 판단하는 기준이다. 기본 값으로 과반이 기준이다. 따라서 기본적으로 Clustering은 홀수개의 컴퓨터만 설정할 수 있다.

Clustering 구조

MariaDB Clustering 구축

1. 서버 중지 (Clustering 구축할 컴퓨터)

systemctl stop mariadb

 

2. Clustering 설정 추가

vi /etc/mysql/mariadb.conf.d/50-server.cnf

VIM 편집기로 설정창 들어가자.

[galera]
wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_address="gcomm://" # 클러스터링 주소입력 / 처음 클러스터링하고 있어서 빈칸이다.
binlog_format=row
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0
wsrep_cluster_name="[클러스터링 이름]"	# 3대의 컴퓨터를 묶었을 때 내가 지어줄 이름
wsrep_node_address="[현재 컴퓨터 IP 주소]" # 현재 컴퓨터의 IP 주소

Clustering 설정

위에서 설정한 설정 코드를 적용시키기 위해서 프로그램을 재시작 및 Clustering을 시작한다.

systemctl restart mariadb
galera_new_cluster

 

3.  클러스터에 참여할 컴퓨터 설정 추가

이제 다른 2대의 설정을 밑의 코드처럼 진행하자.

vi /etc/mysql/mariadb.conf.d/50-server.cnf

맨 마지막 줄에 다음 설정을 추가하자.

[galera]
wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_address="gcomm://[클러스터 IP주소 1],[클러스터 IP주소 2],[클러스터 IP주소 3]"
binlog_format=row
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0
wsrep_cluster_name="[위에서 설정한 클러스터 이름]"
wsrep_node_address="[현재 컴퓨터 IP 주소]"

Clustering 설정

systemctl restart mariadb

위에서 설정한 설정 코드를 적용시키기 위해서 프로그램을 재시작한다.

 

4. 최종 확인

mariadb Client에 접속해서 지금 클러스터링이 잘 되고 있는지 확인하자.

mariadb -u root -p

Client에서 접속해서 다음 명령어를 작성하면 사진처럼 나와야 한다.

show status like 'wsrep_cluster_status';
show status like 'wsrep_cluster_size';
show status like 'wsrep_local_state_comment';

클러스터링 설정 완료

 


클러스터 서버 1대 다운 상황

DB 서버 한대가 강제 종료 당했다.

DB 서버 중 한대만 강제 종료를 진행해보자

한대의 서버가 강제 종료 당했다. 그럼에도 Clustering이 잘 동작하고 있다.

3개의 서버 중 한대가 다운되더라도 2개의 서버가 살아있으므로 쿼럼 유지가 된다.

따라서 Clustering을 유지하고 있다.


쿼럼 유지 실패 상황

과반수 이상의 서버가 다운되어 쿼럼을 유지 못한 상황이다.

만약 쿼럼을 유지 못했다면, 마지막 살아있는 DB3에서 새로운 데이터를 생성하고자 하면 다음 사진처럼 에러가 나온다.

데이터 생성시 에러 호출

그리고 클러스터링 상태를 보기 위해서 다음 명령어를 MariaDB Client에서 실행하면 다음 사진처럼 변경되어 나온다.

show status like 'wsrep_cluster_status';
show status like 'wsrep_cluster_size';
show status like 'wsrep_local_state_comment';

쿼럼 실패 후 클러스터링 설정 변경

그럼 이 상태에서 DB1을 다시 실행시키고 mariaDB 서버를 재시작해보자.

그럼 다음 사진처럼 재시작이 안되고 무한 로딩에 걸리게 된다.

무한 로딩중...

즉, 클러스터링에서 쿼럼 유지가 안된다면 DB 서버만 재시작하는게 아니라 클러스터링 설정을 수정해야 한다.

따라서 다음 명령어를 쳐서 마지막까지 살아있던 DB를 종료시키고, 클러스터링 설정을 수정하자.

systemctl stop mariadb
vi /var/lib/mysql/grastate.dat

위 파일에서 safe_to_bootstrap : 0 → safe_to_bootstrap : 1로 설정을 변경하자.

클러스터링 설정 변경

그 후에 다시 MariadB 서버 설정 파일에 들어가서 wsrep_cluster_address를 다음 사진처럼 수정하자.

vi /etc/mysql/mariadb.conf.d/50-server.cnf

MariaDB 서버 설정 변경

이렇게 수정한 후에 다음 명령어를 쳐서 mariaDB 재시작 및 Cluster 재시작을 해주면 다시 Clustering이 시작된다.

systemctl start mariadb
galera_new_cluster

혹시라도 틀린 내용이 있다면 댓글로 알려주시면 감사하겠습니다!!

KeepAlived란?

  • C언어로 작성된 로드밸런싱 및 고가용성을 제공하는 프레임워크이다.
  • 게이트웨이 이중화 구성을 위해 VRRP 프로토콜 사용한다.
  • VRRP를 통해서 KeepAlived가 같은 공유기에 연결되어있는 모든 기기에게 가상 IP 주소를 가지고 있다고 통신을 제공한다

통신중

VRRP란?

VRRP(Virtual Router Redundancy Protocol)로, 가상 라우터 다중화 프로토콜임과 동시에 게이트워이 장애 복구를 위한 프로토콜이다.

게이트웨이 이중화 구성은 크게 2가지 목적으로 구현된다.

  • Load balancing : 똑같은 기능을 수행하는 장비를 여러 개 구성하여 네트워크 부하를 분산
  • Failover : 하나의 장비가 죽었을 때 다른 장비로 전환되어 서비스 단절 최소화

VRRP의 이중화 구성의 경우 Filaover 목적으로 Master / Slave 전환을 위해 사용한다.

Master와 Slave는 하나의 VIP(Vitural IP)로 묶여 있으며, 각각 RIP(Real IP)를 가지고 있다. (Master: Active / Slave: Stand-By 상태)

만약 Master 장비 장애 발생 시 Slave 장비가 VIP를 가져와 Master 역할 수행하게 된다.

Hot Site 구축 상황

MariaDB 설정 방법

Master Computer 설정 방법

리플리케이션을 구축하기 위해서는 DB에서 Master 및 Slave 설정을 진행해야 한다.

mysqldump -u root -p --all-databases > backup.sql

위 명령어를 이용해서 백업 파일을 만든다.

그 후 Slave 컴퓨터에게 이 백업 파일을 전송한 후, 데이터를 삽입시킨다.

scp  [백업 파일 경로]/backup.sql   [Linux ID]@[Slave IP]:[백업 파일 경로]/backup.sql // 데이터 전송 명령어
mariadb -u root -p < [파일 경로]/backup.sql

이 후에 master 컴퓨터에서 master 설정을 진행해야 한다.

vi /etc/mysql/mariadb.conf.d/50-server.cnf

이렇게 vim 편집기를 이용해서 '50-server.cnf'를 열고 109번 라인에 가면 다음 화면처럼 나온다.

109번째 라인

여기서 다음 코드를 복사해서 붙여넣으면 된다.

log-bin # Log 작성을 시작한다는 명령어
server_id=1 # 서버 Id를 나타내는 명령어
log-basename=master1 # 이 로그 파일 이름을 지정하는 명령어
binlog-format=mixed # 로그 파일이 2진수와 언어로 섞이도록 작성한다는 명령어

이렇게 한 후, 저장하면 된다.

설정을 적용시키기 위해서 재시작을 한번 하자.

systemctl restart mariadb

그 후에 mariadb 클라이언트 프로그램에 접속해서 실제로 master 설정이 적용되었는지 확인하자. (다음 명령어는 mariadb 클라이언트 프로그램에서 실행해야 한다.)

더보기
mariadb -u root -p

위 명령어를 통해서 클라이언트 프로그램에 접속하자.

 

show master status;

master 설정이 적용되면 위와 같은 화면이 나온다.

그 후에 Slave 및 WorkBench가 접속할 mariadb ID를 만들어줘야 한다.

CREATE USER '[Slave에서 접속할 ID]'@'%' IDENTIFIED BY '[비밀번호]'; # MariaDB ID 생성
GRANT REPLICATION SLAVE ON *.* TO '[Slave에서 접속할 ID]'@'%'; # 전 권한 부여
FLUSH PRIVILEGES; # 권한 적용
CREATE USER '[WorkBench에서 접속할 ID]'@'%' IDENTIFIED BY '[비밀번호]'; # MariaDB ID 생성
GRANT REPLICATION SLAVE ON *.* TO '[WorkBench에서 접속할 ID]'@'%'; # 전 권한 부여
FLUSH PRIVILEGES; # 권한 적용

Slave Computer 설정 방법

Master 컴퓨터에서 보낸 데이터를 Slave 컴퓨터에 복사해야 한다.

mariadb -u root -p < [Master에서 보낸 파일 경로]

그 후에 Slave 컴퓨터에서 Slave 설정을 진행해야 한다.

vi /etc/mysql/mariadb.conf.d/50-server.cnf

이렇게 Vim 편집기를 통해서 내부 설정을 다음처럼 설정하자. 위와 같이 109번 줄이다.

[mariadb]
server_id=2

109번 줄

이제 MariaDB에 들어가서 master 컴퓨터를 연동해야 한다.

mariadb -u root -p // MariaDB Client 프로그램에 접속하자.
CHANGE MASTER TO
	MASTER_HOST='[마스터 서버 IP]',
	MASTER_USER='[마스터에서 생성한 ID]',
	MASTER_PASSWORD='[마스터에서 생성한 PW]',
	MASTER_PORT=3306,
	MASTER_LOG_FILE='[마스터에서 show master status 했을 때 File 이름]',
	MASTER_LOG_POS=[마스터에서 show master status 했을 때 position 번호],
	MASTER_CONNECT_RETRY=10; # 마스터에게 정보를 받는 주기

위 설정처럼 설정하면 Master 연동은 끝난다.

START SLAVE;

위 명령어를 통해 리플리케이션 구축은 끝난다.

SHOW SLAVE STATUS\G

제대로 작동하고 있는지 확인하고 싶으면 위 명령어를 입력한 후

  • Slave_IO_Running : YES
  • Slave_SQL_Running : YES

라고 로그가 나오는 지 확인하면 된다.

Slave컴퓨터에서 Master 컴퓨터 연결 완료

더보기

만약 START SLAVE 명령어에서 에러 로그가 출력되거나 위 로그가 NO 혹은 다른 영어가 존재한다면 Slave 컴퓨터에서 Master 설정을 다시 해주면 된다.

STOP SLAVE;
RESET SLAVE;

 

KeepAlived 설정 방법 (with Ubuntu)

KeepAlived를 설치하자 (각 DB 컴퓨터에 설치해야 한다.)

apt install -y keepalived

그 후에 keepAlived 설정파일을 생성하고, 설정코드를 입력하자.

vi /etc/keepalived/keepalived.conf
global_defs {
    router_id node01 # 이 설정 컴퓨터 이름이다, Master와 Slave에서 달라야 한다.
    enable_script_security
    script_user root
}

vrrp_script track_mariadb { # 공유기를 통해 내부 컴퓨터들에게 보내는 메시지를 설정한다.
    script "systemctl is-active mariadb" # MariaDB에 연결하고 있기 때문에 이렇게 작성한다.
    interval 5 # 5초에 한번씩 메시지를 날린다.
    fall 4 # 4번 이상 실패하면 컴퓨터가 다운되었다고 가정한다.
    rise 2 # 2번 이상 성공하면 컴퓨터가 작동한다고 가정한다.
}

vrrp_instance VRRP1 {
    state MASTER # backup 용 설정은 state BACKUP이라고 작성하면 된다.
    interface ens33
    virtual_router_id 101
    priority 200 # 우선순위를 말한다. 우선순위가 높으면 높을수록 Master 컴퓨터이다.
    advert_int 1
    virtual_ipaddress {
        [설정한 가상 IP 주소]/24
    }

    track_script {
        track_mariadb 
    }
}

Slave 컴퓨터에도 위와 같이 설치 및 설정을 진행하면 끝난다.

그 후에 Master나 Slave가 아닌 컴퓨터에서 MariaDB Client로 접속을 시도하자. (With Mysql Workbench)

workbench 사용해서 접속
Master DB가 다운된 후, Slave DB에 연결되었다.

참고 자료

https://velog.io/@suk13574/keepalived%EB%A1%9C-%EC%9D%B4%EC%A4%91%ED%99%94-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0

 

keepalived로 이중화 구성하기

C언어로 작성된 로드밸런싱 및 고가용성을 제공하는 프레임워크이다.이중화 구성을 위해 VRRP 프로토콜 사용한다.VRRP(Virtual Router Redundancy Protocol)로, 게이트워이 장애 복구를 위한 프로토콜이다.VR

velog.io

https://limvo.tistory.com/13

 

[네트워크] VRRP란? (게이트웨이 이중화 구성 - FHRP)

네트워크 이중화 작업을 할 때 VRRP 프로토콜을 사용해서 한다는 말을 많이 들어봤을 것이다. 이중화 구성을 하는 이유는 크게 두가지로 다음과 같다. Load balancing : 똑같은 기능을 수행하는 장비

limvo.tistory.com

혹시라도 틀린 내용이 있다면 댓글로 알려주시면 감사하겠습니다!!

Haproxy란??

Haproxy는 고가용성, 로드 밸런서 및 프록시 기능을 제공하는 오픈소스 라이브러리입니다.

고가용성이란?

서버, 네트워크, 프로그램등의 정보 시스템이 상당히 오랜 기간 동안 지속적으로 정상 운영이 가능한 성질을 말합니다.

로드 밸런서란?

로드 밸런싱은 애플리케이션 가용성을 최적화하고 긍정적인 최종 사용자 경험을 제공하기 위해 여러 서버에 네트워크 트래픽을 효율적으로 분산하는 프로세스를 말합니다.

프록시란?

클라이언트가 자신을 통해서 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템이나 응용 프로그램을 의미합니다.

따라서 서버와 클라이언트 사이에서 존재하는 중계기입니다.


이런 Haproxy를 활용해서 리플리케이션 중 미러 사이트를 구축할 수 있다.

오늘 구축할 컴퓨터 형태

MariaDB 설정 방법

Master Computer 설정 방법

리플리케이션을 구축하기 위해서는 DB에서 Master 및 Slave 설정을 진행해야 한다.

mysqldump -u root -p --all-databases > backup.sql

위 명령어를 이용해서 백업 파일을 만든다.

그 후 Slave 컴퓨터에게 이 백업 파일을 전송한 후, 데이터를 삽입시킨다.

scp  [백업 파일 경로]/backup.sql   [Linux ID]@[Slave IP]:[백업 파일 경로]/backup.sql // 데이터 전송 명령어
mariadb -u root -p < [파일 경로]/backup.sql

이 후에 master 컴퓨터에서 master 설정을 진행해야 한다.

vi /etc/mysql/mariadb.conf.d/50-server.cnf

이렇게 vim 편집기를 이용해서 '50-server.cnf'를 열고 109번 라인에 가면 다음 화면처럼 나온다.

109번째 라인

여기서 다음 코드를 복사해서 붙여넣으면 된다.

log-bin # Log 작성을 시작한다는 명령어
server_id=1 # 서버 Id를 나타내는 명령어
log-basename=master1 # 이 로그 파일 이름을 지정하는 명령어
binlog-format=mixed # 로그 파일이 2진수와 언어로 섞이도록 작성한다는 명령어

이렇게 한 후, 저장하면 된다.

설정을 적용시키기 위해서 재시작을 한번 하자.

systemctl restart mariadb

그 후에 mariadb 클라이언트 프로그램에 접속해서 실제로 master 설정이 적용되었는지 확인하자. (다음 명령어는 mariadb 클라이언트 프로그램에서 실행해야 한다.)

더보기
mariadb -u root -p

위 명령어를 통해서 클라이언트 프로그램에 접속하자.

show master status;

master 설정이 적용되면 위와 같은 화면이 나온다.

그 후에 Slave 및 WorkBench가 접속할 mariadb ID를 만들어줘야 한다.

CREATE USER '[Slave에서 접속할 ID]'@'%' IDENTIFIED BY '[비밀번호]'; # MariaDB ID 생성
GRANT REPLICATION SLAVE ON *.* TO '[Slave에서 접속할 ID]'@'%'; # 전 권한 부여
FLUSH PRIVILEGES; # 권한 적용
CREATE USER '[WorkBench에서 접속할 ID]'@'%' IDENTIFIED BY '[비밀번호]'; # MariaDB ID 생성
GRANT REPLICATION SLAVE ON *.* TO '[WorkBench에서 접속할 ID]'@'%'; # 전 권한 부여
FLUSH PRIVILEGES; # 권한 적용

Slave Computer 설정 방법

Master 컴퓨터에서 보낸 데이터를 Slave 컴퓨터에 복사해야 한다.

mariadb -u root -p < [Master에서 보낸 파일 경로]

그 후에 Slave 컴퓨터에서 Slave 설정을 진행해야 한다.

vi /etc/mysql/mariadb.conf.d/50-server.cnf

이렇게 Vim 편집기를 통해서 내부 설정을 다음처럼 설정하자. 위와 같이 109번 줄이다.

[mariadb]
server_id=2

109번 줄

이제 MariaDB에 들어가서 master 컴퓨터를 연동해야 한다.

mariadb -u root -p // MariaDB Client 프로그램에 접속하자.
CHANGE MASTER TO
	MASTER_HOST='[마스터 서버 IP]',
	MASTER_USER='[마스터에서 생성한 ID]',
	MASTER_PASSWORD='[마스터에서 생성한 PW]',
	MASTER_PORT=3306,
	MASTER_LOG_FILE='[마스터에서 show master status 했을 때 File 이름]',
	MASTER_LOG_POS=[마스터에서 show master status 했을 때 position 번호],
	MASTER_CONNECT_RETRY=10; # 마스터에게 정보를 받는 주기

위 설정처럼 설정하면 Master 연동은 끝난다.

START SLAVE;

위 명령어를 통해 리플리케이션 구축은 끝난다.

SHOW SLAVE STATUS\G

제대로 작동하고 있는지 확인하고 싶으면 위 명령어를 입력한 후

  • Slave_IO_Running : YES
  • Slave_SQL_Running : YES

라고 로그가 나오는 지 확인하면 된다.

Slave컴퓨터에서 Master 컴퓨터 연결 완료

더보기

만약 START SLAVE 명령어에서 에러 로그가 출력되거나 위 로그가 NO 혹은 다른 영어가 존재한다면 Slave 컴퓨터에서 Master 설정을 다시 해주면 된다.

STOP SLAVE;
RESET SLAVE;

Haproxy 설정 방법 (With Unbuntu)

Haproxy를 Ubuntu에 설치하자

apt update
apt install haproxy

그 후에 Haproxy 설정을 들어가서 로드 밸런싱 설정을 진행하자.

vi /etc/haproxy/haproxy.cfg

vi /etc/haproxy/haproxy.cfg 설정 화면

위 설정 파일의 맨 마지막에 다음과 같은 설정 코드를 작성하고 저장하자.

listen stats
    bind *:9000
    mode  http
    option dontlog-normal
    stats enable
    stats realm Haproxy\ Statistics
    stats uri /stats

frontend dbserver
  bind *:3306
  mode tcp
  default_backend mariadb_backend

backend mariadb_backend
    mode tcp
    option mysql-check user haproxy
    server db1 [Master 컴퓨터 IP]:3306 check       # Master 컴퓨터라고 지정한다(Check는 평소에 확인)
    server db2 [Slave 컴퓨터 IP]:3306 check backup # Slave 컴퓨터라고 지정한다.(backup 용)

이렇게 작성한 후 다음 명령어를 통해서 프로그램을 다시 시작하자.

systemctl restart haproxy

그 후에 Master나 Slave가 아닌 컴퓨터에서 MariaDB Client로 접속을 시도하자. (With Mysql Workbench)

workbench 사용해서 접속

SHOW VARIABLES LIKE 'server_id';

Haproxy IP로 접근한 상태(Master ID가 제대로 나온다.)
Master DB가 다운된 후, Slave DB에 연결되었다.

더보기

만약 클라이언트 접속이 안된다면 다음 명령어를 DB 컴퓨터의 DB 클라이언트 프로그래에서 실행하여 차단당한 IP를 삭제하자. (이때, DB서버 컴퓨터에서 진행해야 한다.)

 mariadb-admin flush-hosts -u root -p

참고 자료

https://hoing.io/archives/2196

 

HAProxy 설치 및 로드밸런싱 설정 - MySQL 로드밸런싱 및 Client HA 구성

포스팅에서는 L4, L7 기능 및 고가용성 기능을 지원하는 오픈소스 솔루션인 HAProxy에 대해서 설치 및 설정 그리고 MySQL에서 HAProxy를 사용하는 내용에 대해서 다루고 있습니다.

hoing.io

https://www.ibm.com/kr-ko/topics/load-balancing

 

로드 밸런싱이란? | IBM

로드 밸런싱은 애플리케이션 가용성을 최적화하고 긍정적인 최종 사용자 경험을 제공하기 위해 여러 서버에 네트워크 트래픽을 효율적으로 분산하는 프로세스입니다.

www.ibm.com

https://ko.wikipedia.org/wiki/%ED%94%84%EB%A1%9D%EC%8B%9C_%EC%84%9C%EB%B2%84

 

프록시 서버 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 프록시 서버 역할을 하는 세 번째 컴퓨터를 통해 연결된 두 컴퓨터 간의 통신이다. 밥(Bob)은 프록시에 대해서만 알고 앨리스(Alice)를 직접 식별하거나 연락할 수

ko.wikipedia.org

혹시라도 틀린 내용이 있다면 댓글로 알려주시면 감사하겠습니다!!

DRP(Disaster Recovery Plan)란?

재해 복구 계획(Disaster Recovery Plan)은 팀이 예상치 못한 에러나 공격을 받았을 때, 효과적으로 대응하는 방법론을 말합니다.

이를 통해 비지니스 연속성을 지키고, 서비스 사용자는 사용자 경험이 떨어지지 않도록 유지할 수 있게 됩니다.

재해 복구 계획은 소프트웨어에서 미러 사이트, 핫 사이트, 웜 사이트, 콜드 사이트로 크게 4가지로 분류됩니다.

  • 미러 사이트(Mirror Site) : 주 시스템 서버 센터 동일한 수준의 데이터와 시스템을 원격지에 구축, 주 시스템 서버 센터도 실행 중 & 원격 센터도 실행 중인 상태를 의미한다.
  • 핫 사이트(Hot Site) : 주 시스템 서버 센터 동일한 수준의 데이터와 시스템을 원격지에 구축, 주 시스템 서버 센터는 실행 중 & 원격 센터는 대기 중인 상태를 의미한다.
  • 웜 사이트(Warm Site) : 주 시스템 서버 센터 동일한 수준의 데이터만 원격지에 구축, 주 시스템 서버 센터는 실행 중인 상태를 의미한다.
  • 콜드 사이트(Cold Site) : 최소한의 준비만 (데이터도 큰 정보만 백업해놓고 나머진 백업 안해놓음) 해놓은 상태를 의미한다.

리플리케이션(Replication)

리플리케이션(Replication)은 가장 위에 Master가 존재하고, 그 밑에 Slave가 존재하는 구조이다.

이때, Master에는 추가, 조회, 수정, 삭제 모든 권한이 존재하고, Slave에는 조회 권한만 존재한다.

하지만 실무에서는 Master는 쓰기권한만(추가, 수정, 삭제 권한), Slave에는 조회 권한만 존재하도록 시스템을 구축해놓는다.

Replication 구조

하지만 이렇게 되는 경우, Master 컴퓨터가 공격당하거나, 예상치 못한 오류로 전원이 꺼진다면 쓰기 권한을 가진 컴퓨터가 사라져서 제대로 된 서비스를 제공할 수 없다.

따라서 Master이자 Slave인 컴퓨터를 여러대 놓아서 운영하기도 한다.

Master & Slave 컴퓨터 구조

리플리케이션의 장점

  • 대부분의 데이터는 조회가 60 ~ 80%를 차지하고 있어 성능이 크게 향상된다.
  • 비동기 방식으로 운영되어 지연시간이 크게 저하되지는 않는다.

리플리케이션 단점

  • 마스터 컴퓨터가 다운되면 전체적인 서비스 복구가 어렵다.
  • 데이터 불일치가 일어날 수 있다.(비동기 방식이기 때문에)

리플리케이션 동작 방식 (With MariaDB)

리플리케이션 동작 방식

  1. Master DB에서 새로운 데이터가 저장된다.
  2. 이때, Master DB에 존재하는 Log에 위 동작이 기록된다.
  3. 동기화 시간마다 Slave DB는 Master DB에 들어가서 Log파일을 읽는다.
  4. 이때, 새로운 데이터가 존재하면 Log에 적힌대로 복사해서 Slave DB에 저장한다. 

클러스터링(Clustering)

클러스터링(Clustering)은 각 노드가 평등하게 존재하는 구조를 의미한다.

그렇기에 각 노드의 컴퓨터들은 동기 방식으로 데이터를 처리한다.

Clustering 구조

클러스터링의 장점

  • 데이터의 불일치가 일어나지 않는다.
  • 시스템에서 장애없이 꾸준히 이용할 수 있다.

클러스터링의 단점

  • 리플리케이션에 비해서 성능이 떨어진다.

클러스터링 동작 방식

클러스터링 동작 방식

  1. 한 DB에 데이터가 저장되는 동작이 실행된다.
  2. 실제 DB에 저장하기 전에 클러스터링 되어있는 다른 DB에게 데이터 복제를 요청한다.
    1. 모든 DB가 응답하면 실제로 데이터가 작성된다.
    2. 만약 모든 DB가 응답하지 않으면 잠시 정지한다. (응답이 올 때까지)

참고 자료

https://www.ibm.com/kr-ko/topics/disaster-recovery-plan

 

재해 복구 계획이란 무엇인가요? | IBM

재해 복구 계획은 조직이 예기치 않은 사고에 효과적으로 대응하고 비즈니스 운영을 재개하는 방법을 설명하는 상세한 문서입니다.

www.ibm.com

https://mangkyu.tistory.com/97

 

[Database] 리플리케이션(Replication) vs 클러스터링(Clustering)

1. 리플리케이션(Replication)이란? [ 리플리케이션(Replication)이란? ] 리플리케이션이란 여러 개의 DB를 권한에 따라 수직적인 구조(Master-Slave)로 구축하는 방식이다. 리플리케이션에서 Master Node는 쓰

mangkyu.tistory.com

혹시라도 틀린 내용이 있다면 댓글로 알려주시면 감사하겠습니다!!

성능 테스트란??

개발자가 만든 프로그램이 얼마나 많은 요청을 감당해 낼 수 있는지 확인하는 방법은 성능테스트이다.

따라서 프로그램이 만들어지면 성능 테스트를 통해서 기준 지표를 정하게 되고, 그 기준에 따라서 서버를 증가시킬지 아니면 시스템 아키텍처를 변화시켜서 감당해낼지 결정하게 된다.

JMeter

Java를 기반으로 동작하는 부하 테스트 프로그램이다.

따라서 Java가 기본적으로 설치되어있어야 한다.

설치 방법

1. https://jmeter.apache.org/download_jmeter.cgi

 

Apache JMeter - Download Apache JMeter

Download Apache JMeter We recommend you use a mirror to download our release builds, but you must verify the integrity of the downloaded files using signatures downloaded from our main distribution directories. Recent releases (48 hours) may not yet be ava

jmeter.apache.org

위 사이트에 들어가서 해당하는 JMeter 파일을 다운받는다.

2. 압축 파일을 푼 후에, 다음 위치에 찾아들어가서 jmeter.bat 파일을 실행시킨다.

\apache-jmeter-5.6.3\bin\jmeter.bat

3. Test Plan 우클릭 → Add → Threads(Users) → Thread Group 클릭한다.

Thread Group 설정

  • Number of Threads(user) : 동시에 부하를 가할 쓰래드의 수를 의미한다.
  • Ramp-up period(seconds) : 쓰래드를 점진적으로 시간에 따라서 부하시킬 시간을 의미한다.
  • Loop Count : 부하 동작을 반복 수를 의미한다.

설정 후의 Thread Group

4. Thread Group 우클릭 → Add → Config Element→ JDBC Connection Configuration 클릭한다.

Variable Name of created pool : 뒤에 Request와 연결할 이름이다. (기본키라고 생각해도 무방하다.)

스크롤을 내리면 다음과 같다.

  • Validation Query : DBMS와 연결을 끊기지 않게 하기 위해서 가짜로 보내는 쿼리를 의미한다. 이 쿼리를 선택해야 부하 연결을 할 수 있다.
  • Database URL : DBMS에 연결할 URL을 의미한다.
  • JDBC Driver class : Java언어를 통해 DBMS와 연결할 것이므로 JDBC에 맞게 Class를 선택한다.
  • Username : DBMS의 유저 이름을 의미한다.
  • Password : DBMS의 유저 이름에 해당하는 비밀번호를 의미한다.

4. Thread Group 우클릭 → Add → Sampler → JDBC Request 클릭한다.

Variable Name of Pools declared in JDBC Connection Configuration : 앞에서 정했던 Configuration과 연결할 이름이다.

Query Type : 실행할 명령어의 타입을 결정한다.

Select Statement 일반적인 SELECT 쿼리를 실행할 때 사용. 결과 집합을 반환하며, 변수로 결과를 저장할 수 있음.
Update Statement UPDATE, INSERT, DELETE 쿼리 모두에 사용. 데이터 변경 쿼리(삽입, 수정, 삭제)에 적합.
Callable Statement 데이터베이스의 저장 프로시저나 함수 호출에 사용. IN/OUT 파라미터 지정 가능.
Prepared Select Statement 파라미터 바인딩이 필요한 SELECT 쿼리. 쿼리 실행 전에 변수값을 바인딩하여 효율적으로 실행.
Prepared Update Statement 파라미터 바인딩이 필요한 UPDATE/INSERT/DELETE 쿼리. 변수값을 바인딩하여 실행.
Commit 현재 트랜잭션의 변경 내용을 데이터베이스에 반영(커밋)함.
Rollback 현재 트랜잭션의 변경 내용을 취소(롤백)함.
Autocommit (false) 자동 커밋을 비활성화(수동 트랜잭션 관리). 이후 쿼리는 명시적 Commit 또는 Rollback 필요.
Autocommit (true) 자동 커밋 활성화(각 쿼리 실행 후 자동으로 커밋).

Query : 실제 쿼리문을 작성하면 된다.

5. Test Plan 우클릭 → Add → Listener → Summary Report 클릭한다.

부하 테스트 후 Summary Report 화면

5. Test Plan 우클릭 → Add → Listener → View Results Tree 클릭한다.

부하 테스트 후 화면

이렇게 실제 트래픽을 활용해서 부하 테스트를 진행하고, 데이터를 얻을 수 있다.

Prometheus

Prometheus란?

위에서 부하 테스트를 진행하거나 실제로 운영 서비스를 하고 있을 때, 컴퓨터에서 나오는 로그를 수집하는 프로그램이다.

다른 프로그램들도 많지만 다들 유료이므로... 무료인 Prometheus를 사용한다.

Prometheus 설치 방법(with Linux)

apt update
apt -y install prometheus prometheus-node-exporter

위 명령어로 Prometheus 및 Prometheus-node-exporter를 설치한다.

Prometheus-node-exporter :  HW(하드웨어)의 로그 데이터를 수집하고 저장한다.

Prometheus : exporter에서 데이터를 수집해놓은 것을 가지고 오는 프로그램이다.

이렇게 설치한 후에 Prometheus 및 exporter를 재시작 후 해당하는 Exporter를 설치하여 실행하면 데이터를 전송할 수 있다.

systemctl restart prometheus 
systemctl restart prometheus-node-exporter
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.17.2/mysqld_exporter-0.17.2.linux-amd64.tar.gz
tar zxvf mysqld_exporter-0.17.2.linux-amd64.tar.gz
cd mysqld_exporter-0.17.2.linux-amd64
vi .my.cnf

[client]
user=exporter
password=qwer1234
host=127.0.0.1

후에 Status → Targets 화면에 들어가면 다음과 같은 화면이 나온다.

Targets 화면

여기서 하나의 데이터를 클릭한다면 다음처럼 계속 데이터를 수집하고 있다는 것을 알 수 있다.

데이터 수집중...

Targets 추가하기

vi /etc/prometheus/prometheus.yml

위 명령어를 통해 접근하면 다음처럼 나온다.

 

여기서 - job_name이 Prometheus의 큰 선택 메뉴이다.

 

또한 targets에 내가 데이터를 수집하고 싶은 컴퓨터 IP주소를 입력하고, exporter의 포트 번호를 입력하면 된다.

 

node-exporter는 기본 포트가 9100번이다.

 

또한 다른 job_name을 하나의 데이터로 보기 위해서는 밑에 Lables를 붙여서 동시에 데이터를 처리할 수도 있다.

 

위 설정을 다 한 후에 다음 명령어로 재시작을 하면 적용된다.

 

systemctl restart prometheus

Grafana

Grafana란?

Prometheus같은 프로그램이 수집한 데이터를 개발자가 보기 좋게 변환시켜주는 프로그램을 의미한다.

즉, 그래픽 툴이라고 봐도 무방하다.

Grafana 설치 방법 (with Linux)

wget -q -O /usr/share/keyrings/grafana.key https://packages.grafana.com/gpg.key

1. 위 명령어를 이용해서 Grafana의 공개키를 등록한다.

apt update
apt -y install grafana

2. 그 후에 apt 업데이트 후 Grafana 설치를 진행한다.

systemctl restart grafana-server

3. Grafana를 재시작하면 끝난다.

참고로 Grafana는 컴퓨터 IP + 3000번 포트로 접속하면 된다.

http://Grafana컴퓨터 IP주소:3000

그럼 다음처럼 화면이 나온다.

처음에 하고싶은 ID와 비밀번호를 입력하자.(차피 내부 로그인 로직이기에 난 admin, admin을 입력했다.)

Login 화면

로그인에 성공하면 밑과 같은 화면이 나온다.

Grafana 화면

이제, Prometheus에서 주는 데이터를 받기 위해서 Connection → Data sources 메뉴로 들어간다.

Data Source 메뉴 접속

접속하면 다음과 같은 화면이 나오는데, 위에 Add new data source버튼을 클릭하자.

Add new data source 버튼 클릭

버튼을 클릭하면 다음 화면이 나오는데, 이때 Prometheus를 클릭하자.

Prometheus 클릭

그럼 Prometheus 설정을 하기 위한 설정창이 나오게 되는데, 이때 Prometheus의 IP주소를 입력하자. (기본적으로 Prometheus의 포트번호는 9090이다.)

Prometheus 설정창

IP 주소 입력 후에 스크롤을 끝까지 내리면 Save & Test라는 화면이 나온다. 이것을 클릭하면 된다.ㅇ

Data Source 저장

이렇게 되면 성공적으로 연결을 했다는 공지와 함께 창이 변하지 않는다. 확인하기 위해서 다시 Connections → Data Sources 메뉴를 클릭한다.

제대로 추가되었는지 확인차 다시 메뉴로

그럼 이렇게 잘 추가된 것을 확인할 수 있다.

Data Source 추가 완료

이제, DashBoard를 통해서 데이터를 보기 좋게 바꿔줘야 한다.

하지만 처음부터 우리가 다 DashBoard를 개발할 것은 아니고 Grafana DashBoard을 통해서 들고온 후, 각자 입맛에 맞게 조정하면 된다.

위 링크로 들어가서 스크롤을 내리면 다른 개발자들이 만든 DashBoard를 공유하고 있다.

필요한 데이터를 보여주는 DashBoard를 클릭하자

들어간 후에, 스크롤을 내리면 옆에 Copy ID to clipboard 버튼이 있다. 이 버튼을 클릭해서 ID를 알고 있자.(꼭 필요하니, 메모장에다가 저장해두자.)

Clip Board ID 복사

다시 Grafana IP주소로 돌아와서 DashBoard에 있는 new버튼 클릭 → Import 버튼을 클릭하자.

DashBoard 추가

그럼 아래처럼 화면이 나오는데, 1번에 우리가 찾은 ID를 입력한 후에 Load버튼을 클릭하자.

DashBoard 추가

그럼 밑처럼 Prometheus 데이터 선택 및 Import 버튼을 누르면 DashBoard가 추가된다.

DashBoard Data 추가 및 Import 완료
Dash 생성 완료

이렇게 프로그램 성능 튜닝할 때 이런 데이터를 보면서 조정하면 된다!!

참고 자료

https://grafana.com/blog/2023/08/24/grafana-security-update-gpg-signing-key-rotation/

 

Grafana security update: GPG signing key rotation | Grafana Labs

Grafana Labs Team   ·   23 May 2025   ·   6 min read Grafana security release: Medium and high severity security fixes for CVE-2025-4123 and...

grafana.com

혹시라도 틀린 내용이 있다면 댓글로 알려주시면 감사하겠습니다!!

Transsaction이란??

여러 작업을 하나의 논리적 단위로 묶은 것을 의미한다. 따라서 여러 SQL을 하나로 묶어서 실행하는 단위를 말한다.

Transaction의 특성

  • 원자성(Atomicity) : 트랜잭션의 작업은 한번에 모두 처리해야 한다. (따라서 DB는 LOCK을 이용해서 처리한다.) 따라서 중간에 실패하면 모두 롤백(Roll Back)이 일어나야 한다.
  • 일관성(Consistency) : 트랜잭션이 시작되기 전과 후의 데이터베이스는 항상 일관성 있는 상태여야 한다. (즉, 변경이 없어야 한다.)
  • 고립성(Isolation) : 동시에 여러 트랜잭션이 실행될 때, 각각의 트랜잭션은 독립적으로 실행된 것처럼 보인다. 다른 트랜잭션이 실행중인 데이터를 읽거나 수정하면 안된다.
  • 지속성(Durability) : 트랜잭션이 완료되면 그 결과는 영구적으로 데이터베이스에 반영되어야 하며, 시스템 장애가 발생하더라도 유지된다.

Transaction의 상태

  • 활성 (Active) : 트랜잭션이 실행 중인 상태.
  • 완료 (Committed) : 트랜잭션이 정상적으로 완료되어 데이터베이스에 반영된 상태.
  • 철회 (Rollback) : 트랜잭션이 실패하여 이전 상태로 복구된 상태.
  • 대기 (Blocked) : 다른 트랜잭션이 데이터를 잠그고 있어 실행할 수 없는 상태.

격리 수준 (Isolation Levels)

  • Read Uncommitted : 한 트랜잭션이 커밋되지 않은 데이터를 다른 트랜잭션이 읽을 수 있다. (Dirty Read 발생 가능)
  • Read Committed : 커밋된 데이터만 읽을 수 있다. 다른 트랜잭션이 커밋되지 않은 데이터를 읽을 수 없다. (Consistency가 깨짐)
  • Repeatable Read : 같은 트랜잭션 내에서 읽은 데이터는 트랜잭션이 끝날 때까지 일관되게 유지된다. (Phantom Read 방지 불가능)
  • Serializable : 트랜잭션들이 마치 직렬로 실행된 것처럼 완벽하게 격리된다. 가장 높은 격리 수준.

Read Uncommited

Transaction 중에서도 DB의 실제 값(HDD에 저장되어 있는)을 읽는 상태를 의미한다.

따라서 Dirty Read가 발생한다.

0. 다음 코드로 자동 커밋 모드를 해제하자.

set autocommit = false;

auto commit 모드 해제

1. 다음 코드로 현재 적용하고 있는 격리 수준을 알아보자.

select @@tx_isolation; # 트랜잭션 레벨 확인

Transaction의 격리 수준이 평소에 Repeatable Read로 설정되어 있다.

 

2. 다음 코드를 통해서 격리 상태를 Read Uncommitted로 변경하자.

set session transaction isolation level read uncommitted; #격리 상태를 Read Uncommitted로 변경
select @@tx_isolation;

Read Uncommitted로 변경 완료

이제 하나의 상황을 가정하여 Transaction을 작동시켜보자

A : start Transaction → update Data → sleep → commit
B : start Transaction → sleep → Read Data → commit

Dirty Read 발생

Read Committed

위와 똑같은 상황을 동작시키면 다음 사진처럼 Dirty Read는 일어나지 않았다.

그러나 A에서 Commit을 일어난 후 B에서 조회를 하면 전의 상태와 다르게 수정이 된다.

A : start Transaction → update Data → sleep → commit
B : start Transaction → sleep → Read Data → sleep → commit

Commit 후 다시 B에서 조회

이렇게 된 경우 Non-Repeatable Read(2번 조회시 데이터가 달라지는 현상)가 발생한다.

Repeatable Read

그래서 조회할 때마다 같은 결과를 제공하기 위해서 공유 락을 건 후에, 다른 트랜잭션이 들어와서 데이터 수정을 못하여 같은 결과를 계속해서 제공합니다.

 A 의 Commit이 진행된 이후, B를 조회하면 다음과 같습니다.

그러나 이런 Repeatable Read에서도 삽입하는 경우에는 일부 DBMS에서는 Phantom Read 현상이 발생할 수 있습니다. (이런

경우에는 스토리지 엔진에 의해서 차이가 납니다. / Maria DB에서는 이 스토리지 엔진이 기본적으로 Phantom Read 현상을 방지합니다.)

A : start Transaction → Insert Data → sleep → commit
B : start Transaction → sleep → Read Data → sleep → commit

Serializable

Serializable를 사용한다면 위의 모든 문제를 다 해결할 수 있다.

그러나 Serializable는 더 넓은 범위의 Lock 적용으로 인해서 위의 격리 수준보다 성능이 떨어진다.

따라서 각 프로젝트와 기능에 따라서 격리 수준을 다르게 적용하는 것이 필요하다.


혹시라도 틀린 내용이 있다면 댓글로 알려주시면 감사하겠습니다!!

SQL(Structured Query Language)문법 종류

  • DDL(Data Definition Laguge) : Table을 생성하거나 변경하거나, 삭제하는 명령어를 말한다.(Create, Alter, Drop)
  • DML(Data Manipulation Laguage) : 실제 데이터를 조회하거나 삽입, 삭제, 수정하는 명령어를 말한다.(Select, Insert, Update, Delete)
  • DCL(Data Control Laguage) : 데이터베이스에 접근하고 객체들을 사용하도록 권한을 제공하고 회수하는 명령어를 말한다.(Grant, Revoke)

쿼리(Query)

Create

CREATE DATABASE [데이터베이스 이름];  #데이터베이스 생성

CREATE TABLE [테이블 이름] (
	[속성 이름] [타입]
	[속성 이름] [타입]
);                                   #테이블 생성

위처럼 작성하면 된다. 예시는 다음과 같다.

use user;                                   # 데이터베이스 선택

create table user(
    id int primary key auto_increment,      # 양의 정수, 기본키 지정, 자동 증가 옵션
    email varchar(50) not null unique key,  # 50자 글자, null값 불가
    name varchar(20) default '기본 이름',    # 20자 글자, null이라면 '기본 이름'을 자동으로 추가함
    password varchar(200) not null          # 200자 글자, null값 불가
);

Table이 만들어졌고, 컬럼과 제약조건이 생성되었다.


Alter

ALTER TABLE [테이블 이름] [명령어] [해당 컬럼] [추가 명령어];

 

여기서 명령어는 다음과 같다.

  • ADD : 컬럼 추가
  • DROP : 컬럼 삭제
  • RENAME : 컬럼 이름 변경
  • MODIFY : 컬럼 제약 조건 수정
alter table user add profile_image varchar(100) default 'default.png'; #profile_image라는 컬럼 추가

alter add 후 새로운 컬럼 추가

alter table user drop profile_image;          #profile_image 컬럼 삭제

alter drop 후 데이터 컬럼 삭제

alter table user rename column name to nickname;   # name이라는 컬럼 이름을 nickname으로 변경

alter rename 후 name 컬럼이 nickname 컬럼으로 변경
alter modify 변경 전

alter table user modify nickname varchar(50);   # nickname이라는 컬럼 20자 제약 조건을 50자로 변경

alter modify 후 제약 조건 변경 완료


Drop

drop table user; # user라는 테이블을 삭제

Drop table 후 테이블이 삭제됨

drop database dbex; # 데이터베이스 삭제

Drop database 후 데이터베이스 자체가 삭제됨


Select-From

select문은 데이터베이스에서 데이터를 조회할 때, 사용한다.

대부분의 성능이슈는 데이터를 조회할 때 발생한다.

따라서 select 쿼리문이 성능 최적화가 가장 많이 요구된다.

select 작성 방법은 다음과 같다.

select [조회할 컬럼1], [조회할 컬럼2], ... [조회할 마지막 컬럼]
from [조회할 테이블]
where [조회 조건];

select *
from [조회할 테이블]
where [조회 조건];

이때, *은 모든 컬럼을 의미한다.

또한 where은 조회 조건을 의미하지만, 아예 작성을 안하면 테이블에 존재하는 모든 튜플을 조회한다.

select * from payment; # *은 모든것을 의미한다.

select *로 모든 컬럼 조회
select 컬럼 및 where 조건넣은 조회

Where

where은 조회 조건을 달아서 특정 데이터만 읽어오고 싶을 때 사용한다.

이때, 여러개의 조건을 동시에 달기 위해서 AND, LIKE, IN같은 문법이 추가적으로 사용한다.

And

여러개의 조건을 동시에 사용할 때 사용한다.

select [조회할 컬럼]
from [테이블 이름]
where [튜플 조건] and [튜플 조건];

where의 and 조건으로 조회

Like

문자열 중 일부만 알고 있을 때 사용한다.

select [조회할 컬럼]
from [테이블 이름]
where [문자열 컬럼] like [비슷한 문자열%]; # 앞 문장은 완전히 동일하고 뒷 문장은 달라도 된다.
										# %는 *를 의미한다.

select [조회할 컬럼]
from [테이블 이름]
where [문자열 컬럼] like [%비슷한 문자열]; # 뒷 문장은 완전히 동일하고 앞 문장은 달라도 된다.

select [조회할 컬럼]
from [테이블 이름]
where [문자열 컬럼] like [%비슷한 문자열%]; # 앞 문장, 뒷 문장은 달라도 되고, 중간 문장은 같다.

LIKE로 문자열 조회

In

문법 안에 배열을 통해서 조회하고 싶을 때 사용한다.

select [조회할 컬럼]
from [테이블 이름]
where [조회할 컬럼] in [튜플 조건들]

where의 In 문법으로 배열 조건으로 조회

Join

2개 이상의 테이블을 동시에 조회할 때 사용한다.

Inner Join

2개의 테이블 중 조건에 맞는 교집합만 데이터로 인식한다.(만약 조건에 맞지 않는다면 데이터 조회 자체가 안된다.)

select [조회할 컬럼]
from [테이블 이름]
where [튜플 조건]
inner join [테이블 이름] on [join 조건];

Inner Join 조회

left Join

2개의 테이블 중 기준 테이블과 

select [조회할 컬럼]
from [테이블 이름]   # 기준 테이블이 들어가야 한다.
where [튜플 조건]
left join [테이블 이름] on [join 조건];

Left Join 조회

as

테이블 이름이 너무 길 때, 간단한 별명으로 설정하고 코드를 작성할 때 사용한다.

select [조회할 컬럼]
from [테이블 이름] as [별명]
where [튜플 조건];

as로 SQL 읽기 편하게 작성

Order by

데이터를 정렬시킬 때 사용한다. (오름차순 : asc, 내림차순 : desc)

select [조회할 컬럼]
from [테이블 이름]
where [튜플 조건]
order by [기준 컬럼] [내림차순, 오름차순];

Order by로 ID순으로 정렬

is null

데이터가 null 값인지 확인하기 위해서 사용한다.

select [조회할 컬럼]
from [테이블 이름]
where [튜플 조건] is null;

Null값 조회

group by

여러개의 데이터 중 하나의 데이터를 기준으로 잡을 때 사용한다.(대표적으로 나라별 사람을 세고 싶을 때, 나라를 기준으로 데이터를 정렬해야 한다. 이럴때 사용한다.)

select [조회할 컬럼]
from [테이블 이름]
where [튜플 조건]
inner join [테이블 이름] on [join 조건]
group by [기준 컬럼];

기준 튜플로 데이터 조회

having

Group By에서 조건을 추가적으로 더 걸고 싶을 때 사용한다.

select [조회할 컬럼]
from [테이블 이름]
where [튜플 조건]
inner join [테이블 이름] on [join 조건]
group by [기준 컬럼]
having [튜플 조건];

기준 튜플의 조건 추가 검색

Limit

조회한 데이터 중 몇개만 보고 싶을 때 사용한다.

select [조회할 컬럼]
from [테이블 이름]
where [튜플 조건]
limit [개수]

select [조회할 컬럼]
from [테이블 이름]
where [튜플 조건]
limit [offset], [개수]

이때, offset은 앞에서 몇개를 제외한다는 것을 의미한다. (예를들어 10, 10이면 위에서 11번째부터 20번째 데이터만 읽어온다.)

데이터의 최대값 지정

Distinct

중복되는 데이터를 제거해서 보고 싶을 때 사용한다.

select distinct [조회할 컬럼 이름]
from [테이블 이름]
where [조회할 튜플 조건]

중복 제거 후 데이터 조회

서브 쿼리(SubQuery)

복잡한 쿼리를 작성할 때 사용한다. 

Join으로 쿼리를 작성하기 어려운 경우에 많이 사용한다.

둘의 성능 차이는 상황마다 다르지만 이 블로그에 따르면 다음과 같다.

  • JOIN: 여러 테이블의 데이터를 결합해야 한다면 기본적으로 선택.
  • 서브쿼리: 특정 조건을 필터링하거나 집계 값을 활용할 때 적합.
select [조회할 컬럼 이름]
from [테이블 이름]
where ([select [조회할 컬럼 이름]
        from [테이블 이름]
        where [조회할 튜플 조건]
);

서브 쿼리 이용해서 데이터 조회


Update

데이터를 수정할 때 사용한다.

update [테이블 이름] set [변경할 컬럼] = [변경 값] where [변경할 튜플 조건]

Update 전 상태
Update 후 상태


Insert

데이터를 새롭게 추가할 때 사용한다.

INSERT INTO [테이블 이름] [(테이블 조건1, 테이블 조건 2, ..., 테이블 조건 n)]
VALUE [데이터 1, 데이터 2, ..., 데이터 n)];

INSERT INTO [테이블 이름] [(테이블 조건1, 테이블 조건 2, ..., 테이블 조건 n)]
VALUES 
[데이터 1, 데이터 2, ..., 데이터 n)],
[데이터 1, 데이터 2, ..., 데이터 n)],
[데이터 1, 데이터 2, ..., 데이터 n)],
[데이터 1, 데이터 2, ..., 데이터 n)],
[데이터 1, 데이터 2, ..., 데이터 n)];

데이터 삽입


Delete

데이터를 삭제할 때 사용한다.

DELETE FROM [테이블 이름] WHERE [튜플 조건];

데이터 삭제

참고 문헌

https://brownbears.tistory.com/180

 

[DB] DDL, DML, DCL 이란?

명령어 종류 명령어 설명 데이터 조작어(DML : Data Manipulation LanguageSELECT 데이터베이스에 들어 있는 데이터를 조회하거나 검색하기 위한 명령어를 말하는 것으로 RETRIEVE 라고도 함INSERTUPDATEDELETE 데

brownbears.tistory.com

https://0and24.tistory.com/50

 

[SQL] Join vs SubQuery: 언제, 왜, 어떻게 선택할까?

며칠 전, 다대다 면접에서 면접관 한 분이 저에게 물었습니다."혹시 조인과 서브쿼리 중 어떤 것이 성능이 더 좋나요?"순간 잠시 생각을 한 뒤 이렇게 대답했습니다:"많은 양의 데이터를 다루지

0and24.tistory.com

 

혹시라도 틀린 내용이 있다면 댓글로 알려주시면 감사하겠습니다!!

+ Recent posts