Redis 常见 7 种使用场景 (PHP 实战)

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

简单字符串缓存实战

$redis->connect('127.0.0.1', 6379);
$strCacheKey  = 'Test_bihu';

//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->age); //输出数据

//HSET 应用
$arrWebSite = [
    'google' => [
        'google.com',
        'google.com.hk'
    ],
];
$redis->hSet($strCacheKey, 'google', json_encode($arrWebSite['google']));
$json_data = $redis->hGet($strCacheKey, 'google');
$data = json_decode($json_data);
print_r($data); //输出数据

简单队列实战


redis-connect('127.0.0.1', 6379);
strQueueName  = 'Test_bihu_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 "---- 进队列成功 ----"; 
//查看队列strCount = redis-lrange(strQueueName, 0, -1); 
echo "当前队列数据为:";
print_r(strCount); 
//出队列 redis-lpop(strQueueName); 
echo "---- 出队列成功 ----"; 
//查看队列strCount = redis-lrange(strQueueName, 0, -1); 
echo "当前队列数据为:"; 
print_r(strCount);

简单发布订阅实战


//以下是 pub.php 文件的内容 cli下运行
ini_set('default_socket_timeout', -1);
redis->connect('127.0.0.1', 6379);strChannel = 'Test_bihu_channel';

//发布
redis->publish(strChannel, "来自{strChannel}频道的推送");
echo "---- {strChannel} ---- 频道消息推送成功~ ";
redis->close();

//以下是 sub.php 文件内容 cli下运行
ini_set('default_socket_timeout', -1);redis->connect('127.0.0.1', 6379);
strChannel = 'Test_bihu_channel';

//订阅
echo "---- 订阅{strChannel}这个频道,等待消息推送...----  ";
redis->subscribe([strChannel], 'callBackFun');
function callBackFun(redis,channel, msg)
{
    print_r([
        'redis'   =>redis,
        'channel' => channel,
        'msg'     =>msg
    ]);
}

简单计数器实战


redis->connect('127.0.0.1', 6379);strKey = 'Test_bihu_comments';

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

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

strNowCount =redis->get(strKey);

echo "---- 当前数量为{strNowCount}。 ---- ";

排行榜实战


redis->connect('127.0.0.1', 6379);strKey = 'Test_bihu_score';

//存储数据
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}由大到小的排序 ----"; 
print_r(dataOne);dataTwo = redis->ZRANGE(strKey, 0, -1, true); 
echo "---- {strKey}由小到大的排序 ---- ";
 print_r(dataTwo);

简单字符串悲观锁实战

解释:悲观锁(Pessimistic Lock), 顾名思义,就是很悲观。
每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁。
场景:如果项目中使用了缓存且对缓存设置了超时时间。
当并发量比较大的时候,如果没有锁机制,那么缓存过期的瞬间,
大量并发请求会穿透缓存直接查询数据库,造成雪崩效应。


/**
 * 获取锁
 * @param  String  key    锁标识
 * @param  Intexpire 锁过期时间
 * @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  Stringkey 锁标识
 * @return Boolean
 */
public function unlock(key = ''){
    returnthis->_redis->del(key);
}

// 定义锁标识key = 'Test_bihu_lock';

// 获取锁
is_lock = lock(key, 10);
if (is_lock) {
    echo 'get lock success';
    echo 'do sth..';
    sleep(5);
    echo 'success';
    unlock(key);
} else { //获取锁失败
    echo 'request too frequently';
}

简单事务的乐观锁实战

解释:乐观锁(Optimistic Lock), 顾名思义,就是很乐观。
每次去拿数据的时候都认为别人不会修改,所以不会上锁。
watch命令会监视给定的key,当exec时候如果监视的key从调用watch后发生过变化,则整个事务会失败。
也可以调用watch多次监视多个key。这样就可以对指定的key加乐观锁了。
注意watch的key是对整个连接有效的,事务也一样。
如果连接断开,监视和事务都会被自动清除。
当然了exec,discard,unwatch命令都会清除连接中的所有监视。

$strKey = 'Test_bihu_age';

$redis->set($strKey,10);

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

echo "---- Current Age:{$age} ---- ";

$redis->watch($strKey);

// 开启事务
$redis->multi();

//在这个时候新开了一个新会话执行
$redis->set($strKey,30);  //新会话

echo "---- Current Age:{$age} ---- "; //30

$redis->set($strKey,20);

$redis->exec();

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

echo "---- Current Age:{$age} ---- "; //30

//当exec时候如果监视的key从调用watch后发生过变化,则整个事务会失败
暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇