redis比mysql访问速度快吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis比mysql访问速度快吗相关的知识,希望对你有一定的参考价值。

  您好,我来为您解答:
  首先,我们知道,mysql是持久化存储,存放在磁盘里面,检索的话,会涉及到一定的IO,为了解决这个瓶颈,于是出现了缓存,比如现在用的最多的 memcached(简称mc)。首先,用户访问mc,如果未命中,就去访问mysql,之后像内存和硬盘一样,把数据复制到mc一部分。

  redis和mc都是缓存,并且都是驻留在内存中运行的,这大大提升了高数据量web访问的访问速度。然而mc只是提供了简单的数据结构,比如 string存储;redis却提供了大量的数据结构,比如string、list、set、hashset、sorted set这些,这使得用户方便了好多,毕竟封装了一层实用的功能,同时实现了同样的效果,当然用redis而慢慢舍弃mc。

  内存和硬盘的关系,硬盘放置主体数据用于持久化存储,而内存则是当前运行的那部分数据,CPU访问内存而不是磁盘,这大大提升了运行的速度,当然这是基于程序的局部化访问原理。

  推理到redis+mysql,它是内存+磁盘关系的一个映射,mysql放在磁盘,redis放在内存,这样的话,web应用每次只访问redis,如果没有找到的数据,才去访问Mysql。

  然而redis+mysql和内存+磁盘的用法最好是不同的。
  转载,仅供参考。
  如果我的回答没能帮助您,请继续追问。
参考技术A 前者是内存数据库,数据保存在内存中,当然速度快。
后者是关系型数据库,功能强大,数据访问也就慢。
像memcache,mongoDB,Redis,都属于No sql系列。
不是一个类型的东西,应用场景也不太一样,还是要看你的需求来决定。
参考技术B 那肯定的,redis也叫缓存数据库,他是吃内存的,你说快不快。redis不要存太多东西,常用的,访问频繁的可以放在redis

PHP使用Redis实现消息队列

消息队列可以使用MySQL来实现,可以参考博客PHP使用MySQL实现消息队列,虽然用MySQL可以实现,但是一般不这么用,因为MySQL的数据都存在硬盘中,而从硬盘中对MySQL的操作,I/O花费的代价很大,所以一般使用缓存来实现,因为缓存的数据是在内存中,访问内存的速度远快于访问硬盘的速度。另一方面,Redis有list类型的数据结构,非常适合做消息队列。

这里举一个很简单的秒杀例子:秒杀的名额只有5个,即消息队列的长度为5,名额已经满了之后,通知后来的人已经秒杀结束。然后后台会从消息队列中读取数据,然后将数据存到数据库中。因为消息队列长度只有5个,而且秒杀的那短短1,2秒并没有直接操作数据库,所以对于数据库来说,并没有什么压力。

先看一下数据库表(seckill)的结构:

mysql> desc seckill;
+----------+---------+------+-----+---------+----------------+
| Field    | Type    | Null | Key | Default | Extra          |
+----------+---------+------+-----+---------+----------------+
| id       | int(11) | NO   | PRI | NULL    | auto_increment |
| order_id | int(11) | NO   |     | NULL    |                |
| mobile   | int(8)  | YES  |     | 8888888 |                |
+----------+---------+------+-----+---------+----------------+
3 rows in set (0.11 sec)

  然后是进行秒杀的用户程序(user.php),为了模拟,这里使用for循环来实现在短时间内发起大量的请求,但是要知道这是不准确的。

<?php
    $redis=new Redis();
    $redis->connect("127.0.0.1",6379);

    $key="seckill";
    for($i=0;$i<10;$i++){
        $order_id=rand(100000,999999);
        $mobile=rand(11111111,99999999);
        $value=$order_id."#".$mobile;//连接之后作为值
        if($redis->llen("seckill") <5 ){
            echo "秒杀成功,订单号为$order_id, 手机号为$mobile\\n";
            $redis->lpush($key,$value);
        } else {
            echo "秒杀已经结束\\n";
        }
    }
?>

  运行结果:

[root@localhost ~]# php user.php
秒杀成功,订单号为643275, 手机号为50104929
秒杀成功,订单号为393012, 手机号为31213041
秒杀成功,订单号为994790, 手机号为23107569
秒杀成功,订单号为186135, 手机号为36549273
秒杀成功,订单号为821972, 手机号为11217760
秒杀已经结束
秒杀已经结束
秒杀已经结束
秒杀已经结束
秒杀已经结束

  

然后是后台程序将redis中订单读出,处理后存进数据库。

<?php
    $redis=new Redis();
    $redis->connect("127.0.0.1",6379);
    $pdo=new PDO("mysql:host=localhost;dbname=test","root","root");
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt=$pdo->prepare("insert into seckill(id,order_id,mobile) values(?,?,?)");
    $key="seckill";

    while($redis->llen($key)){
        //因为消息队列中添加消息是使用lpush,所以这里使用rpop
        $order=$redis->rpop($key);
        list($order_id,$mobile)=explode("#",$order);
        echo "正在处理订单$order_id\\t";
        try{
            $res=$stmt->execute(array(null,$order_id,$mobile));
            if(!$res){
                throw new PDOException("wrong");
            }
        } catch (PDOException $e){
            echo $e->getMessage();
            echo "订单处理失败\\n";
            $redis->rpush($key,$order_id."#".$mobile);//将数据恢复达到队列中
            continue;
        }
        echo "订单处理完成\\n";
    }
?>

  运行:

[root@localhost ~]# php consumer.php
正在处理订单643275      订单处理完成
正在处理订单393012      订单处理完成
正在处理订单994790      订单处理完成
正在处理订单186135      订单处理完成
正在处理订单821972      订单处理完成

  查看数据库:

mysql> select * from seckill;
+----+----------+----------+
| id | order_id | mobile   |
+----+----------+----------+
|  1 |   643275 | 50104929 |
|  2 |   393012 | 31213041 |
|  3 |   994790 | 23107569 |
|  4 |   186135 | 36549273 |
|  5 |   821972 | 11217760 |
+----+----------+----------+
5 rows in set (0.00 sec)

  

 

以上是关于redis比mysql访问速度快吗的主要内容,如果未能解决你的问题,请参考以下文章

php+mssql 访问速度慢是啥原因?

玩转Linux系统之轻松搭建Redis集群

微服务连接不上redis会直接访问数据库吗

.htaccess 文件中的大量条目会减慢站点访问速度吗?

堆上分配的数据访问速度是不是比栈上分配的数据慢?

redis