这是学习笔记的第 1817篇文章
在完成了前面三个系列的优化之后,一个明确的问题摆在我面前,如果实现动态调度。
动态调度的需求是怎样的呢?比如现在10:00,我需要10:30同步一次数据,那么10:30的时候同步时,我需要考虑现在的主从延迟,如果延迟较大,我需要把延迟的时间减掉,所以10:30开始同步的时间可能是10:28,可能是10:29,但是很可能不是10:30,另外一点就是假设是从10:29:00开始,那再下次调度的时候,起始时间怎么算,应该是10:29:01开始,下一次的调度程序怎么知道这个信息呢。
此外,如果现在的调度时间是30分钟,如果要调整为20分钟,怎么灵活支持。
这些问题摆在我面前,我发现暂时没有太好的解决方式。所以先做了手工调度,在这个过程中一点一点的琢磨怎么做到自动化的方式。
手工操作的一个好处就是通过大量的手工操作,你知道要改进什么,同时通过这些手工的不便捷性,告诉你什么才是正确的处理方式。
手工同步一共做了13次,每次都需要认真记录下时间点,如果一个时间点记录错误,所有的数据都就乱了。
第1次手工同步
sh a.sh '2018-11-29 10:40:01' '2018-11-29 11:30:00'|tee check2.log
第2次手工同步
sh a.sh '2018-11-29 11:30:01' '2018-11-29 11:40:00'|tee check3.log
第3次手工同步
sh a.sh '2018-11-29 11:40:01' '2018-11-29 13:35:00'|tee check4.log
第4次手工同步
sh a.sh '2018-11-29 13:35:01' '2018-11-29 13:50:00'|tee check4.log
第5次手工同步
sh b.sh
sh a.sh '2018-11-29 13:50:01' '2018-11-29 14:15:00'|tee check4.log
第6次手工同步
sh b.sh
sh a.sh '2018-11-29 14:15:01' '2018-11-29 14:25:00'|tee check4.log
第7次手工同步
sh b.sh
sh a.sh '2018-11-29 14:25:01' '2018-11-29 14:40:00'|tee check4.log
第8次手工同步
sh b.sh
sh a.sh '2018-11-29 14:55:01' '2018-11-29 15:15:00'|tee check4.log
第9次手工同步
sh b.sh
sh a.sh '2018-11-29 15:15:01' '2018-11-29 15:35:00'|tee check4.log
第10次手工同步
sh b.sh
sh a.sh '2018-11-29 15:35:01' '2018-11-29 16:00:00'|tee check4.log
第11次手工同步
sh b.sh
sh a.sh '2018-11-29 16:00:01' '2018-11-29 16:40:00'|tee check4.log
第12次手工同步
sh b.sh
sh a.sh '2018-11-29 16:40:01' '2018-11-29 17:25:00'|tee check4.log
第13次手工同步
sh b.sh
sh a.sh '2018-11-29 17:25:01' '2018-11-29 17:50:00'|tee check4.log
对我来说,最有压力的事情就是,如果这个事情今天搞不定,我就需要熬夜手工跑任务了。所以这种压力也是无形的动力。
最后写了一个版本的脚本,通过反复测试,达到了预期的效果。
部分代码如下所示:
slave_delay=`/usr/local/mysql/bin/mysql -udba_admin -pxxxx -h127.0.0.1 -P4306
-e "show slave status\G"|grep "Seconds_Behind_Master"|awk '{print $2}'`
echo "MySQL Slave delay: "$slave_delay
start_time_str=`cat /tmp/end_time`
start_time_int=`date -d "$start_time_str" +%s`
start_time_new_int=`expr ${start_time_int} + 1`
echo $start_time_new_int
start_time_new_str=`date -d @${start_time_new_int} +"%Y-%m-%d %H:%M:%S"`
echo $start_time_new_str
buffer_seconds=60
diff_seconds=`expr ${slave_delay} + ${buffer_seconds}`
end_time=`date -d "-${diff_seconds} seconds" +'%Y-%m-%d %H:%M:%S' `
echo $end_time
sh /root/a.sh "$start_time_new_str" "${end_time}" >> /root/log/data_sync_to_infobright.log
echo "end of process....." `date` >> /root/log/data_sync_to_infobright.log
脚本的思路是,数据同步需要两个参数,起始时间和截止时间,起始时间是通过上一次脚本执行生成的一个时间戳文件来得到的,即/tmp/end_time
截止时间是通过获得当前时间,然后计算延迟时间,两者相减,在这个基础上,设置一个缓冲时间(现在是设置了一分钟,预防其他异常情况),这样一来 当前时间 - 延迟时间 -缓冲时间,就得到了截止时间。
在这个基础上去抽取数据,如果计算得到的截止时间比起始时间早,整个抽取的逻辑就类似于 where 1>2,是抽不出数据的。
白天的时候,业务使用频率较高,可以把刷新频率设置的快一些,比如10分钟,而晚上的时候可以设置的慢一些,比如半个小时或者1个小时。
总之,满足了需求就是好的方案。