Mac下安裝
在composer.json中引入最新版本的predis
composer require predis/predis
把下載predis 庫(kù)加入到vendor,并且composer.lock里可以看到其版本
composer update
修改配置文件
.env中(.env里沒(méi)有值才會(huì)讀database.php里的default值)
CACHE_DRIVER=redis
SESSION_DRIVER=redis
REDIS_CLIENT=predis
測(cè)試下能不能用
use Illuminate\Support\Facades\Redis;
class IndexController
{
public function useRedis()
{
Redis::set('foo', 2);
return Redis::get('foo');
}
}
原理
Redis 是開(kāi)源免費(fèi)的奸例,遵守BSD協(xié)議割去,是一個(gè)高性能的key-value非關(guān)系型數(shù)據(jù)庫(kù)抒钱,與傳統(tǒng)數(shù)據(jù)庫(kù)不同的是 redis 的數(shù)據(jù)是存在內(nèi)存中的了袁,所以讀寫(xiě)速度?程谷裕快水慨,因此 redis 被?泛應(yīng)?于緩存?向得糜。另外,redis 也經(jīng)常?來(lái)做分布式鎖晰洒。redis 提供了多種數(shù)據(jù)類(lèi)型來(lái)?持不同的業(yè)務(wù)場(chǎng)景朝抖。除此之外,redis ?持事務(wù) 谍珊、持久化治宣、LUA腳本、LRU驅(qū)動(dòng)事件砌滞、多種集群?案侮邀。
特點(diǎn)
- 支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保存在磁盤(pán)中贝润,重啟的時(shí)候可以再次加載進(jìn)行使用
- 性能極高 – Redis 讀的速度是 110000 次 /s, 寫(xiě)的速度是 81000 次 /s
原子性 - Redis 的所有操作都是原子性的绊茧,意思就是要么成功執(zhí)行要么失敗完全不執(zhí)行。單個(gè)操作是原子性的打掘。多個(gè)操作也支持事務(wù)华畏,即原子性鹏秋,通過(guò) MULTI 和 EXEC 指令包起來(lái)。- 其他特性 - Redis 還支持 publish/subscribe 通知亡笑,key 過(guò)期等特性侣夷。
5種基本數(shù)據(jù)結(jié)構(gòu)的使用場(chǎng)景和操作函數(shù)
(一)String
這個(gè)其實(shí)沒(méi)啥好說(shuō)的,最常規(guī)的set/get操作仑乌,value可以是String也可以是數(shù)字百拓。一般做一些復(fù)雜的計(jì)數(shù)功能的緩存。
public function useRedisString(){
Redis::del('foo');
Redis::set('k1','v1');
var_dump(Redis::get('k1'));
Redis::del('k1');
$array1 = ['user1'=>'lili','user2'=>'jojo','user3'=>'xixi'];
Redis::mset($array1);
var_dump(Redis::mget(array_keys($array1)));
var_dump(Redis::get('user2'));
// 模糊搜索鍵信息
var_dump(Redis::keys('use*'));
var_dump(Redis::keys('k1'));
// 獲取緩存時(shí)間
var_dump(Redis::ttl('str2'));
var_dump(Redis::exists('foo'));
}
(二)hash
這里value存放的是結(jié)構(gòu)化的對(duì)象绝骚,比較方便的就是操作其中的某個(gè)字段耐版。博主在做單點(diǎn)登錄的時(shí)候,就是用這種數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)用戶(hù)信息压汪,以cookieId作為key粪牲,設(shè)置30分鐘為緩存過(guò)期時(shí)間,能很好的模擬出類(lèi)似session的效果止剖。
function useRedisHash(){
Redis::hset('hash1','k1','v1');
Redis::hset('hash1','k2','v2');
Redis::hget('hash1','k1');
Redis::hexists('hash1','k2');
Redis::hlen('hash1');
Redis::hdel('hash1','k2');
// hsetnx 增加一個(gè)value,但不能重復(fù)
Redis::hsetnx('hash1','k1','v2'); // true
Redis::hsetnx('hash1','k1','v2'); // false
// 存腺阳、取多個(gè)元素
Redis::hmset('hash1',array('k3'=>'v3','k4'=>'v4'));
Redis::hmget('hash1',array('k3','k4'));
Redis::hincrby('hash1','k5',3); // 不存在,則存儲(chǔ)并返回 3穿香;存在亭引,即返回 原有值 + 3;
Redis::hincrby('hash1','k5',10); // 返回13
// hkeys 返回hash表中的所有key
Redis::hkeys('hash1');
// hvals 返回hash表中的所有value
Redis::hvals('hash1');
// hgetall 返回整個(gè)hash表元素
Redis::hgetall('hash1');
}
(三)list
使用List的數(shù)據(jù)結(jié)構(gòu)皮获,可以做簡(jiǎn)單的消息隊(duì)列的功能焙蚓。另外還有一個(gè)就是,可以利用lrange命令洒宝,做基于redis的分頁(yè)功能购公,性能極佳,用戶(hù)體驗(yàn)好雁歌。
function useRedisList()
{
//rpush/rpushx 有序列表操作,從隊(duì)列后插入元素宏浩;lpush/lpushx 和 rpush/rpushx 的區(qū)別是插入到隊(duì)列的頭部,同上,'x'含義是只對(duì)已存在的 key 進(jìn)行操作
Redis::rpush('footList1', 'bar1'); // 返回列表長(zhǎng)度 1
Redis::lpush('footList1', 'bar2'); // 返回列表長(zhǎng)度 2
Redis::rpushx('footList1', 'bar3'); // 返回 3, rpushx只對(duì)已存在的隊(duì)列做添加,否則返回 0
//llen返回當(dāng)前列表長(zhǎng)度
var_dump(Redis::llen('footList1')); //返回3
//lrange 返回隊(duì)列中一個(gè)區(qū)間的元素
var_dump(Redis::lrange('footList1', 0, 1)); // 返回?cái)?shù)組包含第 0 個(gè)至第 1 個(gè), 共2個(gè)元素
var_dump(Redis::lrange('footList1', 0, -1)); //返回第0個(gè)至倒數(shù)第一個(gè), 相當(dāng)于返回所有元素
//lindex 返回指定順序位置的 list 元素
var_dump(Redis::lindex('footList1', 1)); // 返回'bar1
//lset 修改隊(duì)列中指定位置的value
Redis::lset('footList1', 1, '123'); // 修改位置 1 的元素, 返回 true
//lrem 刪除隊(duì)列中左起指定數(shù)量的字符
Redis::lrem('footList1', 1, '_'); // 刪除隊(duì)列中左起(右起使用-1) 1個(gè) 字符'_'(若有)
//lpop/rpop 類(lèi)似棧結(jié)構(gòu)地彈出(并刪除)最左或最右的一個(gè)元素
Redis::lpop('footList1');
Redis::rpop('footList1');
//ltrim隊(duì)列修改,保留左邊起若干元素靠瞎,其余刪除
Redis::ltrim('footList1', 0, 1); // 保留左邊起第 0 個(gè)至第 1 個(gè)元素
//rpoplpush 從一個(gè)隊(duì)列中 pop 出元素并 push 到另一個(gè)隊(duì)列
Redis::rpush('list1', 'ab0');
Redis::rpush('list1', 'ab1');
Redis::rpush('list2', 'ab2');
Redis::rpush('list2', 'ab3');
Redis::rpoplpush('list1', 'list2'); // 結(jié)果list1 =>array('ab0'), list2 =>array('ab1','ab2','ab3')
Redis::rpoplpush('list2', 'list2'); // 也適用于同一個(gè)隊(duì)列, 把最后一個(gè)元素移到頭部 list2 =>array('ab3','ab1','ab2')
//linsert在隊(duì)列的中間指定元素前或后插入元素
Redis::linsert('list2', 'before', 'ab1', '123'); //表示在元素 'ab1' 之前插入 '123'
Redis::linsert('list2', 'after', 'ab1', '456'); //表示在元素 'ab1' 之后插入 '456'
//blpop/brpop 阻塞并等待一個(gè)列隊(duì)不為空時(shí)比庄,再pop出最左或最右的一個(gè)元素(這個(gè)功能在php以外可以說(shuō)非常好用)
Redis::blpop('list3', 10); // 如果 list3 為空則一直等待,直到不為空時(shí)將第一元素彈出, 10 秒后超時(shí)
}
(四)set
因?yàn)閟et堆放的是一堆不重復(fù)值的集合。所以可以做全局去重的功能乏盐。為什么不用JVM自帶的Set進(jìn)行去重佳窑?因?yàn)槲覀兊南到y(tǒng)一般都是集群部署,使用JVM自帶的Set父能,比較麻煩神凑,難道為了一個(gè)做一個(gè)全局去重,再起一個(gè)公共服務(wù)法竞,太麻煩了耙厚。
另外,就是利用交集岔霸、并集薛躬、差集等操作,可以計(jì)算共同喜好呆细,全部的喜好型宝,自己獨(dú)有的喜好等功能。
sadd增加set集合元素絮爷, 返回true趴酣, 重復(fù)返回false
Redis::sadd('set1', 'ab');
Redis::sadd('set1', 'cd');
Redis::sadd('set1', 'ef');
//srem 移除指定元素
Redis::srem('set1', 'cd'); // 刪除'cd'元素
//spop 彈出首元素
Redis::spop('set1'); // 返回 'ab'
//smove 移動(dòng)當(dāng)前set集合的指定元素到另一個(gè)set集合
Redis::sadd('set2', '123');
Redis::smove('set1', 'set2', 'ab'); // 移動(dòng)'set1'中的'ab'到'set2', 返回true or false;此時(shí) 'set1'集合不存在 'ab' 這個(gè)值
//scard 返回當(dāng)前set表元素個(gè)數(shù)
Redis::scard('set2'); // 返回 2
//sismember 判斷元素是否屬于當(dāng)前set集合
Redis::sismember('set2', '123'); // 返回 true or false
//smembers 返回當(dāng)前set集合的所有元素
Redis::smembers('set2'); // 返回 array('123','ab')
//sinter/sunion/sdiff 返回兩個(gè)表中元素的交集/并集/補(bǔ)集
Redis::sadd('set1', 'ab') ;
Redis::sinter('set2', 'set1') ; //返回array('ab')
//sinterstore/sunionstore/sdiffstore 將兩個(gè)表交集/并集/補(bǔ)集元素 copy 到第三個(gè)表中
Redis::set('foo', 0);
Redis::sinterstore('foo', 'set1'); // 等同于將'set1'的內(nèi)容copy到'foo'中坑夯,并將'foo'轉(zhuǎn)為set表
Redis::sinterstore('foo', array('set1', 'set2')); // 將'set1'和'set2'中相同的元素 copy 到'foo'表中, 覆蓋'foo'原有內(nèi)容
//srandmember 返回表中一個(gè)隨機(jī)元素
Redis::srandmember('set1') ;
(五)sorted set
sorted set多了一個(gè)權(quán)重參數(shù)score,集合中的元素能夠按score進(jìn)行排列岖寞。可以做排行榜應(yīng)用柜蜈,取TOP N操作仗谆。另外,參照另一篇《分布式之延時(shí)任務(wù)方案解析》淑履,該文指出了sorted set可以用來(lái)做延時(shí)任務(wù)隶垮。最后一個(gè)應(yīng)用就是可以做范圍查找。
public function RedisZset($value='')
{
// code...
Redis::del('zset'); //清空表
// 添加元素
Redis::zadd('zset',1, 'book'); //重復(fù)添加返回0
Redis::zadd('zset',2,'dog');
Redis::zadd('zset',3,'banaa');
Redis::zadd('zset',4,'apple');
// 查看集合中所有的元素
$zset = Redis::zrange('zset',0,-1);
//返回 元素的score
$score = Redis::zscore('zset','dog');
//刪除集合中的元素
Redis::zrem('zset', 'book');
//返回集合中介于 min 與 max值得個(gè)數(shù)
Redis::zcount('zset',3,5);
//返回有序集合中score介于min和max之間的值
$arr = Redis::zrangebyscore('zset',3,5);
return $arr;
}
https://learnku.com/docs/lls-mysql/redis/6592
maxmemory-policy noeviction