Управление часовыми поясами
Doris позволяет настраивать часовые пояса. В этом документе описаны назначение параметров часовых поясов в Doris, способы их просмотра и настройки, влияние часового пояса на функции и типы данных, обработка летнего времени и рекомендации по работе с данными, зависящими от часового пояса.
Сценарии применения
| Сценарий | Описание |
|---|---|
| Инициализация кластера | Настройка time_zone после развертывания с учетом региона работы или единого стандарта |
| Загрузка данных из разных часовых поясов | Загрузка данных с информацией о часовом поясе или без нее через Stream Load, Broker Load и аналогичные механизмы |
| Согласование результатов функций | Настройка часового пояса для значений, возвращаемых такими функциями, как NOW(), CURTIME() и FROM_UNIXTIME |
| Обработка летнего времени | Работа с именованными часовыми поясами (например, America/Los_Angeles), в которых действует переход на летнее время |
| Обновление данных о часовых поясах | Обновление данных о часовых поясах на машинах BE после выпуска новой версии tzdata организацией IANA |
Основные понятия
В Doris есть два параметра, связанных с часовыми поясами:
| Параметр | Можно изменить | Описание |
|---|---|---|
system_time_zone | Нет | Автоматически задается системой при запуске сервера на основе локального часового пояса машины. После установки изменить его нельзя. |
time_zone | Да | Текущий часовой пояс кластера. При запуске кластера совпадает с system_time_zone и остается неизменным, если его не изменить вручную. |
Просмотр и настройка часового пояса
Просмотр текущего часового пояса
Чтобы просмотреть переменные, связанные с часовыми поясами, выполните следующий оператор SQL:
show variables like '%time_zone%';
Настройка часового пояса
Измените time_zone с помощью оператора SET:
SET [global] time_zone = 'Asia/Shanghai';
- Без ключевого слова
global: изменение действует только в текущем сеансе. - С ключевым словом
global: Doris FE сохраняет параметр, и он действует во всех последующих новых сеансах.
Источник данных о часовых поясах
Данные о часовых поясах включают их названия, соответствующие смещения времени, переходы на летнее время и другие сведения. На машине BE эти данные берутся из каталога, возвращаемого командой TZDIR. Если команда не поддерживается, источником служит каталог /usr/share/zoneinfo.
Форматы значений часового пояса
Значения часового пояса можно задавать в нескольких форматах. Doris полностью поддерживает следующие стандартные форматы:
| Тип | Пример | Описание |
|---|---|---|
| Стандартное имя часового пояса | Asia/Shanghai, America/Los_Angeles, Etc/GMT+3 | Берется из локальных данных о часовых поясах |
| Стандартный формат смещения | +02:30, -10:00 | Нестандартные смещения, такие как +12:03, не поддерживаются |
| Сокращенное обозначение часового пояса | GMT, UTC | Соответствует часовому поясу +00:00 |
| Сокращенное обозначение часового пояса | CST | Соответствует часовому поясу Asia/Shanghai |
| Одна буква Z | Z | Обозначает часовой пояс Zulu, соответствующий часовому поясу +00:00 |
Кроме того, регистр букв при разборе не учитывается.
Из-за различий в реализации некоторые другие форматы сейчас поддерживаются в отдельных механизмах загрузки. В производственной среде нельзя полагаться на форматы, не перечисленные здесь. Их поведение может измениться в любой момент. Следите за соответствующими обновлениями в списке изменений каждого выпуска.
Влияние часового пояса
Влияние на функции
Часовой пояс влияет на значения, возвращаемые функциями времени, такими как NOW() и CURTIME(), а также на значения времени, отображаемые в SHOW LOAD и SHOW BACKENDS.
При этом он не влияет на значения LESS THAN для столбцов секционирования с типами даты и времени в CREATE TABLE и не влияет на отображаемые значения данных, хранящихся в типах DATE или DATETIME.
Функции, на которые влияет часовой пояс:
| Функция | Поведение |
|---|---|
FROM_UNIXTIME | Принимает временную метку UTC и возвращает дату и время в часовом поясе, заданном переменной сеанса Doris time_zone. Например, если time_zone имеет значение CST, FROM_UNIXTIME(0) возвращает 1970-01-01 08:00:00. |
UNIX_TIMESTAMP | Принимает дату и время и возвращает временную метку UTC, интерпретируя входное значение в часовом поясе, заданном переменной сеанса Doris time_zone. Например, если time_zone имеет значение CST, UNIX_TIMESTAMP('1970-01-01 08:00:00') возвращает 0. |
CURTIME | Возвращает текущее время в часовом поясе, заданном переменной сеанса Doris time_zone. |
NOW | Возвращает текущие дату и время в часовом поясе, заданном переменной сеанса Doris time_zone. |
CONVERT_TZ | Преобразует дату и время из одного указанного часового пояса в другой. |
Влияние на типы данных даты и времени
Типы DATE / DATETIME
Для типов DATE и DATETIME поддерживается преобразование часовых поясов при загрузке данных:
- Данные с часовым поясом: например, если входное значение равно
2020-12-12 12:12:12+08:00, а заголовок Stream Loadtimezoneимеет значение+00:00, в Doris фактически сохраняется значение2020-12-12 04:12:12. - Данные без часового пояса: например,
2020-12-12 12:12:12рассматривается как абсолютное время, и преобразование не выполняется.
Тип TIMESTAMPTZ
Тип TIMESTAMPTZ также поддерживает преобразование часовых поясов при загрузке данных: входное значение времени всегда преобразуется в UTC (всемирное координированное время), а при выводе применяется часовой пояс текущего сеанса.
- Данные с часовым поясом: например, для значения
2020-12-12 12:12:12+08:00Doris использует указанную информацию о часовом поясе для преобразования. - Данные без часового пояса: например, для значения
2020-12-12 12:12:12Doris использует настройку часового пояса текущего сеанса для преобразования.
Параметр time_zone текущего сеанса влияет на вывод значений типа TIMESTAMPTZ. Например, если в текущем сеансе задано time_zone="+08:00", а значение TIMESTAMPTZ равно 2020-12-12 12:12:12+08:00, изменение time_zone меняет выводимое значение:
set time_zone = "+08:00";
select * from tz_test;
+---------------------------+
| tz |
+---------------------------+
| 2020-12-12 12:12:12+08:00 |
+---------------------------+
set time_zone = "+07:00";
select * from tz_test;
+---------------------------+
| tz |
+---------------------------+
| 2020-12-12 11:12:12+07:00 |
+---------------------------+
Летнее время
Летнее время означает, что фактическое смещение именованного часового пояса меняется в определенном диапазоне дат.
Например, в часовом поясе America/Los_Angeles ежегодно действует один период летнего времени, который начинается примерно в марте и заканчивается примерно в ноябре. При переходе на летнее время в марте фактическое смещение America/Los_Angeles меняется с -08:00 на -07:00. После окончания летнего времени в ноябре оно меняется обратно с -07:00 на -08:00.
Если вы не хотите использовать летнее время, задайте для time_zone значение -08:00 вместо America/Los_Angeles.
Рекомендации
Работа с данными, зависящими от часового пояса
При работе с часовыми поясами важны три основных фактора:
- Часовой пояс кластера: переменная сеанса
time_zone. - Часовой пояс загрузки: заголовок
timezone, указанный при использовании Stream Load, Broker Load и аналогичных механизмов загрузки. - Часовой пояс данных: литерал часового пояса в данных (например,
+08:00в2023-12-12 08:00:00+08:00).
Doris поддерживает загрузку данных из любого часового пояса. Поскольку такие типы данных времени в Doris, как DATETIME, не содержат внутри себя информацию о часовом поясе, а сохраненные данные после загрузки не меняются при изменении часового пояса, загружаемые в Doris данные времени делятся на две категории:
-
Абсолютное время
Абсолютное время означает, что сценарий использования данных не зависит от часового пояса. Для таких данных не указывайте суффикс часового пояса при загрузке. Данные сохраняются без изменений.
-
Время в определенном часовом поясе
Время в определенном часовом поясе означает, что сценарий использования данных зависит от часового пояса. Для таких данных указывайте суффикс конкретного часового пояса при загрузке. Во время загрузки данные преобразуются в часовой пояс, заданный параметром кластера Doris
time_zoneили заголовкомtimezoneв Stream Load или Broker Load.После загрузки такие данные хранятся как абсолютное время в часовом поясе, указанном при загрузке. При последующих загрузках и запросах необходимо сохранять тот же часовой пояс, чтобы не нарушить смысл данных.
Пример оператора INSERT
Doris > select @@time_zone;
+---------------+
| @@time_zone |
+---------------+
| Asia/Shanghai |
+---------------+
Doris > insert into dt values('2020-12-12 12:12:12+02:00'); --- The ingested data specifies the time zone as +02:00
Doris > select * from dt;
+---------------------+
| dt |
+---------------------+
| 2020-12-12 18:12:12 | --- Converted to the Doris cluster time zone Asia/Shanghai. Subsequent ingestion and queries must keep this time zone.
+---------------------+
Doris > set time_zone = 'America/Los_Angeles';
Doris > select * from dt;
+---------------------+
| dt |
+---------------------+
| 2020-12-12 18:12:12 | --- If time_zone is changed, the time value does not change, and its meaning at query time becomes inconsistent.
+---------------------+
Пример Stream Load
Для таких механизмов загрузки, как Stream Load и Broker Load, преобразование часовых поясов можно выполнять с помощью заголовка timezone. Например:
cat dt.csv
2020-12-12 12:12:12+02:00
curl --location-trusted -u root: \
-H "Expect:100-continue" \
-H "strict_mode: true" \
-H "timezone: Asia/Shanghai" \
-T dt.csv -XPUT \
http://127.0.0.1:8030/api/test/dt/_stream_load
Doris > select @@time_zone;
+---------------+
| @@time_zone |
+---------------+
| Asia/Shanghai |
+---------------+
Doris > select * from dt;
+---------------------+
| dt |
+---------------------+
| 2020-12-12 18:12:12 | --- Converted to the Doris cluster time zone Asia/Shanghai. Subsequent ingestion and queries must keep this time zone.
+---------------------+
- Для таких механизмов загрузки, как Stream Load и Broker Load, заголовок
timezoneимеет приоритет над параметром кластера Doristime_zone, поэтому при загрузке их значения должны совпадать. - Для таких механизмов загрузки, как Stream Load и Broker Load, заголовок
timezoneвлияет на функции, используемые при преобразовании данных во время загрузки. - Если заголовок
timezoneне указан при загрузке, по умолчанию используется текущий часовой пояс кластера.
Основные рекомендации
- Перед началом использования определите, какой часовой пояс должен представлять кластер, задайте
time_zoneи больше не меняйте его. - При загрузке задавайте в заголовке
timezoneто же значение, что и в параметре кластераtime_zone. - Для абсолютного времени не указывайте суффикс часового пояса при загрузке. Для времени с учетом часового пояса указывайте суффикс конкретного часового пояса. При загрузке данные преобразуются в часовой пояс Doris
time_zone.
Рекомендации по летнему времени
Время начала и окончания летнего времени берется из текущего источника данных о часовых поясах и может не совпадать в точности с официальным временем, установленным в соответствующем регионе на текущий год. Эти данные поддерживает ICANN.
Чтобы обработка летнего времени соответствовала официальным правилам текущего года, убедитесь, что Doris использует последние данные о часовых поясах, опубликованные ICANN. Способ загрузки описан ниже.
Обновление информации о часовых поясах
Данные о часовых поясах и летнем времени периодически меняются по разным причинам. IANA регулярно фиксирует эти изменения и обновляет соответствующие файлы часовых поясов. Чтобы информация о часовых поясах в Doris соответствовала последним данным IANA, воспользуйтесь одним из следующих двух способов:
Способ 1: обновление с помощью менеджера пакетов
В зависимости от менеджера пакетов текущей операционной системы обновите данные о часовых поясах соответствующей командой:
# yum
sudo yum update tzdata
# apt
sudo apt update tzdata
Обновленные таким способом данные находятся в системном каталоге $TZDIR (обычно /usr/share/zoneinfo).
Способ 2: получение базы данных часовых поясов IANA напрямую (рекомендуется)
В большинстве дистрибутивов Linux данные tzdata обновляются через менеджер пакетов с задержкой. Если вам нужна более высокая точность данных о часовых поясах, загружайте данные, которые IANA периодически публикует, напрямую:
wget https://www.iana.org/time-zones/repository/tzdb-latest.tar.lz
Затем следуйте инструкциям README в распакованном каталоге, чтобы сформировать необходимые данные zoneinfo. Скопируйте сформированные данные в каталог $TZDIR, перезаписав существующие файлы.
После выполнения всех указанных выше операций на машине BE необходимо перезапустить соответствующий BE, чтобы изменения вступили в силу.
Часто задаваемые вопросы
Вопрос: почему после изменения time_zone неожиданно меняются результаты запросов к существующим данным?
Такие типы, как DATETIME, не содержат внутри себя информацию о часовом поясе, и изменение часового пояса кластера после загрузки не меняет сохраненные значения. Перед началом использования определите часовой пояс кластера, задайте time_zone и больше не меняйте его.
Вопрос: почему смещение времени в данных, загруженных через Stream Load, не соответствует ожиданиям?
Значение заголовка timezone не совпадает с параметром кластера time_zone. Значение заголовка timezone должно совпадать с параметром кластера time_zone.
Вопрос: почему время, возвращаемое NOW(), не совпадает с местным временем?
Параметр кластера time_zone не соответствует локальному часовому поясу. Измените его с помощью SET global time_zone = 'Asia/Shanghai'.
Вопрос: почему переход на летнее время в именованном часовом поясе не соответствует правилам текущего года?
Данные tzdata на машине BE устарели. Обновите tzdata с помощью менеджера пакетов или загрузите tzdata IANA напрямую, затем перезапустите BE.
Вопрос: что делать, если я использую America/Los_Angeles, но не хочу включать летнее время?
Именованные часовые пояса включают правила летнего времени. Вместо них используйте формат с фиксированным смещением, например -08:00.
Дополнительные материалы
- Список форматов часовых поясов: Список часовых поясов базы данных tz
- База данных часовых поясов IANA: База данных часовых поясов IANA
- База данных часовых поясов ICANN: Архивы tz-announce