no image
[Server] 로드 밸런싱(Load balancing)
💻로드 밸런싱 로드 밸런싱은 부하분상 또는 컴퓨터 네트워크 기술의 일종으로 중앙처리장치 혹은 저장장치와 같은 컴퓨터 자원들에게 작업을 나누는 것을 의미한다. 로드 밸런싱는 서버에 가해지는 부하를 분산 해주는 장치 또는 기술이다. 운영중인 서비스가 규모가 커지고, 클라이언트의 수가 늘어나면 기존 초기 서버만으로는 정상적으로 운영하는 것이 불가능하다,이런 트래픽이 증가하는것에 대한 해결책은 스케일 아웃과 스케일 업이 있다. 스케일 업과 스케일 아웃에 대해서 간단하게 설명하자면 스케일 업은 서버의 자체 성능을 높이는 것이고 스케일 아웃은 서버의 개수를 늘리는 것이다. 여기서 스케일 아웃은 여러 대의 서버로 트래픽을 균등하게 분산해주는 로드밸런싱이 반드시 필요하다. 💻트래픽을 분산하는 방식 1. 라운드로빈 방식..
2021.11.05
no image
[프로그래머스]타겟 넘버(JAVA)
문제 n개의 음이 아닌 정수가 있습니다. 이 수를 적절히 더하거나 빼서 타겟 넘버를 만들려고 합니다. 예를 들어 [1, 1, 1, 1, 1]로 숫자 3을 만들려면 다음 다섯 방법을 쓸 수 있습니다. -1+1+1+1+1 = 3 +1-1+1+1+1 = 3 +1+1-1+1+1 = 3 +1+1+1-1+1 = 3 +1+1+1+1-1 = 3 사용할 수 있는 숫자가 담긴 배열 numbers, 타겟 넘버 target이 매개변수로 주어질 때 숫자를 적절히 더하고 빼서 타겟 넘버를 만드는 방법의 수를 return 하도록 solution 함수를 작성해주세요. 제한사항 주어지는 숫자의 개수는 2개 이상 20개 이하입니다. 각 숫자는 1 이상 50 이하인 자연수입니다. 타겟 넘버는 1 이상 1000 이하인 자연수입니다. 입출력..
2021.10.25
no image
[AWS]EC2에 JDK 11설치하기
yum에는 설치가능한 JDK가 1.8까지만 존재하기 때문에 JDK 11을 설치하기 위해선 다른 방법을 이용해야 한다. 우선 설치할 수 있는 자바 버전을 보자 $ yum list java*jdk-devel 위처럼 자바 11이 표시되지 않는다. 그래서 설치하는 방법은 아마존에서 제공하는 OpenJDK 인 Amazon Coretto를 받아 설치할 수 있다. # aws coreetto 다운로드 $ sudo curl -L https://corretto.aws/downloads/latest/amazon-corretto-11-x64-linux-jdk.rpm -o jdk11.rpm # jdk11 설치 $ sudo yum localinstall jdk11.rpm # jdk version 선택 $ sudo /usr/sbi..
2021.10.25
Dev
no image
[AWS] EC2 인스턴스 구축하기
운영 서버를 구축할 수 있는 클라우드 서비스에서 대표적인 EC2(Elastic Compute Cloude)를 생성하는 과정에 대해서 정리해보려고 한다. 1) 인스턴스 생성하기 AWS의 가입한 후 , 로그인을 하면 좌측 상단에 서비스를 누르고 EC2를 선택해준다. 그러면 아래 화면처럼 뜰 것이다. 그다음 오른쪽 상단에 인스턴스 시작을 눌러준다. 2) EC2의 운영체제 선택 인스턴스 생성을 누르면 아래 화면처럼 EC2 운영체제를 선택하는 화면이 나온다. 여기서 프리티어를 사용할 수 있는 Amazon Linux를 선택해준다.(CentOs와 내부적으로 동일하기 때문에 CentOs라고 봐도 무방하다.) 3) 인스턴스 유형 선택 인스턴스 유형은 프리티어를 지원하는 t2.micro를 선택하고, 다음: 인스턴스 세부 ..
2021.10.24
no image
[MYSQL]효율적인 트래픽 분산을 위한 Master/Slave 동적 라우팅
사용자가 지속적으로 증가하면 많은 양의 트래픽이 발생한다. 그러므로 하나의 DB서버로 쓰기와 읽기 작업이 모두 진행된다면 쉽게 DB서버에 부하가 발생할 수 있다. 이 문제에 대한 해결책으로 Master Server 이외에도 추가적으로 Replication된 Slave Server를 두고 읽기 작업(read_only)은 Slave Server로 향하게 함으로서 트래픽이 분산되어 DB서버의 부하를 막을수 있다. 또한 Master Server로 단일 서버일 때 부하로 인해 MYSQL서버가 죽어 서비스를 중단시키는 문제를 사전에 방지할 수 있다. 우선 MYSQL Replication에 대해서 먼저 알아보자 ➡️MYSQL Replication MYSQL Replication은 2대 이상의 MYSQL 서버가 동일한..
2021.10.24
no image
[프로그래머스] 튜플(JAVA)
문제 셀수있는 수량의 순서있는 열거 또는 어떤 순서를 따르는 요소들의 모음을 튜플(tuple)이라고 합니다. n개의 요소를 가진 튜플을 n-튜플(n-tuple)이라고 하며, 다음과 같이 표현할 수 있습니다. (a1, a2, a3, ..., an) 튜플은 다음과 같은 성질을 가지고 있습니다. 중복된 원소가 있을 수 있습니다. ex : (2, 3, 1, 2) 원소에 정해진 순서가 있으며, 원소의 순서가 다르면 서로 다른 튜플입니다. ex : (1, 2, 3) ≠ (1, 3, 2) 튜플의 원소 개수는 유한합니다. 원소의 개수가 n개이고, 중복되는 원소가 없는 튜플 (a1, a2, a3, ..., an)이 주어질 때(단, a1, a2, ..., an은 자연수), 이는 다음과 같이 집합 기호 '{', '}'를 이..
2021.10.23
no image
[프로그래머스]자물쇠와 열쇠(JAVA)
문제 문제 설명 고고학자인 "튜브"는 고대 유적지에서 보물과 유적이 가득할 것으로 추정되는 비밀의 문을 발견하였습니다. 그런데 문을 열려고 살펴보니 특이한 형태의 자물쇠로 잠겨 있었고 문 앞에는 특이한 형태의 열쇠와 함께 자물쇠를 푸는 방법에 대해 다음과 같이 설명해 주는 종이가 발견되었습니다. 잠겨있는 자물쇠는 격자 한 칸의 크기가 1 x 1인 N x N 크기의 정사각 격자 형태이고 특이한 모양의 열쇠는 M x M 크기인 정사각 격자 형태로 되어 있습니다. 자물쇠에는 홈이 파여 있고 열쇠 또한 홈과 돌기 부분이 있습니다. 열쇠는 회전과 이동이 가능하며 열쇠의 돌기 부분을 자물쇠의 홈 부분에 딱 맞게 채우면 자물쇠가 열리게 되는 구조입니다. 자물쇠 영역을 벗어난 부분에 있는 열쇠의 홈과 돌기는 자물쇠를 ..
2021.10.22
no image
세션 관리 전략
📂Session Session(세션)이란 일정 시간 동안 같은 브라우저로부터 들어오는 요청을 하나의 상태로 보고 그 상태를 유지하는 기술이다. 사용자가 웹 브라우저를 통해 웹 서버에 요청을 보내면 웹 서버는 사용자의 웹 브라우저를 식별하기 위한 세션을 생성한다. 예를 들어 세션을 통해 사용자의 로그인 정보를 저장해, 사용자가 Cookie를 통해 Session 정보를 보내면 사용자가 로그인한 상태임을 확인하고 서비스를 이용할 수 있다. ➕전략 웹 서버에 과도한 트래픽이 몰리는 경우 성능이 떨어지는 것을 막기 위해 서버를 스케일 아웃을 할 수 있다. 이러한 경우 브라우저의 요청을 처리하는 웹 서버는 여러 대가 되고 로드 밸런서가 사용자의 요청을 각 서버에 할당해 줄 수 있다. 이러한 경우는 사용자의 로그인 ..
2021.10.21
Dev
728x90

https://nesoy.github.io/articles/2018-06/Load-Balancer

💻로드 밸런싱

로드 밸런싱은 부하분상 또는 컴퓨터 네트워크 기술의 일종으로 중앙처리장치 혹은 저장장치와 같은 컴퓨터 자원들에게 작업을 나누는 것을 의미한다.

로드 밸런싱는 서버에 가해지는 부하를 분산 해주는 장치 또는 기술이다.

운영중인 서비스가 규모가 커지고, 클라이언트의 수가 늘어나면 기존 초기 서버만으로는 정상적으로 운영하는 것이 불가능하다,이런 트래픽이 증가하는것에 대한 해결책은 스케일 아웃스케일 업이 있다.

 

스케일 업과 스케일 아웃에 대해서 간단하게 설명하자면 

  • 스케일 업은 서버의 자체 성능을 높이는 것이고
  • 스케일 아웃은 서버의 개수를 늘리는 것이다.

여기서 스케일 아웃은 여러 대의 서버로 트래픽을 균등하게 분산해주는 로드밸런싱이 반드시 필요하다.


💻트래픽을 분산하는 방식 

 

1. 라운드로빈 방식(Round Robin)

  • 서버에 들어온 요청을 순서대로 배정하는 방식이다.  클라이언트의 요청을 순서대로 분배하기 때문에 여러 대의 서버가 동일한 스팩을 갖고 있고, 서버와의 연결이 오래 지속되지 않는 경우에 활용하기 적합하다.

2. 가중 라운드로빈 방식

  • 각각의 서버마다 가중치를 매기고 가중치가 높은 서버에 클라이언트 요청을 우선적으로 배분한다.주로 서버의 트래픽 처리 능력이 상이한 경우 사용되는 부하 분산 방식이다. 만약 A가 3이라는 가중치를 부여 받고 B가 1이라는 가중치를 부여 받으면 각각 3개와 1개의 요청을 처리한다.

 

3. IP 해시 방식

  • 클라이언트의 IP주소를 특정 서버로 매핑하여 요청을 처리하는 방식이다. 사용자의 IP를 해싱해 로드를 분산하기 떄문에 사용자가 항상 통일한 서버로 연결되는 것을 보장한다.

 

4. 최소 연결 방식

  • 요청이 들어온 시점에 가장 적은 연결상태를 보이는 서버에 우선적으로 트래픽을 배분한다. 자주 세션이 길어지거나, 서버에 분배된 트래픽들이 일정하기 않은 경우에 적합한 방식이다.

 

5. 최소 리스폰타임

  • 서버의 현재 연결 상태와 응답시간을 모두 고려하여 트래픽을 배분한다. 가장 적은 연결 상태와 가장 짧은 응답시간을 보이는 서버에 우선적으로 로드를 배분하는 방식이다.

네트워크 통신 시스템은 크게 7가지의  계층으로 나뉜다.  각각의 계층이 L1/L2 ... L7에 해당한다. 상위 계층에서 사용되는 장비는 하위 계층의 장비가 갖고 있는 기능을 모두 가지고 있으며, 상위 계층으로 갈수록 더 정교한 로드밸런싱이 가능하다.

로드밸런싱에는 L4 로드밸런서와 L7 로드밸런서가 가장 많이 활용된다. 왜냐하면 L4 로드밸런서부터 포트정보를 바탕으로 로드 분산하는 것이 가능하기 때문이다.  한 대의 서버에 각기 다른 포트번호를 부여하여 다수의 서버 프로그램을 운영하는 경우라면 최소 L4 로드밸런서 이상을 사용해야만 한다.

 

L7 로드밸런서는 애플리케이션 계층(HTTP,FTP,SMTP)에서 로드를 분산하기 때문에 HTTP헤더, 쿠키등과 같은 사용자의 요청을 기준으로 특정 서버에 트래픽을 분산하는 것이 가능하다.패킷의 내용을 확인하고 그 내용에 따라 로드를 특정 서버에 분배하는 것이 가능한 것이다.

위 그림처럼 URL에 따라 로드를 분산시키거나, HTTP헤더의 쿠키값에 따라 부하를 분산하는 등 클라이언트의 요청을 보다 세분화해서 전달할 수 있다.L7 로드밸런서는 DoS/DDos와 같은 비정상적인 트래픽을 필터링할 수 있어 네트워크 보안 분야에서도 활용된다.

L4 로드밸런서는 네트워크 계층이나 트랜스포트 계층의 정보를 바탕으로 로드를 분산한다.IP주소나 포트 번호 ,MAC 주소 , 전송 프로토콜에 따라 트래픽을 나누는 것이 가능하다.

728x90

'Dev > 인프라' 카테고리의 다른 글

Docker  (1) 2024.09.10
[Server] CI/CD  (0) 2021.11.08
[AWS] EC2 인스턴스 구축하기  (0) 2021.10.24
[Server]운영 서버에 대한 정리  (0) 2021.10.21
서버확장 : 스케일 업(Scale Up) , 스케일 아웃(Scale Out)  (0) 2021.09.30
728x90

 

문제 

n개의 음이 아닌 정수가 있습니다. 이 수를 적절히 더하거나 빼서 타겟 넘버를 만들려고 합니다. 예를 들어 [1, 1, 1, 1, 1]로 숫자 3을 만들려면 다음 다섯 방법을 쓸 수 있습니다.

-1+1+1+1+1 = 3 +1-1+1+1+1 = 3 +1+1-1+1+1 = 3 +1+1+1-1+1 = 3 +1+1+1+1-1 = 3

사용할 수 있는 숫자가 담긴 배열 numbers, 타겟 넘버 target이 매개변수로 주어질 때 숫자를 적절히 더하고 빼서 타겟 넘버를 만드는 방법의 수를 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 주어지는 숫자의 개수는 2개 이상 20개 이하입니다.
  • 각 숫자는 1 이상 50 이하인 자연수입니다.
  • 타겟 넘버는 1 이상 1000 이하인 자연수입니다.

입출력 예

numbers                                                                                                                     target                          return

[1, 1, 1, 1, 1] 3 5

 

풀이

완전탐색을 이용해 모든 경우를 탐색하면 된다.

재귀를 통해 누적합 값을 구해서 타겟값이랑 동일하면 카운트 해주는 방식으로 풀었다.

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
31
32
public class TargetNumber {
    static int answer = 0;
    public int solution(int[] numbers, int target) {
        answer = 0;
        dfs(numbers,target,0,0);
 
        return answer;
    }
 
    public void dfs(int[]numbers,int target,int index,int sum){
        //모든 정수를 탐색 후  누적합이 타겟값과 동일하면 ++해준다.
        if(index == numbers.length){
            if(sum == target)answer++;
                return;
        }
        // 현재 인덱스의 정수를 합해줌   
        sum += numbers[index];
        
        //탐색 
        dfs(numbers,target,index+1,sum);
        
        // 더해준 정수를 다시 빼준다.
        sum -= numbers[index];
        
        //현재 인덱스 정수를 빼준다.
        sum +=(-1* numbers[index]);
        
        //탐색 
        dfs(numbers,target,index+1,sum);
    }
}
 
cs
728x90

[AWS]EC2에 JDK 11설치하기

ryudjae
|2021. 10. 25. 02:05
728x90

yum에는 설치가능한 JDK가 1.8까지만 존재하기 때문에 JDK 11을 설치하기 위해선 다른 방법을 이용해야 한다.

우선 설치할 수 있는 자바 버전을 보자

$ yum list java*jdk-devel

 

위처럼 자바 11이 표시되지 않는다. 그래서 설치하는 방법은 아마존에서 제공하는 OpenJDK 인 Amazon Coretto를 받아 설치할 수 있다.

# aws coreetto 다운로드
$ sudo curl -L https://corretto.aws/downloads/latest/amazon-corretto-11-x64-linux-jdk.rpm -o jdk11.rpm

# jdk11 설치
$ sudo yum localinstall jdk11.rpm

# jdk version 선택
$ sudo /usr/sbin/alternatives --config java

# java 버전 확인
$ java --version

# 다운받은 설치키트 제거
$ rm -rf jdk11.rpm

 이전 버전을 지울려면 

$ yum list installed | grep "java"

로 리스트를 확인하고 

 

$ sudo yum remove 지우고 싶은 버전

을 입력하면 된다.

728x90

'Dev' 카테고리의 다른 글

[Database]트랜잭션 격리 수준(TransactionIsolationLevel)  (0) 2022.01.09
[프로그래밍] 애자일 소프트웨어 개발  (0) 2021.11.13
세션 관리 전략  (0) 2021.10.21
REST API  (0) 2021.10.09
DataBase Engine(데이터 베이스 엔진)  (0) 2021.09.28
728x90

운영 서버를 구축할 수 있는 클라우드 서비스에서 대표적인 EC2(Elastic Compute Cloude)를 생성하는 과정에 대해서 정리해보려고 한다.

 

1) 인스턴스 생성하기

AWS의 가입한 후 , 로그인을 하면 좌측 상단에 서비스를 누르고 EC2를 선택해준다. 그러면 아래 화면처럼 뜰 것이다.

그다음 오른쪽 상단에 인스턴스 시작을 눌러준다.

 

 

2) EC2의 운영체제 선택

인스턴스 생성을 누르면 아래 화면처럼 EC2 운영체제를 선택하는 화면이 나온다. 여기서 프리티어를 사용할 수 있는 Amazon Linux를 선택해준다.(CentOs와 내부적으로 동일하기 때문에 CentOs라고 봐도 무방하다.)

 

 

3) 인스턴스 유형 선택

인스턴스 유형은 프리티어를 지원하는 t2.micro를 선택하고, 다음: 인스턴스 세부 정보 구성을 누른다.

 

4) 인스턴스 세부 정보 구성 

네트워크(VPC), 서브넷에선 디폴트 값을 그대로 사용한다. 다음:스토리지 추가를 누른다.

 

5) 스토리지 추가

스토리지는 로컬 PC의 디스크와 같은 장치를 얘기한다. 프리티어로 30기가까지 사용할 수 있지만 지금 진행 중인 프로젝트에는 30기가까지 필요 없어 기본값인 8기가로 설정해주었다. 나머지는 굳이 설정을 할 필요가 없다.

다음으로 다음: 태그 추가를 눌러준다

 

5) 태그 추가

태그는 인스턴스에 할당하는 키 값을 얘기한다. 인스턴스가 여러 개 있을 경우 이를 태그별로 구분하면 검색이나 그룹 짓기가 편하기 때문에 본인이 알아볼 수 있는 값으로 설정한다.

다음: 보안 그룹 구성

 

6) 보안 그룹 구성 

보안 그룹은 매우 중요하다. 보안 그룹을 잘못 설정하면 타인이 무단으로 접속하면 비용이 과도하게 발생될 수 있다.

SSH(22) 포트는 AWS EC2에 터미널로 접속할 때를 얘기한다. 여기서 주의할 점은 0.0.0.0/0 ,::/0으로 그냥 설정할 경우 외국인들이 비트코인 채굴을 내 서버에서 하는 일이 발생한다. SSH IP 설정은 반드시 내 IP로 본인 집 IP를 설정해준다.

다른 곳에서 할 경우 SSH IP를 추가해주면 된다.

HTTP/HTTPs는 외부에서 이 사이트의 웹서비스 접근할 때 사용하는 유형이기 때문에 80,443 포트를 열어 놓는다.

설정을 완료했으면 검토 및 시작 버튼을 누른다.

 

 

 

7) 검토

자신이 설정한 대로 잘 설정이 됐는지 확인을 해준다. 그다음 완료를 누르면 키 페어를 생성하는 창이 나오는데 새로 원하는 이름으로 생성하여 잘 보관하여야 한다. 인스턴스를 접속할 때 반드시 필요하기 때문이다.

아래 그림처럼 실행되면 정상적으로 생성된 것이다.

 

 

8) Elastic IP(탄력적 IP) 등록

네트워크 및 보안에서 탄력적 IP를 클릭한 후 우측 상단에 탄력적 IP주소 할당을 클릭해 준다.

탄력적 IP를 생성하는 이유는 EC2 인스턴스에 고정 IP가 할당된 상태가 아니라서 , 인스턴스를 재시작할 때마다 새 IP가 할당돼서 도메인 연결을 할 수 없게 된다.

 

아래 그림처럼 화면이 나오면 할당 버튼을 클릭해준다.

다음으로 탄력적 IP주소를 클릭한다.

 

방금 생성한 EC2 인스턴스에 주소를 연결해준다(인스턴스를 클릭하면 아까 생성한 인스턴스가 보일 것이다).

연결을 클릭한 다음 인스턴스에 가서 탄력적 IP가 정상적으로 연결되었는지 확인해준다.

이로서 EC2 인스턴스 생성하는 것은 마무리되었다.

 

 

이제 인스턴스에 접속하는 방법을 알아보자

우선 터미널에 들어가 키 페어를 저장해놓은 디렉토리로 이동한다.

 

 

pem 키페어 파일의 권한을 변경해준다.

$ chmod 600 키페어이름.pem

 

아래 명령어를 입력하여 접속한다.

$ ssh -i 키페어경로/키페어.pem ec2-user@ec2의 퍼블릭 IPv4주소 또는 도메인

 

정상적으로 접속했다면 아래처럼 화면이 나타날 것이다.

 

 

 

그러나 접속하는 명령어 자체가 좀 복잡하고 번거로워 보인다. 

한 번의 설정으로 짧은 명령어로 접속할 수 있도록 해보자.

 

우선 키 페어 pem 파일을 아래 명령어로 복사해준다.

$ cp 키페어.pem ~/.ssh/

 

 

키페어 pem 파일이 복사가 정상적으로 되었는지 확인해보자

$cd ~/.ssh/
$ll

 

정상적으로 복사가 되었다면 아래처럼 디렉터리 내부에 키 페어 파일이 있을 것이다.

복사한 파일도 권한을 변경해준다.

$ chmod 600 키페어이름.pem

 

 

권한을 변경하고 나서 아래 명령어로 접속해서 config파일을 생성 후 작성한다.

 

$ vi ~/.ssh/config
Host 본인 서비스명
    HostName ec2의 탄력적 IP 주소
    User ec2-user
    IdentityFile ~/.ssh/키페어이름.pem

 

생성한 config 파일은 실행 권한이 필요하므로 권한을 설정해준다.

$chmod 700 ~/.ssh/config

 

 

이제 아래 명령어로 바로 접속할 수 있다.

$ssh config에 등록한서비스명

 명령어를 입력하면 아래처럼 인스턴스에 접속이 완료된다.

 

 

 

인스턴스 운영체제 종류에 따라 사용자 이름이 달라지기 때문에 인스턴스 종류를 확인 후 본인이 선택한 운영체제에 맞게 설정하면 된다.

각 Linux 인스턴스는 기본 Linux 시스템 사용자 계정으로 시작됩니다. 기본 사용자 이름은 인스턴스를 시작할 때 지정된 AMI에 의해 결정됩니다.

  • Amazon Linux 2 또는 Amazon Linux AMI의 경우 사용자 이름은 ec2-user입니다.
  • CentOS AMI의 경우 사용자 이름은 centos입니다.
  • Debian AMI의 경우 사용자 이름은 admin입니다.
  • Fedora AMI의 경우 사용자 이름은 ec2-user 또는 fedora입니다.
  • RHEL AMI의 경우 사용자 이름은 ec2-user 또는 root입니다.
  • SUSE AMI의 경우 사용자 이름은 ec2-user 또는 root입니다.
  • Ubuntu AMI의 경우 사용자 이름은 ubuntu입니다.

 


REFERENCE

728x90
728x90

사용자가 지속적으로 증가하면 많은 양의 트래픽이 발생한다. 그러므로 하나의 DB서버로 쓰기와 읽기 작업이 모두 진행된다면 쉽게 DB서버에 부하가 발생할 수 있다.

이 문제에 대한 해결책으로 Master Server 이외에도 추가적으로 Replication된 Slave Server를 두고 읽기 작업(read_only)은 Slave Server로 향하게 함으로서 트래픽이 분산되어 DB서버의 부하를 막을수 있다.

또한 Master Server로 단일 서버일 때 부하로 인해 MYSQL서버가 죽어 서비스를 중단시키는 문제를 사전에 방지할 수 있다.

 

우선 MYSQL Replication에 대해서 먼저 알아보자 


➡️MYSQL Replication

  • MYSQL Replication은 2대 이상의 MYSQL 서버가 동일한 데이터를 담도록 실시간으로 동기화 하는 기술이다.
  • Replication은 INSERT나 DELETE와 같은 쿼리를 사용해 데이터를 변경할 수 있는 서버와 SELECT쿼리로 데이터를 읽기만 할 수 있는 서버로 나뉜다.
  • MYSQL에서는 쓰기와 읽기 역할로 구분해, 쓰기를 master server 읽기를 slave server라고 한다. 
  • MYSQL Replication에서 master server는 반드시 1개이고 slave server는 1개 이상으로 구성될 수 있다.

 

https://blog.seulgi.kim/2015/05/how-mysql-replication.html

 

📁master server

  • MYSQL의 바이너리 로그가 활성화되면 어떤 MYSQL 서버든지 master server가 될수 있다.
  • 애플리케이션 입장에서 보면 master서버는 데이터가 생성,변경,삭제되는 시작점이라고 볼 수 있다.
  • Replication에 참여하는 서버들중에 변경이 허용되는 서버는 Replication되는 데이터의 일관성을 보장하기 위해 master server로 한정되는 경우가 많다.
  • slave server에서 변경된 데이터를 요청하면 master server는 그 바이너리 로그를 읽어 slave server로 넘긴다. 
  • slave server에서 변경된 데이터를 요청하면 데이터를 slave server로 넘기는 역할은 master server 장비중에 dump thread가 전담한다.

📁slave server

  • master server가 바이너리 로그를 가지고 있다면 slave server는 릴레이 로그를 가지고 있다.slave server의 I/O 스레드는 master server에 접속해 변경 내역을 요청하고 받아 온 변경 내역을 릴레이 로그에 기록한다.
  • 데이터를 받아 올 마스터 장비의 정보(IP주소와 포트번호, 접속계정)를 가지고 있는 경우 slave server가 된다.
  • slave server의 SQL 스레드가 릴레이 로그에 기록된 변경 내역을 재실행함으로써 슬레이브의 데이터를 마스터와 동일한 상태로 유지한다.
  • I/O스레드와 SQL스레드는 master server에서는 가동되지 않으며, 복제가 설정된 slave server에서 자동으로 가동하는 스레드이다.

 

💡Replication할때 주의할 점 

  • slave server는 하나의 master server만 설정이 가능하다.
  • 마스터와 Slave Server의 데이터 동기화를 위해 Slave Server는 읽기 전용으로 설정한다.
  • Slave Server용 장비와 마스터와 동일한 사양이 좋다.
    • 여러 개의 스레드로 실행된 쿼리가 Slave Server에서 지연되지 않고 하나의 스레드로 처리될 수 있다.
    • 데이터 변경은 데이터 조회보다는 10프로 수준으로 유지되는것이 일반적이기 때문에 master server와 Slave Server를 같은 사양으로 유지할 때가 많다.
    • Slave Server는  master server가 다운된 경우 그에 대한 복구 대안으로 사용될 때도 많기 때문에 사양을 동일하게 맞추는 경우가 대부분이다.
  • Replication이 불필요한 경우 바이너리 로그를 중지한다.
    • 바이너리 로그를 안정적으로 기록하기 위해 갭 락(Gap lock)을 유지하고, 매번 트랜잭션 이 커밋될 때 마다 데이터를 변경시킨 쿼리 문장을 바이너리 로그에 기록해야 한다. 바이너리 로그를 기록하는 작업은 AutoCommit이 활성화 된 MySQL 서버에서 심각한 부하로 나타날 때가 많다.
  • 바이너이 로그와 트랜잭션 격리 수준 
    • 바이너리 로그 파일릉 어떤 내용이 기록되느냐에 따라 statement 포맷 방식과 row포맷 방식이 있다. row포맷 방식은 master server에서 실행된 쿼리에 의해 코드 값을 기록하는 방식이고, statement 포맷 방식은 바이너리 로그 파일에 master server에서 실행되는 쿼리 문장을 기록하는 방식이다.

 

바이너리 로그 파일에 SQL 문장을 기록하는 방식을 문장 기반 복제 라고 하며, 변경된 레코드를 바이너리 로그에 기록하는 방식을 레코드 기반의 복제라고 한다.

 

문장 기반 복제에는 Mysql Replication시 주의해야할 점이 있다. master server에 쓰기 작업이 일어나고 Slave Server에 복제가 되기 전에 Slave Server에 읽기 요청이 일어난다면, 일관되지 않는 값을 얻게된다. 따라서, SQL 기반의 복제가 정상적으로 작동하려면 REPEATABLE-READ 이상의 트랜잭션 격리 수준을 사용해야 하며, 그로 인해 InnoDB 테이블에서는 레코드 간의 간격을 잠그는 갭락이나 넥스트 키 락이 필요해진다.

 

반면 레코드 기반의 복제는 master  Slave MySQL 서버 간의 네티워크 트레픽을 많이 발생시킬 수 있지만 READ-COMMITTED 트랜잭션 격리 수준에서도 작동할 수 있으며 InnoDB 테이블에서 잠금의 경합은 줄어들게 된다.

REFERENCE

https://junghyungil.tistory.com/177

728x90
728x90

 

문제

셀수있는 수량의 순서있는 열거 또는 어떤 순서를 따르는 요소들의 모음을 튜플(tuple)이라고 합니다. n개의 요소를 가진 튜플을 n-튜플(n-tuple)이라고 하며, 다음과 같이 표현할 수 있습니다.

  • (a1, a2, a3, ..., an)

튜플은 다음과 같은 성질을 가지고 있습니다.

  1. 중복된 원소가 있을 수 있습니다. ex : (2, 3, 1, 2)
  2. 원소에 정해진 순서가 있으며, 원소의 순서가 다르면 서로 다른 튜플입니다. ex : (1, 2, 3) ≠ (1, 3, 2)
  3. 튜플의 원소 개수는 유한합니다.

원소의 개수가 n개이고, 중복되는 원소가 없는 튜플 (a1, a2, a3, ..., an)이 주어질 때(단, a1, a2, ..., an은 자연수), 이는 다음과 같이 집합 기호 '{', '}'를 이용해 표현할 수 있습니다.

  • {{a1}, {a1, a2}, {a1, a2, a3}, {a1, a2, a3, a4}, ... {a1, a2, a3, a4, ..., an}}

예를 들어 튜플이 (2, 1, 3, 4)인 경우 이는

  • {{2}, {2, 1}, {2, 1, 3}, {2, 1, 3, 4}}

와 같이 표현할 수 있습니다. 이때, 집합은 원소의 순서가 바뀌어도 상관없으므로

  • {{2}, {2, 1}, {2, 1, 3}, {2, 1, 3, 4}}
  • {{2, 1, 3, 4}, {2}, {2, 1, 3}, {2, 1}}
  • {{1, 2, 3}, {2, 1}, {1, 2, 4, 3}, {2}}

는 모두 같은 튜플 (2, 1, 3, 4)를 나타냅니다.

특정 튜플을 표현하는 집합이 담긴 문자열 s가 매개변수로 주어질 때, s가 표현하는 튜플을 배열에 담아 return 하도록 solution 함수를 완성해주세요.

[제한사항]

  • s의 길이는 5 이상 1,000,000 이하입니다.
  • s는 숫자와 '{', '}', ',' 로만 이루어져 있습니다.
  • 숫자가 0으로 시작하는 경우는 없습니다.
  • s는 항상 중복되는 원소가 없는 튜플을 올바르게 표현하고 있습니다.
  • s가 표현하는 튜플의 원소는 1 이상 100,000 이하인 자연수입니다.
  • return 하는 배열의 길이가 1 이상 500 이하인 경우만 입력으로 주어집니다.

[입출력 예]

s                                                                                                                                               result

"{{2},{2,1},{2,1,3},{2,1,3,4}}" [2, 1, 3, 4]
"{{1,2,3},{2,1},{1,2,4,3},{2}}" [2, 1, 3, 4]
"{{20,111},{111}}" [111, 20]
"{{123}}" [123]
"{{4,2,3},{3},{2,3,4,1},{2,3}}" [3, 2, 4, 1]

풀이

맨 첫번째,맨 마지막 {}을 2개를 없애준다.(ex ->"2},{2,1},{2,1,3},{2,1,3,4"))

그리고 중간 },{ 을 기준으로 나눠준다. 나눠준 배열을 2차원 배열에다 넣어준다.

그 다음 길이를 기준으로 배열을 정렬해준다.(길이가 작은 순서대로)

2차원 배열에서 값을 꺼내와서 하나씩 나눠준다. 나눠준 다음 list안에 값이 있는지 확인하고 없다면 값을 삽입해준다.

마지막으로 arraylist를 int[]로 변환 해준다.

이미 정렬을 한 상태이기 때문에 튜플에 대한 조건은 만족한다.

 

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
31
32
33
34
35
36
37
38
39
40
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
 
public class Tuple {
    public int[] solution(String s) {
        s = s.substring(2,s.length()-2);  //처음과 마지막 특수기호 없애기 
        String []arr = s.split("\\},\\{");  
        String [][] tup = new String[arr.length][1];
        for(int i = 0; i < tup.length; i++){
            tup[i][0= arr[i];  //기호를 뺀 값을 2차원 배열에 삽입 
        }
 
        Arrays.sort(tup, new Comparator<String[]>() { //길이 정렬
            @Override
            public int compare(String[] o1, String[] o2) {
                if(o1[0].length() < o2[0].length()){
                    return -1;
                }else if(o1[0].length() > o2[0].length()){
                    return 1;
                }else {
                    return 0;
                }
            }
        });
 
        ArrayList<Integer> list = new ArrayList<>();
        for(int i = 0; i < tup.length; i++){
            String[]splitValue = tup[i][0].split(",");  //하나씩 나눈다.
            for(int j = 0; j <  splitValue.length; j++){
                if(!list.contains(Integer.parseInt(splitValue[j]))){  //이미 값이 들어가 있는지 여부 
                    list.add(Integer.parseInt(splitValue[j]));
                }
            }
        }
        int[] answer = list.stream().mapToInt(Integer::intValue).toArray();  //arraylist를 int[]로 변환 
        return answer;
    }
}
 
cs
728x90
728x90

 

 

문제


문제 설명

고고학자인  "튜브"는 고대 유적지에서 보물과 유적이 가득할 것으로 추정되는 비밀의 문을 발견하였습니다. 그런데 문을 열려고 살펴보니 특이한 형태의 자물쇠로 잠겨 있었고 문 앞에는 특이한 형태의 열쇠와 함께 자물쇠를 푸는 방법에 대해 다음과 같이 설명해 주는 종이가 발견되었습니다.

잠겨있는 자물쇠는 격자 한 칸의 크기가  1 x 1  N x N 크기의 정사각 격자 형태이고 특이한 모양의 열쇠는 M x M 크기인 정사각 격자 형태로 되어 있습니다.

자물쇠에는 홈이 파여 있고 열쇠 또한 홈과 돌기 부분이 있습니다. 열쇠는 회전과 이동이 가능하며 열쇠의 돌기 부분을 자물쇠의 홈 부분에 딱 맞게 채우면 자물쇠가 열리게 되는 구조입니다. 자물쇠 영역을 벗어난 부분에 있는 열쇠의 홈과 돌기는 자물쇠를 여는 데 영향을 주지 않지만, 자물쇠 영역 내에서는 열쇠의 돌기 부분과 자물쇠의 홈 부분이 정확히 일치해야 하며 열쇠의 돌기와 자물쇠의 돌기가 만나서는 안됩니다. 또한 자물쇠의 모든 홈을 채워 비어있는 곳이 없어야 자물쇠를 열 수 있습니다.

열쇠를 나타내는 2차원 배열 key와 자물쇠를 나타내는 2차원 배열 lock이 매개변수로 주어질 때, 열쇠로 자물쇠를 열수 있으면 true를, 열 수 없으면 false를 return 하도록 solution 함수를 완성해주세요.

제한사항

  • key는 M x M(3 ≤ M ≤ 20, M은 자연수)크기 2차원 배열입니다.
  • lock은 N x N(3 ≤ N ≤ 20, N은 자연수)크기 2차원 배열입니다.
  • M은 항상 N 이하입니다.
  • key와 lock의 원소는 0 또는 1로 이루어져 있습니다.
    • 0은 홈 부분, 1은 돌기 부분을 나타냅니다.

입출력 예

keylockresult

[[0, 0, 0], [1, 0, 0], [0, 1, 1]] [[1, 1, 1], [1, 1, 0], [1, 0, 1]] true

입출력 예에 대한 설명

key를 시계 방향으로 90도 회전하고, 오른쪽으로 한 칸, 아래로 한 칸 이동하면 lock의 홈 부분을 정확히 모두 채울 수 있습니다.

 

풀이


특정 알고리즘을 사용하지 않고 푸는 문제이다. 원래는 접근을 하고 구현하는데 고생을 하는데 이 문제는 접근부터 엄청 고생을 했다. 결국은 카카오에서 해준 해설을 보았다. 해설에 따르면

  • lock 배열을 확장하고 
  • key를 돌려가면서 
  • key가 lock에 맞는지 확인하는 과정이다.

lock 배열을 확장하는 이유는 키의 일부가 자물쇠의 영역을 벗어나도 키로 자물쇠를 열 수 으면 정답이 된다. 확장은 lock과 key가 겹칠 수 있는 모든 경우를 탐색할 수 있을 정도로 확장을 해줘야한다.그리고 주의할 점은 키의 크기와 자물쇠의 크기는 항상 같지 않다는 조건이다.

 

 우선은 lock 배열을 *3 해주어 확장한 다음 중앙에 기존의 lock값을 삽입한다.  그 다음으로 중앙에 열쇠값을 채워 넣어준다. 만약 중앙에 원래 lock값이 모두 1이라면 열쇠랑 자물쇠랑 딱 맞다는 것이기 때문에 true를 반환한다.

 

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public class LockAndKey {
    public boolean solution(int[][] key, int[][] lock) {
        int n = key.length;
        int m = lock.length;
        int[][] copyLock = new int[m*3][m*3];
 
        //새로만든 기존 lock의 크기 *3의 배열의 중앙에 lock배열 삽입
        for(int i = 0; i < m; i++){
            for (int j = 0; j < m; j++){
                copyLock[i+m][j+m] = lock[i][j];
            }
        }
 
 
        // 0,90,180,270도 방향 확인
        for(int c = 0; c < 4; c++){
            key = rotate(key);
 
            //시작점 탐색용 0,0 부터 n*2,n*2까지
            for (int x =0; x < m*2; x++){
                for(int y = 0; y < m*2; y++){
 
                    //자물쇠에 열쇠끼우기
                    for(int i=0; i < n; i++){
                        for (int j =0; j<n; j++){
                            copyLock[x+i][y+j] += key[i][j];
                        }
                    }
 
                    //모두 일치해서 잘끼워졌다면 모두 1이 되어야한다.
                    if (check(copyLock))return true;
 
 
                    //만약 리턴되지 않으면 맞지 않은것이기 때문에 다시 열쇠를 뺴준다.
                    for (int i = 0; i < n; i++){
                        for (int j = 0; j < n; j++){
                            copyLock[x+i][y+j] -=key[i][j];
                        }
                    }
                }
            }
        }
        return false;
    }
 
 
    //열쇠가 자물쇠에 맞는지 확인하는 로직
    private boolean check(int[][] copyLock) {
        int cnt = 0;
        int len = copyLock.length/3;
        for(int i = len; i < len *2; i++){
            for (int j =len; j<len*2; j++){
                if(copyLock[i][j] == 1)cnt++;
            }
        }
        return cnt == len * len;
    }
 
    //key가 회전하는 로직
    private int[][] rotate(int[][] key) {
        int len = key.length;
        int [][] temp = new int[len][len];
        for(int i = 0; i < len; i++){
            for(int j = 0; j < len; j++){
                temp[i][j] = key[len-j-1][i];
            }
        }
        return temp;
    }
}
 
cs
728x90

세션 관리 전략

ryudjae
|2021. 10. 21. 23:29
728x90

📂Session


Session(세션)이란 일정 시간 동안 같은 브라우저로부터 들어오는 요청을 하나의 상태로 보고 그 상태를 유지하는 기술이다. 사용자가 웹 브라우저를 통해 웹 서버에 요청을 보내면 웹 서버는 사용자의 웹 브라우저를 식별하기 위한 세션을 생성한다.

예를 들어 세션을 통해 사용자의 로그인 정보를 저장해, 사용자가 Cookie를 통해 Session 정보를 보내면 사용자가 로그인한 상태임을 확인하고 서비스를 이용할 수 있다.

 

➕전략


웹 서버에 과도한 트래픽이 몰리는 경우 성능이 떨어지는 것을 막기 위해 서버를 스케일 아웃을 할 수 있다. 이러한 경우 브라우저의 요청을 처리하는 웹 서버는 여러 대가 되고 로드 밸런서가 사용자의 요청을 각 서버에 할당해 줄 수 있다.

이러한 경우는 사용자의 로그인 정보를 일관되게 저장하고 빠르게 응답을 처리하기 위한 세션 관리 전략이 필요하다.

 

🏁Sticky Session

웹 브라우저 요청로드 밸런서를 거치면서 매번 다른 서버에게 할당될 수 있다. 이런 경우 웹서버 별로 별도의 Session Storage를 가지고 있다면 다른 웹서버에 존재하는 웹 브라우저의 세션 정보가 무시될 수 있다.

 

Sticky Session은 이러한 문제점을 해결할 수 있다. 웹 브라우저의 요청을 IP 나 Cookie를 통해서 식별해 특정 서버에서만 처리하게끔 하는 방식이다. 이 방식을 사용하면 사용자의 요청이 여러 서버에서 처리될 수 없으므로 사용자의 세션 정보가 일관되게 유지된다.

 

Sticky Session의 단점은 트래픽이 특정 서버에 할당된 사용자들에게서만 발생된다면, 로드 밸런싱이 균등하게 이루어지지 않는 상황이 되어 분산 서버의 장점을 활용할 수가 없다.

 

 

🏁Session Clustering

 

세션 저장소의 복제

  •  모든 서버끼리 동일한 Session Storage를 갖는 방식이다. 한 Session Storage에서 발생한 변화는 다른 서버의 Session Storage로 복제된다.이 방식을 사용하면 사용자의 요청이 처음 생성한 Session Storage가 아니라 다른 서버로 요청이 보내졌어도 저장소가 복제되어 모든 사용자의 세션 정보를 가지고 있어 세션 불일치 문제는 발생하지 않는다. 그러나 서버의 숫자만큼 Session Storage를 복제시키는데 불필요한 비용이 발생하고 스케일 아웃을 하더라도 비효율적이다. 
  • 많은 메모리가 필요하고 성능 저하도 발생한다.
  • 세션 불일치 문제가 발생할 가능성이 완전 없는 것은 아니다. 세션 데이터의 복제 작업 중에 모두 복제가 되기 전에 요청이 들어가면 시간 차이로 인해 세션 불일치가 생길 수 있다.
  • 새로운 서버를 생성하면 기존에 존재하던 WAS에 새로운 서버 IP/PORT를 입력하여 클러스터링 해줘야 한다. 그러면 기존 서버의 수정이 발생하고 에러가 생길 가능성이 생긴다.

 

🏁Session Storage

 

https://velog.io/@sileeee/세션-불일치-문제-해결방법

독립된 Session Storage

  • Session Storage가 분리되면 서버가 늘어나도 외부 저장소의 정보만 각각의 서버에 입력해주면 데이터를 읽어올 수 있다. 그래서 특정 서버에 트래픽이 몰리는 문제는 발생하지 않고, 대규모 클러스터 환경에서 성능을 향상할 수 있다.
  • 세션이 수정되어도 Session Storage에 있는 데이터만 수정하면 되어 WAS간의 통신이 필요하지 않다.
  • 각 서버와 연결된 독립 저장소를 구성하는 것이다. 여러 대의 서버가 하나의 Session Storage를 공유하기 때문에 데이터 동기화 비용이 발생하지 않는다. 일반적으로 Redis와 Memcached와 같은 In-memory 스토리지를 활용한다.
  • 단점은 Session Storage가 다운되면 세션 정보를 잃어 버릴수 있다. 해결책은 동일한 Session Storage를 하나 더 만들어 구성한다.
728x90

'Dev' 카테고리의 다른 글

[프로그래밍] 애자일 소프트웨어 개발  (0) 2021.11.13
[AWS]EC2에 JDK 11설치하기  (0) 2021.10.25
REST API  (0) 2021.10.09
DataBase Engine(데이터 베이스 엔진)  (0) 2021.09.28
프록시(Proxy)란  (0) 2021.07.26