티스토리 뷰

반응형

시간 관련된 필드를 다룰때 글로벌을 고려하면 복잡할게 많아진다. 동일한 이벤트 발생 시점이라도 어떤 타임존에 있느냐에 따라서 시간을 표시하는게 달라지기 때문이다. 이런걸 고려하기 위해서 요즘은 절대적인 날짜값을 저장하고, 타임존 정보를 이용해서 시간을 다루는 필드들도 생겨나기 시작했다.

 

물론, 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] PostgreSQL 연동시 Doesn't support Postgres type 'jsonb' yet 문제

문제 Flink 에서 기본적으로 제공하는 JDBC Connector 는 Mysql , Derby, PostgreSQL 3개지를 지원한다. 나는 sql-client.sh 를 통해서 쿼리기반으로 데이터를 다루는걸 자주 이용하는데 카탈로그 등록이 되서 바.

ngela.tistory.com

코드를 찾아서 수정해 본 경험에 의하면 Flink 내부에서는 TIMESTAMP_LTZ 타입을 다룰때는 UTC+00 의 값으로 된걸 Input 으로 사용하고, 이 값에서 table.local-time-zone 을 고려해서  offset 을 계산후 로컬시간으로 변환한 결과를 출력해주는 차이가 있어 보인다.

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함