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 相关文章推荐
杏林同学录(七)
Oct 09 PHP
PHP简介
Oct 09 PHP
js下函数般调用正则的方法附代码
Jun 22 PHP
PHP 数组排序方法总结 推荐收藏
Jun 30 PHP
php xml 入门学习资料
Jan 01 PHP
PHP中foreach循环中使用引用要注意的地方
Jan 02 PHP
phpphp图片采集后按原路径保存图片示例
Feb 18 PHP
浅谈php扩展imagick
Jun 02 PHP
php简单操作mysql数据库的类
Apr 16 PHP
PHP抓取网页、解析HTML常用的方法总结
Jul 01 PHP
PHP中empty和isset对于参数结构的判断及empty()和isset()的区别
Nov 15 PHP
php如何把表单内容提交到数据库
Jul 08 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
php将access数据库转换到mysql数据库的方法
2014/12/24 PHP
详解php中的implements 使用
2017/06/13 PHP
js+FSO遍历文件夹下文件并显示
2007/03/07 Javascript
本地对象Array的原型扩展实现代码
2010/12/04 Javascript
js写出遮罩层登陆框和对联广告并自动跟随滚动条滚动
2014/04/29 Javascript
JQuery中两个ul标签的li互相移动实现方法
2015/05/18 Javascript
使用DNode实现php和nodejs之间通信的简单实例
2015/07/06 NodeJs
DropDownList实现可输入可选择(两种版本可选)
2016/12/07 Javascript
jQuery实现的简单悬浮层功能完整实例
2017/01/23 Javascript
详解小程序开发经验:多页面数据同步
2019/05/18 Javascript
vue.js表单验证插件(vee-validate)的使用教程详解
2019/05/23 Javascript
js设置默认时间跨度过程详解
2019/07/17 Javascript
vue keep-alive列表页缓存 详情页返回上一页不刷新,定位到之前位置
2019/11/26 Javascript
使用Angular9和TypeScript开发RPG游戏的方法
2020/03/25 Javascript
Taro小程序自定义顶部导航栏功能的实现
2020/12/17 Javascript
[01:05:07]DOTA2-DPC中国联赛 正赛 DLG vs Dragon BO3 第一场2月1日
2021/03/11 DOTA
Mac中Python 3环境下安装scrapy的方法教程
2017/10/26 Python
连接pandas以及数组转pandas的方法
2019/06/28 Python
django mysql数据库及图片上传接口详解
2019/07/18 Python
django框架cookie和session用法实例详解
2019/12/10 Python
Python动态声明变量赋值代码实例
2019/12/30 Python
Python startswith()和endswith() 方法原理解析
2020/04/28 Python
python为什么会环境变量设置不成功
2020/06/23 Python
详解python with 上下文管理器
2020/09/02 Python
html table呈现个人简历以及单元格宽度失效的问题解决
2021/01/22 HTML / CSS
意大利单身交友网站:Meetic
2020/07/12 全球购物
介绍一下Python下range()函数的用法
2013/11/07 面试题
写给爸爸的道歉信
2014/01/15 职场文书
自我评价的范文
2014/02/02 职场文书
个人对照检查材料思想汇报
2014/09/26 职场文书
2014年班主任工作总结
2014/11/08 职场文书
个人党性分析材料
2014/12/19 职场文书
秋季运动会开幕词
2015/01/28 职场文书
2015年度党员自我评价范文
2015/03/03 职场文书
消防演习感想
2015/08/10 职场文书
Django中celery的使用项目实例
2022/07/07 Python