레이블이 MSSQL POLYBASE인 게시물을 표시합니다. 모든 게시물 표시
레이블이 MSSQL POLYBASE인 게시물을 표시합니다. 모든 게시물 표시

2019년 10월 10일 목요일

[ERROR] HdfsBridge::recordReaderFillBuffer - Unexpected error encountered filling record reader buffer: ClassCastException:

Polybase로 EXTERNAL TABLE을 만드려고 할 때 다음과 같은 에러가 발생했다.

HdfsBridge::recordReaderFillBuffer - Unexpected error encountered filling record reader buffer: ClassCastException: 



원인은 confidence 컬럼의 DECIMAL 타입이 문제였고 confidence이 부동소수점으로 간주되어 DECIMAL(NUMERIC) 타입을 사용할 수가 없는 것이었다.

이를 근사치를 표현하는 부동소수점 표현 타입인 FLOAT으로 바꾸면 바로 해결이 된다.


아래처럼 FLOAT 형식으로 바꾸어서 실행한다.


결과는 다음처럼 잘 나온다.



그래도 같은 에러가 떨어진다면 이상한 문자가 섞여있는 것으로 추정할 수 있다.

예를 들어서 float형식에 2.0834406E-5 같이 E가 섞여서 들어온다면 같은 문제가 발생한다.
저런 경우 E를 제거하고  0.00002083441 식으로 넘기던지 하면 해결될 것이다.
(예외상황 제보해주신 김현경님 감사합니다.)

2019년 4월 2일 화요일

MSSQL Polybase CETAS 배치 생성할 때 팁 - 약속된 파일을 하나 더 내린다.

시나리오 : 하둡 데이터를 MSSQL로 매일 특정 시간에 가져오는 배치를 짠다고 가정한다.
예를 들어 하둡 경로가 다음처럼 떨궈진다.
/app/hadoop/korea/visit/20190101
/app/hadoop/korea/visit/20190102
/app/hadoop/korea/visit/20190103
/app/hadoop/korea/visit/20190104
....
위와 같은 방식으로 날짜를 바꾸면서 하둡 데이터를 떨구고 있다고 가정한다.

그리고 이후 다른 시스템으로 해당 하둡 데이터를 가져가는 배치가 있다고 생각한다.

가령 SSIS를 활용해서 MSSQL로 하둡 데이터를 가져간다고 가정한다.

보통 MSSQL문법으로 하둡 경로를 알고 있을 때 우리는 다음과 같은 문법으로 외부테이블을 생성할 수 있다.
CREATE EXTERNAL TABLE ~
LOCATION ~
하지만 특정 상황이 발생하여 데이터를 못 떨궜을 경우 해당 경로가 없어서 저 CREATE(일명 CETAS) 문을 실행할 수가 없다.


이때 우리는 배치에서 주기적으로 하둡 경로를 반복적으로 체크하면서 생성된 이후에 데이터를 가져오면 된다.


하둡 명령어 중에 fs -test -e /app/hadoop/korea/visit/20190101 (-s는 file, -d는 디렉토리이면.. 등 여러 옵션이 있다.)를 먼저 날리고 0을 반환하면 경로가 있다는 의미이다.

즉 아래 명령어를 먼저 날려보고

경로가 존재하지 않으면 1을 return 한다.

경로가 존재하면 0을 return 한다.


이걸 활용하면 다음과 같은 방법이 가능하다.
1. 하둡 데이터를 떨굴 때 원하는 것을 다 떨구면 해당 경로에 success라는 크기가 0인 파일을 하나 더 떨구게 한다.
2. 가져가는 배치쪽에서 loop를 만들고 반복문 안에서 데이터를 가져오기 전에 fs -test -s /app/hadoop/korea/visit/20190101/success 를 날린다
3. 리턴값이 0이면 루프를 탈출하고 1이면 10분에 한번씩 저 명령어를 하둡에 찔러본다.
4. 루프를 탈출하면 mssql에서 create external table 문 실행한다.

이런식으로 데이터가 생성될때까지 기다리고 일정 횟수 이상이되면 그냥 skip하도록 배치를 짜면 나름(?) 방어로직이 될 것이다.

2019년 3월 30일 토요일

MSSQL(PDW)에서 ORC 타입으로 하둡에 데이터를 내리고 하이브 테이블 생성하기

MSSQL및 PDW(parallel data warehouse)에는 하둡과 연결고리가 잘 되어있다.
이들이 지원하는 PolyBase라는 기능은 RDBMS의 데이터와 하둡에 저장된 데이터를 조인할 수 있도록 하는데 예를 들어 하둡에 저장되어 있는 데이터를 RDBMS로 가져오고 둘을 조인해서 원하는 측정값을 뽑아내기에 매우 유용하다.

위 처럼 HDFS -> MSSQL(PDW) 로의 데이터 이동이 아닌 MSSQL(PDW) -> HDFS로 데이터를 내리는 것도 가능하며 예제는 다음과 같다. (PDW 기준으로 예제를 작성하였다.)

다음 예제는 ORC 타입으로 데이터를 내리는 방법이고 파케이(parquet)나 텍스트 등 다양한 타입 및 압축(Gzip, Snappy 등)으로 데이터 포맷을 생성할 수 있다.

먼저 데이터 소스랑 파일 포맷을 생성한다. (각 DB별로 생성할 수 있다.)


USE TEST_DB;
-- 데이터 소스 생성
IF EXISTS (SELECT * FROM sys.external_data_sources WHERE name = 'HDFS_DS_SNAPSHOT')
   DROP EXTERNAL DATA SOURCE HDFS_DS_SNAPSHOT

CREATE EXTERNAL DATA SOURCE HDFS_DS_SNAPSHOT
WITH (TYPE = HADOOP
, LOCATION = N'hdfs://XXX.XXX.XXX.XXX:8020'
, RESOURCE_MANAGER_LOCATION = N'XXX.XXX.XXX.XXX:8050')
GO

-- 파일 포맷 생성
IF EXISTS (SELECT * FROM sys.external_file_formats WHERE name = 'HDFS_FF_ORC')
   DROP EXTERNAL FILE FORMAT HDFS_FF_ORC

CREATE EXTERNAL FILE FORMAT HDFS_FF_ORC
WITH (
    FORMAT_TYPE = ORC,
    DATA_COMPRESSION = 'org.apache.hadoop.io.compress.SnappyCodec'
);

-- 생성된 데이터 소스 및 파일 포맷 확인
SELECT * FROM sys.external_data_sources
SELECT * FROM sys.external_file_formats


-- 하둡에 월 파티션으로 데이터 내리기

DECLARE @DT VARCHAR(8) = '20170101'
DECLARE @SQL NVARCHAR(4000);

WHILE(1=1)
BEGIN
      SET @SQL  = N' IF  OBJECT_ID(''TEST_DB..HDFS_TEST_TABLE_'+@DT+''') IS NOT NULL
                       DROP EXTERNAL TABLE HDFS_TEST_TABLE_' + @DT + '

      CREATE EXTERNAL TABLE HDFS_TEST_TABLE_' + @DT + '
      WITH (LOCATION=' + '''/apps/hive/xxxxxxxx/yyyyyyyy/zzzzzzzzz/TEST_TABLE/yyyymmdd=' + @DT + ''',
           DATA_SOURCE = HDFS_DS_SNAPSHOT,
           FILE_FORMAT = HDFS_FF_ORC,
           REJECT_TYPE = PERCENTAGE,
           REJECT_SAMPLE_VALUE = 10000,
           REJECT_VALUE = 0.1
      ) AS
      SELECT *
      FROM TEST_TABLE
      WHERE ' + N'DT' + ' >= ''' + @DT +  ''' AND ' + N'DT' +  ' < CONVERT(VARCHAR(8),DATEADD(MM,1,''' + @DT + '''),112) '

      --PRINT @SQL
      SET @DT = CONVERT(VARCHAR(8),DATEADD(MM,1,@DT),112)
      IF(@DT > '20180101')
        BREAK;
END



다음부터는 하이브에서 진행하며 위에서 생성한 HDFS를 사용한다.
-- 하이브에서 테이블 만들기
 CREATE EXTERNAL TABLE HDFS_TEST_TABLE
(
    `COL1` bigint ,
    `COL2` bigint ,
    `COL3` bigint ,
)
PARTITIONED BY (YYYYMMDD STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS ORC
LOCATION '/apps/hive/xxxxxxxx/yyyyyyyy/zzzzzzzzz/TEST_TABLE';

-- 파티션 적용하기
ALTER TABLE database_name.HDFS_TEST_TABLE ADD PARTITION (YYYYMMDD='20170101');
ALTER TABLE database_name.HDFS_TEST_TABLE ADD PARTITION (YYYYMMDD='20170201');
ALTER TABLE database_name.HDFS_TEST_TABLE ADD PARTITION (YYYYMMDD='20170301');
ALTER TABLE database_name.HDFS_TEST_TABLE ADD PARTITION (YYYYMMDD='20170401');
ALTER TABLE database_name.HDFS_TEST_TABLE ADD PARTITION (YYYYMMDD='20170501');
ALTER TABLE database_name.HDFS_TEST_TABLE ADD PARTITION (YYYYMMDD='20170601');
ALTER TABLE database_name.HDFS_TEST_TABLE ADD PARTITION (YYYYMMDD='20170701');
ALTER TABLE database_name.HDFS_TEST_TABLE ADD PARTITION (YYYYMMDD='20170801');
ALTER TABLE database_name.HDFS_TEST_TABLE ADD PARTITION (YYYYMMDD='20170901');
ALTER TABLE database_name.HDFS_TEST_TABLE ADD PARTITION (YYYYMMDD='20171001');
ALTER TABLE database_name.HDFS_TEST_TABLE ADD PARTITION (YYYYMMDD='20171101');
ALTER TABLE database_name.HDFS_TEST_TABLE ADD PARTITION (YYYYMMDD='20171201');


정리하면 MSSQL(PDW)에서 데이터 소스와 파일 포맷을 만들어주고 이를 활용해서 HDFS로 데이터를 내린다. 그리고 하이브에서 내린 데이터를 가지고 외부 테이블을 생성하면 된다.

2018년 10월 19일 금요일

SSIS에서 MSSQL Polybase로 Hadoop 데이터를 외부 테이블 생성할 때 팁

시나리오
하둡 데이터를 MSSQL로 매일 특정 시간에 가져오는 배치를 짠다고 가정한다. 이 경우 MSSQL에서는 해당 테이블을 polybase로 External Table을 만들게 된다.

예를 들어 하둡의 특정 경로 /app/analy/ods/visit/20181101처럼 끝에 날짜 포맷만 바꾸면서 데이터를 저장하고 이 데이터를 mssql로 가져오는 경우이다. 하나의 프로세스(배치)로 이루어지면 떨궈질때까지 기다리고 다 떨궈지면 가져오면 되지만 이 경우에는 하둡 데이터를 저장하는 것, MSSQL로 가져오는 것이 분리되어 있는 경우라고 가정한다.

우리는 하둡 경로를 알고 있을 때 MSSQL에서 다음처럼 데이터를 가져올 수 있다.
CREATE EXTERNAL TABLE ~
LOCATION ~
그러나 이 처럼 단순하게 해결되지 않는 경우가 있다.


문제점
특정 상황이 발생하여 하둡에 데이터가 생성되지 못했을 경우 CREATE 문을 실행하면 PATH가 존재하지 않는다는 에러가 난다.


해결방법
우리는 주기적으로 하둡 경로를 반복체크하면서 데이터가 생성된 이후에 MSSQL로 가져오면 된다.

하둡 명령어 중에 fs -test -s /app/analy/ods/visit/20181101 (-e는 path, -d는 directory, -f는 file 등 여러 옵션이 있다) 를 먼저 날려보고 결과로 0을 리턴하면 path가 존재한다는 의미이다.


즉 정리하면 다음과 같다.

1. 하둡 데이터를 떨굴 때 원하는 것을 다 떨구면 해당 경로에 success라는 크기가 0인 파일이나 폴더를 하나 더 떨구게 한다. (혹은 데이터 생성을 시작 할 때 start라는 폴더나 파일을 생성하게 하고 완료되면 success를 생성하게 해도 된다.)
2. 배치에서 데이터를 가져올 때 루프를 만들고 안에서 테이블을 생성하기 전에 fs -test -s /app/analy/ods/visit/20181101/success 를 날리도록 한다.
3. 리턴값이 0이면 success가 데이터가 존재하는 것이기 때문에 루프를 탈출하고 아니면 주기적으로 위의 명령어를 하둡에 찔러보게 한다.
4. 루프를 탈출하면 MSSQL에서 CREATE EXTERNAL TABLE 문 실행한다.

이런 방법을 데이터가 생성되기전까지 기다리는 것이기 때문에 보다 안전할 수 있다.

2022년 회고

 올해는 블로그 포스팅을 열심히 못했다. 개인적으로 지금까지 경험했던 내용들을 리마인드하자는 마인드로 한해를 보낸 것 같다.  대부분의 시간을 MLOps pipeline 구축하고 대부분을 최적화 하는데 시간을 많이 할애했다. 결국에는 MLops도 데이...