2021년 3월 14일 일요일

Apache Phoenix - EMR Phoenix 설정(NamespaceMapping)


EMR Phoenix사용중에 같은 테이블명의 QA환경, 개발환경을 구현해야 할 때가 있다.

Phoenix 스키마를 사용하여 

  • QA.TEST_TABLE
  • DEV.TEST_TABLE

과 같이 구분시킨다.



[ 1 ]

위와 같이 사용하기 위해선 네임스페이스 관련 hbase-site.xml설정을 해야하는데

Hbase의 Master, Region서버 모두 설정값을 수정한다.


sudo vi /usr/lib/hbase/conf/hbase-site.xml 

[ 네임스페이스 관련 ]

  <property>
    <name>phoenix.schema.isNamespaceMappingEnabled</name>
    <value>true</value>
  </property>

  <property>
    <name>phoenix.schema.mapSystemTablesToNamespace</name>
    <value>true</value>
  </property>


[ 성능관련 ]
  <property>
    <name>phoenix.functions.allowUserDefinedFunctions</name>
    <value>true</value>
  </property>

  <property>
    <name>phoenix.query.maxServerCacheBytes</name>
    <value>2097152000</value>
  </property>

  <property>
    <name>phoenix.mutate.maxSize</name>
    <value>20000000</value>
  </property>

  <property>
    <name>phoenix.mutate.batchSize</name>
    <value>10000</value>
  </property>




[ 2 ]

설정값 변경 후 서비스를 재시작한다.

systemctl --type=service | grep hbase (서비스이름확인)

sudo systemctl restart hbase-master.service (마스터노드에서)

sudo systemctl restart hbase-region.service (리전노드에서 )

sudo systemctl restart phoenix-queryserver.service (마스터노드에서)





[ 에러 ]

ERROR: SYSTEM.MUTEX is disabled.

or

AvaticaClientRuntimeException: Remote driver error: RuntimeException: org.apache.phoenix.exception.PhoenixIOException: SYSTEM:CATALOG -> PhoenixIOException: SYSTEM:CATALOG -> TableNotFoundException: SYSTEM:CATALOG. Error -1 (00000) null

과 같은 에러메세지가 쿼리서버에서 나타나면 주키퍼 Znode를 최신화시켜주어야한다.


bin/hbase clean --cleanZk 

명령어 이후 [2]와 같이 서비스를 재시작한다.






2021년 3월 9일 화요일

[ Algorithm ] 위장 - Hash


문제 ]

스파이들은 매일 다른 옷을 조합하여 입어 자신을 위장합니다.

예를 들어 스파이가 가진 옷이 아래와 같고 오늘 스파이가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야 합니다.

종류이름
얼굴동그란 안경, 검정 선글라스
상의파란색 티셔츠
하의청바지
겉옷긴 코트

스파이가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요.

제한사항

  • clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다.
  • 스파이가 가진 의상의 수는 1개 이상 30개 이하입니다.
  • 같은 이름을 가진 의상은 존재하지 않습니다.
  • clothes의 모든 원소는 문자열로 이루어져 있습니다.
  • 모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 '_' 로만 이루어져 있습니다.
  • 스파이는 하루에 최소 한 개의 의상은 입습니다.

입 출력 예

CLOTHESRETURN
[[yellow_hat, headgear], [blue_sunglasses, eyewear], [green_turban, headgear]]5
[[crow_mask, face], [blue_sunglasses, face], [smoky_makeup, face]]3



제출 ]

import java.util.*;

class Solution {
    public int solution(String[][] clothes) {
        int answer = 1;
        Map<String, Integer> clothesMap = new HashMap<>(); // 종류 : 갯수
        
        //의상을 키값으로 의상당 종류수 카운트
        for (int i = 0; i < clothes.length; i++) {
            clothesMap.put(clothes[i][1], clothesMap.getOrDefault(clothes[i][1], 0)+1);
        }
        
        // 경우의 수 체크 
        for (int val : clothesMap.values()){
            answer *= (val+1);
        }
        // 모두 다 안입는 경우는 존재하지 않으므로 -1
        return answer-1;
    }
}



풀이 ]

getOrDefault(Object key, V DefaultValue) 를 사용하여 

종류를 키값으로 종류당 의상 수를 벨류값으로 맵 자료형을 선언한다. 

경우의 수를 체크하고 제한사항에 모두 안입는 경우는 없다고하니

결과값에 -1을 해준다.



2021년 3월 8일 월요일

[ Algorithm ] 전화번호 목록 - Hash


문제]

전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.

전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.

  • 구조대 : 119
  • 박준영 : 97 674 223
  • 지영석 : 11 9552 4421
제한 사항
  • phone_book의 길이는 1 이상 1,000,000 이하입니다.
  • 각 전화번호의 길이는 1 이상 20 이하입니다.

전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요.

 

https://programmers.co.kr/learn/courses/30/lessons/42577?language=java



제출1]

import java.util.*;

class Solution {
    public boolean solution(String[] phone_book) {

        boolean answer = true;
        Arrays.sort(phone_book, Comparator.comparing(String::length));
        
        for(int i=0;i<phone_book.length-1;i++) {
            for(int j=i+1;j<phone_book.length;j++){
                if(phone_book[j].startsWith(phone_book[i]))    
                    return false;
            }    
        }
        
        return answer;
    }
}

->런타임에러



해쉬맵 자료형을 이용한 풀이

제출2]

import java.util.*;

class Solution {
    public boolean solution(String[] phone_book) {

        boolean answer = true;
        HashMap<String, String> hm = new HashMap<String, String>();
        
        for(int i=0;i<phone_book.length;i++)
            hm.put(phone_book[i],i);

        for(String key : hm.keySet()){
            for(int idx=0;idx<key.length();idx++){
                if(hm.containsKey(key.substring(0,idx)))
                    return false;
            }    
        }
        
        return answer;  
    }
}


2021년 3월 5일 금요일

Apache Hue - Hbase Table 안보일 시

 

[ Error Message ]

HUE HBASE API ERROR: TSOCKET READ 0 BYTES


[ 해결 ]

hbase.regionserver.thrift.http = enable 로 설정

[ Zookeeper ] zookeeper.out Error & Unable to load database on disk


[ ERROR 1 ]

zookeeper.out파일은 zookeeper server의 로그내역을 포함한 파일이다.

해당파일의 크기가 커지면서 디렉토리의 파일사이즈 가용량이 넘어서 

bash: cannot create temp file for here-document: No space left on device

에러메세지가 뜬다.


[ 해결 1 ]

아래 파일로 설정값을 변경한다.

/zookeeper/conf/log4j.properties

log4j.rootLogger=INFO, ROLLINGFILE
log4j.appender.ROLLINGFILE.File=${zookeeper.log.dir}/zookeeper.log 
log4j.appender.ROLLINGFILE.MaxFileSize=10MB
log4j.appender.ROLLINGFILE.MaxBackupIndex=10

해당파일을 최대 10MB 사이즈로 최신데이터를 Rotate시킨다. 


[ ERROR2 ]

Zookeeper서버의 트랜잭션 로그에 있는 일부 파일이 손상되어

서버가 DB를 읽지 못한다. 

노드실행시 작성되는 내용을 /version-2/acceptedEpoch파일에 업데이트 실패시

URL : https://issues.apache.org/jira/browse/ZOOKEEPER-2307


에러메세지

ERROR Unable to load database on disk 

(org.apache.zookeeper.server.quorum.QuorumPeer)

...

...


[ 해결 2 ]

에러로 인해 zookeeper/version-2 안의

파일설정값들이 일관성이 없는 상태

  • 해당 디렉토리 폴더를 backup
  • zookeeper중지 $ /zookeeper/bin/zkServer.sh stop
  • zookeeper/version-2/ 모든파일 삭제 
  • zookeeper시작 $/ zookeeper/bin/zkServer.sh start
  • 상태확인 $ /zookeeepr/bin/zkServer.sh status


참조 

2021년 3월 1일 월요일

Apache Phoenix - Thick Server 접속 Java예제코드


package com;


import java.sql.*;

import java.util.HashMap;


public class App 

{

    private static Connection connect;

    private static Statement statement;

    private static PreparedStatement preparedStatement;

    private static ResultSet resultSet;

    private static String serverURL;


    static {

        connect = null;

        statement = null;

        preparedStatement = null;

        resultSet = null;

        serverURL = "jdbc:phoenix:12.234.56.78:2181:/hbase";

    }


    public static Connection connect() throws Exception {

        Class.forName("org.apache.phoenix.jdbc.PhoenixDriver");

        connect = DriverManager.getConnection(serverURL);

        return connect;

    }


    public static HashMap<Integer, String> getSelect() throws Exception {

        

        connect = connect();

        final HashMap<Integer, String> record = new HashMap<Integer, String>();

        preparedStatement = connect.prepareStatement("select * from TEST;");

        resultSet = preparedStatement.executeQuery();

        

        while (resultSet.next()) {

            Integer myKey = resultSet.getInt(1);

            String myColumn = resultSet.getString(2);

            record.put(myKey, myColumn);

        }


        connect.close();

        return record;

    }


    public static void main( String[] args )

    {

        try {

            HashMap<Integer, String> record = new HashMap<Integer, String>();

            record = getSelect();

            System.out.println(record);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}



Apache Phoenix - 기존 HBase테이블 Mapping


기존 HBase 테이블에 Phoenix 테이블을 매핑하는 법은 

기존에 있는 HBase 테이블과 똑같은 이름의 Phoenix테이블 또는 뷰를 생성한다.

또한 두 테이블 컬럼의 자료형이 일치해야하는데, 

특히 숫자의 경우 Hbase와 Phoenix의 표현방식이 다르므로 표현되기 어렵다. 


"Phoenix will flip the first bit so that negative values will sort before positive values. Because HBase sorts row keys in lexicographical order and negative value’s first bit is 1 while positive 0 so that negative value is ‘greater than’ positive value if we don’t flip the first bit. So if you stored integers by HBase native API and want to access them by Phoenix, make sure that all your data types are UNSIGNED types."

간단히 말하면 HBase에 맵핑된 컬럼의 숫자 값을 Phoenix에서 액세스하려면 

모든 데이터 유형이 UNSIGN 형식이여야 한다. 

Hbase : var - Integer

Phoenix : var - Integer 

일 경우 매핑이 되지 않는다.



예시 ]

HBase 테이블을 생성한다.

create 'T1', {NAME => 'F1', VERSIONS => 5}


매핑되는 Phoenix테이블을 생성한다.

CREATE VIEW t1 ( pk VARCHAR PRIMARY KEY, f1.val VARCHAR )

Or 

CREATE TABLE t1 ( pk VARCHAR PRIMARY KEY, val VARCHAR )



결과 확인 ]

1. Hbase 테이블 값 변경시 Phoenix 테이블 변경 값 확인

2. Phoenix 테이블 값 변경시 Hbase 테이블 변경 값 확인




참조 : 

https://phoenix.apache.org/faq.html