Rumah pembangunan bahagian belakang tutorial php 如何利用Redis锁解决高并发问题

如何利用Redis锁解决高并发问题

Sep 10, 2018 pm 02:45 PM
Keselarasan tinggi

高并发问题是我们经常可以遇到的问题,那么该如何解决高并发这个问题呢?本篇文章介绍的内容就是利用Redis锁解决高并发问题,一起来看看吧。

这里我们主要利用Redis的setnx的命令来处理高并发。

setnx 有两个参数。第一个参数表示键。第二个参数表示值。如果当前键不存在,那么会插入当前键,将第二个参数做为值。返回 1。如果当前键存在,那么会返回0。

创建库存表

CREATE TABLE `storage` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `number` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
Salin selepas log masuk

设置初始库存为10

创建订单表

CREATE TABLE `order` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `number` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
Salin selepas log masuk

测试不用锁的时候

$pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'root');
$sql="select `number` from  storage where id=1 limit 1";
$res = $pdo->query($sql)->fetch();
$number = $res['number'];
if($number>0)
{
    $sql ="insert into `order`  VALUES (null,$number)";

    $order_id = $pdo->query($sql);
    if($order_id)
    {

        $sql="update storage set `number`=`number`-1 WHERE id=1";
        $pdo->query($sql);
    }
}
Salin selepas log masuk

ab测试模拟并发,发现库存是正确的。

mysql> select * from storage;
+----+--------+
| id | number |
+----+--------+
|  1 |      0 |
+----+--------+
1 row in set (0.00 sec)
Salin selepas log masuk

在来看订单表

mysql> select * from `order`;
+----+--------+
| id | number |
+----+--------+
|  1 |     10 |
|  2 |     10 |
|  3 |      9 |
|  4 |      7 |
|  5 |      6 |
|  6 |      5 |
|  7 |      5 |
|  8 |      5 |
|  9 |      4 |
| 10 |      1 |
+----+--------+
10 rows in set (0.00 sec)
Salin selepas log masuk

发现存在几个订单都是操作的同一个库存数据,这样就可能引起超卖的情况。

修改代码加入redis锁进行数据控制

<?php
/**
 * Created by PhpStorm.
 * User: daisc
 * Date: 2018/7/23
 * Time: 14:45
 */
class Lock
{
    private static $_instance ;
    private   $_redis;
    private function __construct()
    {
        $this->_redis =  new Redis();
        $this->_redis ->connect('127.0.0.1');
    }
    public static function getInstance()
    {
        if(self::$_instance instanceof self)
        {
            return self::$_instance;
        }
        return self::$_instance = new  self();
    }

    /**
     * @function 加锁
     * @param $key 锁名称
     * @param $expTime 过期时间
      */
    public function set($key,$expTime)
    {
        //初步加锁
        $isLock = $this->_redis->setnx($key,time()+$expTime);
        if($isLock)
        {
            return true;
        }
        else
        {
            //加锁失败的情况下。判断锁是否已经存在,如果锁存在切已经过期,那么删除锁。进行重新加锁
            $val = $this->_redis->get($key);
            if($val&&$val<time())
            {
                $this->del($key);
            }
            return  $this->_redis->setnx($key,time()+$expTime);
        }
    }


    /**
     * @param $key 解锁
     */
    public function del($key)
    {
        $this->_redis->del($key);
    }

}



$pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'root');
$lockObj = Lock::getInstance();
//判断是能加锁成功
if($lock = $lockObj->set('storage',10))
{
    $sql="select `number` from  storage where id=1 limit 1";
    $res = $pdo->query($sql)->fetch();
    $number = $res['number'];
    if($number>0)
    {
        $sql ="insert into `order`  VALUES (null,$number)";

        $order_id = $pdo->query($sql);
        if($order_id)
        {

            $sql="update storage set `number`=`number`-1 WHERE id=1";
            $pdo->query($sql);
        }
    }
    //解锁
    $lockObj->del('storage');

}
else
{
    //加锁不成功执行其他操作。
}
Salin selepas log masuk

再次进行ab测试,查看测试结果

mysql> select * from `order`;
+----+--------+
| id | number |
+----+--------+
|  1 |     10 |
|  2 |      9 |
|  3 |      8 |
|  4 |      7 |
|  5 |      6 |
|  6 |      5 |
|  7 |      4 |
|  8 |      3 |
|  9 |      2 |
| 10 |      1 |
+----+--------+
10 rows in set (0.00 sec)
Salin selepas log masuk

发现订单表没有操作同一个库存数据的情况。所以利用redis锁是可以有效的处理高并发的。

这里在加锁的时候其实是可以不需要判断过期时间的,这里我们为了避免造成死锁,所以加一个过期时间的判断。当过期的时候主动删除该锁。

相关推荐:

php利用文件锁来解决高并发问题

使用Redis来存储PHP的session如何解决并发一致性的问题

Atas ialah kandungan terperinci 如何利用Redis锁解决高并发问题. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Minta kaedah penjadualan dan peruntukan tugas dalam persekitaran konkurensi tinggi PHP Minta kaedah penjadualan dan peruntukan tugas dalam persekitaran konkurensi tinggi PHP Aug 10, 2023 pm 01:24 PM

Meminta penjadualan dan kaedah pengagihan tugas dalam persekitaran konkurensi tinggi PHP Dengan perkembangan pesat Internet, PHP, sebagai bahasa pembangunan back-end yang digunakan secara meluas, menghadapi lebih banyak permintaan serentak tinggi. Dalam persekitaran konkurensi tinggi, cara melaksanakan penjadualan permintaan dan pengagihan tugas telah menjadi isu penting yang perlu diselesaikan semasa pembangunan. Artikel ini akan memperkenalkan beberapa kaedah penjadualan permintaan dan peruntukan tugas dalam persekitaran konkurensi tinggi PHP dan memberikan contoh kod. 1. Pengurusan proses dan baris gilir tugas Dalam persekitaran konkurensi tinggi PHP, pengurusan proses dan baris gilir tugas adalah kaedah pelaksanaan yang biasa digunakan.

Bagaimana untuk mencapai keselarasan tinggi dan pengimbangan beban permintaan dalam FastAPI Bagaimana untuk mencapai keselarasan tinggi dan pengimbangan beban permintaan dalam FastAPI Jul 31, 2023 pm 01:50 PM

Bagaimana untuk mencapai keselarasan tinggi dan pengimbangan beban permintaan dalam FastAPI Pengenalan: Dengan pembangunan Internet, keselarasan tinggi aplikasi web telah menjadi masalah biasa. Apabila mengendalikan sejumlah besar permintaan, kami perlu menggunakan rangka kerja dan teknologi yang cekap untuk memastikan prestasi sistem dan kebolehskalaan. FastAPI ialah rangka kerja Python berprestasi tinggi yang boleh membantu kami mencapai keselarasan tinggi dan pengimbangan beban. Artikel ini akan memperkenalkan cara menggunakan FastAPI untuk mencapai keselarasan tinggi dan pengimbangan beban permintaan. Kami akan menggunakan Python3.7

Seni bina rangka kerja Golang dalam sistem konkurensi tinggi Seni bina rangka kerja Golang dalam sistem konkurensi tinggi Jun 03, 2024 pm 05:14 PM

Untuk sistem konkurensi tinggi, rangka kerja Go menyediakan mod seni bina seperti mod saluran paip, mod kumpulan Goroutine dan mod baris gilir mesej. Dalam kes praktikal, tapak web konkurensi tinggi menggunakan proksi Nginx, gerbang Golang, kumpulan Goroutine dan pangkalan data untuk mengendalikan sejumlah besar permintaan serentak. Contoh kod menunjukkan pelaksanaan kumpulan Goroutine untuk mengendalikan permintaan masuk. Dengan memilih corak dan pelaksanaan seni bina yang sesuai, rangka kerja Go boleh membina sistem konkurensi tinggi berskala dan sangat serentak.

Gunakan fungsi pembangunan swoole untuk mencapai komunikasi rangkaian serentak yang tinggi Gunakan fungsi pembangunan swoole untuk mencapai komunikasi rangkaian serentak yang tinggi Aug 08, 2023 pm 01:57 PM

Gunakan fungsi pembangunan Swoole untuk mencapai komunikasi rangkaian konkurensi tinggi Ringkasan: Swoole ialah rangka kerja komunikasi rangkaian berprestasi tinggi berdasarkan bahasa PHP Ia mempunyai ciri seperti coroutine, IO tak segerak dan berbilang proses, dan sesuai untuk membangunkan tinggi-. aplikasi rangkaian concurrency. Artikel ini akan memperkenalkan cara menggunakan Swoole untuk membangunkan fungsi komunikasi rangkaian konkurensi tinggi dan memberikan beberapa contoh kod. Pengenalan Dengan perkembangan pesat Internet, keperluan untuk komunikasi rangkaian menjadi lebih tinggi dan lebih tinggi, terutamanya dalam senario konkurensi tinggi. Pembangunan PHP tradisional menghadapi keupayaan pemprosesan serentak yang lemah

Kemahiran pengoptimuman membaca dan menulis pangkalan data dalam pemprosesan konkurensi tinggi PHP Kemahiran pengoptimuman membaca dan menulis pangkalan data dalam pemprosesan konkurensi tinggi PHP Aug 12, 2023 pm 04:31 PM

Teknik pengoptimuman membaca dan menulis pangkalan data dalam pemproses konkurensi tinggi PHP Dengan perkembangan pesat Internet, bilangan lawatan tapak web juga telah meningkat lebih tinggi dan lebih tinggi. Dalam aplikasi Internet hari ini, pemprosesan concurrency yang tinggi telah menjadi masalah yang tidak boleh diabaikan. Dalam pembangunan PHP, operasi baca dan tulis pangkalan data adalah salah satu kesesakan prestasi. Oleh itu, dalam senario konkurensi tinggi, adalah sangat penting untuk mengoptimumkan operasi baca dan tulis pangkalan data. Berikut akan memperkenalkan beberapa teknik pengoptimuman baca dan tulis pangkalan data dalam pemprosesan konkurensi tinggi PHP, dan memberikan contoh kod yang sepadan. Menggunakan teknologi pengumpulan sambungan untuk menyambung ke pangkalan data akan

Prestasi rangka kerja PHP dalam senario konkurensi tinggi Prestasi rangka kerja PHP dalam senario konkurensi tinggi Jun 06, 2024 am 10:25 AM

Dalam senario konkurensi tinggi, mengikut ujian penanda aras, prestasi rangka kerja PHP ialah: Phalcon (RPS2200), Laravel (RPS1800), CodeIgniter (RPS2000) dan Symfony (RPS1500). Kes sebenar menunjukkan bahawa rangka kerja Phalcon mencapai 3,000 pesanan sesaat semasa acara Double Eleven di tapak web e-dagang.

Aplikasi fungsi golang dalam senario konkurensi tinggi dalam pengaturcaraan berorientasikan objek Aplikasi fungsi golang dalam senario konkurensi tinggi dalam pengaturcaraan berorientasikan objek Apr 30, 2024 pm 01:33 PM

Dalam senario konkurensi tinggi pengaturcaraan berorientasikan objek, fungsi digunakan secara meluas dalam bahasa Go: Berfungsi sebagai kaedah: Fungsi boleh dilampirkan pada struktur untuk melaksanakan pengaturcaraan berorientasikan objek, mengendalikan data struktur dengan mudah dan menyediakan fungsi tertentu. Berfungsi sebagai badan pelaksanaan serentak: Fungsi boleh digunakan sebagai badan pelaksanaan goroutine untuk melaksanakan pelaksanaan tugas serentak dan meningkatkan kecekapan program. Berfungsi sebagai panggil balik: Fungsi boleh dihantar sebagai parameter kepada fungsi lain dan dipanggil apabila peristiwa atau operasi tertentu berlaku, menyediakan mekanisme panggil balik yang fleksibel.

Teknik dan prinsip pengimbangan beban dalam persekitaran konkurensi tinggi PHP Teknik dan prinsip pengimbangan beban dalam persekitaran konkurensi tinggi PHP Aug 12, 2023 am 10:57 AM

Teknik dan prinsip pengimbangan beban dalam persekitaran konkurensi tinggi PHP Dalam aplikasi Internet hari ini, konkurensi tinggi telah menjadi isu penting. Untuk aplikasi PHP, cara berkesan menangani senario konkurensi tinggi telah menjadi masalah yang perlu difikirkan dan diselesaikan oleh pembangun. Teknologi pengimbangan beban telah menjadi salah satu cara penting untuk menangani konkurensi yang tinggi. Artikel ini akan memperkenalkan teknik dan prinsip pengimbangan beban dalam persekitaran konkurensi tinggi PHP dan mendalami pemahaman melalui contoh kod. 1. Prinsip pengimbangan beban Pengimbangan beban merujuk kepada pengagihan seimbang beban permintaan pemprosesan kepada berbilang pelayan.

See all articles