PHP结合Redis+MySQL实现冷热数据交换应用案例详解


Posted in PHP onJuly 09, 2019

本文实例讲述了PHP结合Redis+MySQL实现冷热数据交换应用案例。分享给大家供大家参考,具体如下:

场景:某网站需要对其项目做一个投票系统,投票项目上线后一小时之内预计有100万用户进行投票,希望用户投票完就能看到实时的投票情况

这个场景可以使用redis+mysql冷热数据交换来解决。

何为冷热数据交换?

冷数据:之前使用的数据,热数据:当前使用的数据。
交换:将Redis中的数据周期的存储到MySQL中

业务流程

用户进行投票后,首先将投票数据保存到Redis中,这些数据就是热数据,然后定期(如5s)将热数据保存到MySQL中,这些数据就变为冷数据,然后将冷数据从Redis中删除,周而复始,知道一个小时投票结束。

项目结构图

PHP结合Redis+MySQL实现冷热数据交换应用案例详解

index.html文件

这是投票的首页,有3个投票按钮,模拟给3个用户投票,点击按钮,使用ajax调用vote.php文件

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
  <title>Document</title>
</head>
<script src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script>
<body>
  <p><span id="uid1">0</span><input type="button" value="用户1" onclick="vote(1);" /></p>
  <p><span id="uid2">0</span><input type="button" value="用户2" onclick="vote(2);" /></p>
  <p><span id="uid3">0</span><input type="button" value="用户3" onclick="vote(3);" /></p>
</body>
<script>
  function vote(i){
    $.get('vote.php?uid='+i,function(rs){
      var span = '#uid'+i;
      $(span).html(rs);
    });
  }
</script>
</html>

vote.php

这个文件主要实现投票的逻辑。首先连接上Redis服务器,然后保存投票人id,然后将投票人id为key记录每个用户的票数,然后返回给index.html文件,最后使用global_voteid作为key记录总票数,也可以作为MySQL的自增长的键。然后记录uid,ip,time等数据。

注意格式有一定的要求:

假如voteid为3,记录的是ip,那么键为vote:3:ip:127.0.0.1

<?php
$redis = new Redis();
$redis->connect('localhost',6379);
//计算每个用户的总票数
$uid = intval($_GET['uid']);
//$uid = mt_rand(1,3);//随机指定投票人员,方便进行压力测试
echo $redis->incr($uid);
$voteid = $redis->incr('global_voteid');
$redis->set('vote:'.$voteid.':uid',$uid);
$ip = $_SERVER['REMOTE_ADDR'];
$redis->set('vote:'.$voteid.':ip',$ip);
$redis->set('vote:'.$voteid.':time',time());

重点内容

这个文件主要实现冷热数据交换,首先连接MySQL数据库和redis服务器,然后每隔5秒去执行while循环,在while循环里获取自增长的投票主键和最近一次插入mysql的投票主键(位置)。判断插入的位置是否存在,如果不存在就从头插入,如果全部插入完毕,就进行等待,如果没有插入完毕,就进行插入操作。

<?php
//连接数据库
$pdo = new PDO('mysql:host=localhost;dbname=test','root','1234');
$pdo->query('set names utf8');
//连接redis
$redis = new Redis();
$redis->connect('localhost',6379);
//永真循环
while(true){
  $vid = $redis->get('global_voteid');//自增长的主键
  $last = $redis->get('last');//最近一次插入mysql的投票主键
  //如果没有插入数据库,刚开始的肯定为true
  if(!$last){
    $last = 0;//设置为0
  }
  //如果所有的数据都被插入到MySQL中
  if($vid == $last){
    echo "wait\n";//输出等待
  }else{
    //进行插入到数据库操作
    $sql = 'insert into vote(vid,uid,ip,time) values';
    for($i = $vid;$i>$last;$i--){
      $k1 = 'vote:'.$i.':uid';
      $k2 = 'vote:'.$i.':ip';
      $k3 = 'vote:'.$i.':time';
      $row = $redis->mget([$k1,$k2,$k3]);
      $sql.="($i,$row[0],'$row[1]',$row[2]),";
            $redis->delete($k1,$k2,$k3);
    }
    $sql = substr($sql,0,-1);
    $pdo->exec($sql);
    $redis->set('last',$vid);//设置插入的主键位置
    echo 'OK';
  }
  sleep(5);//每隔5秒执行循环
}

vote表

PHP结合Redis+MySQL实现冷热数据交换应用案例详解

运行步骤:

1、使用php命令行工具调用swap.php

PHP结合Redis+MySQL实现冷热数据交换应用案例详解

2、使用Apache的ab工具进行压力测试。

PHP结合Redis+MySQL实现冷热数据交换应用案例详解

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP Array交叉表实现代码
Aug 05 PHP
PHP获取表单textarea数据中的换行问题
Sep 10 PHP
PHP得到mssql的存储过程的输出参数功能实现
Nov 23 PHP
php foreach正序倒序输出示例代码
Jul 01 PHP
php使用递归计算文件夹大小
Dec 24 PHP
php模拟post提交数据的方法
Feb 12 PHP
前端必学之PHP语法基础
Jan 01 PHP
在PHP站点的页面上添加Facebook评论插件的实例教程
Jan 08 PHP
[原创]php求圆周率的简单实现方法
May 30 PHP
图文详解PHP环境搭建教程
Jul 16 PHP
php生成条形码的图片的实例详解
Sep 13 PHP
解决Laravel使用验证时跳转到首页的问题
Nov 17 PHP
PHP+Redis开发的书签案例实战详解
Jul 09 #PHP
使用composer命令加载vendor中的第三方类库 的方法
Jul 09 #PHP
Laravel+Intervention实现上传图片功能示例
Jul 09 #PHP
Laravel框架实现多个视图共享相同数据的方法详解
Jul 09 #PHP
Laravel5.1框架注册中间件的三种场景详解
Jul 09 #PHP
PHP使用 Pear 进行安装和卸载包的方法详解
Jul 08 #PHP
PHP 7.4中使用预加载的方法详解
Jul 08 #PHP
You might like
ThinkPHP查询返回简单字段数组的方法
2014/08/25 PHP
Thinkphp中volist标签mod控制一定记录的换行BUG解决方法
2014/11/04 PHP
php中get_object_vars()方法用法实例
2015/02/08 PHP
JavaScript和JQuery的鼠标mouse事件冒泡处理
2015/06/19 Javascript
JavaScript中的闭包
2016/02/24 Javascript
详解JavaScript的AngularJS框架中的作用域与数据绑定
2016/03/04 Javascript
AngularJs实现分页功能不带省略号的代码
2016/05/30 Javascript
Angularjs中使用layDate日期控件示例
2017/01/11 Javascript
jQuery树插件zTree使用方法详解
2017/05/02 jQuery
详解微信小程序 template添加绑定事件
2017/06/23 Javascript
js数字滑动时钟的简单实现(示例讲解)
2017/08/14 Javascript
浅谈在react中如何实现扫码枪输入
2018/07/04 Javascript
Angular4.x Event (DOM事件和自定义事件详解)
2018/10/09 Javascript
微信小程序实现文字跑马灯
2020/05/26 Javascript
vue-router源码之history类的浅析
2019/05/21 Javascript
JS实现点击生成UUID的方法完整实例【基于jQuery】
2019/06/12 jQuery
vue scroll滚动判断的实现(是否滚动到底部、滚动方向、滚动节流、获取滚动区域dom元素)
2020/06/11 Javascript
[02:17]DOTA2亚洲邀请赛 RAVE战队出场宣传片
2015/02/07 DOTA
Python下线程之间的共享和释放示例
2015/05/04 Python
python的mysqldb安装步骤详解
2017/08/14 Python
python+opencv识别图片中的圆形
2020/03/25 Python
Python基础教程之异常详解
2019/01/10 Python
Python 内置变量和函数的查看及说明介绍
2019/12/25 Python
使用python-cv2实现Harr+Adaboost人脸识别的示例
2020/10/27 Python
html5 sessionStorage会话存储_动力节点Java学院整理
2017/07/06 HTML / CSS
详解HTML5中的manifest缓存使用
2015/09/09 HTML / CSS
季度思想汇报
2014/01/01 职场文书
安全协议书范本
2014/04/21 职场文书
整顿机关作风心得体会
2014/09/10 职场文书
学习朴航瑛老师爱岗敬业先进事迹思想汇报
2014/09/17 职场文书
销售代理协议书
2014/09/30 职场文书
综合实践活动报告
2015/02/05 职场文书
基石观后感
2015/06/12 职场文书
大学生心理健康教育心得体会
2016/01/12 职场文书
《鸟的天堂》教学反思
2016/02/19 职场文书
Python机器学习算法之决策树算法的实现与优缺点
2021/05/13 Python