runsisi's

technical notes

Ceph 与夏令时

2019-02-12 runsisi#ceph#ntp

  1. 夏令时的英文是 Daylight Saving Time(DST);
  2. 夏令时是一个政府政策,而不是一个客观的物理规律;
  3. NTP 永远使用 UTC 时间,不存在时区以及夏令时的概念;
  4. 在 Linux 系统上,根据时区的设置,当需要进入夏令时的时间到了,系统会自动进行本地显示时间的调整(相应的 c 接口提供的 localtime 等 api 返回的结果会自动调整),具体哪个时区存在夏令时,以及什么时候进行时间的调整,这是由系统的 tzdata 这个安装包里面的数据决定的,完全不需要管理员进行手工调整,更不应该直接修改 NTP 时钟源(实际上如果这样做应该会存在冲突);
  5. 参考第 2 条,tzdata 是根据各国政府的政策动态更新的;
  6. 参考第 2 条,客户如果需要使用自定义的夏令时方案(即与 tzdata 中定义的,实际上也就是与国家政策不一致),则需要定制 tzdata 数据;
  7. ceph 不受 tzdata 规则所引起的本地时间变化的影响;

为什么 ceph 所在节点不能手工调整时间(注意要区别于 tzdata 定义的夏令时规则导致的时间跳变):

ceph 内部的定时器、时间戳等功能都需要得到当前时间(UTC 时间),调用的系统接口如下:

在 Linux 系统下调用 clock_gettime(CLOCK_REALTIME, &tp)

在非 Linux 系统(如 FreeBSD、MAC)下调用 gettimeofday(&tv, NULL)

而这两个接口都受系统时间调整的影响。

综上:

  1. 夏令时的问题应该由数据中心的维护人员来考虑,Ceph 不用考虑;
  2. Ceph 非常依赖时间的稳定,主要影响定时器、超时时间计算等;
  3. 调整时区或 tzdata 预定义的夏令时规则导致的本地时间变化不影响 Ceph,因为 gettimeofday / clock_gettime / chrono 等时间接口 / 库在不指定时区参数的情况下不受时区影响,而 Ceph 在使用这些接口/库时都没有指定时区;
  4. 调整时间(不管是向前还是向后,特别是小时级别的时间)会导致 Ceph 集群完全瘫痪(调整后的几分钟之内可能不会,但之后会),需要重启所有 Ceph 服务才能解决。

查看某个时区的夏令时信息:

~$ zdump -v Asia/Tokyo
Asia/Tokyo  -9223372036854775808 = NULL
Asia/Tokyo  -9223372036854689408 = NULL
Asia/Tokyo  Sat Dec 31 14:59:59 1887 UTC = Sun Jan  1 00:18:58 1888 LMT isdst=0 gmtoff=33539
Asia/Tokyo  Sat Dec 31 15:00:00 1887 UTC = Sun Jan  1 00:00:00 1888 JST isdst=0 gmtoff=32400
Asia/Tokyo  Sat May  1 14:59:59 1948 UTC = Sat May  1 23:59:59 1948 JST isdst=0 gmtoff=32400
Asia/Tokyo  Sat May  1 15:00:00 1948 UTC = Sun May  2 01:00:00 1948 JDT isdst=1 gmtoff=36000
Asia/Tokyo  Sat Sep 11 13:59:59 1948 UTC = Sat Sep 11 23:59:59 1948 JDT isdst=1 gmtoff=36000
Asia/Tokyo  Sat Sep 11 14:00:00 1948 UTC = Sat Sep 11 23:00:00 1948 JST isdst=0 gmtoff=32400
Asia/Tokyo  Sat Apr  2 14:59:59 1949 UTC = Sat Apr  2 23:59:59 1949 JST isdst=0 gmtoff=32400
Asia/Tokyo  Sat Apr  2 15:00:00 1949 UTC = Sun Apr  3 01:00:00 1949 JDT isdst=1 gmtoff=36000
Asia/Tokyo  Sat Sep 10 13:59:59 1949 UTC = Sat Sep 10 23:59:59 1949 JDT isdst=1 gmtoff=36000
Asia/Tokyo  Sat Sep 10 14:00:00 1949 UTC = Sat Sep 10 23:00:00 1949 JST isdst=0 gmtoff=32400
Asia/Tokyo  Sat May  6 14:59:59 1950 UTC = Sat May  6 23:59:59 1950 JST isdst=0 gmtoff=32400
Asia/Tokyo  Sat May  6 15:00:00 1950 UTC = Sun May  7 01:00:00 1950 JDT isdst=1 gmtoff=36000
Asia/Tokyo  Sat Sep  9 13:59:59 1950 UTC = Sat Sep  9 23:59:59 1950 JDT isdst=1 gmtoff=36000
Asia/Tokyo  Sat Sep  9 14:00:00 1950 UTC = Sat Sep  9 23:00:00 1950 JST isdst=0 gmtoff=32400
Asia/Tokyo  Sat May  5 14:59:59 1951 UTC = Sat May  5 23:59:59 1951 JST isdst=0 gmtoff=32400
Asia/Tokyo  Sat May  5 15:00:00 1951 UTC = Sun May  6 01:00:00 1951 JDT isdst=1 gmtoff=36000
Asia/Tokyo  Sat Sep  8 13:59:59 1951 UTC = Sat Sep  8 23:59:59 1951 JDT isdst=1 gmtoff=36000
Asia/Tokyo  Sat Sep  8 14:00:00 1951 UTC = Sat Sep  8 23:00:00 1951 JST isdst=0 gmtoff=32400
Asia/Tokyo  9223372036854689407 = NULL
Asia/Tokyo  9223372036854775807 = NULL

从上面的输出可以明显看到,日本东京从 1951 年开始就没有使用夏令时的政策了,但是如果日本东京的客户有夏令时的需求,则需要定制 tzdata 数据

时区相关的系统命令:

~$ timedatectl status
~$ timedatectl list-timezones
~$ sudo timedatectl set-timezone

所有的 tzdata 数据都在 /usr/share/zoneinfo/ 文件夹下,/etc/localtime 实际上就是指向 /usr/share/zoneinfo/ 下定义的一个时区数据。

验证 tzdata 定义的夏令时规则:

~$ zdump -v America/Chicago
...
America/Chicago  Sun Mar 11 07:59:59 2018 UT = Sun Mar 11 01:59:59 2018 CST isdst=0 gmtoff=-21600
America/Chicago  Sun Mar 11 08:00:00 2018 UT = Sun Mar 11 03:00:00 2018 CDT isdst=1 gmtoff=-18000
America/Chicago  Sun Nov  4 06:59:59 2018 UT = Sun Nov  4 01:59:59 2018 CDT isdst=1 gmtoff=-18000
America/Chicago  Sun Nov  4 07:00:00 2018 UT = Sun Nov  4 01:00:00 2018 CST isdst=0 gmtoff=-21600
...
~$ sudo timedatectl set-timezone America/Chicago
~$ sudo date -s '20180311 01:58:01'
~$ date
2018年 03月 11日 星期日 01:59:53 CST
~$ date -u
2018年 03月 11日 星期日 07:59:56 UTC
~$ date
2018年 03月 11日 星期日 01:59:58 CST
~$ date
2018年 03月 11日 星期日 03:00:01 CDT
~$ date -u
2018年 03月 11日 星期日 08:00:06 UTC

其中 CST 是 Central Standard Time,CDT 是 Central Daylight Time,用于北美(存疑,我国的也是这样,当前只需要知道 ST、DT 的区别就可以了)。

需要注意的是,在安装自定义的 tzdata 数据后,进程如果不重启的话是无法感知到夏令时变化的(包括系统进程都是如此),因此在日志、界面等需要展示本地时间的情况下仍然显示的是时间没有任何变化的样子(类似于夏令时从来发生过切换)。

参考资料

Do NTP Time Servers Adapt to Accommodate Daylight Saving Shifts?

Again, the answer is no. Network time servers, as well as being unaffected by time-zones, are also immune daylight saving time rules. Network time servers, such as those developed by Galleon Systems, only track UTC and serve time in UTC format. The fact that time servers track UTC is a convenient feature of network time protocol, because all that’s required is the IP address of a time server in order to synchronise it. Irrespective of the location of the time server, and the time-zone in which it operates, it’s the responsibility of the user to configure the time-zone on their computer.

Updating Daylight Saving Time on Linux

https://chrisjean.com/updating-daylight-saving-time-on-linux/

tz database

https://en.wikipedia.org/wiki/Tz_database

Daylight saving time: What’s up with those time servers?

https://www.networkworld.com/article/2295152/infrastructure-management/daylight-saving-time—what-s-up-with-those-time-servers-.html

Daylight Saving Time Rules

https://www.nist.gov/pml/time-and-frequency-division/popular-links/daylight-saving-time-dst

NTP Time Servers – Are They Affected By Daylight Savings Time?

http://www.galsys.co.uk/news/ntp-time-servers-affected-daylight-savings-time-galleon-systems-answers/