第一种方法:使用insert into 插入
从Redis每次获取100条数据,根据条件去插入到Mysql数据库中:
条件:
如果当前队列中的值大于1000条,则会自动的条用该方法,该方法每次获取从队列的头部每次获取100掉数据插入到Mysql数据库中,同时以当前队列的长度为插入条件。
1000为原始数据,从队列头获取100条,插入到Mysql数据,同时删除已经插入的数据,再通过队列的长度判断是否继续插入,直到循环不满足条件为止。
[1]获取头100条数据:$redis->lRange($liveKey,0,99)
[2]删除头100条数据:$redis->lTrim($liveKey, 100, -1);
[1]获取当前队列长度:$redis->lLen($liveKey);
public function redisSaveMysqlAction() { $liveKey = $this->request->getQuery('liveKey'); if(empty($liveKey)){ $result = array("errcode" => 500, "errmsg" => "this parameter is empty!"); return $this->toJson($result); } $redis = new \Redis(); $redis->connect('1.1.2.16', '6379'); $redisInfo = $redis->lRange($liveKey,0,99); $dataLength = $redis->lLen($liveKey); while($dataLength > 200) { try { $this->db->begin(); foreach ($redisInfo as $action) { $sql = "INSERT INTO livecomment (liveId,username,createTime,userId,content) VALUES (?, ? ,?,? ,?)"; $this->db->execute($sql, array( json_decode($action,true)['roomId'], json_decode($action,true)['userName'], json_decode($action,true)['createTime'], json_decode($action,true)['userId'], json_decode($action,true)['content'], )); } $redis->set('message_insert_success', '1'); $redis->lTrim($liveKey, 100, -1); $redisInfo = $redis->lRange($liveKey,0,99); // 这句也要重新的获取,不然就会插入重复的数据,也就是获取删除后的数据 $dataLength = $redis->lLen($liveKey); //注意这句一定要加上的,做为下一次的判断标准,当插入完后和删除后,重新获取列表的长度,作为条件依据 $redis->set('dataLength_backenk', $dataLength); $this->db->commit(); } catch (\Exception $e) { $redis->set('message_insert_fail', '0'); $this->db->rollback(); } } $redis->set('log'.$liveKey,$redis->incr('request_counts')); $result = array("errcode" => 200, "errmsg" => "Data Insert into Success!",'data'=>'dataLength:'.$dataLength.'liveKey:'.$liveKey); return $this->toJson($result);
第二种方法:使用优化SQL语句:将SQL语句进行拼接,使用 insert into table () values (),(),(),()然后再一次性插入,如果字符串太长,则需要配置下MYSQL,在mysql 命令行中运行 :set global max_allowed_packet = 2*1024*1024*10;
拼接后的字符串:
'insert into twenty_million (value) values('50'),('50'),('50'),('50'),('50'),('50'),('50'),('50'),('50'),('50')'
实际案例:
/** * 获取Redis数据批量的保存到Redis中去解析Redis数据的json格式 */ public function RedisSaveToMysqlJsonAction() { $redis = RedisInstance::getInstance(); $redis->select(1); $redisInfo = $redis->lRange('message01',0,9999); $dataLength = $redis->lLen('message01'); $redis->set('dataLength_front',$dataLength); $t1=microtime(true); while($dataLength > 20000) { try { $this->db->begin(); $sql = "INSERT INTO stream_name (name,createTime,userId,content) VALUES"; foreach ($redisInfo as $action) { $sql .= "('" . json_decode($action, true)['userName'] . "', '" . json_decode($action, true)['createTime'] . "', '" . json_decode($action, true)['userId'] . "', '" . json_decode($action, true)['content'] . "'),"; } $sql = rtrim($sql, ','); $this->db->execute($sql); $redis->lTrim('message01', 10000, -1); $redisInfo = $redis->lRange('message01',0,9999); $dataLength = $redis->lLen('message01'); $this->db->commit(); } catch (\Exception $e) { $redis->set('message_catch', json_encode($e)); $this->db->rollback(); } } echo 'ENDTIME:'.(microtime(true)-$t1)."<BR/>"; echo 'success'; die; }
输出结果为:
ENDTIME:3.0146479606628(s)
success