ホームページ >バックエンド開発 >PHPチュートリアル >[高同時実行性のシンプルなソリューション] redis キャッシュ キュー + mysql バッチ ストレージ + php オフライン統合
要件の背景: 統計ログ ストレージと統計を呼び出す需要があり、これには mysql 内のストレージが必要です。保存されるデータのピーク値は 1 日に数千万に達する可能性があり、直接ストレージの同時実行性がボトルネックとなります。高すぎると、mysql がダウンする可能性があります。
思考: アプリケーション Web サイトのアーキテクチャの進化の過程では、最新のフレームワークとツール技術を適用することが確かに最良の選択ですが、既存のフレームワークに基づいてシンプルで信頼性の高いソリューションを提案できるのであれば、おそらくそれが最善の選択です。自分自身を改善しようとする試み。解決策:
完了しました。以下は Xiaoyan の簡単な実装プロセスです
同時実行性が高いため、コードはできるだけシンプルかつ直接的である必要があります。
connect('xx', 6379);$redis->auth("password");// 加上时间戳存入队列$now_time = date("Y-m-d H:i:s");$redis->rPush("call_log", $interface_info . "%" . $now_time);$redis->close();/* vim: set ts=4 sw=4 sts=4 tw=100 */?>
Redis メッセージ キュー内のデータを定期的に読み取り、バッチで保存します。
connect('ip', port);$redis_xx->auth("password");// 获取现有消息队列的长度$count = 0;$max = $redis_xx->lLen("call_log");// 获取消息队列的内容,拼接sql$insert_sql = "insert into fb_call_log (`interface_name`, `createtime`) values ";// 回滚数组$roll_back_arr = array();while ($count lPop("call_log"); $roll_back_arr = $log_info; if ($log_info == 'nil' || !isset($log_info)) { $insert_sql .= ";"; break; } // 切割出时间和info $log_info_arr = explode("%",$log_info); $insert_sql .= " ('".$log_info_arr[0]."','".$log_info_arr[1]."'),"; $count++;}// 判定存在数据,批量入库if ($count != 0) { $link_2004 = mysql_connect('ip:port', 'user', 'password'); if (!$link_2004) { die("Could not connect:" . mysql_error()); } $crowd_db = mysql_select_db('fb_log', $link_2004); $insert_sql = rtrim($insert_sql,",").";"; $res = mysql_query($insert_sql); // 输出入库log和入库结果; echo date("Y-m-d H:i:s")."insert ".$count." log info result:"; echo json_encode($res); echo "n"; // 数据库插入失败回滚 if(!$res){ foreach($roll_back_arr as $k){ $redis_xx->rPush("call_log", $k); } } // 释放连接 mysql_free_result($res); mysql_close($link_2004);}// 释放redis$redis_cq01->close();?>
?php/*** static log :每天离线统计代码日志和删除五天前的日志** @Author:cuihuan@baidu.com* 2015-11-06* */// 离线统计$link_2004 = mysql_connect('ip:port', 'user', 'pwd');if (!$link_2004) { die("Could not connect:" . mysql_error());}$crowd_db = mysql_select_db('fb_log', $link_2004);// 统计昨天的数据$day_time = date("Y-m-d", time() - 60 * 60 * 24 * 1);$static_sql = "get sql";$res = mysql_query($static_sql, $link_2004);// 获取结果入库略// 清理15天之前的数据$before_15_day = date("Y-m-d", time() - 60 * 60 * 24 * 15);$delete_sql = "delete from xxx where createtime
主にデプロイメント、バッチ ウェアハウス スクリプトと日レベルの統計スクリプトの呼び出し、crontab ルーチンの実行。
# 批量入库脚本*/2 * * * * /home/cuihuan/xxx/lamp/php5/bin/php /home/cuihuan/xxx/batchLog.php >>/home/cuihuan/xxx/batchlog.log# 天级统计脚本0 5 * * * /home/cuihuan/xxx/php5/bin/php /home/cuihuan/xxx/staticLog.php >>/home/cuihuan/xxx/staticLog.log
要約: 高い同時実行性に対処する他の複雑な方法と比較して、このソリューションはシンプルで効果的です。プレッシャーに耐えるために Redis キャッシュを使用し、データベースのボトルネックを解決するために mysql バッチ ウェアハウスを使用し、統計データを解決するためにオフライン計算を使用し、ライブラリのサイズを確保します。