注:以Ubuntu为例说明
在Linux计算机上,有两个时间,一个是硬件时间(BIOS中记录的时间,称为hwclock),另一个是操作系统时间(osclock)。硬件时钟由BIOS电池供电,
当计算机关机后,会继续运行,BIOS电池一般可使用几年,如果没电了,那BIOS中的数据会恢复出厂设置。
1. 硬件时间
时间是有时区的,无论硬件时间还是操作系统时间。hwclock的时区在/etc/default/rcS文件中设置,里面有一个参数UTC,默认值为True,表示使用UTC时
区,如果设置为no,那表示使用osclock的时区。建议hwclock与osclock设置相同的时区。注:由于我的osclock也是UTC时间,所以这里UTC=yes还是
UTC=no都是一样的。
# assume that the BIOS clock is set to UTC time (recommended)
UTC=yes
查看硬件时间
njsqrt3@test:~$ sudo hwclock -r
Sun Dec :: AM UTC -1.044336 seconds
njsqrt3@test:~$
将osclock写入hwclock
zhj@test:~$ sudo hwclock -w
zhj@test:~$
2.操作系统时间
osclock的时区配置文件为/etc/timezone,如果你想修改,那最好使用sudo dpkg-reconfigure tzdata来修改时区,不建议直接修改/etc/timezone文件,
如果你想修改为UTC时间,那执行sudo dpkg-reconfigure tzdata命令时,选择None of the above->UTC 即可
zhj@test:~$ cat /etc/timezone
Etc/UTC
zhj@test:~$
查看osclock
zhj@test:~$ date
Sun Dec :: UTC
zhj@test:~$
修改osclock
#修改时/分/秒
sudo date -s hh:mm:ss #修改年/月/日
sudo date -s MM/DD/YY
我们一般会使用ntp同步osclock,这一点是非常重要的,无论你是单台主机还是集群,你要保证你的时间必须与国际原子时同步,如果你不同步,那你主机的时
间与国际原子时相差几秒甚至几分钟都是有可能的,想象一下,如果新浪微博的服务器没有同步时间,假设当前国际原子时间为2014-12-28T14:20:00Z,而新
浪微博服务器的时间为1989-06-04T10:00:00Z,那我发的微博就穿越了到了1989年6月4日,那天在*发生了大动乱,如果新浪微博的应用服务器集群之间
也没有时间同步,假定server1为2014-12-28T09:00:00Z,server2为2014-12-27T09:00:00Z,两者相差一天。我发微博时用的是server1,我的一个朋
友评论了我的微博,评论使用的是server2,这他妈奇迹就出现了,他的评论时间比我发微博的时间还早。
如果是单台主机,那我们的主机当ntp客户端就行了,找一个ntp服务器(如0.ubuntu.pool.ntp.org)直接使用ntpdate命令就可以同步,一般我们将它做成
cron定时任务,该任务将osclock与国际原子时同步后,还要将osclock写入hwclock(后面会讲为何将osclock刷入hwclock)。那如果是集群呢?我们一般是将其
中一台主机做成ntp服务器,安装ntpd软件(该软件就叫ntp,为了与ntp协议区分,这里用它的守护进程名ntpd代替),通过sudoapt-get install ntp安装,这
个软件既可以做服务端也可以做客户端。做为客户端,它从上层的ntp server那里获取到国际原子时;做为服务端,它为集群内中的客户机提供国际原子时
间。这样做可以节约外网网络带宽。
注:ntpd软件与ntpdate软件不能同时运行。对于集群中的ntp server服务器,要安装ntpd,配置好ntpd后,它会自动定时同步上层ntp server的时间到
osclock,不过它没有写入hwclock的配置项,所以我们还要手动在cron添加定时任务,将osclock写入hwclock。对于集群中的客户机,编写cron任务,用
ntpdate命令(一般的,在安装好Ubuntu后,就有该命令了)从集群ntp server的那里获取标准时间,更新osclock,同时更新后,也要将osclock写入hwclock。
3.硬件时间与操作系统时间的交互
下面说一下硬件时间与操作系统时间的交互流程
1、开机时,操作系统从BIOS中读取硬件时间+时区,然后根据osclock的时区,转换为对应的时间。然后操作系统时间与硬件时间就独立运行,相互不影响,我们
通过应用程序获取的时间用的都是操作系统时间。这一步是开机时os自动完成的。
2、主机运行过程中,通过ntp保证osclock与国际原子时同步,再将osclock同步到hwclock。这一步需要自己配置实现
3、关机时,osclock写入hwclock。这一步是关机时os自动完成的。不过我们要考虑异常关机的情况,当异常关机时,osclock可能没有写入hwclock,这就是为什
么在第2步中将osclock定时刷入hwclock的原因。如果不定时刷入,那osclock与hwclock差距比较大时,若异常关机,osclock就丢掉了,再开机时,osclock就是
错误的,在第一个ntp同步到来时,osclock就一直是错误的。而且如果使用的是ntpd,ntpd是渐进调整,要经过多个ntp同步周期后才会将osclock调整为国际原子
时,另外,如果osclock与ntp server的时间差超过1000秒,那ntp server就不会更新osclock了。(别,如果你安装了Ubuntu GUI,并设置了
System Settings->Time&Date->Automatically from the Internet,那它会自动同步时间)
4、ntpd与ntpdate
参见https://help.ubuntu.com/10.04/serverguide/NTP.html
ntpd当发现ntp client与ntp server时间不相同时,使用渐进同步,如果ntp server与client之间的差距超过1000秒,那就直接不同步了;ntpdate是跃迁式
同步,一步到位。ntpd与ntpdate是不能同时运行的,如下,在ntpd运行的情况下,执行ntpdate时会出错。ntpd和ntpdate使用的都是123号端口,然后我们把
ntpd停掉,再执行ntpdate,就可以了。
zhj@test:~$ sudo ntpdate .ubuntu.pool.ntp.org
Dec :: ntpdate[]: the NTP socket is in use, exiting
zhj@test:~$
zhj@test:~$ sudo service ntp stop
* Stopping NTP server ntpd [ OK ]
zhj@test:~$ date
Sun Dec :: UTC
zhj@test:~$ sudo ntpdate .ubuntu.pool.ntp.org
Dec :: ntpdate[]: adjust time server 202.112.31.197 offset 0.018119 sec
zhj@test:~$
一般的,在集群的ntp server主机上,考虑到该主机时间与国际原子时可能超过1000秒,一般先停止ntpd,然后用ntpdate同步一下时间,然后再开启ntpd
服务,自动定时同步。而集群中的ntp客户机,就在cron定时执行ntpdate和hwclock -w任务就行了。当然,如果你不嫌麻烦,也可以在客户机上安装ntpd服务,
前面我们提到ntpd既可以做服务端,又可以做客户端,这个在ntpd的配置文件/etc/ntp.conf中配置一下就行,restrict项只保留默认的下面四项即可,其它
restrict项注释掉,另外,你还是要在cron中设置定时任务hwclock -w
# By default, exchange time with everybody, but don't allow configuration.
restrict - default kod notrap nomodify nopeer noquery
restrict - default kod notrap nomodify nopeer noquery # Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict ::
参考:
linux系统时间和硬件时钟问题(date和hwclock)
鸟哥的 Linux 私房菜 -- 服务器架设篇目录 NTP 时间服务器