https://leetcode.com/problems/palindrome-number/

 

 

주어진 숫자가 팰린드롬을 충족하는지 확인한다.

직관적으로, 두 개의 포인터를 생성하여 비교하는 방법을 이용할 수 있겠다.

첫번째 포인터는 왼쪽에서부터 오른쪽으로,

두번째 포인터는 오른쪽에서 왼쪽으로 순회한다.

그리고 그 포인터가 가리키는 값이 다르면 곧바로 False 를 출력한다.

음수는 minus 부호 때문에 팰린드롬을 충족하지 않는다.

따라서 곧바로 False 출력한다.

 

 

class Solution:
    def isPalindrome(self, x: int) -> bool:
        if x<0 : return False
        x = str(x)
        mid = int(len(x)/2)
        for i in range(0,mid):
            l = x[i]
            r = x[-i-1]
            if l!=r: return False
        return True

 

 

이 방법 외에, 숫자값을 뒤집은 새로운 숫자를 만들어서 비교하는 방법도 있겠다.

 

class Solution:
    def isPalindrome(self, x: int) -> bool:
        if x<0 : return False
        a = str(x)
        b = a[::-1]
        return a==b

 

 

 

 


 

< English (feedback by ChatGPT) >

 

 

 

Task is to check if the given number is satisfied Palindrome or not.

(The task is to check whether the given number is a palindrome.)

 

Intuitionally, we can use two pointers to compare.

(Intuitively, we can use two pointers to compare the digits.)

 

First pointer iterates from left to right

(The first pointer iterates from left to right,)

 

Second pointer iterates from right to left.

(and the second pointer iterates from right to left.)

 

And return False when the two pointer's values are not matched.

(If the values pointed to by the two pointers do not match, we immediately return False.)

 

Minus number has '-' mark so it can't be Palindrome.

(Negative numbers are not palindromes because of the minus sign (-),)

 

So return False.

(so we can return False right away.)

 

Another solution is to compare a new reverse number of the given number.

(Alternatively, we can reverse the number and compare it with the original.)








 

 

 

 

 

https://leetcode.com/problems/two-sum/

 

 

list와 숫자 하나(target)가 주어진다.

list 내에는 숫자 두 개를 더해서 target 이 만들어지는 쌍이 무조건 존재한다.

이 쌍의 index 를 찾아내어 출력하면 된다.

 

간단하게 생각하면, for문을 두 번 돌아 쉽게 해결할 수 있다.

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        for l in range(0,len(nums)-1):
            for r in range(l+1, len(nums)):
                if(nums[l]+nums[r]==target):
                    return [l,r]

 

이렇게 제출 할 경우, time complexity (time big O) 는 O(n2)

이보다 더 효율적인 방법으로 문제를 해결할 수 있다.

 

list 는 정렬된 상태로 주어진 게 아니기 때문에,

list 를 순회하는 것은 피할 수 없다.

list 를 순회할 때 나머지 쌍을 이루는 숫자는 정해져있다.

바로, target - list[i]

즉, list 에 list[i] 와 target-list[i] 가 둘 다 존재하는지 확인하고, 존재하면 그 둘의 index 를 출력하면 된다.

(이 때 둘의 index 는 동일하면 안 된다)

list 에서 특정 값을 검색하는 작업도 O(n) 시간이 들기 때문에,

list 값과 index 를 미리 hashing 한 dictionary 를 사용하여 O(1) 으로 빠르게 검색한다.

 

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        d = {}
        for i in range(0, len(nums)):
            d[nums[i]] = i
        for i in range(0, len(nums)):
            if( (target-nums[i]) in d and d[target-nums[i]]!=i ):
                return [i, d[target-nums[i]]]

 

 

 

 

 


< English (feedback by ChatGPT) >

 

One list and one integer(target) are given.

(A list and a single integer (target) are given.)

 

There must be a pair of integers in the list which sum to 'target'.

(There is guaranteed to be a pair of numbers in the list whose sum equals the target.)

 

We need to find the two indexes of the pair.

(Our task is to find and return the indexes of the two numbers.)

 

Simply we can use double for loops to solve this problem.

(We can simply solve this problem by using two nested for-loops.)

 

But in this case, the time complexity is O(n^2) and we can do better than this.

(However, in that case, the time complexity would be O(n²), and we can find a more efficient solution.)

 

List is given not being sorted. So it's inevitable to iterate through the list.

(The list is not sorted when given, so iterating through it is unavoidable.)

 

During the iteration, a rest integer of the pair is already set, and it is 'target - list[i]'

(During iteration, the other number needed to complete the pair is determined — it is target - list[i].)

 

It means, we can check if 'list[i]' and 'target-list[i]' exist in the list and return the pair's indexes.

(In other words, we need to check whether both list[i] and target - list[i] exist in the list, and if they do, return their indexes.)

 

shouln't be correspond with each indexes

(The two indexes must not be the same.)

 

It takes O(n) time to search an element in list.

(Since searching for an element in a list takes O(n) time,)

 

Instead, we can use dictionary with list values and it's index to search fast by hashing with O(1) time.

(we can instead use a dictionary that maps each list value to its index, allowing for O(1) time lookup via hashing.)

 

 

git add 를 실행한 이후, git diff 를 통해 차이를 확인할 수 없음
왜냐면 staged 상태(add 한 이후)이기 때문에.
staged 상태인 파일 변화를 확인하려면 --cached 혹은 --staged 옵션을 추가

git diff --cached
git diff --staged

 

-v 옵션을 통해, commit message 에 diff 메세지도 추가 가능

git commit -v

 

-a 옵션을 통해, git 이 tracking하는 모든 파일을 stage area 에 넣고 commit 할 수 있음
즉, git add 를 생략하고 바로 commit 가능함

git commit -a

 

local machine 에서 파일을 지웠다고 해서, git 의 repo에서도 파일이 지워진 것은 아님
git rm 를 통해 git 에도 '해당 파일을 지웠다'는 걸 알려줘야 함

 

git rm 명령어는 local machine 의 파일까지 같이 삭제함
local 에서는 삭제하지 않고, git 에서만 삭제 및 tracking을 하지 않도록 하려면 --cached 옵션 사용

git rm --cached README.md

 

최근 로그의 diff 결과를 최근 2개 보여주는 명령어

git log -p -2

 

로그에서 각 커밋의 통계 정보 확인하는 명령어

git log --stat

 

로그에서 브랜치 상태 그래프를 같이 보여주는 명령어

git log --graph

 

지난 2주 동안 만들어진 커밋을 보여주는 명령어

git log --since=2.weeks

 

코드에서 추가 및 제거된 내용(업데이트 된 내용)을 검색할 수 있는 옵션은 -S
예를 들어, 문제를 일으키는 "issued_function_name" 라는 함수가 어느 커밋에서 발생했는지 검색하려면

git log -p -S issued_function_name

 

특정 경로 내 파일들의 로그(커밋 정보)를 보여주는 옵션은 --
예를 들어, /a/b/c, ./d/e 두 위치 안에 있는 파일들의 커밋 로그를 보려면

git log -- /a/b/c ./d/e

 

git commit 실행했을 때, (commit 에 포함되어야 할)어떤 파일 추가하는 것을 깜빡했다면
add 한 이후 --amend 명령어를 사용하여 commit 에 포함시킬 수 있음
예를 들어

git commit -m "commit without a file"  # 넣어야 할 파일을 빠뜨린 채로 commit
git add forgotten_file  # 잊은 파일을 추가
git commit --amend  # commit 에 합침

참고로 첫번째로 진행한 커밋(git commit -m "commit without a file") 기록은 사라지게 됨

 

remote 저장소 리스트를 보려면
git remote -v

결과 :
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)

여기서 origin 은, git clone시 사용된 git주소의 별명(단축 이름)임
remote 저장소 이름을 보려면

git remote
remote 저장소를 추가하려면

git remote add pb_repo https://github.com/paulboone/ticgit

git remote -v 실행 결과 :
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
pb_repo https://github.com/paulboone/ticgit (fetch)
pb_repo https://github.com/paulboone/ticgit (push)

 

로컬에는 없지만 리모트 저장소의 모든 데이터를 가져오려면

git fetch origin  # origin 저장소에서 가져옴
git fetch pb_repo  # pb_repo 저장소에서 가져옴
git fetch  # 로컬에 등록된 모든 저장소에서 가져옴

fetch 를 통해 가져온 데이터는 로컬 브랜치에 자동으로 Merge 하지 않음
로컬 브랜치에 병합(merge)하려면, 수동으로 처리해야 함
로컬에는 없지만 리모트 저장소의 모든 데이터를 가져와서 로컬 브랜치에 merge 까지 하려면

git pull

 

리모트 저장소의 자세한 정보를 보려면

git remote show origin 

 

'HEAD' 는 작업중인 브랜치를 가리키는 포인터
git checkout 등으로 작업 브랜치를 바꾸면, HEAD 포인터가 옮겨진 브랜치를 가리키도록 바뀜

 

 

https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EB%B8%8C%EB%9E%9C%EC%B9%98%EC%99%80-Merge-%EC%9D%98-%EA%B8%B0%EC%B4%88

위와 같이, master 브랜치를 기준으로 두 개의 브랜치(hotfix, iss53)가 추가되었고
master 브랜치와 hotfix 브랜치를 병합해야 하는 경우

git checkout master
git merge hotfix

결과 : 
Updating f42c576..3a0874c
Fast-forward
 index.html | 2 ++
 1 file changed, 2 insertions(+)

여기서 fast-forward 병합이 이루어짐
hotfix 는 master 브랜치를 기반으로 업데이트 된 브랜치기 때문에,
단순히 master 브랜치를 가리키는 포인터가 hotfix 브랜치를 가리키도록 이동한 것 (결과 아래) 

https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EB%B8%8C%EB%9E%9C%EC%B9%98%EC%99%80-Merge-%EC%9D%98-%EA%B8%B0%EC%B4%88

 

 

 

 

https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EB%B8%8C%EB%9E%9C%EC%B9%98%EC%99%80-Merge-%EC%9D%98-%EA%B8%B0%EC%B4%88

 

위와 같이, iss53에 따로 커밋이 이루어지고 이를 master 브랜치에 병합하는 경우

git checkout master
git merge iss53

결과 : 
Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)

iss53 은 (현재) master 브랜치에서 뻗어나온 브랜치가 아니기 때문에, fast forward merge 를 할 수 없음
대신, 각 브랜치(master, iss53)가 가리키는 커밋 두 개와 공통 조상 하나를 사용하여 3-way merge 를 함
master 브랜치 커밋(C4)과 iss53 브랜치 커밋(C5)을 합친 하나의 새로운 커밋(C6)을 생성한 후,
master 브랜치가 C6 커밋을 가리키도록 만듦으로써 3-way merge 를 마무리함

https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EB%B8%8C%EB%9E%9C%EC%B9%98%EC%99%80-Merge-%EC%9D%98-%EA%B8%B0%EC%B4%88
https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EB%B8%8C%EB%9E%9C%EC%B9%98%EC%99%80-Merge-%EC%9D%98-%EA%B8%B0%EC%B4%88

 

 

 

 

만약 위의 케이스에서 hotfix 와 iss53 에서 동일한 파일을 서로 다르게 업데이트 한 경우,
충돌로 인해 3-way merge 진행시 merge 가 진행되지 못함
merge 충돌 발생시 어떤 파일을 merge 할 수 없었는지 확인하려면

git status


git 에서 <<<<, >>>> 등으로 충돌 난 부분을 표시해줌
그리고 개발자는 이 파일의 충돌 난 부분을 수동으로 수정함
파일 수정이 마무리되면, git add 명령을 시작으로 다시 커밋을 진행

 

브랜치 목록에서 이미 merge 가 된 브랜치를 보려면

git branch --merged

이 명령으로 나타나는 브랜치들은 이미 merge 가 마무리 된 것이기 떄문에 삭제해도 무방
브랜치 목록에서 merge 가 되지 않은 브랜치를 보려면

git branch --no-merged

이 명령으로 나타나는 브랜치들은 merge 가 마무리되지 않음

 

 

 

 

 

https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-Rebase-%ED%95%98%EA%B8%B0

위와 같이, C4와 C3 커밋으로 나뉜 브랜치 둘을 병합하기 위해, merge 명령어를 사용할 수 있음
merge 명령어를 사용하면 새로운 커밋이 하나 생성되며 C4, C3 내용이 병합됨

새로운 커밋이 아닌, (fast-forward 하여 병합하기 위해) C4를 C3의 자손으로 만드는 방법을 rebase 라고 함
아래 순서대로 rebase 및 merge 진행

git checkout experiment
git rebase master
git checkout master
git merge experiment

rebase 진행 한 이후. https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-Rebase-%ED%95%98%EA%B8%B0

 

merge(fast-forward) 진행 한 이후. https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-Rebase-%ED%95%98%EA%B8%B0

 

 

 

 

Rebase를 하든지, Merge를 하든지 최종 결과물은 같고 커밋 히스토리만 다르다는 것이 중요
Rebase 의 경우는 브랜치의 변경사항을 순서대로 다른 브랜치에 적용하면서 합치고
Merge 의 경우는 두 브랜치의 최종결과만을 가지고 합침

 

 

 

1.


Apache Hive는 Hadoop 기반의 데이터 웨어하우스 시스템으로,
HDFS, S3 등에 저장된 대량의 데이터 대상으로 SQL을 사용할 수 있도록 도와줌

Hive 는 데이터를 따로 저장하는 storage 가 아님, 다른 저장소(HDFS, S3) 에 있는 데이터에 작업을 날려서 실행하는 것임
(근데 그 작업이 쿼리를 실행하는 작업)

쿼리를 실행 할 때는 다음과 같은 요소들을 사용
- Hive Query Engine 에서 HiveQL로 작성된 쿼리를 실행 계획으로 변환하고 실행
- Execution Engine Hive 에서 쿼리를 실제 실행 (MapReduce, Tez, Spark 등의 엔진 사용)

Hive 가 HDFS 내의 데이터를 읽으려면
HDFS 내의 데이터가 규칙적인 path(by partitioning) 및 파일 포맷(Orc, Parquet, Text 등)을 갖고 있어야 함
HDFS 의 데이터에 대한 메타 정보(데이터베이스, 테이블, 컬럼, 파티션, 파일 포맷, 데이터 위치 등)는
Hive Metastore 에 구조화된 형태로 저장됨
테이블 정의와 파티션 정보도 메타스토어에 저장됨.
테이블이 HDFS 내의 어느 디렉토리에 저장되어 있는지, 각 파티션이 어떤 경로에 위치하는지 등의 정보가 메타스토어에 기록됨

create external table 을 사용하여 테이블을 만들고 location 을 설정했다면,
사용자가 hive 를 통하지 않고 직접 HDFS 에 데이터를 넣었어도 Hive 에서 해당 location 에 접근해서
(create external table 실행할 때 미리 생성해둔 ) metadata를 기반으로 데이터를 읽을 수 있음(schema-on-read)
다시 말해, 테이블이 Hive Metastore에 존재하면, 해당 테이블의 메타데이터를 통해 HDFS에서 실제 데이터를 찾을 수 있기 때문에
사용자가 직접 데이터를 HDFS 에 저장했더라도 쿼리가 가능함

Hive 에서 처리하는 "데이터베이스", "테이블" 이라는 개념은, HDFS 데이터를 구분하고 관리하기 위한 논리적인 개념임
(실제 HDFS 에 "데이터베이스", "테이블"이 있는 것이 아님)
실제 HDFS 의 directory 가 Hive 에서 바라볼 때 "데이터베이스"가 됨
그리고 데이터베이스 dir 아래 위치한 dir 혹은 파일이 "테이블"이 됨

Hive는 배치 처리 시스템이기 때문에, 실시간 데이터 분석에는 부적합함.
Presto 같은 실시간 쿼리 엔진 사용하면 됨
그리고 Hive는 기본적으로 Append-only 모델이기 때문에, 데이터를 삭제하거나 업데이트하는 것이 어려움.
ACID Transactions(Hive 3.0 이상) 또는 Hudi, Iceberg 같은 테이블 포맷 사용하여 해결



하이브에서 작성된 쿼리는 일련의 job(MR, spark, etc)으로 변환되어 실행됨

하이브는 HDFS 에 저장된 데이터에 스키마를 입히는 방식으로 데이터를 테이블로 구조화 (읽기 스키마)

테이블 스키마, 파티션 같은 메타데이터를 메타스토어라 불리는 DB(MySQL, derby 등) 에 저장
메타스토어가 로컬 머신에 있으면, 한번에 한명의 유저만 사용 가능(derby DB를 사용하지 말아야 하는 이유)
실제 운영 환경에선 공유 원격 메타스토어를 사용

Hive 는 HADOOP_HOME 환경변수가 설정되어 있다면 HDFS 사용 가능


'hive' 명령어를 사용하면, 사용자 머신에 메타스토어 데이터베이스를 만듦
hive 명령어 실행한 위치에 metastore_db 라는 디렉터리 만들어 그 안에 필요한 파일 저장

local 데이터를 읽고 local 에 저장할 수 있음
저장시 데이터를 변경하지 않고 그대로 저장
local 에 저장할 때 하이브가 저장하는 경로는 웨어하우스 디렉터리(기본값 /user/hive/warehouse)

하이브는 특정 테이블 질의할 때 모든 파일을 다 읽음
그래서 효율적인 쿼리를 위해 버켓팅, 파티셔닝이 필요



하이브 속성 설정 우선순위
1. hive> 에 넣는 SET 명령어
2. 명령어에 넣는 -hiveconf 옵션
3. *-site.xml
4. *-default.xml



Hive 쿼리 실행 엔진은 MR, Tez, Spark 를 지원


 

2.


하이브 서비스
- cli : hive 드라이버에 바로 접근. 접근 권한 확인 하지 않아서 되도록 hiveserver2 사용
- hiveserver2 : 다른 언어로 개발된 클라이언트와 연동 가능하도록 하이브 쓰리프트 서비스 실행
  hiveserver2 로 쓰리프트 서비스가 실행되고,
  이를 통해 다른 언어에서 thrift, JDBC, ODBC 연결자로 하이브에 연결 가능
  접근 권한 확인 등을 hiveserver2 에서 진행
- beeline : JDBC 로 hiveserver2 프로세스에 접근하는 명령행 인터페이스
- hwi : 하이브 웹 인터페이스
- 메타스토어 : 기본적으로 메타스토어는 하이브 서비스와 동일한 프로세스에서 실행됨
  이 서비스는 메타스토어를 독립형 원격 프로세스로 실행함

 

 

3.


메타스토어는 하이브 메타데이터를 저장하는 핵심 저장소
메타스토어는 서비스데이터 보관 저장소로 나뉨

내장 메타스토어
- 메타스토어 서비스 : 하이브 서비스와 동일한 JVM 내에서 동작
- 메타스토어 저장소 : 하이브 서비스와 동일한 JVM 내에서 동작. derby
  local 에 데이터 저장하는 derby 데이터베이스
  derby 는 한 번에 db파일 하나에만 접근 가능해서 하나의 하이브 세션만 사용 가능
  (다른 사용자 등에 의해) 두 번째 세션 사용 불가
  따라서 다중 세션(다중 사용자) 지원 불가

로컬 메타스토어
- 메타스토어 서비스 : 하이브 서비스와 동일한 JVM 내에서 동작
- 메타스토어 저장소 : 원격 머신에서 별도의 프로세스로 실행되는 데이터베이스. mysql, postgresql etc
  다중 세션(다중 사용자) 지원 가능
  mysql, postgresql 등을 원격 데이터베이스로 사용

원격 메타스토어
- 메타스토어 서비스 : 하나 이상의 메타스토어 서버가 하이브 서비스와 별도의 JVM 프로세스로 실행
- 메타스토어 저장소 : 원격 머신에서 별도의 프로세스로 실행되는 데이터베이스. mysql, postgresql etc
  클라이언트와 메타스토어 서버는 thrift로 통신함
  데이터베이스 계층이 방화벽 역할을 대신하기 때문에
  클라이언트는 데이터베이스 자격 증명을 얻을 필요가 없어서 관리성과 보안성이 높아진다는데
  무슨 말인지 모르겠음
  메타스토어 서비스가 별도의 서버에서 실행되면, 가용성과 확장성이 제공됨


 

 

4.


rdb 와 hive 차이
- rdb 는 쓰기 스키마, hive 는 읽기 스키마
  쓰기 스키마는 index 를 지원해서 쿼리가 빠르지만,
  읽기 스키마는 디스크 직렬화가 필요없어서 데이터 write 가 매우 빠름
- rdb 의 트랜잭션, 색인 기능은 hive 에서 일부 지원
  트랜잭션(update)이 활성화된 hive 는 update 가 가능하지만,
  실제 테이블 내 데이터가 업데이트를 하는 건 아니update 내역을 별도의 작은 델타 파일로 저장
- hive 의 insert into : 하이브 테이블, 파티셔닝 된 테이블 내에 데이터를 추가하며 insert 함
  insert overwrite : 하이브 테이블, 파티셔닝 된 테이블 내의 데이터를 모두 지우고 insert 함
- 데이터를 읽을 때 SHARED_READ lock 을 얻는데,
  해당 lock 이 존재하면 다른 사용자가 읽기 가능, update 불가능
- 데이터를 update 할 때 EXCLUSIVE lock 을 얻는데,
  해당 lock 이 존재하면 다른 사용자가 읽기/update 가 불가능

hive 가 지원하는 색인
- 콤팩트 색인 : HDFS 블록 넘버로 색인
- 비트맵 색인 : 특정 값이 출현하는 행을 효율적으로 저장하기 위해 압축된 비트셋으로 색인
색인을 위한 데이터는 별도의 테이블에 저장됨

 

6.


하이브 테이블의 데이터 저장소는 local disk, s3, HDFS 등 다양하게 사용 가능

관리 테이블 : 하이브가 데이터를 직접 관리
  직접 관리한다고 해도, 데이터는 여전히 HDFS 등 외부 저장소에 있음
  직접 관리한다는 의미는, 테이블이 삭제되었을 때 데이터가 실제로 삭제된다는 의미임
  load 쿼리 사용시, 해당 데이터가 웨어하우스 디렉터리(local, HDFS 등)으로 이동
  drop table 쿼리 사용시, 해당 데이터와 메타데이터가 실제로 삭제

외부 테이블 : 하이브가 데이터를 직접 관리하지 않음
  drop 쿼리 사용시, 메타데이터만 삭제되고 데이터는 삭제되지 않음


파티션 : 데이터를 각 dir 에 나눠 저장. PARTITIONED BY
  year=2024/month=01/ 같은 구조로 HDFS에 저장됨.
버킷 : 지정한 컬럼값을 해쉬 처리 한 후, 버킷수로 나눈 나머지만큼 파일로 나눠 저장. dir 가 아닌 파일에 저장. CLUSTERED BY

버킷을 사용하는 이유
- 매우 효율적인 쿼리가 가능
  테이블에 대한 추가 구조를 부여하게 되고, 쿼리 수행 시 이 추가 구조 사용 가능
- 효율적인 샘플링에 유리
- 버켓팅한 테이블은 조인시에 SMB(sort merge bucket) 조인으로 처리하여 속도 향상



row format : 행 구분자 설정, 특정 행의 필드가 저장된 방식 설정

- 지정가능한 구분자 
  FIELDS TERMINATED BY '\t'            -- 칼럼을 구분하는 기준
  COLLECTION ITEMS TERMINATED BY ','   -- 리스트를 구분하는 기준
  MAP KEYS TERMINATED BY '='           -- 맵데이터의 키와 밸류를 구분하는 기준
  LINES TERMINATED BY '\n'             -- 로(row)를 구분하는 기준
  ESCAPED BY '\\'                      -- 값을 입력하지 않음
  NULL DEFINED AS 'null'               -- null 값을 표현(0.13 버전에서 추가)

- 특정 행의 필드 저장 방식 : 데이터 저장시 SerDe 를 통해 직렬화하여 저장하고 읽을 때 역직렬화하여 읽나 봄
기본서데, 정규식(RegExSerDe), JSON(JsonSerDe), CSV(OpenCSVSerde)가 존재함

stored as : 데이터를 저장하는 파일 포맷 지정
저장 포맷은 TEXTFILE, SEQUENCEFILE, ORC, PARQUET 등이 존재
바이너리인 sequence, orc, parquet 등은 행의 형식이 바이너리 포맷에 따라 결정되므로 row format 지정 불필요

참고 https://wikidocs.net/23469



hive 는 읽기 스키마를 사용하기 때문에
테이블의 이름 변경, 테이블의 정의 변경, 새로운 컬럼 추가 등이 자유로움


 

셔플 조인은 가장 느린 조인

맵(Map) 단계에서 각 테이블을 읽고, 조인 컬럼을 키로 설정하여 셔플

리듀서로 데이터가 이동되고 리듀서에서 테이블을 조인

 

버켓팅 되어있으면 Bucket Map Join 이 빨라짐.

https://data-flair.training/blogs/bucket-map-join/

join 의 기준이 되는 key 들이 모두 버케팅 되어있는 상황에서 Join 을 진행하면,

작은 테이블의 버킷들(Table a, Table c)이 큰 테이블의 버킷(Table b)의 메모리에 모두 복사됨

이렇게되면 join 에 필요한 모든 key 가 하나의 Mapper 에서 접근 가능하기 때문에 join 속도 향상

작은 테이블 크기가 메모리에 올라갈 정도로 작아야 함

브로드캐스트 조인임.

 

Sort Merge Join 은 조인 테이블이 버켓팅 되어 있을 때 사용 가능

버켓팅된 키의 정보를 이용하여 빠르게 조인

다음 절차로 join 이 진행됨

- Table a 와 Table b 에서 join 에 필요한 데이터를 읽음

- 별도의 공간에서 읽은 데이터를 정렬sort 함

- 정렬된 데이터를 기준으로 join 함

 

참고 : https://coding-factory.tistory.com/757

 

 


hive 명령어와 beeline 명령어 차이?

- hive 명령어는 하이브 옵션 설정, 쿼리 실행 등이 가능

- beeline 은 단지 hive 에 thrift 로 접근하는 인터페이스

 

thrift : 다양한 언어로 개발된 소프트웨어들을 쉽게 결합(통신)하는 프레임워크. 내부에서 RPC 사용

JDBC :

- Java Database Connectivity

- JAVA 언어로 DB 에 접근해 DML 쿼리 하기 위한 인터페이스

- Java와 연동되는 DBMS에 따라 그에 맞는 JDBC를 설치할 필요가 있음

ODBC

- Open Database Connectivity

- 응용프로그램에서 다양한 DB 에 접근해 DML 쿼리하기 위한 인터페이스

- 접속처의 데이터베이스가 어떠한 DBMS에 의해 관리되고 있는지 의식할 필요가 없음

 

hive 에서 orc 를 사용하는 이유

- 높은 압축률

- 컬럼 기반 포맷이라 처리 속도가 빠름

- 스키마를 가지고 있음

- orc 는 hive 에 최적화되어있고, parquet 은 spark 에 최적화 되어있음

 

 

 

ORDER BY vs DISTRIBUTE BY vs SORT BY vs CLUSTER BY

 

ORDER BY

- 매퍼에서 나오는 모든 데이터를 하나의 리듀서로 몰아서 정렬 수행

- 리듀서가 하나 뿐이라, 저장되는 파일도 하나

- limit 을 추가하여 리듀서에 부하를 줄이는 게 좋음

- order by COLUMN

 

SORT BY

- ORDER BY 와 다르게, 리듀서가 하나 이상, 각 리듀서에서 정렬 수행

- 각 리듀서별로 정렬하기 때문에, 모든 리듀서 결과는 전체 정렬 되어있지 않음

- 리듀서 개수를 1로 설정하면 ORDER BY 와 같은 결과

- sort by COLUMN

 

DISTRIBUTE BY

- distributed by 의 대상이 되는 컬럼의 값 기준으로 group 지어 하나의 리듀서에 들어감

정렬 수행하지 않음

- 예)

  정렬 대상 : a a b c c c d

  리듀서 1) a d a

  리듀서 2) c b c c

  (리듀서 개수와 상관 없이) 같은 값은 모두 하나의 리듀서에 몰려 있음. 

 

CLUSTER BY : 

 

- distributed by 와 sort by 를 같이 사용

- 즉, distributed by 실행하며 정렬까지 진행

- 예)

  정렬 대상 : a a b c c c d

  리듀서 1) a a d

  리듀서 2) b c c c

 

참고) https://saurzcode.in/2015/01/hive-sort-order-distribute-cluster/

 

 

 

Hive 정적 파티션 vs 동적 파티션

 

정적 파티션

- 데이터의 테이블에 파티션 값을 직접 입력

  예)

  INSERT INTO TABLE tbl(yymmdd='20220625')
  SELECT name FROM temp;

  > hdfs://hive/tables/yymmdd=20220625/

 

동적 파티션

- 데이터의 컬럼값을 기준으로 파티션이 생성

- 쿼리 시점에 어떤 데이터가 어떤 파티션에 가는지 모름

- 동적 파티션은 느림

  예)

  INSERT INTO TABLE tbl(yymmdd)
  SELECT name, yymmdd FROM temp;

  > hdfs://hive/tables/yymmdd=20220625/

  > hdfs://hive/tables/yymmdd=20220626/

  > hdfs://hive/tables/yymmdd=__HIVE_DEFAULT_PARTITION__/

 

 

 

HDFS 에서 작은 파일들 합치기

https://gyuhoonk.github.io/hive-merge-query

 

결론

작은 파티션들이 많으면, HDFS IO 도 많아지고 NN memory 에 부담도 커짐

Hive

- insert into 등의 쿼리는 매퍼만 동작하는데,

  매퍼에서 읽은 데이터를 그대로 HDFS 블럭으로 저장하기 때문에 블럭 개수가 늘어남

  이를 합쳐주기 위해 (sort by 등을 추가하여) 리듀서를 추가

Spark

- 셔플 파티션은 기본값이 200 이라서, 셔플 후에는 200개의 작은 파티션들이 생성되어 HDFS 에 저장됨

  이를 합쳐주기 위해 셔플 파티션 값을 조정하거나, repartition 혹은 coalesce 를 사용하여 파티션 개수 줄임

 

 

 

< Presto >


Apache Presto 는 Hive 와 마찬가지로, 대규모 데이터에 대한 SQL 기반 쿼리 처리 시스템
Hive 처럼 외부 스토리지(HDFS, S3)에 저장된 데이터 대상으로 쿼리를 사용할 수 있도록 도와줌

하지만 Hive와 다른 목적과 작동 방식을 갖음

- 목적
  - Hive : batch 쿼리 처리
  - Presto : realtime 분석 쿼리 처리
- 실행 엔진
  - Hive : MR, Tez, Spark
  - Presto : 자체 엔진(MPP:massively parallel processing)
- 처리 방식
  - Hive : 디스크 기반
  - Presto : in-memory 기반
- 속도
  - Hive : 대용량 데이터 처리하므로 느림
  - Presto : 빠름 (...)
- 데이터 소스
  - Hive : HDFS, ORC, Parquet
  - Presto : HDFS, ORC, Parquet, MySQL, Kafka, Cassandra 등 다양하게 지원
- 사용 사례
  - Hive : 대량 데이터 ETL, 데이터 웨어하우스에서 OLAP 에 사용
  - Presto : BI, 실시간 대시보드, 쿼리 성능이 중요한 환경, 대화형 분석 환경 제공

Presto 로 대용량 데이터 ETL 혹은 배치 처리하기는 부적합함.
이런 경우는 Hive 를 사용하고, 실시간 분석 처리할 때 Presto 사용

Hive 와 Presto 를 혼합하여 사용하기도 함
이를테면, 대량의 데이터를 HDFS 에 적재할 때는 Hive 를 사용하고,
데이터를 조회할 때는 Presto 를 사용하는 식.

 

 

< Iceberg >


Apache Iceberg 는 대규모 데이터 레이크에서 테이블을 효율적으로 관리하기 위해 설계된 테이블 포맷
HDFS, S3 등 다양한 스토리지에서 대량의 데이터를 안정적으로 관리하고 빠르게 쿼리할 수 있도록 최적화 됨



Iceberg 의 장점은 다음과 같음
- 대용량 데이터(수십~수백 페타바이트) 처리 최적화
- ACID 트랜잭션 지원 (데이터 일관성 보장)
  (ACID : 원자성(Atomicity), 일관성(Consistency), 격리성(Isolation), 지속성(Durability) )
- Schema Evolution 지원 (스키마 변경 가능)
- Partition Evolution 지원 (파티셔닝 변경 가능)
- Time Travel 지원 (과거 데이터 조회 가능)
- 다양한 엔진(Hive, Spark, Trino, Flink, Presto)과 호환




 

 

https://spark.apache.org/docs/latest/index.html

 

-  pandas API on Spark for pandas workloads

 

- Downloads are pre-packaged for a handful of popular Hadoop versions

 

- Spark runs on both Windows and UNIX-like systems, and it should run on any platform that runs a supported version of Java

 

- it is necessary for applications to use the same version of Scala that Spark was compiled for

For example, when using Scala 2.13, use Spark compiled for 2.13

 

- use this class in the top-level Spark directory.

 

- with this approach, each appliction is given a maximum amount of resources it can use

and holds onto them for its whole duration.

 

- Resource allocation can be configured as follows, based on the cluster type.

 

- At a high level, Spark should relinquish executors when they are no longer used and acquire when  they are needed.

 

- We need a set of heuristics to determine when to remove and request executors.

 

- By default, Spark's scheduler runs jobs in FIFO fashion.

 

- If the jobs at the head of the queue don't need to use the whole cluster, 

later jobs can start torun right away, but if the jobs at the head of the queue are large,

then ddlater jobs may be delayed significantly.

 

- Under fair sharing, Spark assigns tasks between jobs in a "round robin" fashion,

so that all jobs get a roughly equal share of cluster resources.

 

- This feature is disabled by default and available on all coarse-grained cluster managers.

 

- Without any intervention, newly submitted jobs go into a default pool

 

- This is done as follows

 

- This setting is per-thread to make it easy to have a  thread run multiple jobs on behalf of the same user.

 

- If you would like to clear the pool that a thread is associated with, simply call this.

 

- jobs run in FIFO order.

 

- each user's queries will run in order instead of later queries taking resources from that user's earlier ones.

 

- At a high level, every Spark application consists of a driver program that runs the user's main function and executes various parallel opperations on a cluster.

 

- ...the cluster that can be operated on in parallel.

 

- This guide shows each of these features in each of Spark's supported languages.

 

- it's easiest to follow along with if you launch Spark's interactive shell.

 

 

 

 

 

 

 

 

 

 

 

 

 

- It is not only Value but also Pointer, both of these together make up the node.

 

- We do it by just having the next value of A node be the B node.

 

- the same is true of the C node.

 

- if you look at how we're going to have to traverse this, we are going to have to start at head.

 

- that's what we are going to do down here with this print statement.

 

- the syntac is a little bit different than if you are going to use dictionaries.

 

 

 

 

- Our managers deal with all kinds of clients every day. So I can say that we maintain the highest level of service.

 

- In my work I follow the best practices to maintain clean and easy to understand python codes.

 

- In my previous project I carried out the responsibilities of both the Project Manager and the Team Leader.

 

carry out : to do something, to perform

both A and B

 

- As a QA specialist I worked with a test environment where I tested many aspects of the platform

  to ensure that it works as desired.

 

- A cloud architect oversees application architecture

  and deploys it in cloud environments like public cloud, private cloud and hybrid cloud.

 

to oversee : to watch over and control something to make sure that the work is good or satisfactory, to supervise

 

- I took a course where I learned how to design and write programs that are easy to maintain.

 

to design : to create, draw, or construct something

 

- I will set up all the necessary equipment in my home office to work remotely on this project

 

- I'm an IT Technician, so I install and configure different software on all computers in the office.

 

to install : to put a new program or piece of software into a computer

to configure : to chagne setting of software on a computer

 

- As a Jr Software Engineer, I assist and participate in the research, design, development and testing software and tools.

 

to assist : to help someone or something

 

- I am a web designer, so I know hot to provide the best UX for your website visitors.

 

- Project managers usually estimate new projects by analogy, using previous projecs and past experience.

 

to estimate : to give a general idea of the cost of work or the time you need to do the work

analogy : a comparison of two things based on their being alike in some way

 

- Sometimes I need to google my questions, for ex "how to execute the code inside of function in JS"

 

- Working on my project I improved my time management and organizational skills.

 

- press the F2 key on your keyboard

 

- The screen resolution is 1366x768

 

- I prefer work with desktop

 

- Workstation PCs have multiple processor cores.

 

- Some tablets have a long battery life

 

- The volume on my speakers won't ture up.

 

- My printer broke down, so I printed out these documentations at work.

 

- 'ram' is not countable, so only possible to say 'ram is' or 'ram was', not 'rams' or 'rams are'

 

- with a cable : wired mouse, wired connection(Ethernet)

- without a cable : wireless mouse, wireless connection(WiFi)

 

- ISP stands for Internet Service Provider.

 

- so many folers on my desktop

 

- start or shut down a computer.

- turn on or turn off a computer

 

- to crash / to freeze up : when a computer suddenly stops working

 

- to look up a word or address : to find something.

  we can use 'nslookup' command in terminal to query to DNS server.

 

- It will take about two hours to key in all this data.

 

to key in : to enter info into computer

 

- a shortcut key : 단축키.

 

Use Ctrl + L shortcut to see the last saved version.

 

- 'perform' is used a lot more than my thought. for ex, the server performs instructions written in code.

 

- use only the numbers in given array.

 

- I assigned the number 33 to age variable.

 

- fraction : 분수

- numerator : 분자

- denominator : 분모

  ex, 1/3 : one thrid, 2/3 : two thirds, 1/2 : a half(second), 1/4 : a quarter, 3/4 : three quarters

 

- decimal : 소수

- decimal point : 소수점

- floating point : 부동소수점

  ex, 1.23 : one point two three, 15.1 : fifteen point one

 

'double' also has a point but 'float' and 'double' are different each.

let's look up how they consist differently.

 

- I created an array of strings.

 

- To debug is to investigate the program and fix bugs.

 

- Comment is a text written around code that is ignored by the computer.

It is used for writing extra info about your code to help you undertand it later.

so we can say, 'leave comments in your code.'

 

- 'Comment out' is to turn a piece of code into a comment with the help of special characters.

like, //, #, -- ... etc

you can comment out some lines to see how it works without them.

 

- Constant is a variable that never changes its value.

for ex, val a = 1, final int a= 1

we can say "In Java, a constant is assigned using the final keyword"

"the PI constant has the value of 3.14"

 

- If you try to divide a number by zero, your program will crash.

A program crashes when it stops running because of an error.

 

- An 'executable' is a program which is ready to be run. 

Short for executable file, executable program

A common filename extension .exe means that it is an executable file.

it sounds '엨즤큐터블'

 

- To declare(선언) in programming means to say that something exists

usually a variable, a function, or a class.

I've only declared a function, but I haven't written it yet.

 

- To implement(구현) means to write and complete something in code

for example, to implement a function or a class

I declared a function and implemented it. It works well! 

 

- To instantiate(인스턴스화) means to create an object from a class.

I instantiated another object of the Student class.

it sounds '인스탠시에이트'

 

- A loop is a piece of code that runs itself many times.

It can also be used as a verb - to loop or to iterate

I used a "for" loop to run this code for every value in the array.

I iterate throught every element in the list.

 

- He read some data values from another source over the internet.

 

- Syntax is the grammatical rules of a programming language.

Syntax determines if code is written correctly or not.

 

- find any typing mistakes if you got a syntax error.

 

 

 

 

 

 

 

'English' 카테고리의 다른 글

Study English 24.07.03-05  (0) 2024.07.06
Study English 24.06.29-07.02  (0) 2024.07.02
Study English 24.06.28  (0) 2024.06.29
Study English 24.06.27  (0) 2024.06.27
Study English 24.06.26  (0) 2024.06.26

+ Recent posts