这篇主要讲如何将数据保存回Mysql,但是里面还会涉及到如何将错误信息以及提示信息保存到文件里,方便以后的运维,再有就是如何使用PHP写进程BAT。
Redis数据刷回数据库前的知识准备
首先针对上篇提到的关于redis刷回数据库的安全性的设计模式,因为我们使用的是list来做数据索引,所以在我们将list数据提取出来的时候,一旦redis在这时候出现异常,就会导致刚提取出来的数据丢失!有些小伙伴就说,丢失就丢失呗,才一点数据。但是我们做程序,就应该以严谨为基础,所以下面就来说下Redis List这位大佬给我们提供了什么帮助。
Redis List -》RpopLpush()函数
使用方法:RPOPLPUSH source destination
说明:命令RPOPLPUSH在一个原子时间内,执行以下两个动作:①命令RPOPLPUSH在一个原子时间内,执行以下两个动作;②将source弹出的元素插入到列表destination,作为destination列表的的头元素。
设计模式:
Redis的列表经常被用作队列(queue),用于在不同程序之间有序地交换消息(message)。一个程序(称之为生产者,producer)通过命令将消息放入队列中,而另一个程序(称之为消费者,consumer)通过RPOP命令取出队列中等待时间最长的消息。
不幸的是,在这个过程中,一个消费者可能在获得一个消息之后崩溃,而未执行完成的消息也因此丢失。
使用RPOPLPUSH命令可以解决这个问题,因为它在返回一个消息之余,还将该消息添加到另一个列表当中,另外的这个列表可以用作消息的备份表:假如一切正常,当消费者完成该消息的处理之后,可以用LREM命令将该消息从备份表删除。
Redis数据刷回数据库
方面文字太多?没关系。下面先来一段代码!我们的主体部分:
index.php:
1 <?php 2 require_once(__DIR__."/Mysql.class.php"); 3 require_once(__DIR__."/Redis.class.php"); 4 require_once(__DIR__."/Output_Log.class.php"); 5 6 7 $rel = true; //无限循环的变量 8 $num = 0; //用来没数据时的判断依据 9 date_default_timezone_set("Asia/Shanghai"); 10 $now = date("Y-m-d H:i:s"); //当前时间 11 //file log 12 $txt = dirname(__DIR__)."/Script_Log/clickgood_log.txt"; 13 $output = new OutputLog(); 14 $test = $output->open($txt,"a+"); 15 16 while($rel) 17 { 18 $redis = new RedisCtrl(); 19 20 //开始干活 21 if($num==0){ 22 //这里就是将信息输出到文件里记录,下面很多地方都是一样的。 23 $text = "start ".$name."\n"; 24 echo $text; 25 $output->write($test,$text); 26 } 27 28 //获取备份队列的长度 29 $copylistlength = $redis->llen("comment:uploadcopylist"); 30 31 //我这里展示的是第一数据回滚到mysql,小伙伴想批量回滚的,自己改装下就可以用了。 32 //自己动手丰衣足食! 33 if($copylistlength>1) 34 { 35 //由于是单一数据回滚,所以我要判断它是否超过我设定的值,小伙伴们最好也自己定一个阈值。 36 //report error 37 echo $now." ->false\n"; 38 $rel = false; 39 return; 40 } 41 else if($copylistlength==1) 42 { 43 //这里判断防止上次redis出现错误,导致数据没有及时回到mysql 44 $data = $redis->rpop("comment:uploadcopylist"); 45 $rel = $redis->UpdateClickGoodDataToMysql($data); 46 $text = $rel."\n"; 47 echo $text; 48 $output->write($test,$text); 49 } 50 else 51 { 52 //获取主要队列的长度 53 $listlength = $redis->llen("comment:uploadlist"); 54 if ($listlength>0) { 55 //使用之前说到的设计模式 56 $data = $redis->rpoplpush("comment:uploadlist","comment:uploadcopylist"); 57 58 $rel = $redis->UpdateClickGoodDataToMysql($data); 59 $text = $rel."\n"; 60 echo $text; 61 $output->write($test,$text); 62 }else{ 63 // 队列为空 64 // 打印关闭信息,这里的写法算是维持进程窗口不关闭,需要手动关闭 65 // 如果想让它执行完自动关闭的, 66 // 把下面改写成$rel = false; 67 if($num<=3){ 68 $text = $now." -> please close .\n"; 69 echo $text; 70 $output->write($test,$text); 71 $num++; 72 } 73 else 74 { 75 $output->close($test); 76 } 77 } 78 } 79 80 }