일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- Galera Cluster
- redis
- 디자인 패턴
- 백준
- Kafka
- Heap
- Spring
- IT
- react
- JavaScript
- Java
- c언어
- C
- 알고리즘
- 자료구조
- 네트워크
- MySQL
- 컴퓨터구조
- JPA
- Data Structure
- 운영체제
- 파이썬
- MSA
- Proxy
- Algorithm
- spring webflux
- OS
- mongoDB
- 자바
- design pattern
Archives
- Today
- Total
시냅스
MariaDB 설치부터 Galera Cluster 구성까지 본문
이 글에서는 Cent OS 를 기준으로 MariaDB 설치부터 Galera Cluster 구성까지 살펴봅니다.
실제로 운영하며 겪었던 TroubleShooting 및 중요사항에 대해 설명합니다.
MariaDB 설치
/etc/yum.repos.d/MariaDB.repo
를 등록합니다.- MariaDB 공식 repo 링크
- 위 링크에서 현재 환경에 맞는 OS, MariaDB Version 을 선택합니다.
yum install MariaDB
명령어로 MariaDB 를 설치합니다.mariadb --version
명령어로 설치를 확인합니다.systemctl start mariadb
로 실행 후mysql -uroot -p
로 접속합니다.- 이 때 root 는 아직 password 가 설정되지 않은 상태이므로 password 를 설정해야 합니다.
- OS cli 로 나와
mysql_secure_installation
명령어를 실행하여 각 설정을 해줍니다. - 혹은
alter user 'root'@'localhost' identified by '{NEW_PASSWORD}';
로 설정합니다.
- OS cli 로 나와
- 이 때 root 는 아직 password 가 설정되지 않은 상태이므로 password 를 설정해야 합니다.
Galera Cluster 설치
yum install galera rsync
로 galera 와 rsync 를 설치합니다.- rsync 는 상태 전송 (데이터를 동기화) 하는 도구입니다.
- galera 와 rsync 는 MariaDB 패키지에 포함되어 있으므로 이미 설치되어 있을 수도 있습니다.
- 이후 galera 실행을 위한 설정 파일을 작성합니다.
galera 설정파일
[mysqld]
# (This must be substituted by wsrep_format)
binlog_format=ROW
# Currently only InnoDB storage engine is supported
default-storage-engine=innodb
# to avoid issues with 'bulk mode inserts' using autoinc
innodb_autoinc_lock_mode=2
# Override bind-address
# In some systems bind-address defaults to 127.0.0.1, and with mysqldump SST
# it will have (most likely) disastrous consequences on donor node
bind-address=0.0.0.0
##
## WSREP options
##
# Enable wsrep
wsrep_on=1
# Full path to wsrep provider library or 'none'
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
# Provider specific configuration options
#wsrep_provider_options=
# Logical cluster name. Should be the same for all nodes.
wsrep_cluster_name="galera_cluster"
# Group communication system handle
wsrep_cluster_address="gcomm://192.168.10.10, 192.168.10.11, 192.168.10.12"
#wsrep_cluster_address="gcomm://"
# Human-readable node name (non-unique). Hostname by default.
wsrep_node_name="node1"
# Base replication <address|hostname>[:port] of the node.
# The values supplied will be used as defaults for state transfer receiving,
# listening ports and so on. Default: address of the first network interface.
wsrep_node_address="192.168.10.10"
# Address for incoming client connections. Autodetect by default.
#wsrep_node_incoming_address=
# How many threads will process writesets from other nodes
wsrep_slave_threads=1
# DBUG options for wsrep provider
#wsrep_dbug_option
# Generate fake primary keys for non-PK tables (required for multi-master
# and parallel applying operation)
wsrep_certify_nonPK=1
# Maximum number of rows in write set
wsrep_max_ws_rows=0
# Maximum size of write set
wsrep_max_ws_size=2147483647
# to enable debug level logging, set this to 1
wsrep_debug=0
# convert locking sessions into transactions
wsrep_convert_LOCK_to_trx=0
# how many times to retry deadlocked autocommits
wsrep_retry_autocommit=1
# change auto_increment_increment and auto_increment_offset automatically
wsrep_auto_increment_control=1
# retry autoinc insert, which failed for duplicate key error
wsrep_drupal_282555_workaround=0
# enable "strictly synchronous" semantics for read operations
wsrep_causal_reads=0
# Command to call when node status or cluster membership changes.
# Will be passed all or some of the following options:
# --status - new status of this node
# --uuid - UUID of the cluster
# --primary - whether the component is primary or not ("yes"/"no")
# --members - comma-separated list of members
# --index - index of this node in the list
wsrep_notify_cmd=
##
## WSREP State Transfer options
##
# State Snapshot Transfer method
wsrep_sst_method=rsync
# Address which donor should send State Snapshot to.
# Should be the address of THIS node. DON'T SET IT TO DONOR ADDRESS!!!
# (SST method dependent. Defaults to the first IP of the first interface)
#wsrep_sst_receive_address=
# SST authentication string. This will be used to send SST to joining nodes.
# Depends on SST method. For mysqldump method it is root:<root password>
wsrep_sst_auth=root:
# Desired SST donor name.
#wsrep_sst_donor=
# Reject client queries when donating SST (false)
#wsrep_sst_donor_rejects_queries=0
# Protocol version to use
# wsrep_protocol_version=
- 첨부한 파일은 galera cluster 의 실행을 돕기위한 설정파일입니다.
- 위 파일의 위치는
/etc/my.cnf.d/galera.cnf
혹은 다른 cnf 파일에 추가하여도 무관합니다.
- 위 파일의 위치는
wsrep_cluster_address
,wsrep_node_name
,wsrep_node_address
를 현재 환경에 맞게 변경해야합니다.wsrep_cluster_address
에 가장 먼저 위치한 node 가 donor 입니다.- donor 는 특별한 명령어로 실행되므로 아래에서 설명합니다.
wsrep_provider
는find / -name libgalera_smm.so
명령어를 통해 dir 를 찾아 기입합니다.- 참고
- galera 는 상태 전송을 위해 Maria / MySQL DB default
3306
포트 이외 추가 3개를 사용합니다. 4444
,4567
,4568
- 따라서, 해당 포트에 방화벽 설정을 해제해야 합니다.
- galera 는 상태 전송을 위해 Maria / MySQL DB default
Galera Cluster 실행
wsrep_cluster_address
에 가장 먼저 위치한 node 를galera_new_cluster
명령어로 실행합니다.- 위처럼 실행된 node 는 Donor 입니다.
- Donor 는 Cluster 에 상태를 전파하는 node 입니다.
- 데이터의 전송은 각 노드가 노드에게로 이뤄지지만 SST 즉, 새로운 노드가 참여하거나 큰 데이터를 전송해야 할 필요가 있을 때에는 Donor 가 수행합니다.
- 다만 Donor 는 운영 중에 가변적으로 변경되며
show status like 'wsrep_local_index';
로 검색했을 때 가장 낮은 index 를 갖는 node 가 Donor 입니다.
- 다른 노드들(Joiner) 는
systemctl start mariadb.service
로 실행합니다.
- 위처럼 실행된 node 는 Donor 입니다.
show status like 'wsrep_%size';
로 clustering 이 잘 되었는지 확인합니다.- 만약
wsrep_cluster_size
가 연결한 노드의 수만큼 보여진다면, 정상적으로 clustering 이 완료된 것입니다. - 혹은 database, table 등을 만들어 함께 연동되는지 확인할 수 있습니다.
- 만약
Galera Cluster 중지
- galera cluster 는 구성이 쉬운 만큼 관리하기 까다롭습니다.
- 항상 graceful 하게 종료해야 되나 (
systemctl stop mariadb.service
), 동일한 명령어를 기입했음에도 그렇지 못한 경우들이 있습니다.- graceful 하지 못하게 종료된 경우를 판단하는 방법은 다음과 같습니다.
- 아래는
/var/lib/mysql/grastate.dat
파일입니다.# GALERA saved state version: 2.1 uuid: 00000000-0000-0000-0000-000000000000 seqno: -1 safe_to_bootstrap: 0
/var/lib/mysql/grastate.dat
파일은 현재 node 의 clustering 현황을 보여줍니다.- galera cluster 는 uuid 를 통해 각 node 를 특정하고, seqno 를 사용하여 진행된 transaction 을 판단합니다.
- 이때 seqno 가
-1
이라는 것은 실행중인 경우이나, 실제로 node가 종료된 상황이라면 에러가 난 상황이라고 판단할 수 있습니다. - 위와같이 에러가 난 상황에는
galera_recovery
를 사용하여 에러 핸들링을 시도할 수 있습니다.- 위 명령어는 마지막으로 실행했다고 판단하는 위치로 seqno를 되돌려 줍니다.
- 만약 이 방법으로도 되돌려지지 않는다면 mysql 을 새로 설치하여 clustering 을 하는 방법이 빠릅니다.
Galera Cluster 재기동
- galera cluster 는 전체를 down 시킨 후 전체를 재기동 시키는 것을 권장하지 않습니다.
- Active / Active 구조이기 때문에 어떤 것이든 master / donor 가 될 수 있습니다.
- 따라서 재기동을 할 때에는 단순히
systemctl start mariadb.service
로 기존 cluster 에 편입시키면 됩니다. - 다만, 이때
galera.cnf
의wsrep_cluster_address
의 맨 앞에 자신의 host 가 와서는 안됩니다. - 위에서 설명했듯, donor 가 가장 맨 앞에 위치하지만 뒤늦게 편입되는 node 는 donor 가 될 수 없기 때문입니다.
- 따라서 재기동을 위해서 맨 앞에 위치한 해당 node 의 host 순서를 무작위로 위치시키기만 하면 됩니다.
- 그럼에도 불구하고 전체 cluster 를 down 시킨 후 재기동 해야 한다면
- 각 노드의
grastate.dat
파일의seqno
를 확인합니다. - 여기에서 확인된
seqno
가 가장 높은 node 가 donor 가 되어야 합니다. - 따라서 확인된 노드 중 가장 높은
seqno
를 가지고 있는 노드를wsrep_cluster_address
의 맨 앞에 위치시킵니다. - 이후 앞서 살펴봤듯이 donor 는
galera_new_cluster
로, joiner 는systemctl start mariadb.service
로 실행시킵니다.
- 각 노드의
참고 - 성능을 위한 설정
[mysqld]
# 백업 서버를 위해 설정한 옵션, 백업하며 최대 네트워크 송수신할 수 있는 크기 정의
# 최대값 1GB, 필요에 따라 줄일 수 있음
max_allowed_packet = 1GB
# Transaction이 Commit 되었을 때 redo log 를 어떻게 flush 할지 결정
# buffer pool - log buffer - OS buffer - Disk (redo log)
# 0 : 1초 주기로 log 를 디크스로 flush
# 1 : transaction 이 커밋될 때마다 로그를 디스크로 flush
# 2 : transaction 이 커밋될 때마다 OS Buffer 로 flush (OS Buffer 가 1초 주기로 Disk 에 flush)
# 우리 서버는 Galera cluster 로 Multi Master 이기 때문에 0으로 설정
innodb_flush_log_at_trx_commit=0
[galera]
# write set을 쓰는 back ground thread 설정
# 물리적 코어의 1 또는 2배수 권장
# 우리 서버는 api 서버들과 함께 돌기 때문에 절반으로 설정
wsrep_slave_thread=7
# SST -> IST를 위한 galera cache 설정
wsrep_provider_options="gcache.size=2G;gcache.recover=yes"
# sync 방식을 rsync -> mariabackup 으로 변경
wsrep_sst_method=mariabackup
- galera cluster 는 데이터를 동기화할 때 실제로는 반동기식으로 작동합니다.
인증
이라는 절차를 통해 우선 데이터들을 PK를 사용해서 확인하고 commit 을 background thread에 요청한 후 다른 MariaDB Server 에 데이터 복제 요청을 합니다.- 따라서 데이터만 확인하여 sync 가 됐다고 판단하고 실제 data flush 는 비동기적으로 이뤄지게 됩니다.
- 또한 이 데이터를 확인할 때에는
first committer wins
이라는 규칙을 따릅니다.- 같은 PK 로 들어온 데이터에 대해 X 락을 설정하면서, 먼저 commit 한 node 의 데이터를 받아들이겠다는 정책입니다.
- 먼저 commit 한 node 의 데이터는 받아들이면서, 나중에 들어온 데이터에 대해서는 deadlock 을 발생시킵니다.
- 만약 PK 를 A.I. 로 사용하고 있다면 Insert 시에는 발생 확률이 낮지만 여전히 Udate, Delete 시 deadlock 발생 확률이 있습니다.
- 이를 회피하고 성능을 위해 IST 방식을 적극적으로 사용해야 합니다..
- 상태 전송 방식
- SST
- 파일 (.idb, .frm) 을 직접 주고 받는 방식입니다.
- 파일을 받아 db 에 적용하는 방식으로 진행합니다.
- 다만 성능을 위해 회사에서는
mariabackup
을 사용하고 있는데,mariabackup
의 경우 GCache 를 적극적으로 사용하며 SST 를 하므로 운용상 유의가 필요합니다.
- 파일 (.idb, .frm) 을 직접 주고 받는 방식입니다.
- IST
- GCache 라는 galera 특유의 cache 에 Write-Set(데이터를 동기화할 때 주고받는 형식)을 저장하면서 동기화를 수행합니다.
- 차후 GCache 에 저장된 ws 에 대해서는 데이터 동기화가 필요한 시점에 local 에 있는 GCache 를 먼저 조회해 변경된 사항이 있는지 판단합니다.
- 변경된 사항이 있다면 파일 자체를 주고 받지 않고, 변경된 데이터에 대해서만 동기화를 진행합니다.
- SST
끝!
'데이터베이스 > MySQL' 카테고리의 다른 글
Galera Cluster 상태 전송에 대한 이해 (0) | 2024.01.10 |
---|---|
Galera Cluster 의 Boostrap 과 구성 파일 이해 (0) | 2023.10.24 |
GTID 와 Galera Cluster (1) | 2023.10.09 |
검색기능 개발 (MySQL Full-Text Index, Search) (0) | 2023.08.03 |
페이징 성능 최적화 - No Offset 은 왜 빠를까? (0) | 2023.06.10 |
Comments