ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Vitess] Vitess 환경에서 Primary-Replica Replication 구축하기
    Database/Vitess 2023. 4. 10. 06:26
    728x90
    반응형

    - 목차

     

    들어가며.

    최근 들어 Docker 를 활용해서 Vitess Cluster 를 구축하는 방법들에 대한 글들을 작성하고 있습니다.

    이번 글의 주제는 2개 이상의 vttablet 을 실행해서 Primary-Replica 구성을 구축하고, Replication 을 구현입니다.

    아래의 링크의 글을 통해서 1개의 PRIMARY vttablet 을 구축하는 내용을 확인하실 수 있습니다.

     

    https://westlife0615.tistory.com/274

     

    [Vitess] Docker 환경에서 vttablet 실행하기: 단계별 가이드

    - 목차 들어가며.이번 글에서는 1개의 vttablet 을 Docker 를 통해서 실행하는 방법에 대해서 알아보려고 합니다.vttablet 을 실행시키기 위해서 다양한 Vitess 구성 요소가 필요합니다.아래는 필수적으

    westlife0615.tistory.com

     

    MySQL Replication 이란 ?

    MySQLReplication 은 데이터베이스 서버 간 데이터를 동기화하는 핵심 기술로,

    하나의 Primary 서버에서 데이터를 작성하면, 여러 Replica 서버로 해당 변경 사항이 복제됩니다.

    이는 내부적으로 2개의 MySQL 서버가 DML 쿼리의 변경 내용을 공유하는 과정이라고도 볼 수 있습니다.

     

    MySQL 내부에는 흔히 binlog 라고 불리는 파일이 있습니다.

    binlog 파일의 내부에는 Insert, Update, Delete 와 관련된 쿼리들의 기록됩니다.

     

    아주 간단한 예시를 먼저 보여드리겠습니다.

    먼저 MySQL Docker Container 를 실행시킨 이후에 /var/lib/mysql 폴더 내부의 구조를 확인합니다.

     

    docker run -d --name mysql --platform linux/amd64 -e MYSQL_ALLOW_EMPTY_PASSWORD=1 mysql:8.0.23

     

    아래의 이미지처럼 binlog.000001 과 binlog.000002 파일이 존재합니다.

    이 파일이 위에서 말씀드린 DML 쿼리가 기록되는 binlog 파일들이며 쿼리가 늘어날수록 binlog 파일의 갯수도 많아집니다.

     

     

    binlog 내부의 기록은 mysqlbinlog 명령어를 통해서 확인할 수 있습니다.

    간단한 테스트를 위해서 아래의 쿼리들을 실행해보도록 하겠습니다.

     

    CREATE TABLE test_table (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(50) NOT NULL,
        email VARCHAR(100) NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    ) ENGINE=InnoDB;
    
    
    INSERT INTO test_table (name, email) VALUES ('Alice', 'alice@example.com');
    
    UPDATE test_table SET name = 'Andy' WHERE name = 'Alice';
    
    DELETE FROM test_table WHERE name = 'Andy';

     

    그리고 mysqlbinlog 명령어를 통해서 binlog 에 기록된 데이터 변경 사항들을 확인할 수 있습니다.

    mysqlbinlog --base64-output=DECODE-ROWS -vv binlog.000002

     

     

    이렇게 Primary 에 해당하는 MySQL 서버는 binlog 에 데이터의 변경사항을 기록하고, Replica 에 해당하는 MySQL 서버는 Primarybinlog 를 읽어들여 Replication 을 수행하는 구조입니다.

     

    MySQL 의 Replication 은 아래의 링크의 글을 통해서 상세한 내용을 확인하실 수 있습니다.

     

    https://westlife0615.tistory.com/259

     

    MySQL Replication

    소개 * binary log 는 데이터의 변형 사항을 기록하는 로그 파일입니다. Table 에 대한 create, drop, truncate 와 Row 에 대한 insert, update, delete 에 대한 쿼리을 모두 기록합니다. 해당하는 쿼리들은 binary forma

    westlife0615.tistory.com

     

     

    Docker 를 통한 Vitess Cluster 구성하기.

    먼저 Vitess 내부의 Replication 을 구현하기 위해서 먼저 Vitess 구성 요소들을 실행시켜보도록 하겠습니다.

     

    Etcd.

    EtcdVitess Cluster 내부에서 상태 저장소로 사용됩니다.

    어떤 Cell 과 Keyspace 들이 존재하는지, Keyspace 의 Sharding 구성은 어떻게 되는지, Tablet 의 상태는 어떠한지 등에 대한 상태를 저장합니다.

    그리고 여러 Vitess 구성 요소들이 Etcd 를 통해서 Cluster 의 상태를 파악할 수 있습니다.

     

    모든 Vitess 구성 요소들이 "vitess" 네트워크를 사용하도록 하게 위해서 Docker Network 를 생성합니다.

     

    docker network create vitess
    
    docker run --platform linux/amd64 -d --network vitess --name etcd \
    --hostname etcd quay.io/coreos/etcd:v3.5.17 \
    /usr/local/bin/etcd \
    --listen-client-urls=http://0.0.0.0:2379 \
    --advertise-client-urls=http://etcd:2379

     

     

     

    vtctld.

    vtctld 는 Vitess Cluster 에서 API Server 의 역할을 수행합니다.

    vtctldCell, Keyspace, Shard, Tablet 등과 같은 Vitess 의 리소스를 관리 및 처리하는 기능들을 제공합니다.

     

    docker run --platform linux/amd64 -d --network vitess --name vtctld --hostname vtctld vitess/lite:v17.0.7-mysql80 \
    /vt/bin/vtctld \
      --topo_implementation=etcd2 \
      --topo_global_server_address=etcd:2379 \
      --topo_global_root=/vitess/global \
      --logtostderr=true \
      --service_map="grpc-vtctlservice,grpc-vtctl,grpc-vtctld" \
      --port=15000 \
      --grpc_port=15999

     

     

    Cell 생성.

    그리고 Replication 구성을 위해서 2개의 Cell 을 생성합니다.

    zone1, zone2 라는 2개의 Cell 을 생성하고, Primary 와 Replica 가 별도의 Cell 에 위치하도록 해야합니다.

     

    아래의 명령어를 통해서 zone1 과 zone2 Cell 를 생성할 수 있습니다.

     

    docker run --platform linux/amd64 --rm --network vitess vitess/lite:v17.0.7-mysql80 \
    /vt/bin/vtctldclient AddCellInfo --root=/vitess/global --server=vtctld:15999 --server-address=etcd:2379 zone1
    
    docker run --platform linux/amd64 --rm --network vitess vitess/lite:v17.0.7-mysql80 \
    /vt/bin/vtctldclient AddCellInfo --root=/vitess/global --server=vtctld:15999 --server-address=etcd:2379 zone2

     

     

    GetCellInfoNames 명령어를 통해서 생성된 Cell 들을 확인할 수 있습니다.

     

    docker run --platform linux/amd64 --rm --network vitess vitess/lite:v17.0.7-mysql80 \
    /vt/bin/vtctldclient GetCellInfoNames --server=vtctld:15999

     

     

     

    vttablet 생성하기.

     

    Primary 와 Replica 구성을 만들기 위해서 2개의 vttablet 을 실행합니다.

    각 vttablet 의 이름은 zone1-0000000001 와 zone2-0000000002 로 구성하였구요.

    각 Docker Container 를 실행하는 방법은 아래와 같습니다.

     

    vttablet-zone1-0000000001.

    docker run --network vitess --platform linux/amd64 -d \
    --name vttablet-zone1-0000000001 --hostname vttablet-zone1-0000000001 \
    -p 15001:15000 \
    vitess/lite:v17.0.7-mysql80 \
    bash -c '\
    /vt/bin/mysqlctld \
      --tablet_uid=0000000001 \
      --db_charset=utf8mb4 \
      --db_dba_user=root \
      --logtostderr=true \
      --mysql_socket=/vt/vtdataroot/vt_0000000001/mysql.sock \
      --socket_file=/vt/vtdataroot/vt_0000000001/mysqlctl.sock \
      --tablet_uid=0000000001 \
    & \
    /vt/bin/vttablet \
      --db_charset=utf8mb4 \
      --grpc_port=15999 \
      --init_keyspace=test \
      --init_shard=- \
      --init_tablet_type=replica \
      --mysqlctl_socket=/vt/vtdataroot/vt_0000000001/mysqlctl.sock \
      --port=15000 \
      --topo_implementation=etcd2 \
      --topo_global_server_address=etcd:2379 \
      --topo_global_root=/vitess/global \
      --logtostderr=true \
      --tablet-path=zone1-0000000001 \
      --service_map=grpc-queryservice,grpc-tabletmanager,grpc-updatestream'

     

     

    vttablet-zone2-0000000002.

    docker run --network vitess --platform linux/amd64 -d \
    --name vttablet-zone2-0000000002 --hostname vttablet-zone2-0000000002 \
    -p 15002:15000 \
    vitess/lite:v17.0.7-mysql80 \
    bash -c '\
    /vt/bin/mysqlctld \
      --tablet_uid=0000000002 \
      --db_charset=utf8mb4 \
      --db_dba_user=root \
      --logtostderr=true \
      --mysql_socket=/vt/vtdataroot/vt_0000000002/mysql.sock \
      --socket_file=/vt/vtdataroot/vt_0000000002/mysqlctl.sock \
      --tablet_uid=0000000002 \
    & \
    /vt/bin/vttablet \
      --db_charset=utf8mb4 \
      --grpc_port=15999 \
      --init_keyspace=test \
      --init_shard=- \
      --init_tablet_type=replica \
      --mysqlctl_socket=/vt/vtdataroot/vt_0000000002/mysqlctl.sock \
      --port=15000 \
      --topo_implementation=etcd2 \
      --topo_global_server_address=etcd:2379 \
      --topo_global_root=/vitess/global \
      --logtostderr=true \
      --tablet-path=zone2-0000000002 \
      --service_map=grpc-queryservice,grpc-tabletmanager,grpc-updatestream'

     

     

    아래의 사진은 Replica 상태의 vttablet 을 나타냅니다.

    아직까지 Primary vttablet 이 존재하지는 않습니다.

     

     

    GetTablet 명령어는 통해서 Tablet 의 상태를 확인할 수 있습니다.

    아래의 명령어를 실행하여 zone1-0000000001 vttablet 의 상태를 확인해보면

    아래의 결과와 같이 type: 2 인 상태가 확인됩니다. ( type: 2 는 Replica 를 의미합니다. )

     

    docker run --platform linux/amd64 --rm --network vitess vitess/lite:v17.0.7-mysql80 \
    /vt/bin/vtctldclient GetTablet zone1-0000000001 --server=vtctld:15999
    {
      "alias": {
        "cell": "zone1",
        "uid": 1
      },
      "hostname": "vttablet-zone1-0000000001",
      "port_map": {
        "grpc": 15999,
        "vt": 15000
      },
      "keyspace": "test",
      "shard": "-",
      "key_range": {
        "start": "",
        "end": ""
      },
      "type": 2,
      "db_name_override": "",
      "tags": {},
      "mysql_hostname": "vttablet-zone1-0000000001",
      "mysql_port": 3306,
      "primary_term_start_time": null,
      "default_conn_collation": 255
    }

     

     

    PlannedReparentShard 적용하기.

    PlannedReparentShard 명령을 통해서 명시적으로 Replica vttablet 을  Primary 로 승격시킬 수 있습니다.

    저는 zone1-0000000001 vttablet 을 Primary 로 승격시켰고, 자연스레 zone2 의 vttablet 은 Replica 로 구성됩니다.

     

    docker run --platform linux/amd64 --rm --network vitess vitess/lite:v17.0.7-mysql80 \
    /vt/bin/vtctldclient PlannedReparentShard --server=vtctld:15999 test/- --new-primary=zone1-0000000001

     

     

     

    Replication 확인해보기.

    Primary vttablet 에 데이터를 추가하고, Replica vttablet 에서 정상적으로 Replication 이 동작하는지 확인해보도록 하겠습니다.

    Primary vttablet 에 아래의 SQL Query 를 실행해주시면 replication_test Table 과 Record 가 생성됩니다.

     

    CREATE TABLE replication_test (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(50) NOT NULL,
        value INT NOT NULL
    ) ENGINE=InnoDB;
    
    INSERT INTO replication_test (name, value) VALUES ('Test Row 1', 100);

     

     

    그리고 Replica Vttablet 에서 show slave status 상태를 확인해보면 아래와 같이

    Primary Vttablet 의 binlog 를 읽어들여 Replica Vttablet 의 Relay Log 를 생성한 결과 또한 확인할 수 있습니다.

     

    show slave status \G;
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for source to send event
                      Master_Host: vttablet-zone1-0000000001
                      Master_User: vt_repl
                      Master_Port: 3306
                    Connect_Retry: 10
                  Master_Log_File: vt-0000000001-bin.000001
              Read_Master_Log_Pos: 13782
                   Relay_Log_File: vt-0000000002-relay-bin.000002
                    Relay_Log_Pos: 14014
            Relay_Master_Log_File: vt-0000000001-bin.000001

     

     

    반응형
Designed by Tistory.