文档章节

redis队列缓存+sql批量入库+php离线整合(高并发简单解决方案)

ZYallers
 ZYallers
发布于 2017/07/25 15:24
字数 876
阅读 11
收藏 0

redis队列缓存+sql批量入库+php离线整合(高并发简单解决方案)

需求背景:

有个调用统计日志存储和统计需求,要求存储到mysql中;存储数据高峰能达到日均千万,瓶颈在于直接入库并发太高,可能会把mysql干垮。

问题分析

思考:

应用网站架构的衍化过程中,应用最新的框架和工具技术固然是最优选择;但是,如果能在现有的框架的基础上提出简单可依赖的解决方案,未尝不是一种提升自我的尝试。

解决:

  • 问题一:要求日志最好入库;但是,直接入库mysql确实扛不住,批量入库没有问题,done。【批量入库和直接入库性能差异参考文章】
  • 问题二:批量入库就需要有高并发的消息队列,决定采用redis list 仿真实现,而且方便回滚。
  • 问题三:日志量毕竟大,保存最近30条足矣,决定用php写个离线统计和清理脚本。

下面是简单的实现过程

一:设计数据库表和存储

考虑到log系统对数据库的性能更多一些,稳定性和安全性没有那么高,存储引擎自然是只支持select insert 没有索引的archive。如果确实有update需求,也可以采用myISAM。

考虑到log是实时记录的所有数据,数量可能巨大,主键采用bigint,自增即可。

考虑到log系统以写为主,统计采用离线计算,字段均不要出现索引,因为一方面可能会影响插入数据效率,另外读时候会造成死锁,影响写数据。

二:redis存储数据形成消息队列

由于高并发,尽可能简单,直接,上代码。

<?php
/***************************************************************************
*
* 获取到的调用日志,存入redis的队列中.
* $Id$
*
**************************************************************************/
/**
* @file saveLog.php
* @date 2015/11/06 20:47:13
* @author:cuihuan
* @version $Revision$
* @brief
*
**/
// 获取info
$interface_info = $_GET['info'];
// 存入redis队列
$redis = new Redis();
$redis->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 < $max) {
    $log_info = $redis_cq01->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();
?>

四:离线天级统计和清理数据脚本

省略...

五:代码部署

主要是部署,批量入库脚本的调用和天级统计脚本,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

© 著作权归作者所有

共有 人打赏支持
ZYallers
粉丝 1
博文 59
码字总数 19100
作品 0
佛山
程序员
私信 提问
【高并发简单解决方案】redis队列缓存 + mysql 批量入库 + php离线整合

需求背景:有个,要求存储到mysql中;存储数据高峰能达到日均千万,瓶颈在于。 问题分析 思考:应用网站架构的衍化过程中,应用最新的框架和工具技术固然是最优选择;但是,如果能在,未尝不...

太阳黑子
2016/10/28
72
0
高并发简单解决方案————redis队列缓存+mysql 批量入库(ThinkPhP)

问题分析 问题一:要求日志最好入库;但是,直接入库mysql确实扛不住,批量入库没有问题,done。【批量入库和直接入库性能差异】 问题二:批量入库就需要有高并发的消息队列,决定采用redis...

nsns
05/18
0
0
电商那些年,我摸爬打滚出的高并发架构实战精髓

一、关于高并发 高并发是指在同一个时间点,有很多用户同时访问URL地址,比如:淘宝的双11、双12,就会产生高并发。又如贴吧的爆吧,就是恶意的高并发请求,也就是DDOS攻击,再屌丝点的说法就...

Yomut
2016/10/10
391
1
电商高并发架构实战精髓

一、关于高并发 高并发是指在同一个时间点,有很多用户同时访问URL地址,比如:淘宝的双11、双12,就会产生高并发。又如贴吧的爆吧,就是恶意的高并发请求,也就是DDOS攻击,再屌丝点的说法就...

jinjiang2009
2016/10/10
0
0
电商那些年,我摸爬打滚出的高并发架构实战精髓(续)

大型网站要很好地支撑高并发,需要长期的规划设计。在初期,需要把系统进行分层,在发展过程中把核心业务进行拆分成模块单元,根据需求进行分布式部署,可以进行独立团队维护开发。 分层: ...

YYQ
2017/03/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

oh-my-zsh 自定义

GitHub 地址 基于 oh-my-zsh 的自定义配置,增加了一些个人常用插件与皮肤。 采用的是 git submodule 来维护,包括 oh-my-zsh,之所以这么搞,主要是手头有多台 linux 需要维护, 每台机器、...

郁也风
今天
4
0
Docker安装踩坑:E_FAIL 0x80004005的解决

参考 菜鸟教程--Windows Docker 安装 http://www.runoob.com/docker/windows-docker-install.html 官方文档-Install Docker Toolbox on Windows https://docs.docker.com/toolbox/toolbox_in......

karma123
今天
4
0
js垃圾回收机制和引起内存泄漏的操作

JS的垃圾回收机制了解吗? Js具有自动垃圾回收机制。垃圾收集器会按照固定的时间间隔周期性的执行。 JS中最常见的垃圾回收方式是标记清除。 工作原理:是当变量进入环境时,将这个变量标记为“...

Jack088
昨天
17
0
大数据教程(10.1)倒排索引建立

前面博主介绍了sql中join功能的大数据实现,本节将继续为小伙伴们分享倒排索引的建立。 一、需求 在很多项目中,我们需要对我们的文档建立索引(如:论坛帖子);我们需要记录某个词在各个文...

em_aaron
昨天
27
0
"errcode": 41001, "errmsg": "access_token missing hint: [w.ILza05728877!]"

Postman获取微信小程序码的时候报错, errcode: 41001, errmsg: access_token missing hint 查看小程序开发api指南,原来access_token是直接当作parameter的(写在url之后),scene参数一定要...

两广总督bogang
昨天
31
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部