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中取得URL的根域名的代码
Mar 23 PHP
php删除与复制文件夹及其文件夹下所有文件的实现代码
Jan 23 PHP
深入php self与$this的详解
Jun 08 PHP
Windows下的PHP安装文件线程安全和非线程安全的区别
Apr 23 PHP
php中session过期时间设置及session回收机制介绍
May 05 PHP
PHP类的反射用法实例
Nov 03 PHP
php实现约瑟夫问题的方法小结
Mar 23 PHP
PHP错误机制知识汇总
Mar 24 PHP
php的PDO事务处理机制实例分析
Feb 16 PHP
PHP排序二叉树基本功能实现方法示例
May 26 PHP
php ajax confirm 删除实例详解
Mar 06 PHP
PHP 图片合成、仿微信群头像的方法示例
Oct 25 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
一个用于mysql的数据库抽象层函数库
2006/10/09 PHP
php 禁止页面缓存输出
2009/01/07 PHP
PHP实现二叉树的深度优先与广度优先遍历方法
2015/09/28 PHP
php简单实现单态设计模式的方法分析
2017/07/28 PHP
Javascript写了一个清除“logo1_.exe”的杀毒工具(可扫描目录)
2007/02/09 Javascript
js实现两个值相加alert出来精确到指定位
2013/09/25 Javascript
JQuery radio(单选按钮)操作方法汇总
2015/04/15 Javascript
jQuery实现将div中滚动条滚动到指定位置的方法
2016/08/10 Javascript
vue.js初学入门教程(1)
2016/11/03 Javascript
用Angular实时获取本地Localstorage数据,实现一个模拟后台数据登入的效果
2016/11/09 Javascript
JavaScript获取ul中li个数的方法
2017/02/13 Javascript
vuejs项目打包之后的首屏加载优化及打包之后出现的问题
2018/04/01 Javascript
浅谈layui里的上传控件问题
2019/09/26 Javascript
vue项目中定义全局变量、函数的几种方法
2019/11/08 Javascript
jQuery中getJSON跨域原理的深入讲解
2020/09/02 jQuery
JavaScript 判断浏览器是否是IE
2021/02/19 Javascript
[01:09]DOTA2次级职业联赛 - 99战队宣传片
2014/12/01 DOTA
[01:38]DOTA2 2015国际邀请赛中国区预选赛 Showopen
2015/06/01 DOTA
python和ruby,我选谁?
2017/09/13 Python
Python实现PS滤镜碎片特效功能示例
2018/01/24 Python
对python中的 os.mkdir和os.mkdirs详解
2018/10/16 Python
python的mysql数据库建立表与插入数据操作示例
2019/09/30 Python
Pycharm使用远程linux服务器conda/python环境在本地运行的方法(图解))
2019/12/09 Python
python解析xml文件方式(解析、更新、写入)
2020/03/05 Python
对python中arange()和linspace()的区别说明
2020/05/03 Python
解决python图像处理图像赋值后变为白色的问题
2020/06/04 Python
一款利用css3的鼠标经过动画显示详情特效的实例教程
2014/12/29 HTML / CSS
HTML5触摸事件(touchstart、touchmove和touchend)的实现
2020/05/08 HTML / CSS
ECOSUSI官网:女式皮革背包
2019/09/27 全球购物
澳大利亚购买健身器材网站:Gym Direct
2019/12/19 全球购物
40岁生日感言
2014/02/15 职场文书
结婚保证书(三从四德)
2015/02/26 职场文书
2015年个人工作总结报告
2015/04/25 职场文书
党校培训学习心得体会
2016/01/06 职场文书
干货:企业内部人才推荐奖励方案!
2019/07/09 职场文书
Python+Appium自动化测试的实战
2021/06/30 Python