1. Netbeans 란?

Netbeans는 선 마이크로 시스템즈에서 개발하였고, 현재는 오라클에서 후원하고 있는 오픈소스 IDE 프로젝트입니다.
Java, C, C++, PHP등의 다양한 언어를 위한 통합 개발 환경을 제공합니다.

Windows 10에서 Netbeans 설치를 진행하였고, 웹 서버 개발환경에 초점을 맞추었습니다.

2. Netbeans 다운로드

https://netbeans.apache.org/download/nb113/nb113.html

 

Downloading Apache NetBeans 11.3

Apache NetBeans 11.3 runs on the JDK LTS releases 8 and 11, as well as on JDK 14, i.e., the current JDK release at the time of this NetBeans release.

netbeans.apache.org

위 링크로 이동해서, OS에 맞는 Installer를 설치해줍니다.
저는 Windows 10 x64을 사용하고 있어서 Apache-NetBeans-11.3-bin-windows-x64.exe를 설치했습니다.

3. JDK 설치

2020/04/07 - [IT/JAVA] - [Java] Windows 10 Open-JDK 8 다운로드 및 환경변수 설정

작업하는 용도에 맞는 JDK를 설치하면 됩니다.

4. Netbeans 설치

다운받은 Apache-NetBeans-11.3-bin-windows-x64.exe를 실행시키면 Java EE, HTML5/Javascript, PHP 등 여러가지 통합 개발 환경을 지원하는데, 필요한 개발환경만 설치해주시면 됩니다. 특별한 설정 없이 Next 버튼을 누르면 설치가 완료됩니다.

5. Netbeans UTF-8 설정

C:\Program Files\NetBeans-11.3\netbeans\etc\netbeans.conf

netbeans 설정파일을 열어줍니다. netbeans 설정 파일은 설치경로에 따라서 달라질 수 있습니다.

설정파일을 보면 netbeans_default_options="설정 값..." 옵션을 볼 수 있습니다. 해당 옵션 끝에 밑에 명시된 옵션을 추가해줍니다.

-J-Dfile.encoding=UTF-8

ex

JDK 버전을 변경할 경우 jdk 설치 후 netbeans.conf 파일의 default-jdk 경로를 수정하시면 됩니다.
혹은 각 프로젝트 마다 사용하는 jdk를 변경할 수 있습니다.

6. Tomcat 설치

Netbeans 11은 Tomcat을 직접 설치해주어야 합니다.  사용하고 싶은 Tomcat 버전을 다운로드해줍니다.

저는 Tomcat 8을 설치하도록 하겠습니다.

https://tomcat.apache.org/download-80.cgi

 

Apache Tomcat® - Apache Tomcat 8 Software Downloads

Welcome to the Apache Tomcat® 8.x software download page. This page provides download links for obtaining the latest versions of Tomcat 8.x software, as well as links to the archives of older releases. Unsure which version you need? Specification versions

tomcat.apache.org

7. Tomcat Manager 설정

Tomcat Install Path\conf\tomcat-users.xml을 열어줍니다.

<?xml version="1.0" encoding="UTF-8"?>

...
  <role rolename="manager-gui"/>
  <role rolename="manager-script"/>
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <user username="tomcat" password="" roles="tomcat"/>
  <user username="both" password="" roles="tomcat,role1"/>
  <user username="role1" password="" roles="role1"/>
<!-- Tomcat Manager Setting -->
  <user username="bamdule" password="1234" roles="manager-script,admin,manager-gui"/>
  

...

  위와 같이 설정한 다음 저장 후 창을 닫아줍니다.

8. Netbeans 11 실행 

netbeans 11을 실행하면 오른쪽 아래에 에러 툴팁이 노출될 수 있는데, nb-javac-editor 에러일 경우 install을 눌러 nb-javac-editor를 설치해주세요. 
JDK 경로 확인

프로젝트 우 클릭 > Properties > Build > compile > Manage Java Platforms > Platform Folder 확인

9. Apache Tomcat 연동

Tools > Servers > Add Server > Apache Tomcat or TomEE > Server Location 입력 (ex : D:\apache\apache-tomcat-8.5.43) >  Username과 Password의 Tomcat Manager 정보를 입력한다. > Finish

10. Apache Tomcat 실행

실행이 완료되면 Web Applications 리스트를 확인할 수 있습니다.

이 후에는 작업했던 프로젝트 또는 새로운 프로젝트를 생성하여 테스트하면 됩니다.

 

1. Open JDK 8 다운로드

오라클의 OpenJdk
https://jdk.java.net/java-se-ri/8-MR3

OpenJdk
https://github.com/ojdkbuild/ojdkbuild

위 경로 중 한개를 선택해서 JDK를 설치합니다.

2. JDK 환경변수 등록

  • 내 PC 우 클릭> 속성 > 고급 시스템 설정 > 환경 변수로 이동합니다.
  • 시스템 변수 새로 만들기
  • 변수 이름 : JAVA_HOME, 변수 값 : 다운로드받은 Open-JDK 경로 입력 후 확인버튼 클릭 
    ( ex : E:\java\java-1.8.0-openjdk-1.8.0.252-2.b09 )
  • Path 시스템 변수 편집
  • 새로만들기 > %JAVA_HOME%\bin 입력 > 확인 버튼 클릭
  • 환경 변수창의 확인 버튼을 누른 후 시스템 창을 닫아줍니다.

3. JDK 설치 확인

  • cmd 창을 실행합니다.
    ( 윈도우 키 + R 버튼을 누른 후 실행 창이 뜨면 cmd를 입력하고 확인을 눌러줍니다. )
  • java -version을 입력하고, 버전을 확인합니다.

 

 

'IT > JAVA' 카테고리의 다른 글

[JAVA] jjwt library 사용방법 - JWT(Java Web Token)  (0) 2020.08.11
[JAVA] 배열 설명 및 초기화 방법  (0) 2020.07.09
[Java] 람다(Lambda) 란?  (0) 2020.03.13
[JAVA] Java 란?  (0) 2020.03.03
[JAVA] String 메소드 정리  (0) 2019.12.18

1. 람다 함수(Lambda Function)란?

람다 함수는 함수형 프로그래밍 언어에서 사용되는 개념으로 익명 함수라고도 한다.
Java 8 부터 지원되며, 불필요한 코드를 줄이고 가독성을 향상시키는 것을 목적으로 두고있다.

2. 람다 함수의 특징

  • 메소드의 매개변수로 전달될 수 있고, 변수에 저장될 수 있다.
    즉, 어떤 전달되는 매개변수에 따라서 행위가 결정될 수 있음을 의미한다.
  • 컴파일러 추론에 의지하고 추론이 가능한 코드는 모두 제거해 코드를 간결하게 한다.

3. 람다식 표현

  • 파라미터와 몸체로 구분된다.
  • 파라미터와 몸체 사이에 -> 구분을 추가하여 람다식을 완성시킨다. 
  • 몸체 부분이 단일 행일 경우 중괄호와 return문을 생략할 수 있다.
( 파라미터 ) -> { 몸체 }

4. 익명함수를 람다식으로 변경하기

기존 방법

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Thread!");
            }
        }).start();

람다식

        new Thread(() -> {
            System.out.println("Thread!");
        }).start();

기존의 방식은 Thread 사용 시 Runnable 인터페이스를 익명함수로 구현하였지만, Java 1.8부터 람다 함수을 통해 구현할 수 있게 되었다.

람다 함수를 매개변수로 넘기기 위해서는 메소드의 매개변수가 @FunctionalInterface로 선언된 인터페이스여야한다.
@FunctionalInterface이 선언된 인터페이스를 함수 인터페이스라 불리는데, 조건으로 반드시 추상 메소드 한개만 정의되어 있어야 한다.


그러면 람다식을 매개변수로 저장한 Runnable 인터페이스는 함수형 인터페이스일까?

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

Runnable 인터페이스를 보면 @FunctionalInterface와 한개의 추상메소드가 선언되어 있다.
즉, 함수형 인터페이스 조건에 성립하는 것이다.


5. 함수형 인터페이스

함수형 인터페이스의 조건

  • @FunctionalInterface 어노테이션을 선언해야한다.
  • 추상 메소드가 한개만 선언되어야한다.
  • interface로 선언되어야한다.

이렇게 람다식을 위한 함수형 인터페이스 선언 조건에 대해서 알아보았다. 
하지만 Java의 함수형 프로그래밍에는 큰 단점이 있다.  그것은 함수형 인터페이스 안에 선언된 메소드에 종속되는 람다식 밖에 구현할 수 없다는 점이다. 그래서 매개변수의 타입과 개수, 반환 값의 유무 등을 가진 메소드를 하나의 함수형 인터페이스로 구현할 수 없고, 필요한 동작에 따라서 함수형 인터페이스를 만들어줘야한다.

하지만 자바에서 우리가 사용할만한 함수형 인터페이스를 미리 정의해두었다.

  • Suplier<T>
  • Consumer<T>
  • Function<T,R>
  • Predicate<T>

1). Suplier<T>

매개 변수는 없고, 반환 값이 있는 함수형 인터페이스이다.
추상 메소드 T supplier()를 가진다.

        Supplier<String> supplier = () -> "Hello World!";
        System.out.println(supplier.get());

2). Consumer<T>

객체 T를 매개 변수로 받아서 소비한다. 반환 값은 없다.
추상메소드 void accpet(T t)를 가진다.

        Consumer<String> consumer = (str) -> {
            System.out.println(str);
        };
        
        consumer.accept("Hello World!");

3). Function<T,R>

객체 T를 매개 변수로 받아 처리 후 R로 반환한다.
추상메소드 R apply(T t)를 가진다.

        Function<String, Integer> function = (str) -> {
            return str.length();
        };

        System.out.println(function.apply("Hello World!"));

4). Predicate<T>

객체 T를 매개 변수로 받아 처리 후 Boolean으로 반환한다.
추상메소드 Boolean test(T t)를 가진다.

        Predicate<String> predicate = (String str) -> {
            return "Hello World!".equals(str);
        };

        System.out.println(predicate.test("Hello !!"));

위 코드는 단순 예시이고, 더 다양한 함수형 인터페이스가 제공되고 있다. 자세한 사항은 아래 사이트에서 참고하기 바란다.

https://docs.oracle.com/javase/8/docs/api/index.html?org/w3c/dom/Document.html


6. 메소드 참조(Method Reference)

메소드 참조란 함수형 인터페이스에 람다식이 아닌 일반적으로 사용하는 메소드를 참조시키는 방법이다.

참조 조건으로는 함수형 인터페이스의 매개변수 타입과 개수, 반환형이 참조하려는 메소드와 일치해야 한다.

참조 가능한 메소드는 다음과 같다.

  • 일반 메소드
  • static 메소드
  • 생성자

1) 일반 메소드 ( ClassName::MethodName )

        Consumer<String> consumer = System.out::println;
        consumer.accept("Hello World!!");

위에 선언된 consumer는 void accept(String s) 메소드를 참조할 수 있다 그리고 System.out.println()는 void println(String str)로 선언된 메소드이다. 그래서 consumer는 println 메소드를 :: 연산자를 통해 참조 가능하다.

이를 이용해 다음과 같은 연산도 가능해진다.

        List<String> list = Arrays.asList("red", "orange", "yellow", "green", "blue", "indigo", "purple");
        list.forEach(System.out::println);

forEach 메소드는 Consumer 함수형 인터페이스를 인자로 받고 있다.

//interface Iterable<T>

   default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

2) Static 메소드( ClassName::StaticMethod )

Predicate<Boolean> predicate = Objects::isNull;

3) 생성자 ( ClassName::new )

Supplier<String> supplier = String::new;

 

퀵 정렬이란 찰스 앤터니 리처드 호어가 개발한 정렬 알고리즘이다. 컴퓨터로 가장 많이 구현된 정렬 알고리즘 중 하나 이고, 평균적인 상황에서 최고의 성능을 낸다. 

퀵 정렬의 특징

  • 분할 정복 알고리즘이다.
  • 최악 시간복잡도 O(n²), 평균 시간복잡도 O(n log n) 
  • 퀵정렬은 불안정 정렬에 속하며 다른 원소와의 비교만으로 정렬을 수행하는 비교 정렬이다.

퀵 정렬 알고리즘

리스트에서 적절한 피벗(원소) 하나를 고르고, 피벗 앞에는 피벗보다 작은 값들이 오게 하고, 피벗 뒤에는 피벗보다 큰 값들이 오게 한다. 작업이 완료되면 피벗을 기준으로 두 개의 리스트가 생기는데, 각각 리스트에도 이전에 했던 과정을 재귀적으로 반복해준다. 리스트가 더 이상 나누어지지 않는다면, 재귀반환하면서 여러 개의 정렬된 리스트를 하나의 리스트로 결합해준다.

 

퀵 정렬 시간 복잡도

https://gmlwjd9405.github.io/2018/05/10/algorithm-quick-sort.html

퀵 정렬 소스 (JAVA)

import java.util.Arrays;

public class QuickSort {

/*
 오름차순으로 정렬한 퀵 정렬 예제
*/
    public static void main(String[] args) {
        QuickSort quickSort = new QuickSort();
        Integer arr[] = {5, 1, 8, 4, 0, 9, 2, 3, 7, 6};
        quickSort.quickSort(arr, 0, arr.length - 1);
        
        System.out.println(Arrays.toString(arr));

    }

    public void quickSort(Integer[] arr, int s, int e) { 
            int mid = partition(arr, s, e);
            if (s < mid - 1)
                quickSort(arr, s, mid - 1);
            if(mid < e)
                quickSort(arr, mid, e);
    }

    public int partition(Integer[] arr, int s, int e) {
        int pivot = arr[(s + e) / 2];

        while (s <= e) {
            while(pivot > arr[s]) s++;
            while(pivot < arr[e]) e--;
            
            if(s <= e){
                swap(arr, s, e);
                s++;
                e--;
            }
        }

        return s;
    }

    public void swap(Integer arr[], int s, int e){
        int temp = arr[s];
        arr[s] = arr[e];
        arr[e] = temp;
    }
}

퀵 정렬을 자세히 설명해주는 동영상 (추천!)

https://www.youtube.com/watch?v=7BDzle2n47c

 

MariaDB에 일반로그 및 에러로그를 남기는 설정을 진행하겠습니다.

테스트 환경

OS MariaDB Version
CentOS 7 10.4.12

1. MariaDB 로그 설정 및 저장경로 확인

MariaDB에 로그인 후, 다음과 같은 명령어를 입력해줍니다.

SHOW VARIABLES LIKE '%general%';
>
일반 로그의 파일 명과 일반 로그 활성화 유무를 확인합니다

show variables like 'datadir';
>
mariadb의 저장소를 확인합니다.

일반 로그의 파일 명은 galera03.log입니다. 기본적으로 datadir 경로 아래에 저장되어 있습니다. 하지만 로그 설정이 활성화되어 있지 않기 때문에 로그 파일을 활성화시켜주어야 합니다.


2. general_log 활성화

> set global general_log = ON;
Query OK, 0 rows affected (0.002 sec)

> SHOW VARIABLES LIKE '%general%';

 

general_log가 ON으로 변경된 시점부터 /var/lib/mysql/galera03.log 파일에 로그가 쌓이게 됩니다.

general_log 영구 활성화

# vi /etc/my.cnf
...
[mysqld]
general_log=ON
...

MariaDB 종료 시, general_log는 OFF 상태로 변하게 됩니다. 하지만 위와 같이 설정해 두면 MariaDB 리부팅 해도 general_log ON 상태를 유지합니다. 


3. error.log 설정

# vi /etc/my.cnf

...
[mysqld]
general_log=ON
log-error=/var/lib/mysql/error.log

에러로그 파일의 경로를 지정합니다.

# touch /var/lib/mysql/error.log
# chown mysql:mysql /var/lib/mysql/error.log
# systemctl restart mariadb

error.log 파일을 생성하고 mysql에게 소유권을 부여합니다. 그리고 mariadb를 재시작 해줍니다.

위와 같이 설정했다면 바로 error.log가 쌓이는 것을 볼 수 있습니다. 

1. 트리(Tree)

트리는 정점(Node)와 선분(Branch)을 이용하여 사이클이 이루어지지 않게 구성된 자료구조이다.

 트리의 특징

  • 트리는 계층 모델이다.
  • 트리는 비순환 그래프이다.
  • 노드가 N개인 트리는 항상 N-1개의 간선을 가진다.
  • 순회는 Pre-order, In-order, Post-order로 이루어진다.
  • 트리는 이진트리, 이진 탐색 트리, 균형 트리, 이진 힙 등이 있다.

트리의 용어

  • 루트 노드(root node) : 부모가 없는 노드, 트리는 하나의 루트 노드 만을 가진다.
  • 단말 노드(leaf node) : 자식이 없는 노드
  • 내부(internal) 노드 : 단말 노드가 아닌 노드
  • 간선(edge) : 노드를 연결하는 선
  • 형제(sibling) : 같은 부모를 가지는 노드
  • 조상 노드(ancestors node) : 임의의 노드에서 루트 노드에 이르는 경로상에 있는 노드들 (D의 조상은 B, A이다) 
  • 노드의 크기(size) : 자신을 포함한 모든 자손 노드의 개수
  • 노드의 깊이(depth) : 루트에서 어떤 노드에 도달하기 위해 커쳐야하는 간선 수
  • 노드의 레벨(level) : 트리의 특정 깊이를 가지는 노드의 집합
  • 노드의 차수(degree) : 각 노드에서 뻗어나온 가지의 수 (D의 차수는 2이다.)
  • 트리의 차수(degree of tree) : 트리에서 가장 큰 차수 
  • 트리의 높이(height) : 가장 깊숙히 있는 노드의 깊이 (3)

 


2. 그래프(Graph)

노드와 노드를 연결하는 간선들로 구성된 자료구조

그래프의 특징

  • 그래프틑 네트워크 모델이다.
  • 노드들 사이에 방향/무방향 경로를 가질 수 있다.
  • 그래프틑 순환 혹은 비순환이다.
  • 그래프틑 크게 방향 그래프와 무방향 그래프가있다.

 

그래프의 용어

  • 정점(vertext) : 위치라는 개념
  • 간선(edge) : 정점을 연결하는 선
  • 인접 정점(adjacent vertex) : 간선에 직접 연결된 정점
  • 차수(degree) : 한 정점에 연결된 간선의 수 (주로 무방향 그래프에서 사용)
  • 입력 차수(in-degree) : 한 정점으로 들어오는 간선의 수 (주로 방향그래프에서 사용)
  • 출력 차수(out-degree) : 한 정점에서 나가는 간선의 수(주로 방향그래프에서 사용)
  • 사이클(cycle) : 한 정점에서 출발하여 시작했던 정점으로 돌아오는 경로
  • 가중치 그래프 : 간선마다 가중치 값이 매겨져있는 그래프

그래프의 종류

무방향 그래프(Undirected Graph)

  • 간선을 통해 양방향으로 갈 수 있다.
  • 정점 A와  정점 B를 연결하는 간선은 (A,B), (B,A) 이다.

방향 그래프(Directed Graph)

  • 간선에 방향성이 존재하는 그래프
  • A -> B로 갈 수 있는 간선은 (A, B)로 표시한다. 

가중치 그래프(Weighted Graph)

  • 간선을 이동하는데 비용이나 가중치가 할당된 그래프
  • 네트워크라고도 한다.

 

참조 : https://gmlwjd9405.github.io/2018/08/12/data-structure-tree.html

https://justicehui.github.io/easy-algorithm/2018/03/19/GraphIntro/

1. 배열(Array)

배열은 특정 자료형들이 메모리 공간상에 연속적으로 이루어져 있는 자료구조이다.

배열의 특징

  • 메모리상에 연속적으로 저장되는 특성 때문에, 데이터 접근 속도가 빠르다.
  • 인덱스를 통해 접근하기 때문에 어떤 열에 접근하더라도 접근하는 속도가 같다.
  • 배열의 최대크기를 변경 할 수 없다.
  • 삽입/삭제 시 자료의 이동이 생기기 때문에 오버헤드가 발생한다.

2. 연결리스트(LinkedList)

연결리스트는 여러개의 노드들이 연결된 형태의 자료구조이다. 메모리상에 노드들이 흩어져 있으며, 각각의 노드는 다음 노드에 대한 위치 정보를 저장하고 있다. 

연결리스트의 특징

  • 노드는 자료와 링크로 구성된다.
  • 배열 보다 삽입, 삭제 연산이 빠르다.
  • head와 tail이 존재한다. head는 가장 첫번째 노드를 의미하고, tail은 가장 마지막 노드를 의미한다.
  • 자료 외에 링크를 저장하는 변수가 필요함으로 배열 보다 메모리 효율이 떨어진다.
  • 링크가 중간에 끊어지면 다음 노드를 찾는 것이 어렵다.
  • 단순 연결 리스트, 이중 연결리스트, 환형 연결 리스트가 존재한다.

3. 스택

가장 최근에 저장한 자료를 먼저 꺼내는 LIFO(Last In First Out)방식의 자료 구조이다.

스택의 특징

  • 리스트의 마지막 인덱스에서 삽입과 삭제 연산을 수행한다.
  • 마지막으로 저장된 자료의 인덱스를 저장하며 해당 인덱스를 TOP이라고 부른다.
  • 자료를 저장하는 연산을 PUSH라고 한다.
  • 자료를 꺼내는 연산을 POP이라고 한다.
  • 함수 호출 순서 제어, 인터럽트 처리, 수식계산 등 에서 사용한다.

4. 큐

가장 먼저 저장한 자료를  먼저 꺼내는 FIFO(First In First Out) 방식의 자료구조이다.

큐의 특징

  • 가장 먼저 저장한 자료의 위치를 기억하며 Front라고 부른다.
  • 새로운 자료를 보관할 위치를 기억하며 Rear라고 부른다.
  • 큐에 자료를 보관하는 연산을 Put 혹은 Enqueue라고 부른다.
  • 큐에 자료를 꺼내는 연산을 Get 혹은 Dequeue라고 부른다.
  • 스케줄러, 대기순서에 따라 처리되는 연산 등 에서 사용한다. 

참조 : http://ehpub.co.kr/tag/%EC%8A%A4%ED%83%9D%EC%9D%98-%ED%8A%B9%EC%A7%95/

'IT > 자료구조 & 알고리즘' 카테고리의 다른 글

[알고리즘] 퀵 정렬  (0) 2020.03.08
[자료구조] 트리와 그래프  (0) 2020.03.04
[Java] 쉘 정렬 (Shell Sort)  (0) 2019.12.06
[Java] 버블 정렬 (Bubble Sort)  (0) 2019.12.06
[Java] 삽입 정렬 (Insertion Sort)  (0) 2019.12.06

1. Galera Cluster 란? 

  • 오픈소스이다.
  • 동기 방식의 복제를 지원한다.
  • 노드간 통신을 위해 wsrep API를 사용한다.
  • Active-Active 방식의 다중 Master 구성 및 모든 노드에서 Read/Write가 가능하다.
  • 노드의 추가와 제거가 간단하고, 특정 노드에서 장애가 발생하면 자동으로 해당 노드가 제거된다.
  • InnoDB 만 지원한다.
  • Mysql 및 MariaDB 5.5 이상 버전에서 사용가능하다.
wsrep(Write Set REPlication) 란?
MySQL의 InnoDB 스토리지 엔진 내부에서 Write Set을 추출하고 기능을 구현합니다. 
(Write Set은 트랜잭션을 기록하는 모든 논리적 데이터 집합이다.)

노드간 Write Set을 송수신하기 위해서 별도의 복제 플러그인을 사용하며 wsrep에 정의된 call/callback 함수에 의해 동작하는 모듈입니다.

 

Galera Cluster 구성도

각 노드 마다 wsrep 모듈이 존재합니다. 이 모듈은 데이터베이스 복제를 위한 범용 모듈로 여기에 Galera Replication을 연결해주면 데이터베이스 변경이 있을 때 마다 다른 노드로 데이터를 복사합니다.


2. Galera Cluster 설치

System Information

HostName galera03 galera04 galera05
IP Address 192.168.152.143 192.168.152.144 192.168.152.145
OS CentOS 7 CentOS 7 CentOS 7
MariaDB Version MariaDB 10.4 MariaDB 10.4 MariaDB 10.4

 

MariaDB 설치

root 계정으로 MariaDB yum repo를 설치합니다.

[root@galera03 ~]# curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash

mariaDB 최신버전이 다운되므로 10.4버전이 아닐 수도 있습니다. 
10.4 버전을 받고 싶다면 /etc/yum.repos.d/mariadb.repo를 수정해주세요.

모든 repo에 대한 캐시 빌드

[root@galera03 ~]# yum makecache fast

MariaDB 및 Galera 설치

[root@galera03 ~]# yum install -y mariadb-server galera

3. 방화벽 설정 및 Galera Cluster 설정

Galera Cluster에서 사용하는 포트 설명

프로비저닝 포트

클러스터에서 개별 노드로 데이터를 복제하여 노드를 클러스터와 동기화하는 프로세스를 프로비저닝이라고합니다. 
Galera Cluster에는 노드를 프로비저닝하기 위해 사용할 수 있는 두 가지 방법을 제공합니다.

4444 (SST , State Snapshot Transfer)
새 노드가 클러스터에 참여하면 SST를 실행해 다른 노드와 동기화합니다.

4568 (IST , Incremental State Transfer) 
기준 노드와 비교할 때, 누락된 트랜잭션이 존재하면 동기화합니다.

나머지 포트

4567 (Galera Cluster)
각 노드의 연동 상태를 체크하고, 멀티 캐스트 복제 시, 이 포트에서 UDP 전송과 TCP를 모두 사용합니다.

3306 (Maria DB)
MariaDB 클라이언트 연결 및 상태 스냅 샷 전송

mysql 및 4567,4568,4444 포트 허용하기

[root@galera03 ~]# firewall-cmd --state  (방화벽이 실행되지 않았을 경우 systemctl start firewalld 입력)
running
[root@galera03 ~]# firewall-cmd --permanent --add-service=mysql
success
[root@galera03 ~]# firewall-cmd --permanent --add-port={4567,4568,4444}/tcp
success
[root@galera03 ~]# firewall-cmd --reload
success
[root@galera03 ~]# firewall-cmd --list-all

SELinux를 허용 모드로 설정

[root@galera03 ~]# setenforce 0
[root@galera03 ~]# sestatus

Current mode가 permissive 상태여야 합니다.

(MariaDB 클러스터에 대한 모든 작업이 끝나면 SELinux 정책을 1(강제모드)로 변경해주어야 합니다.)

Galera Cluster 설정

[root@galera03 ~]# vi /etc/my.cnf.d/server.cnf
...
[galera]
# Mandatory settings
wsrep_on=ON
wsrep_provider=/usr/lib64/galera-4/libgalera_smm.so
wsrep_cluster_address=gcomm://192.168.152.143,192.168.152.144,192.168.152.145
binlog_format=row
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
...

위 옵션들을 [galera] 아래에 입력해주고, wsrep_cluster_address에는 모든 노드의 IP를 입력해주세요.

(주의할 점은 galera 버전마다 /usr/lib64/galera-4/libgalera_smm.so 경로가 바뀔 수 있습니다.
실제 해당 파일이 존재하는지 확인 후에 설정해주세요.)

여기까지가 galera cluster의 설치 및 설정입니다. galera03과 같이 나머지 galera04, galera05에도 똑같이 작업해줍니다.


4. galera cluster 실행

galera03에서 다음 명령어를 입력해주세요.

[root@galera03 ~]# galera_new_cluster

galera_new_cluster 명령어는 기준 DB를 설정하는 동시에 mariadb를 실행하는 명령어입니다.

(나머지 node들이 실행되면 기준 DB를 기준으로 복제를 시작합니다.)

galera04, galera05 또한 mariadb를 실행해줍니다.

[root@galera04 ~]# systemctl start mariadb.service
[root@galera05 ~]# systemctl start mariadb.service

실행이 완료되었다면 각 노드 마다 Mariadb 비밀번호를 변경해줍니다.

[root@galera03 ~]# /usr/bin/mysqladmin -u root password '변경할 비밀번호 입력'

Mariadb root 계정으로 로그인합니다.

[root@galera03 ~]# mysql -u root -p 
Enter password: 설정한 비밀번호 입력

5. galera 연동 확인

> show global status like 'wsrep_cluster_size';

노드가 모두 연동되었다면 Value에 3이 출력되야합니다.

각 노드에서 위 명령어를 입력해 연동되었는지 확인해주세요.

wsrep 정보를 보고싶다면 다음 명령어를 입력해주세요.

> show status like 'wsrep_%';

여기서 유심히 봐야할 속성은  wsrep_local_state_uuid 속성입니다. 각 노드마다 해당 속성 값이 같은지 확인해주세요.


6. DB 생성 및 테이블 생성

Galera Cluster는 모든 노드가 Read/Write를 지원하기 때문에 기준 노드가 아닌 galera04노드에서 DB생성 및 테이블 생성이 진행되어도 다른 노드에 복제가 이루어집니다.

[ galera04 Node ]

> create database test_db;

Query OK, 1 row affected (0.005 sec)
> use test_db;
Database changed
> create table test_tb ( id int primary key );
Query OK, 0 rows affected (0.021 sec)
> insert into test_tb values(1);
Query OK, 1 row affected (0.020 sec)

위 명령어 실행 후 galera03, galera05에서 각각 test_db, test_tb가 생성되었는지 확인하고 test_tb에 데이터 복제가 되었는지 확인해주세요.

galera03, galera05에서 test_tb를 조회


7. galera cluster 복구 시나리오

1) MariaDB 데몬이 모두 죽었을 경우

SELINUX 허용 설정

setenforce 0

모든 노드의 /var/lib/mysql/grastate.dat 파일을 열어서 safe_to_bootstrap 속성이 1인 값을 찾습니다. 

# vi /var/lib/mysql/grastate.dat

# GALERA saved state version: 2.1
uuid: 2e39d6a4-5df7-11ea-a29f-e38a9ebb7084
seqno: 115
safe_to_bootstrap: 1

safe_to_bootstrap 값이 1인 경우 마지막으로 죽은 노드를 의미하기 때문에 해당 기준 노드로 실행합니다.

galera_new_cluster

실행이 완료 되면 나머지 노드도 실행해줍니다.

systemctl start mariadb

여기까지 완료되었다면 모든 노드에서 MariaDB 로그인 후 연결된 노드 개수가 맞는지 확인합니다.

> show global status like 'wsrep_cluster_size';

각 노드에서 위 명령어 입력 시, 예상했던 노드 개수와 일치하지 않다면, 해당 노드는 동기화 상태가 아닐 확률이 높습니다. 이때, 사용하고 있는 DB의 테이블을 SELECT 해봅니다. 

WSREP has not yet prepared node for application use

위와 같은 오류가 발생하면 동기화 상태가 아니므로 WSREP의 pc.bootstrap 옵션을 YES로 바꾸어주어야 합니다.

> SET GLOBAL wsrep_provider_options='pc.bootstrap=YES';
Query OK, 0 rows affected (0.000 sec)

위 옵션을 적용하고 나서 MariaDB를 옵션을 적용한 노드를 재시작해주어야 합니다.
재시작 후에 test_tb가 잘 조회되는지 확인해주고
show global status like 'wsrep_cluster_size'; 명령어를 입력하여 클러스터 사이즈가 3인지 확인해줍니다.

모든 복구가 완료되면 setenforce 1 명령어를 실행해줍니다.


8. gelera Cluster Test

테스트 환경 

HostName galera03 galera04 galera05
IP Address 192.168.152.143 192.168.152.144 192.168.152.145
OS CentOS 7 CentOS 7 CentOS 7
MariaDB Version MariaDB 10.4 MariaDB 10.4 MariaDB 10.4

 

테스트 설명

Case 1
로그 데이터 10만건 삽입 테스트  

Case 2
새로운 노드 추가 및 동기화 테스트

 

Case 1 - 로그 데이터 10만건 삽입 테스트 

테스트 방법

  • Java에서 Galera Cluster로 이중화된 galera03, galera04을 JDBC를 이용해 연결한다.
  • Galera Cluster에 로그 데이터 10만 건을 삽입한다.

JDBC 연결 URL

jdbc:mariadb:loadbalance://192.168.152.143:3306,192.168.152.144:3306/test_galera

테스트 결과

  • 로그 데이터 10만건 삽입하는데 13분정도 소요되며,  galera03, galera04 동기화 속도가 매우 빠름
  • 로그 삽입 시, 각 노드에 데이터 부하 분산이 골고루 이루어짐

Case 2 - 새로운 노드 추가 및 동기화 테스트 

테스트 내용

  • 기존에 동작하던 galera cluster에 새로운 노드 galera05(192.168.152.145)를 추가해준다. 
  • 데이터 동기화 속도를 측정한다.

테스트 결과

  • 새로운 노드를 galera cluster에 추가 시 모든 데이터베이스, 테이블, 레코드가 복제되며, 이전 테스트에서 삽입한 10만건의 로그데이터가 복제되는데 약 2~5초 정도 소요된다.  

참조 : https://bcho.tistory.com/1062

https://www.centlinux.com/2019/02/install-mariadb-galera-cluster-on-centos-7.html

+ Recent posts