關於redis的實際應用

1.將數據庫數據放入redis緩存,並在redis裏取出數據

<?php
function select($table,$file,$where){
    $conn = mysqli_connect('127.0.0.1','root','root','pzkc');//數據庫帳號密碼爲安裝數據庫時設置
    mysqli_set_charset($conn,'utf8');

    $curr = isset($_REQUEST['curr'])?$_REQUEST['curr']:1;#當前頁
    $limit = 10;#每頁多少行
    $offset = ($curr-1)*$limit;

    $sql = "select {$file} from {$table} WHERE {$where} limit $offset,$limit";
    $res = mysqli_query($conn,$sql);

    return mysqli_fetch_all($res,MYSQLI_ASSOC);#列表

}

function tt(){
    $redis =new \Redis();
    $redis->connect('127.0.0.1', 6379);
    if ($redis->get('putIn') != 'yes') {//第一次進來,緩存數據,比如說我想緩存蔬菜這個分類的所有數據,就用蔬菜這個分類作爲鍵值

        $file = 'a.id,a.title,a.createtime,a.type,a.file_url,b.username';
        $table = 'lyy_ziliao a JOIN lyy_member b ON a.uid=b.id';
        $where = 'a.del=1';
        $lists = select($table, $file, $where);
        //蔬菜1
        $json = json_encode($lists);

        $table = 'lyy_shiyan a JOIN lyy_member b ON a.uid=b.id';
        $lists = select($table, $file, $where);
        //肉類
        $json2 = json_encode($lists);

        $redis->del('shucai', 'routlei', 'putIn');//把鍵值刪除,防止重複
        $redis->lPush('shucai', $json);
        $redis->lPush('roulei', $json2);
        $redis->set('putIn', 'yes');
        echo 'PUTIN SUCCESS' . "</br>";
    }else{
        echo 'PUTIN error' . "</br>";
    }
}

//請求地址
function t2(){
    $redis =new \Redis();
    $redis->connect('127.0.0.1', 6379);

    //獲取到數據
    $json=$redis->lRange('roulei', 0, 0);
    $res=json_decode($json[0],true);//加true是把json轉爲數組使用
    print_r($res);
}
tt();
t2();

2.結合頁面顯示

 <?php
    $name = !empty($_POST['name'])? $_POST['name'] :'';
    $a = t2();
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="a.php" method="post">
    <input type="text" value="<?= $name?>" name="name">
    <input type="submit" value="提交">
</form>
<?php
if ($a){
    echo $a[1]['title'];
}
?>
</body>
</html>

3.簡單字符串緩存實戰

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

//HSET 應用
$arrWebSite = [
    'google' => [
        'google.com',
        'google.com.hk'
    ],
];
$redis->hSet($strCacheKey, 'google', json_encode($arrWebSite['google']));
$json_data1 = $redis->hGet($strCacheKey, 'google');
$data1 = json_decode($json_data1);
print_r($json_data1); //輸出數據

//SET 應用
/*$arrCacheData = [
    'name' => 'job',
    'sex'  => '男',
    'age'  => '30'
];
$redis->set($strCacheKey, json_encode($arrCacheData));
$redis->expire($strCacheKey, 30);  # 設置30秒後過期
$json_data = $redis->get($strCacheKey);
$data = json_decode($json_data);
print_r($data->name); //輸出數據*/

4.簡單隊列實戰

<?php

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$strQueueName  = 'queue';

//進隊列
$redis->rpush($strQueueName, json_encode(['uid' => 1,'name' => 'Job']));
$redis->rpush($strQueueName, json_encode(['uid' => 2,'name' => 'Tom']));
$redis->rpush($strQueueName, json_encode(['uid' => 3,'name' => 'John']));
echo "---- 進隊列成功 ---- <br /><br />";

//查看隊列
$strCount = $redis->lrange($strQueueName, 0, -1);
echo "當前隊列數據爲: <br />";
print_r($strCount);

//出隊列
$redis->lpop($strQueueName);
echo "<br /><br /> ---- 出隊列成功 ---- <br /><br />";

//查看隊列
$strCount = $redis->lrange($strQueueName, 0, -1);
echo "當前隊列數據爲: <br />";

$redis->del($strQueueName);
print_r($strCount);

5.簡單發佈訂閱實戰

6.簡單計數器實戰

<?php

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$strKey = 'Test_num';

//設置初始值
$redis->set($strKey, 0);

$redis->INCR($strKey);  //+1
$redis->INCR($strKey);  //+1
$redis->INCR($strKey);  //+1

$strNowCount = $redis->get($strKey);

echo "當前數量爲{$strNowCount} ";

7.排行榜實戰

<?php

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$strKey = '分數';

//存儲數據
$redis->zadd($strKey, '50', json_encode(['name' => 'Tom']));
$redis->zadd($strKey, '70', json_encode(['name' => 'John']));
$redis->zadd($strKey, '90', json_encode(['name' => 'Jerry']));
$redis->zadd($strKey, '30', json_encode(['name' => 'Job']));
$redis->zadd($strKey, '100', json_encode(['name' => 'LiMing']));

$dataOne = $redis->ZREVRANGE($strKey, 0, -1, true);
echo "---- {$strKey}由大到小的排序 ---- <br /><br />";
print_r($dataOne);

$dataTwo = $redis->ZRANGE($strKey, 0, -1, true);
echo "<br /><br />---- {$strKey}由小到大的排序 ---- <br /><br />";
print_r($dataTwo);

8.簡單字符串悲觀鎖實戰

  • 解釋:悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀。
  • 每次去拿數據的時候都認爲別人會修改,所以每次在拿數據的時候都會上鎖。
  • 場景:如果項目中使用了緩存且對緩存設置了超時時間。
  • 當併發量比較大的時候,如果沒有鎖機制,那麼緩存過期的瞬間,大量併發請求會穿透緩存直接查詢數據庫,造成雪崩效應。
<?php
class a
{
    public $_redis ='';
    public function __construct(){
        $this->_redis = new Redis();
        $this->_redis->connect('127.0.0.1', 6379);
        return $this->_redis;
    }
    /**
     * 獲取鎖
     * @param String $key 鎖標識
     * @param Int $expire 鎖過期時間
     * @return Boolean
     */
    public function lock($key = '', $expire = 5)
    {
        $is_lock = $this->_redis->setnx($key, time() + $expire);
        //不能獲取鎖
        if (!$is_lock) {
            //判斷鎖是否過期
            $lock_time = $this->_redis->get($key);
            //鎖已過期,刪除鎖,重新獲取
            if (time() > $lock_time) {
                $this->unlock($key);
                $is_lock = $this->_redis->setnx($key, time() + $expire);
            }
        }

        return $is_lock ? true : false;
    }

    /**
     * 釋放鎖
     * @param String $key 鎖標識
     * @return Boolean
     */
    public function unlock($key = '')
    {
        return $this->_redis->del($key);
    }

}

// 定義鎖標識
$key = 'lock';
$a = new a();
// 獲取鎖
$is_lock = $a->lock($key, 10);
if ($is_lock)
{
    echo 'get lock success<br>';
    echo 'do sth..<br>';
    sleep(5);
    echo 'success<br>';
    $a->unlock($key);
}

else { //獲取鎖失敗
    echo 'request too frequently<br>';
}

9.簡單事務的樂觀鎖實戰

  • 解釋:樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀。
  • 每次去拿數據的時候都認爲別人不會修改,所以不會上鎖。
  • watch命令會監視給定的key,當exec時候如果監視的key從調用watch後發生過變化,則整個事務會失敗。
  • 也可以調用watch多次監視多個key。這樣就可以對指定的key加樂觀鎖了。
  • 注意watchkey是對整個連接有效的,事務也一樣。
  • 如果連接斷開,監視和事務都會被自動清除。execdiscardunwatch命令都會清除連接中的所有監視。
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
$strKey = 'age';

$redis->set($strKey,10);
$age = $redis->get($strKey);
echo "開始的年齡10:{$age} ………………<br/><br/>";
$redis->watch($strKey);

// 開啓事務
$redis->multi();

//在這個時候新開了一個新會話執行
$redis->set($strKey,30);  //新會話
echo "事務中的年齡30:{$age} ……………… <br/><br/>"; //30
$redis->set($strKey,20);
$redis->exec();
$age = $redis->get($strKey);
echo "事務結束後的年齡20:{$age} ……………… <br/><br/>"; //30
//當exec時候如果監視的key從調用watch後發生過變化,則整個事務會失敗

參考:https://www.cnblogs.com/lauhp/p/8124954.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章