redis 基礎(chǔ)

[TOC]

開啟 redis 擴(kuò)展

官方文檔

  • php.ini
[redis]
extension=redis
redis.pconnect.pooling_enabled = 1

相關(guān)命令

redis 類

$redis = new Redis();
$redis = new Redis([
    'host' => '127.0.0.1',
    'port' => 6379,
    'connectTimeout' => 2.5,
    'auth' => ['root', 'password'],
    'ssl' => ['verify_peer' => false],
]);
$key = 'key1';

連接

ini_set('default_socket_timeout', -1); // 設(shè)置php不斷開連接

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

$redis->pconnect('127.0.0.1', 6379);
$redis->pconnect('/tmp/redis.sock'); // 持久性連接斤寂,php-fpm進(jìn)程結(jié)束之前一直復(fù)用

賬號(hào)密碼

/* Authenticate with the password 'foobared' */
$redis->auth('foobared');

/* Authenticate with the username 'phpredis', and password 'haxx00r' */
$redis->auth(['phpredis', 'haxx00r']);

/* Authenticate with the password 'foobared' */
$redis->auth(['foobared']);

/* You can also use an associative array specifying user and pass */
$redis->auth(['user' => 'phpredis', 'pass' => 'phpredis']);
$redis->auth(['pass' => 'phpredis']);

數(shù)據(jù)庫選擇

$redis->select(0);

設(shè)置統(tǒng)一前綴

$redis->setOption(Redis::OPT_PREFIX, 'myAppName:'); // use custom prefix on all keys

序列化

$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE);     // Don't serialize data
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);      // Use built-in serialize/unserialize
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_IGBINARY); // Use igBinary serialize/unserialize
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_MSGPACK);  // Use msgpack serialize/unserialize
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_JSON); 

keys 數(shù)量

 $redis->dbSize();

清空所有數(shù)據(jù)庫

$redis->flushAll();

清空當(dāng)前數(shù)據(jù)庫

$redis->flushDb();

同步持久化

$redis->save();

獲取 key 類型

所有類型
string: Redis::REDIS_STRING
set: Redis::REDIS_SET

list: Redis::REDIS_LIST
zset: Redis::REDIS_ZSET
hash: Redis::REDIS_HASH
other: Redis::REDIS_NOT_FOUND

$redis->type('key');

獲取過期時(shí)間

ps: If the key has no ttl, -1 will be returned, and -2 if the key doesn't exist

$redis->ttl('key'); // seconds
$redis->pttl('key'); // milliseconds

事務(wù)

mulit

命令塊作為單個(gè)事務(wù)運(yùn)行

$ret = $redis->multi()
    ->set('key1', 'val1')
    ->get('key1')
    ->set('key2', 'val2')
    ->get('key2')
    ->exec();
PIPELINE

只是將更快地傳輸?shù)椒?wù)器豁跑,但沒有任何原子性保證

$ret = $redis->pipeline()
    ->set('key1', 'val1')
    ->get('key1')
    ->set('key2', 'val2')
    ->get('key2')
    ->exec();
執(zhí)行或取消
$redis->exec(); // 執(zhí)行
$redis->discard(); // 取消
watch

在 watch 和 exec 執(zhí)行之間化戳,如果發(fā)現(xiàn)監(jiān)聽的值發(fā)生變化本橙,則執(zhí)行失敗

$redis->watch('x');
$ret = $redis->multi()
    ->incr('x')
    ->exec(); // return true or false

腳本

script
$redis->script('load', $script);
$redis->script('flush');
$redis->script('kill');
$redis->script('exists', $script1, [$script2, $script3, ...]);
eval

Parameters

  • script string.
  • args array, optional.
  • num_keys int, optional. KEYS參數(shù)的個(gè)數(shù) args.length - key 為 ARGV 參數(shù)的個(gè)數(shù)
$redis->eval("return 1");

  • eval 參數(shù)的格式
EVAL script numkeys key [key ...] arg [arg ...]

eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 arg1 arg2 arg3

  1. "key1"
  2. "key2"
  3. "arg1"
  4. "arg2"
  5. "arg3"
lua 腳本
        $script = <<<LUA
local interval_milliseconds = tonumber(ARGV[1])
redis.call('set', KEYS[1], 2)
redis.call('pexpire', KEYS[1], interval_milliseconds)
redis.call('decr', KEYS[1])
local current = redis.call('get', KEYS[1])
local ttl = redis.call('ttl', KEYS[1])
return {current,ttl}
LUA;

$redis->script('load', $script);
$ret = $redis->eval($script, [$key, 1], 1);

string

添加
$redis->set($key, 20); // 設(shè)置
// Will set the key, if it doesn't exist, with a ttl of 10 seconds
$redis->set($key, 'value', ['nx', 'ex'=>10]);
// Will set a key, if it does exist, with a ttl of 1000 milliseconds
$redis->set('key', 'value', ['nx', 'px'=>1000]);
// Set the string value in argument as value of the key if the key doesn't already exist in the database
$redis->setNx($key, 'value');

$redis->incr($key, 2); // 自增2
$redis->decr($key, 2); // 自減2
$redis->incr('key1', 1); /* key1 didn't exists, set to 0 before the increment, ex = -1 */

// 追加內(nèi)容
$redis->set('key', 'value1');
$redis->append('key', 'value2'); /* 12 */
$redis->get('key'); /* 'value1value2' */
獲取
$redis->get($key); // 獲取
$redis->mGet(['key1', 'key2', 'key3']); // ['value1', 'value2', 'value3'];

// 獲取部分內(nèi)容
$redis->set('key', 'string value');
$redis->getRange('key', 0, 5); /* 'string' */
$redis->getRange('key', -5, -1); /* 'value' */

// 獲取并設(shè)置
$redis->set('x', '42');
$exValue = $redis->getSet('x', 'lol'); // return '42', replaces x by 'lol'
刪除

// 刪除
$redis->del($key, 'key2'); /* return 2 */
$redis->del([$key, 'key4']); /* return 2 */
其它
// 重命名
$redis->set('x', '42');
$redis->rename('x', 'y');
$redis->get('y');   // → 42

// 存在
$redis->exists('key');
過期時(shí)間
$redis->expire($key, 3);    // x will disappear in 3 seconds.
$now = time(NULL); // current timestamp
$redis->expireAt('x', $now + 3);

hash

新增
$redis->hSet('key', 'field', 'value');
$redis->hMSet('key', ['field2' => 'value2', 'field3' => 'value3']);
獲取
$redis->hGet('key', 'field'); /* returns "value" */
$redis->hMGet('key', ['field', 'field2']);
$redis->hKeys('key') // ['field', 'filed2', 'field3']
$redis->hVals('key') // ['value', 'value2', 'value3']
$redis->hGetAll('key') // ['field' => 'value', 'field2' => 'value2', 'field3' => 'value3']
刪除
$redis->hDel('key', 'field');
$redis->hDel('key', 'field', 'filed2');
其它
$redis->hExists('key', 'field');

list 列表

新增
$redis->lPush('key1', 'A'); // left push
$redis->rPush('key1', 'B'); // right push
獲取
$redis->lIndex('key1', 0); // 獲取 list 索引
$redis->lGet('key1', 0); // 獲取 list 的值
$redis->lLen('key1'); // 獲取 list 長度
彈出
$redis->lPop('key1'); // left pop
$redis->rPop('key1'); // right pop

Sets 集合(value唯一)

新增
$redis->sAdd('key1', 'member1', 'member2', 'member3'); /* 3, 'key1' => {'member1', 'member2', 'member3'}*/
獲取
$redis->sCard('key1'); /*獲取 set 長度*/
$redis->sDiff('s0', 's1', 's2') // 取差集
$redis->sMembers('key1') // ['member1', 'member2', 'member3']
刪除
$redis->sPop('key1', 2); // 隨機(jī)彈出2個(gè)元素
$redis->sRem('key1', 'member2', 'member3'); // 刪除

Sorted sets(有序集合)

每個(gè)元素都會(huì)關(guān)聯(lián)一個(gè) double 類型的分?jǐn)?shù)。redis 正是通過分?jǐn)?shù)來為集合中的成員進(jìn)行從小到大的排序

新增
$redis->zAdd('key1', 1, 'member1', 'member2', 'member3'); /* 'key1' => {'member1', 'member2', 'member3'}*/
$redis->zAdd('key1', 2, 'member4'); /* 3, 'key1' => {'member1', 'member2', 'member3', 'member4'}*/
獲取
$redis->zCard('key1'); /*獲取 set 長度*/
$redis->zScore('key', 'val2'); // 獲取元素的 score

$redis->zAdd('key', 0, 'val0');
$redis->zAdd('key', 2, 'val2');
$redis->zAdd('key', 10, 'val10');

$redis->zRange('key1', 0, -1); //  ['val0', 'val2', 'val10'] Parameters index start end

$redis->zRangeByScore('key', 0, 3); /* 根據(jù) score 獲取 ['val0', 'val2'] */ Parameters index start_score end_score

$redis->zRangeByScore('key', '-inf', '+inf', ['withscores' => TRUE]); /* ['val0' => 0, 'val2' => 2, 'val10' => 10] */
彈出或刪除
$redis->zPopMin('key1', 2); // 彈出最低分?jǐn)?shù)的2個(gè)元素
$redis->zPopMax('key1', 2); // 彈出最高分?jǐn)?shù)的2個(gè)元素
$redis->zRem('key1', 'member2', 'member3'); // 刪除

Streams

主要用于消息隊(duì)列(MQ锅减,Message Queue)

分組
$obj_redis->xGroup('HELP');
$obj_redis->xGroup('CREATE', $str_key, $str_group, $str_msg_id, [$boo_mkstream]);
$obj_redis->xGroup('SETID', $str_key, $str_group, $str_msg_id);
$obj_redis->xGroup('DESTROY', $str_key, $str_group);
$obj_redis->xGroup('DELCONSUMER', $str_key, $str_group, $str_consumer_name);

$obj_redis->xGroup('CREATE', 'mystream', 'mygroup', 0);
新增消息

消息 message ID糖儡,我們使用 *表示由 redis 生成,可以自定義怔匣,但是要自己保證遞增性

$obj_redis->xAdd('mystream', "*", ['field' => 'value']); // return The added message ID, example: '1530063064286-0'
標(biāo)記為已處理
$obj_redis->xAck($stream, $group, $arr_messages);

$obj_redis->xAck('stream', 'group1', ['1530063064286-0', '1530063064286-1']);
刪除消息
$obj_redis->xDel($str_key, $arr_ids);

$obj_redis->xDel('mystream', ['1530115304877-0', '1530115305731-0']);
獲取消息
$obj_redis->xRead($arr_streams [, $i_count, $i_block]);
$obj_redis->xRead(['stream1' => '1535222584555-0', 'stream2' => '1535222584555-0']);

$obj_redis->xReadGroup($str_group, $str_consumer, $arr_streams [, $i_count, $i_block]);
$obj_redis->xReadGroup('mygroup', 'consumer1', ['s1' => 0, 's2' => 0]);
獲取消息列表
/* Get everything in this stream */
$obj_redis->xRange('mystream', '-', '+');

/* Only the first two messages */
$obj_redis->xRange('mystream', '-', '+', 2);

Pub/sub

subscribe 訂閱
$redis = new Redis();
$redis->connect('192.168.1.62', 6379);
$redis->setOption(Redis::OPT_READ_TIMEOUT, -1); // redis方式設(shè)置不超時(shí)

$redis->subscribe(['chan', 'chan2'], function($redis, $chan, $msg) {
    echo $msg . PHP_EOL;
});
psubscribe 批量訂閱

模糊匹配

$redis->psubscribe(['my*'], function($redis, $pattern, $chan, $msg) {
      echo "Pattern: $pattern\n";
      echo "Channel: $chan\n";
      echo "Payload: $msg\n";
});
publish 發(fā)布
$redis = new Redis();
$redis->connect('192.168.1.62', 6379);
$redis->publish('chan', 'hello, world!'); // send message.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末握联,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子每瞒,更是在濱河造成了極大的恐慌金闽,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剿骨,死亡現(xiàn)場離奇詭異呐矾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)懦砂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門蜒犯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人荞膘,你說我怎么就攤上這事罚随。” “怎么了羽资?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵淘菩,是天一觀的道長。 經(jīng)常有香客問我屠升,道長潮改,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任腹暖,我火速辦了婚禮汇在,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘脏答。我一直安慰自己糕殉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布殖告。 她就那樣靜靜地躺著阿蝶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪黄绩。 梳的紋絲不亂的頭發(fā)上羡洁,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音爽丹,去河邊找鬼筑煮。 笑死,一個(gè)胖子當(dāng)著我的面吹牛习劫,可吹牛的內(nèi)容都是我干的咆瘟。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼诽里,長吁一口氣:“原來是場噩夢啊……” “哼袒餐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谤狡,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對情侶失蹤灸眼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后墓懂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體焰宣,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年捕仔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了匕积。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盈罐。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖闪唆,靈堂內(nèi)的尸體忽然破棺而出盅粪,到底是詐尸還是另有隱情,我是刑警寧澤悄蕾,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布票顾,位于F島的核電站,受9級(jí)特大地震影響帆调,放射性物質(zhì)發(fā)生泄漏奠骄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一番刊、第九天 我趴在偏房一處隱蔽的房頂上張望含鳞。 院中可真熱鬧,春花似錦撵枢、人聲如沸民晒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽潜必。三九已至,卻和暖如春沃但,著一層夾襖步出監(jiān)牢的瞬間磁滚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國打工宵晚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留垂攘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓淤刃,卻偏偏與公主長得像晒他,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子逸贾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容