携程一次Redis迁徙容器后Slowlog“非常”说明
两个批次宿主机一样的内核版本,第一批没题目而第二批有题目,差别只也许在硬件上,很是有也许在计时上,翻看内核的commit log终于让我们发明白这样的commit,如图8所示: 图 8 该commit很是清晰指出,在4.9往后添加了一个宏界说INTEL_FAM6_SKYLAKE_X,但由于搞错了该范例CPU的crystal frequency会导致该范例的CPU每10分钟慢1秒钟。 这时再看看我们的出题目的第二批宿主机xeon bronze 3104正好是skylake-x的处事器,影响4.9-4.13的内核版本,宿主机内核4.10正好中招。 而且NTP每次同步隔断1024秒约慢1700ms,与slowlog非常完全相符,而第一批次的呆板CPU都不是SKYLAKE-X平台的,避开了这个BUG,迁徙之前Redis地址的物理机内核是3.10版本,天然也不存在这个题目。至此,终于解开上面三个迷惑。 五、总结 5.1 题目根因 通过上面的说明可以看出,题目根因在于内核4.9-4.13之间skylake-x平台TSC晶振频率的代码BUG,也就是说同时触发这两个身分城市导致体系时钟变慢,叠加上Redis计时行使的gettimeofday会轻易被NTP修改导致了本文开头诡异的slowlog“非常”。有题目的宿主机内核进级到4.14版本后,时钟变慢的BUG获得了修复。 5.2 怎么获取时钟 对付应用必要解决记录当前时刻的场景,也就是说获取Wall-Clock,可以行使clock_gettime传入CLOCK_REALTIME参数,固然gettimeofday也可以实现同样的成果,但不提议继承行使,由于在新的POSIX尺度中该函数已经被废弃。 对付应用必要记录某个要领耗时的场景,必需行使clock_gettime传入CLOCK_MONOTONIC参数,该参数得到的是自体系开机起单调递增的纳秒级别精度时钟,对比gettimeofday精度进步不少,而且不受NTP等外部处事影响,能精确更精确来统计耗时(Java中对应的是System.nanoTime),也就是说全部行使gettimeofday来统计耗时(Java中是System.currenttimemillis)的做法本质上都是错误的。 【编辑保举】
点赞 0 (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |