Redis-PHP實戰篇——經常使用的使用場景

redis-php實戰

public function getRedis()
{
    $redis = new \Redis();
    $redis->connect(env("REDIS_MASTER",'127.0.0.1'),6379);
    $redis->auth(env('REDIS_AUTH','123456'));
    return $redis;
}

$redis = $this->getRedis();
複製代碼

String 簡單字符串緩存實戰

$key  = 'str:name';
 
// 字符串緩存實戰
$redis->set($key, 'WXiangQian');
$name = $redis->get($key);
echo $name; // WXiangQian
$redis->expire($strCacheKey, 30);  # 設置30秒後過時
複製代碼

HSET 簡單哈希緩存實戰

$key = 'hset:name'

$uid = 1;
$redis->hSet($key, $uid, 'WXiangQian');
$data = $redis->hGet($key, 1);
print_r($data); //輸出數據
複製代碼

排行榜實戰

$strKey = 'zset:ranking_list';
 
//存儲數據
$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);
複製代碼

簡單字符串悲觀鎖實戰

解釋:悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀。php

每次去拿數據的時候都認爲別人會修改,因此每次在拿數據的時候都會上鎖。redis

場景:若是項目中使用了緩存且對緩存設置了超時時間。數據庫

當併發量比較大的時候,若是沒有鎖機制,那麼緩存過時的瞬間,json

大量併發請求會穿透緩存直接查詢數據庫,形成雪崩效應。緩存

/**
 * 獲取鎖
 * @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) {
            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 = 'str:lock';
 
// 獲取鎖
$is_lock = lock($key, 10);
if ($is_lock) {
    echo 'get lock success<br>';
    echo 'do sth..<br>';
    sleep(5);
    echo 'success<br>';
    unlock($key);
} else { //獲取鎖失敗
    echo 'request too frequently<br>';
}
複製代碼

簡單事務的樂觀鎖實戰

解釋:樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀。bash

每次去拿數據的時候都認爲別人不會修改,因此不會上鎖。併發

watch命令會監視給定的key,當exec時候若是監視的key從調用watch後發生過變化,則整個事務會失敗。post

也能夠調用watch屢次監視多個key。這樣就能夠對指定的key加樂觀鎖了。性能

注意watch的key是對整個鏈接有效的,事務也同樣。ui

若是鏈接斷開,監視和事務都會被自動清除。

固然了exec,discard,unwatch命令都會清除鏈接中的全部監視。

$strKey = 'str:age';
 
$redis->set($strKey,10);
 
$age = $redis->get($strKey);
 
echo "---- Current Age:{$age} ---- <br/><br/>"; // 10
 
$redis->watch($strKey);
 
// 開啓事務
$redis->multi();
 
//-------------------------------
/**
 * 在這個時候新開了一個新會話執行
 *
 * redis-cli 執行 $redis->set($strKey,30);  //新會話 模擬其餘終端
 * 這時候$age=30; //30
 */
//-------------------------------
 

 
$redis->set($strKey,20);
 
$redis->exec();
 
$age = $redis->get($strKey);
 
echo "---- Current Age:{$age} ---- <br/><br/>"; //30
 
//當exec時候若是監視的key從調用watch後發生過變化,則整個事務會失敗
複製代碼

悲觀鎖與樂觀鎖的適用場景:

悲觀鎖:比較適合寫入操做比較頻繁的場景,若是出現大量的讀取操做,每次讀取的時候都會進行加鎖,這樣會增長大量的鎖的開銷,下降了系統的吞吐量。

樂觀鎖:比較適合讀取操做比較頻繁的場景,若是出現大量的寫入操做,數據發生衝突的可能性就會增大,爲了保證數據的一致性,應用層須要不斷的從新獲取數據,這樣會增長大量的查詢操做,下降了系統的吞吐量。

總結:兩種所各有優缺點,讀取頻繁使用樂觀鎖,寫入頻繁使用悲觀鎖。

像樂觀鎖適用於寫比較少的狀況下,即衝突真的不多發生的時候,這樣能夠省去了鎖的開銷,加大了系統的整個吞吐量。但若是常常產生衝突,上層應用會不斷的進行retry,這樣反卻是下降了性能,因此這種狀況下用悲觀鎖就比較合適,之因此用悲觀鎖就是由於兩個用戶更新同一條數據的機率高,也就是衝突比較嚴重的狀況下,因此才用悲觀鎖.

悲觀鎖比較適合強一致性的場景,但效率比較低,特別是讀的併發低。樂觀鎖則適用於讀多寫少,併發衝突少的場景

redis篇集合

Redis基礎篇——Redis安裝

Redis基礎篇——介紹以及瞭解

Redis基礎篇——基本用法

Redis進階篇——PHP鏈接redis

Redis-PHP實戰篇——經常使用的使用場景

相關文章
相關標籤/搜索