2021년 2월 14일 일요일

Apache Kafka - 카프카 특징


1. 확장성

분산시스템 적용에 용이하여 부하분산에 유동적이다.

예를 들어 서버 1대당 1000개의 메세지를 1초당 처리할 수 있는 3대의 서버로 구성된 클러스터가 있다. 

총 메세지 가용량은 3000/1s 인데 메세지가 늘어 4000개 메세지를 처리해야 할 때, 클러스터 내 브로커 수 1대만 늘리면 되므로 간단하게 문제를 처리 할 수 있다.



2. 페이지 캐시

리눅스커널은 자주쓰는 데이터의 I/O성능향상을 위해 페이지캐시를 사용하는데, 물리적메모리에 읽고쓰기 작업을 하지 않고 캐시메모리를 통해 이 작업을 수행한다. 

카프카는 빠른 엑세스를 위해 이러한 페이지캐시를 이용하게끔 되어있다. 


Java Heap할당과도 연관이 있는데 Memory가 8GB인 서버에 모든 메모리를 Heap메모리(또는 다른 어플리케이션에 점유된 메모리)에 할당하지 말고 적당량을 남겨 페이지캐시로 사용하여야 한다.  

vi /usr/local/kafka/bin/kafka-server.start.sh

KAFKA_HEAP_OPTS="-Xmx6G -Xms6G    #자바 힙메모리 설정값



3. 배치전송














전송시 I/O 작업이 빈번하면 네트워크 오버헤드가 발생하고 시간도 더 걸리므로

데이터를 묶음으로 보낼 수 있는 기능을 제공한다.


 

2021년 2월 2일 화요일

[ 쿠버네티스 ] 튜토리얼 따라하기1

 



minikube

minikube는 쿠버네티스를 로컬에서 실행할 수 있는 도구이다.

개인용컴퓨터에서 단일 노드 쿠버네티스 클러스터를 실행하여 예제 또는 단순개발작업을 수행 할 수 있다.


쿠버네티스 doc페이지에선 온라인 vm클러스터를 제공해 간단한 예제를 테스트할 수 있는 대화형 튜토리얼 환경을 제공하고 있다.

https://kubernetes.io/ko/docs/tutorials/kubernetes-basics/create-cluster/cluster-interactive/


해당 튜토리얼에서는 아래와 같은 그림의 작업을 수행한다.












1. 클러스터 생성하기

위의 URL에 들어가보면 ubuntu-18.04.4 리눅스 환경에 minikube를 미리 설치한 터미널로 테스트 할 수 있다. 

minikube 설치 참조 : https://minikube.sigs.k8s.io/docs/start/


[ minikube 명령어 ]

minikube version : minikube 버전확인

minikube start : 쿠버네티스 클러스터를 minikube를 통해 실행 


[ kubectl 명령어 ]

쿠버네티스 커맨드 라인도구인 kubectl을 사용하면 쿠버네스트 클러스터에 대한 명령(애플리케이션 배포, 리소스검사/관리, 로그 등)을 실행 할 수 있다. 이 또한 대화형 터미널에 이미 설치 되어있다.

kubectl 설치 참조 : https://kubernetes.io/ko/docs/tasks/tools/install-kubectl/


kubectl version : client와 server 2가지 버전이 나오는데, client버전은 사용하고 있는 kubectl버전을 가리키고, server버전은 master노드에 설치된 kubectl 버전을 가리킨다. master노드 개념은, 쿠버네티스는 마스터노드와 워커노드로 구분되는데 마스터 노드가 워커노드들을 컨트롤 한다 정도로 알자.


kubectl cluster-info : 클러스터 상세정보 

Kubernetes master is running at https://172.17.0.30:8443

KubeDNS is running at https://172.17.0.30:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy


kubectl get nodes : 애플리케이션을 사용할 수 있는 노드들의 정보

NAME       STATUS     ROLES    AGE   VERSION

minikube   NotReady   master   10s   v1.17.3




2. 앱배포하기


Deployment

클러스터를 실행하면, 그 위에 컨테이너화된 애플리케이션을 배포 할 수 있다. 이를 디플로이먼트를 통해 실행하며 이후 마스터가 개별 노드에 실행되도록 스케줄 한다. 

또한 디플로이먼트 컨트롤러가 애플리케이션 인스턴스들을 지속적으로 모니터링하여 장애시 다른 노드의 인스턴스로 교체한다.













[ kubectl 명령어 ]


kubectl create deployment 이름 --image=다운로드 이미지위치

디플로이먼트를 생성한다. 아래 명령어로 쿠버네티스 튜토리얼에서 제공하는 샘플 디플로이먼트를 생성한다.

kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1


kebectl get deployments : 디플로이먼트 리스트 확인

NAME                  READY   UP-TO-DATE   AVAILABLE   AGE

kubernetes-bootcamp   1/1     1            1           6s


kubectl proxy : 클러스터 개인의 네트워크로 전달하는 프록시를 만든다. 프록시는 control-c를 눌러 종료하며, 실행 중 출력이 표시된지 않는다.




3. 앱조사하기


파드








파드는 하나 이상의 애플리케이션의 그룹으로 쿠버네티스의 추상적인 개념이다. 2.앱배포하기에서 디플로이먼트를 통해 애플리케이션을 생성했다. 이때 애플리케이션 인스턴스에 파드는 자동생성된다. 

파트는 쿠버네티스 플랫폼 상에서 최소단위이며, 각 파드는 스케쥴 되어진 노드로 묶인다. 노드가 소멸되거나 삭제되기 전까지 그 노드에 유지된다.

같은 파드내 애플리케이션은 아래와 같은 리소스를 공유한다.

  • 같은 공유 스토리지 볼륨
  • 클러스터 IP와 네트워킹, 포트
  • 컨테이너 이미지, 각 컨테이너가 동작하는 방식에 대한 정보



노드













노드는 파드를 담고있으며, 같은 말로 파드는 언제나 노드 안에서 동작한다. 하나의 노드는 여러 개의 파드를 가질 수 있고, 이러한 노드는 마스터에 의해 관리된다. 쿠버네티스 마스터는 클러스터 내 노드를 통해서 파드에 대한 스켈쥴링을 자동처리한다.

마스터 -> 노드 -> 파드





https://kubernetes.io/ko/docs/tutorials/

2021년 2월 1일 월요일

[ Algorithm ] 같은 숫자는 싫어


문제 ]

배열 arr가 주어집니다. 배열 arr의 각 원소는 숫자 0부터 9까지로 이루어져 있습니다. 이때, 배열 arr에서 연속적으로 나타나는 숫자는 하나만 남기고 전부 제거하려고 합니다. 배열 arr에서 제거 되고 남은 수들을 return 하는 solution 함수를 완성해 주세요. 단, 제거된 후 남은 수들을 반환할 때는 배열 arr의 원소들의 순서를 유지해야 합니다.



제한사항

배열 arr의 크기 : 1,000,000 이하의 자연수

배열 arr의 원소의 크기 : 0보다 크거나 같고 9보다 작거나 같은 정수


입출력 예

arr                 answer

[1,1,3,3,0,1,1] [1,3,0,1]

[4,4,4,3,3]         [4,3]





풀이 ]

public class Solution {

    public int[] solution(int []arr) {

        ArrayList<Integer> tempList = new ArrayList<Integer>();

        int preNum = 10;

        for(int num : arr) {

            if(preNum != num)

                tempList.add(num);           

            preNum = num;

            

        }    


        int[] answer = new int[tempList.size()];

        for(int i=0; i<answer.length; i++) {

            answer[i] = tempList.get(i).intValue();

        }

        return answer;

    }

}

2021년 1월 17일 일요일

Hive [10] - 날짜관련 함수

 

1. 날짜포맷 변환


from_unixtime(bigint unixtime, string format)

return값 : string


unix타임스탬프 값을 정해진 날짜형식에 맞추어 출력한다.

- select from_unixtime(1323308938, 'yyyy-MM-dd') from dual;


20210101포맷을 2021-01-01포맷으로 날짜형식변환도 가능하다.

- select from_unixtime(unix_timestamp('20210101, 'yyyyMMdd'), 'yyyy-MM-dd') from dual;



2. 특정 값 가져오기


날짜 부분만 리턴

select to_date('2021-01-13 10:11:34') from dual;

-> 2021-01-13


연도 부분만 리턴

select year('2021-01-13 10:11:34') from dual;

-> 2021


월 부분만 리턴

select month('2021-01-13 10:11:34') from dual;

-> 1


일 부분만 리턴

select day('2021-01-13 10:11:34') from dual;

-> 13


시간 부분만 리턴

select hour('2021-01-13 10:11:34') from dual;

-> 10


분 부분만 리턴

select minute('2021-01-13 10:11:34') from dual;

-> 11


초 부분만 리턴

select second('2021-01-13 10:11:34') from dual;

-> 34


날짜의 현재 주 수 리턴

select weekofyear('2021-01-13 10:11:34') from dual;

-> 2



3. 날짜 계산 함수

* yyyy-MM-dd 형식으로 입력


날짜비교 함수 

datediff(string enddate, string startdate)

return : int

ex ] select datediff('2021-01-23','2021-01-15')

-> 7


날짜 증가 함수 

date_add(stringdate, int days)

return : string 

ex ] select date_add('2021-01-23',20)

->2021-02-12


날짜 감소 함수 

date_sub(stringdate, int days)

return : string 

ex ] select date_add('2021-01-23',10)

->2021-01-13












from_unixtime(unix_timestamp('20140228' ,'yyyyMMdd'), 'yyyy-MM-dd')

[ Algorithm ] 가운데 글자 가져오기


문제 ] 

단어 s의 가운데 글자를 반환하는 함수. 단어의 길이가 짝수라면 가운데 두글자를 반환하면 됩니다.

sreturn
abcdec
qwerwe



제출 ]

class Solution {

    public String solution(String s) {

        int len = s.length();

        int idx = len / 2;

        return (len%2==0) ? s.substring(idx-1, idx+1) : s.substring(idx, idx+1);

    }

}



풀이 ]

substring 함수를 이용하여 글자의 길이가 홀수면 한글자, 짝수면 두 글자를 반환.

substring대신에 String.split("") 함수를 이용해 String을 Array로 형변환 하여 진행 할 수 도 있다. 


2021년 1월 15일 금요일

[ Algorithm ] 3진법 뒤집기


문제 ]

자연수 n이 매개변수로 주어진다. n을 3진법 상에서 앞뒤로 뒤집은 후, 이를 다시 10진법으로 표현한다. 

n (10진법)n (3진법)앞뒤 반전(3진법)10진법으로 표현
45120000217

따라서 7을 return해야 한다.



제출 ]

class Solution {

    public int solution(int n) {

        StringBuffer sb = new StringBuffer();

        StringBuilder stringBuilder = new StringBuilder();

        

        // 10진법을 3진법

        while( n != 0) {

            sb.append(n % 3);

            n = n / 3;

        }

        

        // 3진법을 10진법으로

        int answer = Integer.parseInt(sb.toString(), 3);

        return answer;

    }

}




풀이 ]


1. 10진법을 3진법으로 변환

2. 3진법 뒤집기

3. 뒤집은 값을 10진법으로 다시표현


[ 1. 10진법을 3진법으로 변환하는 방법 ]

N = 45라고 하면


45 / 3 = 15  ,  45 % 3 = 0 

15 / 3 = 5  , 15 % 3 = 0

5 / 3 = 1 , 5 % 3 = 2

1 / 3 = 0 , 1 % 3 = 1  


십진법 45는 3진법으로 1200이 된다.

즉 N / 3 = 0 이 될때까지 나머지를 구하도록 while문으로 구현한다.



[ 2. 3진법 뒤집기 ]

StringBuffer 클래스는 사용하여 자동적으로 값이 뒤집어지게 한다.

해당 클레스와 관련된 내용을 적자면,


String과 StringBuffer or StringBuilder의 차이 

String은 불변의 속성때문에 새로운 값을 할당할 때마다 새로운 주소를 할당한다. 그에 따른 메모리와 많은 임시가비지가 생성되므로 수정이 많은 작업이면 StringBuffer or StringBuilder와 같은 클래스들을 쓰는게 좋다. 

StringBuffer or StringBuilder는 주소 값을 변경하지 않고 새로운 값을 추가한다. 이 둘의 차이점은 동기화 지원유무이다. 

  • StringBuilder는 여러 쓰레드가 동시에 접근이 가능하능 
  • StringBuffer는 멀티쓰레드 환경에서 데이터변경을 허용하지 않아 비동기 작업에 적합
  • 단일 쓰레드는 StringBuilder보다 StringBuffer가 더 뛰어남


[ StringBuffer와 StringBuilder 테스트 ]

class Solution {
    public int solution(int n) {
        StringBuffer stringBuffer = new StringBuffer();
        StringBuilder stringBuilder = new StringBuilder();

        new Thread(() -> {
            for(int i=0; i<100000; i++) {
                stringBuffer.append(i);
                stringBuilder.append(i);
            }
        }).start();

        new Thread(() -> {
            for(int i=0; i<100000; i++) {
                stringBuffer.append(i);
                stringBuilder.append(i);
            }
        }).start();

        new Thread(() -> {
            try {
                Thread.sleep(5000);

                System.out.println("StringBuffer.length: "+ stringBuffer.length());
                System.out.println("StringBuilder.length: "+ stringBuilder.length());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

    }
}


출력 StringBuffer.length: 977780
StringBuilder.length: 959296


결과 값을 보면, 쓰레드 동기화여부에 따라 데이터크기에 차이가 난다는 것을 볼 수 있다. 



[ 3. 뒤집은 값을 10진법으로 다시표현 ]

Integer객체의 parseInt 함수는 

parseInt(String s, int radix) - return int

두번째 인자를 통해 N진법 String을 10진번 Int형으로 값을 반환 받는다.



2021년 1월 13일 수요일

Hive [9] - Sqoop으로 Hive Table Input시, 구분자 설정

 

Sqoop으로 RDB 데이터를 입력받을 시 Column의 Text데이터가 "안녕하세요, 저는 어쩌고, ..." 와 같은 ','가 포함되었다면 구분자를 변경해야 한다. ( Default ',' )

아래 설정은 \t (탭)으로 구분자를 설정하며 Oozie XML -> Sqoop -> Hive Table에 넣는 과정을 담는다.


[ Oozie XML ]

아래 설정을 추가 한다.

<arg>--fields-terminated-by</arg>

<arg>"\t"</arg>



[ Hive Table Create ]

생성시 Delimited fields를 정의한다. ( 또는 업데이트 )

CREATE TABLE temp.table_temp

(

    id BIGINT,

    name VARCHAR(30),

    pay DECIMAL(10,2)

    tag VARCHAR(200)

)

ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'

STORED AS TEXTFILE;



Hive Table 결과 조회