00. 背景
最近工作的时候遇到一些与ntp时间同步相关的问题:
- ntp 服务对数据库高可用架构的影响(高可用架构失效)
- ntp 与linux系统时区,cpu tick的关系(对时间相关的进程执行有影响)
- ntp 或系统时区调整后,对数据库已有数据有哪些影响?
01. 什么是 ntp 服务?
NTP是网络时间同步协议,就是用来同步网络中各个计算机的时间的协议。
通信原理:首先主机启动NTP。客户端会向NTP服务器发送调整时间的message。然后NTP server会送出当前的标准时间给client,client接受来自server的时间后,会根据这个信息来调整自己的时间。这样就实现了网络对时。
具体有两种同步模式
- 服务器数量比较少的,可以直接与时间服务器同步
- 本地服务器较多,在本地自建时间同步服务器,进行集群间的时间同步
常规操作方式
- 使用ntpd来校准时钟(改变时间快慢),而不是调整计算机时钟上的时间(改变具体时间)。
- 在计算机刚刚启动,但还没有启动很多服务的那个时候可以使用ntpdate同步时间
- NTPD 在和时间服务器的同步过程中,会把 BIOS 计时器的振荡频率偏差记录下来。这样即使网络有问题,本机仍然能维持一个相当精确的走时。
时间同步的两个命令
-
ntpd :校准时间,一点点的校准过来时间的,最终把时间慢慢的校正对。ntpd服务可以在修正时间的同时,会修正cpu tick,tick 属于硬件时钟,能相对的改变时间走的快慢。ntpd有一个自我保护设置: 如果本机与上源时间相差太大, ntpd不运行。
-
ntpdate :不会考虑其他程序是否会有问题,直接同步调整系统时间,有可能会对程序造成影响。
-
cpu tick:类似于cpu的一个刷新频率。例如:在游戏中,游戏世界的变化是离散的,也就是说计算机以一个固定的频率来刷新事物的变化。这个速率如果太慢,那玩家可以感受到东西都是跳变的;这个速率太快,自然就越流畅,但是会吃CPU。系统时间是与CPU的刷新频率相关联的。
02. ntp 时间同步
直接用 ntpdate 命令与时间服务器进行同步(必须先关闭客户端ntpd服务)
ntpdate -u x.x.x.x
这里的x.x.x.x可以是公网时间服务器IP地址,也可以是自建的ntp服务器地址。
几个公网时间服务器:阿里云时间服务器,授时信号来自GPS、北斗两套卫星信号,并配备原子钟守时。
http://time1.aliyun.com
http://time2.aliyun.com
http://time3.aliyun.com
http://time4.aliyun.com
http://time5.aliyun.com
http://time6.aliyun.com
http://time7.aliyun.com
也可以自建ntp服务器(具体配置略,直接介绍常规使用)
# 安装
yum install ntp
# 开机自启动
chkconfig ntpd on
# 查看NTP是否正常运行
netstat -tlunp | grep ntp
# 配置防火墙过滤规则
/sbin/iptables -I INPUT -p udp --dport 123 -j ACCEPT
配置/etc/sysconfig/ntpd文件
- ntp服务,默认只会同步系统时间。如果想要让ntp同时同步硬件时间,可以设置/etc/sysconfig/ntpd文件,在 /etc/sysconfig/ntpd 文件中,添加 SYNC_HWCLOCK=yes 这样,就可以让硬件时间与系统时间一起同步。
启动 ntpd 服务
service ntpd start
配置NTP客户端(其他更详细略,防火墙策略等等):
在所有客户端上vim /etc/ntp.conf,添加:
server x.x.x.x
x.x.x.x 为上面配置的ntp服务器地址
注意:当server与client之间的时间误差过大时(可能是1000秒),处于对修改时间可能对系统和应用带来不可预知的问题,NTP将停止时间同步!所以如果发现NTP启动之后时间并不进行同步时,应该考虑到可能是时间差过大引起的,此时需要先手动进行时间同步 ntpdate 。
查看ntp服务器与上层ntp服务器的状态
ntpq -p
- remote:本机和上层ntp的ip或主机名,“+”有连线可做候选,“*”正在使用的
- refid:更上一层的ntp地址
- st:stratum的 级别
- when:多少秒前曾经同步过时间
- poll: 下次更新在多少秒后
- reach: 已经向上层ntp服务器要求更新的次数
- delay: 网络延迟
- offset: 时间补偿
- jitter: 系统时间与bios时间差
# ntpq -p
remote refid st t when poll reach delay offset jitter
==============================================================================================
* time4.aliyun.co 10.137.38.86 2 u 111 128 377 27.480 -5.995 1.852
手动同步一次时间:/usr/sbin/ntpdate 10.137.38.86 (服务端主机IP,这里客户端需要先关闭NTP服务)
启动NTP服务:
service ntpd start
观察时间同步状况:
ntpq -p
观察同步结果 ntpstat 命令
# ntpstat
unsynchronised
polling server every 8 s
同步失败,同步也需要时间嘛,需等待5-10分钟再次查询:
Every 2.0s: ntpstat Tue Jul 11 16:55:57 2017synchronised to NTP server (10.10.11.247) at stratum 12 time correct to within 605 ms polling server every 128 s
时间同步完成,date一下是不是和服务器主机时间一致!!!
03. linux 系统时间
Linux的时间分为 System Clock(系统时间)和Real Time Clock (硬件时间,简称RTC)。
- 系统时间:指当前Linux Kernel中的时间。
- 硬件时间:主板上有电池供电的时间。
查看系统时间
date
查看硬件时间
hwclock --show
或
clock --show
硬件时间和系统时间的同步。重新启动系统,硬件时间会读取系统时间同步,如果不重新启动的系统,要用hwclock或clock命令实现同步。
硬件时钟与系统时钟同步:(hc代表硬件时间,sys代表系统时间)
# hwclock --hctosys
或者
# clock --hctosys
系统时钟和硬件时钟同步:
# hwclock --systohc
或者
# clock --systohc
时区的设置使用 tzselect 命令
04. 系统时间对数据库有何影响?
数据库时间字段的存储
- 数据库的 “时间字段” 底层其实都是翻译为时间戳存储在磁盘上的
- 例如 insert 一条时间数据字段,会以当前数据库的时区翻译为时间戳后存储在磁盘上(如果直接是时间戳则忽略翻译)。
- 数据库自动生成时间函数(now、system)也会获取当前linux的时间戳,再以当前数据库的时区翻译为时间显示,直接存储对应的linux时间戳。这些函数的显示结果可能与linux时间不一致(linux与数据库时区不同)
数据库时间字段的读取
- 把磁盘上的时间戳翻译为当前数据库的时区时间,然后发送给客户端显示。
- 数据库相关时间函数直接读取linux的时间戳
修改系统时间或时区
-
数据库也有时区相关的参数可以设置,一般在部署的时候就一定确定,后期不改动(会导致时间显示混乱)。
-
数据库的时区一般与linux的时区保持一致。如果不一致,同一个时间戳,在linux显示和数据库显示的不一样。
-
数据库系统时间依赖于linux的系统时间,数据库的一些时间函数now、system 读取linux的时间戳,如果时区不一致,linux与数据库同一个时间戳结果显示不同。
-
修改linux系统时间会对数据库系统时间产生影响,肯定会对now,system产生影响,如果你的业务对时间有唯一性要求,那肯定会报错(如果时间是往未来修改那可以)。
-
ntp 可以把另一台机器上的时间同步到当前服务器(如果是向未来调整时间那没问题),如果一些进程或业务依赖于时间次序,那向过去调整时间,一定会有报错!!!
-
ntp 同步时间或修改linux系统时间时区,不会影响已有的数据,只会影响即将存入的数据。
总结:时区修改有风险,时间修改向未来,具体要看有没有依赖于时间次序的业务(例如,向过去修改时间)。