티스토리 뷰
시간 관련된 필드를 다룰때 글로벌을 고려하면 복잡할게 많아진다. 동일한 이벤트 발생 시점이라도 어떤 타임존에 있느냐에 따라서 시간을 표시하는게 달라지기 때문이다. 이런걸 고려하기 위해서 요즘은 절대적인 날짜값을 저장하고, 타임존 정보를 이용해서 시간을 다루는 필드들도 생겨나기 시작했다.
물론, Flink 에도 타임존을 고려한 날짜 필드가 존재한다. 그게 TIMESTAMP_LTZ 타입이다.
이 타입은 다음과 같이 Flink 에서 타임존 값에 영향을 받는다.
SET 'table.local-time-zone' = 'Asia/Shanghai';
타임존에 맞춰서 조회하려면?
TIMESTAMP_LTZ 필드는 타임존 세팅값에 따라서 값을 계산해서 출력해준다.
쉽게 생각해서 내부적으로는 UTC 와 같은 절대기준(?)의 시간값을 저장하고, 타임존값에 따라 시간값에 영향을 주는 방식이다.
이때 타임존을 변경해주는 설정이 table.local-time-zone 이다.
예를 들어, 타임존의 세팅값에 따라 Flink 에서는 동일한 데이터도 다르게 출력된다.
Flink SQL> set sql-client.execution.result-mode=tableau;
[INFO] Session property has been set.
Flink SQL> SET 'table.local-time-zone' = 'Asia/Seoul';
[INFO] Session property has been set.
-- TIMESTAMP_LTZ 타입필드 : created_at, updated_at, deleted_at
Flink SQL> SELECT id, created_at, updated_at, deleted_at, extra_data, campaign_type FROM postgre.mydb.sample WHERE id = 100324137798794 ;
+----+----------------------+----------------------------+----------------------------+----------------------------+--------------------------------+--------------------------------+
| op | id | created_at | updated_at | deleted_at | extra_data | campaign_type |
+----+----------------------+----------------------------+----------------------------+----------------------------+--------------------------------+--------------------------------+
| +I | 100324137798794 | 2021-05-03 08:39:54.151372 | 2021-05-04 08:43:46.510144 | 2021-05-04 08:43:46.510144 | {"templateKey": "standard_v... | BRAND |
+----+----------------------+----------------------------+----------------------------+----------------------------+--------------------------------+--------------------------------+
Received a total of 1 row
Flink SQL> SET 'table.local-time-zone' = 'UTC';
[INFO] Session property has been set.
Flink SQL> SELECT id, created_at, updated_at, deleted_at, extra_data, campaign_type FROM postgre.mydb.sample WHERE id = 100324137798794 ;
+----+----------------------+----------------------------+----------------------------+----------------------------+--------------------------------+--------------------------------+
| op | id | created_at | updated_at | deleted_at | extra_data | campaign_type |
+----+----------------------+----------------------------+----------------------------+----------------------------+--------------------------------+--------------------------------+
| +I | 100324137798794 | 2021-05-02 23:39:54.151372 | 2021-05-03 23:43:46.510144 | 2021-05-03 23:43:46.510144 | {"templateKey": "standard_v... | BRAND |
+----+----------------------+----------------------------+----------------------------+----------------------------+--------------------------------+--------------------------------+
Received a total of 1 row
위에 보면 동일한 데이터인데, 날짜값 데이터가 타임존 값에 따라 다르게 출력됨을 알수 있다.
UTC 와 타임존
타임존을 이야기 할때 "Asia/Seoul" 와 같은 문자열로 많이 이야기 하는데, 문제는 나라별 시간차를 인지하기 어렵다.
시간계산을 하기 편하려면 기준이 있고, 그 기준에서 얼마나 + 혹은 - 하면 되는지 가이드 하는게 편하다.
그래서 "협정 세계시(UTC)" 라는 시간의 기준을 만들고, 이 기준을 토대로 타임존별 몇시를 더하면 해당 로컬시간이 되는지 계산할수 있게 표기하는게 글로벌 시간과 로컬시간을 변환할 때 더 직관적이다. (참고로 UTC+0 은 그리니치 천문대가 있는 영국이 기준이다)
UTC 로 표현할 때는 Asia/Seoul 같은 문자열값이 아니라, UTC+09 형태로 시간 오프셋 값을 UTC옆에 숫자를 붙여주는 표현해서, 시간을 얼마나 가감해야 하는지 더 직관적으로 표현된다.
한국은 UTC+09
한국의 경우 9시간을 더해야하기 때문에, UTC+09 혹은 UTC+09:00 , UTC+0900 으로 이야기 한다.
아래 데이터 결과는 DBeaver 에서 postgresql 의 테이블을 조회한 결과이다. 잘 보면 날짜 필드옆에 +0900 같은 값이 보일텐데
해당 날짜 필드들은 "timestamptz" 타입이라서 타임존이 고려된 날짜시간 필드이다. 그래서 날짜 옆에 +0900 이런값이 날짜옆에 보이는것이고, 이는 UTC 타임존 기준에서 9시간을 더해서 만들어졌다는걸 의미한다. (즉, UTC 로 역산할땐 9시간을 빼야함)
예를 들어, 한국시간(UTC+9)이 2021-05-03 08:39:54 라면? 런던의 시간은(UTC+0) 2021-05-02 23:39:54 가 된다.
(UTC 에서 더할때는 9를 더해야하지만, 한국시간에서 UTC 를 구할땐 빼야한다는걸 헛갈리지 말자)
TIMESTAMP ? TIMESTAMP_LTZ?
Flink 에서 두 타입의 차이를 느끼는 가장큰 차이는 결론부터 말하면?
table.local-time-zone 옵션에 따라 값이 변경되는가 여부라고 결론 낼 수 있다.
TIMESTAMP 타입
타임존에 따른 값 변화 없음
-- TIMESTAMP 타입의 경우 타임존 바꿔도 값이 동일
Flink SQL> SET 'table.local-time-zone' = 'Asia/Seoul';
Flink SQL> select job_id, base_tm, create_at from postgre.mydb.sample_job limit 1;
+----+--------------------------------+----------------------------+----------------------------+
| op | job_id | base_tm | create_at |
+----+--------------------------------+----------------------------+----------------------------+
| +I | 00000a6b-294a-469b-b34c-b8e... | 2022-01-20 18:50:00.000000 | 2022-01-20 19:10:04.285885 |
+----+--------------------------------+----------------------------+----------------------------+
SET 'table.local-time-zone' = 'UTC';
Flink SQL> select job_id, base_tm, create_at from postgre.mydb.sample_job limit 1;
+----+--------------------------------+----------------------------+----------------------------+
| op | job_id | base_tm | create_at |
+----+--------------------------------+----------------------------+----------------------------+
| +I | 00000a6b-294a-469b-b34c-b8e... | 2022-01-20 18:50:00.000000 | 2022-01-20 19:10:04.285885 |
+----+--------------------------------+----------------------------+----------------------------+
TIMESTAMP_LTZ
타임존 설정이 달라지면 날짜값이 다르게 조회됨. (해당 타임의 시간으로 변환하여 출력됨)
Flink SQL> SET 'table.local-time-zone' = 'Asia/Seoul';
Flink SQL> SELECT id, created_at, updated_at FROM postgre.mydb.sample WHERE id = 100324137798794 ;
+----+----------------------+----------------------------+----------------------------+
| op | id | created_at | updated_at |
+----+----------------------+----------------------------+----------------------------+
| +I | 100324137798794 | 2021-05-03 08:39:54.151372 | 2021-05-04 08:43:46.510144 |
+----+----------------------+----------------------------+----------------------------+
Flink SQL> SET 'table.local-time-zone' = 'UTC';
Flink SQL> SELECT id, created_at, updated_at FROM postgre.mydb.sample WHERE id = 100324137798794 ;
+----+----------------------+----------------------------+----------------------------+
| op | id | created_at | updated_at |
+----+----------------------+----------------------------+----------------------------+
| +I | 100324137798794 | 2021-05-02 23:39:54.151372 | 2021-05-03 23:43:46.510144 |
+----+----------------------+----------------------------+----------------------------+
참고로 Flink 에서 Postgresql JDBC Connector 에서 timestamptz 필드 타입의 조회는 지원하지 않는데, 이걸 조회하도록 수정해서 테스트한건데 이부분이 궁금한 사람은 아래 포스팅을 참고하자.
https://ngela.tistory.com/29?category=1001093
코드를 찾아서 수정해 본 경험에 의하면 Flink 내부에서는 TIMESTAMP_LTZ 타입을 다룰때는 UTC+00 의 값으로 된걸 Input 으로 사용하고, 이 값에서 table.local-time-zone 을 고려해서 offset 을 계산후 로컬시간으로 변환한 결과를 출력해주는 차이가 있어 보인다.
'데이터처리 > Flink' 카테고리의 다른 글
[FLINK] Avro 포맷에서 TO_TIMESTAMP_LTZ 사용시 정밀도 오류 (0) | 2022.07.15 |
---|---|
[FLINK] _metadata 파일 확인하는 방법 (savepoint, checkpoint) (0) | 2022.06.24 |
[Flink] Explode 쿼리 표현하기 - Cross join unnest (0) | 2022.05.31 |
Flink Application 개발시 Avro 라이브러리 충돌 문제 해결방법 (0) | 2022.05.27 |
[Flink] Could not acquire the minimum required resources 이유와 해결방법 (0) | 2022.05.24 |