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 相关文章推荐
mysql,mysqli,PDO的各自不同介绍
Sep 19 PHP
PHP中操作ini配置文件的方法
Apr 25 PHP
修改php.ini不生效问题解决方法(上传大于8M的文件)
Jun 14 PHP
PHP strip_tags()去除HTML、XML以及PHP的标签介绍
Feb 18 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(八)
Jun 23 PHP
CodeIgniter中使用cookie的三种方式详解
Jul 18 PHP
PHP中实现获取IP和地理位置类分享
Feb 10 PHP
从刷票了解获得客户端IP的方法
Sep 21 PHP
PHP 7.0.2 正式版发布
Jan 08 PHP
简述php环境搭建与配置
Dec 05 PHP
PHP面向对象学习之parent::关键字
Jan 18 PHP
tp5(thinkPHP5)框架数据库Db增删改查常见操作总结
Jan 10 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
AM/FM收音机的安装与调试
2021/03/02 无线电
一个取得文件扩展名的函数
2006/10/09 PHP
PHP实现加密的几种方式介绍
2015/02/22 PHP
php实现图片缩略图的方法
2016/03/29 PHP
php实现批量修改文件名称的方法
2016/07/23 PHP
PHP去除字符串最后一个字符的三种方法实例
2017/03/01 PHP
在JavaScript中通过URL传递汉字的方法
2007/04/09 Javascript
js监听表单value的修改同步问题,跨浏览器支持
2009/12/31 Javascript
javascript重复绑定事件造成的后果说明
2013/03/02 Javascript
showModalDialog模态对话框的使用详解以及浏览器兼容
2014/01/11 Javascript
jQuery基于muipicker实现仿ios时间选择
2016/02/22 Javascript
jQuery自适应轮播图插件Swiper用法示例
2016/08/24 Javascript
ionic隐藏tabs的方法
2016/08/29 Javascript
requirejs + vue 项目搭建详解
2017/06/16 Javascript
bootstrap table表格插件之服务器端分页实例代码
2018/09/12 Javascript
vue-router的使用方法及含参数的配置方法
2018/11/13 Javascript
Django发送html邮件的方法
2015/05/26 Python
Python书单 不将就
2017/07/11 Python
python删除本地夹里重复文件的方法
2020/11/19 Python
Python实现的批量修改文件后缀名操作示例
2018/12/07 Python
详解Python_shutil模块
2019/03/15 Python
在Qt中正确的设置窗体的背景图片的几种方法总结
2019/06/19 Python
Python 网络编程之TCP客户端/服务端功能示例【基于socket套接字】
2019/10/12 Python
numpy数组做图片拼接的实现(concatenate、vstack、hstack)
2019/11/08 Python
Python闭包与装饰器原理及实例解析
2020/04/30 Python
关于matplotlib-legend 位置属性 loc 使用说明
2020/05/16 Python
纯css3制作煽动翅膀的蝴蝶的示例
2018/04/23 HTML / CSS
美国购买肉、鸭、家禽、鹅肝和熟食网站:D’Artagnan
2018/11/13 全球购物
POP文化和音乐灵感的时尚:Hot Topic
2019/06/19 全球购物
会计电算化专业应届大学生求职信
2013/10/22 职场文书
学生实习推荐信范文
2013/11/26 职场文书
课堂打架检讨书200字
2014/11/21 职场文书
2014年科技工作总结
2014/11/26 职场文书
2014个人年终工作总结范文
2014/12/15 职场文书
C#连接ORACLE出现乱码问题的解决方法
2021/10/05 Oracle
JavaScript中isPrototypeOf函数
2021/11/07 Javascript