redis入門指南第二版讀書(shū)筆記

redis入門指南第二版讀書(shū)筆記

作者:李子驊

讀者:張劍

Redis是以高性能著稱的內(nèi)存數(shù)據(jù)庫(kù),通常用來(lái)做緩存服務(wù)器。通常人們把它當(dāng)作memcached的替代品。

同時(shí)圍繞Redis也形成了很多產(chǎn)品工具鏈,Redis的命令也成了一種協(xié)議,有些模仿者使用同樣的命令但是在某些方面有所側(cè)重。

通過(guò)replication/persistentce和client-side sharding等特性,用戶可以很方便地將Redis擴(kuò)展成數(shù)百GB數(shù)據(jù)每秒處理上百次請(qǐng)求的系統(tǒng)。

Redis的5種數(shù)據(jù)結(jié)構(gòu)

我們把Redis歸類為內(nèi)存NOSQL Key—Value數(shù)據(jù)庫(kù)。

Redis可以存儲(chǔ)key與五種不同類型的value。

Value的五種類型分別是String,List,Set,HashSet,Zset。

特別說(shuō)明:

String? ? 中存放的是一個(gè)元素,可改變或追加其內(nèi)容(json對(duì)象可以壓縮為二進(jìn)制字符串保存)

List Set? 中存放的是一組元素,List以雙向鏈表方式存儲(chǔ)元素,Set是無(wú)序不可重復(fù)的元素集合

Hash? ? ? 中存放的是一組key-value元素,可看成Map的集合

Sorted Set 中存放的是一組元素,不同的是每個(gè)元素都會(huì)關(guān)聯(lián)一個(gè)double類型的score

1.簡(jiǎn)單類型? String

get,set,del

2.鏈表類型? List? 可重復(fù) 有序

lpush和rpush? 加入到list的頭和尾

lpop和rpop? ? 從list的頭和尾出棧

lindex? ? ? ? 根據(jù)指定位置獲取item

lrange? ? ? ? 獲取某個(gè)范圍內(nèi)的items

eg:

lrange list-key 0 -1? ? 取出list-key中的所有values

利用List可以有幾種變化,比如可以當(dāng)作堆棧先進(jìn)后出,也可以當(dāng)作隊(duì)列先進(jìn)先出

lpush和lpop結(jié)合使用就是堆棧

lpush和rpop結(jié)合使用就是隊(duì)列

3.Set類型? Set? ? 不可重復(fù) 無(wú)序

sadd? ? ? ? ? 添加元素

smembers? ? ? 返回所有元素

sismember? ? ? 查看元素是否在set中

srem? ? ? ? ? 如果存在,則刪除該元素

說(shuō)明:

以上3種類型存放的都是元素

4.Hash 類型? HashSet? 存放 key-value 組

hset? ? ? ? ? 在Hash表中存放key-value

hget? ? ? ? ? 在Hash表中根據(jù)指定key獲取value

hgetall? ? ? 返回Hash表中的所有key-value組

hdel? ? ? ? ? 如果存在,根據(jù)key刪除value

eg:

可以一次性設(shè)置多個(gè)key-value組

hset hash_set_demo1 sub-key1 value1 sub-key2 value2

hget hash_set_demo1 sub-key1

hgetall hash_set_demo1

hdel hash_set_demo1 sub-key2

5.Sorted Sets類型? ? zset 排序的Set

zset-key? ? ? zset

element? ? ? score

Jack? ? ? ? 80

Cooper? ? ? 100

zadd? ? ? ? ? 添加一個(gè)元素到zset中

zrange? ? ? ? 從zset中獲取排序之后的多個(gè)元素

zrangebyscore? 獲得按分?jǐn)?shù)排序后的元素

zrem? ? ? ? ? 如果存在,則從zset中刪除元素

eg:

zadd zset-key 60 Jack 80 Cooper 100 David

127.0.0.1:6379> zrange zset-key 0 -1 withscores

1) "Jack"

2) "60"

3) "Cooper"

4) "80"

5) "David"

6) "100"

127.0.0.1:6379> zrange zset-key 0 -1

1) "Jack"

2) "Cooper"

3) "David"

127.0.0.1:6379> zrangebyscore zset-key 85 100 withscores

1) "David"

2) "100"

127.0.0.1:6379> zrem zset-key Jack

(integer) 1

127.0.0.1:6379> zrem zset-key Cooper

(integer) 0

127.0.0.1:6379> zrange zset-key 0 -1 withscores

1) "David"

2) "100"

Redis的核心內(nèi)容

1.? 5種數(shù)據(jù)類型的核心命令

String類型

存放3種類型的value

字節(jié)(數(shù)組)值

整數(shù)

浮點(diǎn)數(shù)

說(shuō)明:

整數(shù)有自增和自減操作

incr/decr? 整數(shù)自加1(自減1)

incrby/decrby key byNum? 整數(shù)自增(自減)指定值byNum

incrbyfloat key amount? ? 浮點(diǎn)數(shù)自增指定值amount

List類型? 棧和隊(duì)列類型,允許兩頭進(jìn)行出棧和入棧

lpush和rpush? 加入到list的頭和尾

lpop和rpop? ? 從list的頭和尾出棧

lindex? ? ? ? 根據(jù)指定位置獲取item

lrange key start end? ? ? 獲取某個(gè)范圍內(nèi)的items

ltrim? key start end? ? ? 剔除list中索引不在start ~ end 之間的元素

Set類型? ? 存放無(wú)序不可重復(fù)的元素

sadd key item? 添加元素

srem key item? 刪除元素

sismember key item? 查看item是否在set中

scard key? ? ? 返回set中元素?cái)?shù)量

smembers? ? ? 返回set中所有元素

srandmember? key [count]? 從set中返回一個(gè)或count個(gè)隨機(jī)元素

spop key? ? ? 從set中刪除并返回一個(gè)隨機(jī)元素

smove? source-key dest-key? item? 將item元素從source-key 移到dest-key

兩個(gè)set類型的操作

sdiff? key1 [key2...]? 返回在key1中而不再其他key中的元素

sdiffstore

sinter key1 [key2...]? 返回所有key都有的元素

sinterstore

sunion key1 [key2...]? 返回多個(gè)key中的并集

sunionstore

Hash類型? 存放若干key-value,看做存放map的集合

hmget hash key [key...]? ? 從hash中根據(jù)多個(gè)key獲取對(duì)應(yīng)的value

hmset hash key value [key value ...]? 在hash中設(shè)置多個(gè)key及其對(duì)應(yīng)的value

hdel? hash key [key...]? ? 從hash中根據(jù)key刪除

hlen? hash key? ? ? ? ? ? ? 返回hash中的map元素?cái)?shù)量

hexists? hash key? ? 對(duì)應(yīng)的key是否存在hash中

hkeys? hash? ? ? ? ? 獲取hash中所有的key

hvals? hash? ? ? ? ? 獲取hash中所有的value

hgetall hash? ? ? ? ? 獲取hash中所有的key-value鍵值對(duì)

hincrby hash key? ? ? 如果key中存儲(chǔ)的value是int,則value+1

Sorted Set類型? ? zset? 存放排序的元素

zadd key-name score member [score member ...] 增加一個(gè)元素,并給元素一個(gè)對(duì)應(yīng)的score

zrem key-name member [member ...]? 刪除一個(gè)或多個(gè)元素

zcard key-name? 返回zset中元素?cái)?shù)量

zincrby key-name incrment member

zcount key-name min max 返回score在min與max之間的元素,保護(hù)member 與其 對(duì)應(yīng)的 value

zrank key-name member? 返回member元素在zset中的位置

zscore key-name? ? ? ? 返回zset中所有元素?cái)?shù)量

zrange key-name start stop? 返回score在min與max之間的元素

2.? 事務(wù)

和一般的關(guān)系數(shù)據(jù)庫(kù)類似,redis也支持事務(wù)。

但是redis的事務(wù)還是有所區(qū)別:

a.不能回滾,

b.即使其中一個(gè)命令有了運(yùn)行錯(cuò)誤(非語(yǔ)法錯(cuò)誤),也不會(huì)影響到同一事務(wù)中其他命令的執(zhí)行。

c.事務(wù)中的每個(gè)命令的執(zhí)行結(jié)果都是最后一起返回的,所以無(wú)法將前一條命令的結(jié)果作為下一條命令的參數(shù)

結(jié)合WATCH命令

WATCH 命令可以監(jiān)控一個(gè)或多個(gè)鍵,一旦其中有一個(gè)鍵被修改(或刪除),之后的事務(wù)就不會(huì)執(zhí)行。監(jiān)控一直持續(xù)到 EXEC 命令

redis> MULTI

OK

redis> SADD "user:1:following" 2

QUEUED

redis> SADD "user:2:followers" 1

QUEUED

redis> EXEC

1) (integer) 1

2) (integer) 1

3.過(guò)期時(shí)間

過(guò)期時(shí)間經(jīng)常在訪問(wèn)頻率控制和實(shí)現(xiàn)緩存中使用

EXPIRE session:29e3d 900

4.消息通知

利用消息通知,可以實(shí)現(xiàn)任務(wù)隊(duì)列,優(yōu)先級(jí)隊(duì)列,發(fā)布/訂閱模式

這里就用到了list的阻塞彈出命令,不過(guò)下面沒(méi)有提到在消息通知和任務(wù)隊(duì)列里面常用的彈出推入命令(RPOPLPUSH)。

a.任務(wù)隊(duì)列

BRPOP命令和RPOP命令相似,唯一的區(qū)別是當(dāng)列表中沒(méi)有元素時(shí)BRPOP命令會(huì)一直阻塞住連接,直到有新元素加入。

示例代碼:

loop

# 如果任務(wù)隊(duì)列中沒(méi)有新任務(wù),BRPOP 命令會(huì)一直阻塞,不會(huì)執(zhí)行 execute()。

$task = BRPOP queue, 0

# 返回值是一個(gè)數(shù)組(見(jiàn)下介紹),數(shù)組第二個(gè)元素是我們需要的任務(wù)。

execute($task[1])

b.優(yōu)先級(jí)隊(duì)列

BRPOP 命令可以同時(shí)接收多個(gè)鍵,其完整的命令格式為 BLPOP key [key …] timeout,如 BLPOP queue:1 queue:2 0。意義是同時(shí)檢測(cè)多個(gè)鍵,如果所有鍵都沒(méi)有元素則阻塞,如果其中有一個(gè)鍵有元素則會(huì)從該鍵中彈出元素。

示例代碼:

loop

$task =BRPOP queue:confirmation.email,

queue:notification.email, 0

execute($task[1])

這時(shí)一旦發(fā)送確認(rèn)郵件的任務(wù)被加入到 queue:confirmation.email 隊(duì)列中,無(wú)論queue: notification.email還有多少任務(wù),消費(fèi)者都會(huì)優(yōu)先完成發(fā)送確認(rèn)郵件的任務(wù)。

c.發(fā)布/訂閱模式

通過(guò)兩個(gè)命令實(shí)現(xiàn)發(fā)布/訂閱模式

PUBLISH

SUBSCRIBE

5.管道pipeline

管道和事務(wù)類似,不過(guò)管道的主要目的是為了減少來(lái)回通信次數(shù),也就節(jié)省了來(lái)回的通信時(shí)間。

Redis 的底層通信協(xié)議對(duì)管道(pipelining)提供了支持。通過(guò)管道可以一次性發(fā)送多條命令并在執(zhí)行完后一次性將結(jié)果返回,當(dāng)一組命令中每條命令都不依賴于之前命令的執(zhí)行結(jié)果時(shí)就可以將這組命令一起通過(guò)管道發(fā)出。管道通過(guò)減少客戶端與 Redis 的通信次數(shù)來(lái)實(shí)現(xiàn)降低往返時(shí)延累計(jì)值的目的

6.排序

ALPHA參數(shù)

LIMIT參數(shù)

DESC/ASC參數(shù)

by參數(shù)

get參數(shù)

下面是sort在各種數(shù)據(jù)結(jié)構(gòu)的使用實(shí)例

$array_tag_ruby_posts = array(

'2', '11', '6', '12'

// , '26', '28'

);

$redis->del('tag:ruby:posts');

$redis->lpush('tag:ruby:posts', $array_tag_ruby_posts);

echo '----------sort1--------';

echo '
';

print_r($redis->lrange('tag:ruby:posts', 0, -1));

$option1_sort = array(

//? ? 'by' => 'weight_*',

//? ? 'get' => array('value_*', '#'),

'sort' => 'desc',

//? ? 'alpha' => true,

'limit' => array(1, 3),

'store' => 'result');

$redis->sort('tag:ruby:posts', $option1_sort);

echo '
';

//print_r($redis->type('result'));

print_r($redis->lrange('result', 0, -1));

echo '
----------sort2--------
';

$array_sortbylist = array(2, 1, 3);

$redis->del('sortbylist');

$redis->lpush('sortbylist', $array_sortbylist);

print_r($redis->lrange('sortbylist', 0, -1));

echo '
';

$redis->set('itemscore:1', 50);

$redis->set('itemscore:2', 100);

$redis->set('itemscore:3', -10);

$option2_sort = array(

'by' => 'itemscore:*',

//? ? 'get' => array('value_*', '#'),

'sort' => 'desc',

//? ? 'alpha' => true,

//? ? 'limit' => array(1, 3),

'store' => 'result2'

);

$redis->sort('sortbylist', $option2_sort);

print_r($redis->lrange('result2', 0, -1));

echo '
----------sort3--------
';

$redis->del(array('post:2', 'post:6', 'post:11', 'post:12', 'post:26', 'post:28'));

$post2 = array(

'title' => 'Windows 8 app designs',

'time' => '1352620100'

);

$post6 = array(

'title' => 'RethinkDB - An open-source distributed database built with love',

'time' => '1352620000'

);

$post11 = array(

'title' => 'The Nature of Ruby',

'time' => '1352619200'

);

$post12 = array(

'title' => 'Uses for cURL',

'time' => '1352619600'

);

$redis->hmset('post:2',$post2);

$redis->hmset('post:6',$post6);

$redis->hmset('post:11',$post11);

$redis->hmset('post:12',$post12);

$option3_sort = array(

'by' => 'post:*->time',

'get' => array('post:*->title','post:*->time', '#'),

'sort' => 'desc',

//? ? 'alpha' => true,

//? ? 'limit' => array(1, 3),

'store' => 'result3'

);

$redis->sort('tag:ruby:posts',$option3_sort);

print_r($redis->lrange('result3',0,-1));

7.節(jié)省空間

a.命名簡(jiǎn)化

b.內(nèi)部編碼優(yōu)化

本書(shū)里面沒(méi)有的內(nèi)容

1.Redis HyperLogLog起始版本:2.8.9

Redis HyperLogLog是用來(lái)做基數(shù)統(tǒng)計(jì)的算法。優(yōu)點(diǎn)是,在輸入元素的數(shù)量或者體積非常非常大時(shí),計(jì)算基數(shù)所需的空間總是固定的、并且是很小的。

在 Redis 里面,每個(gè) HyperLogLog 鍵只需要花費(fèi) 12 KB 內(nèi)存,就可以計(jì)算接近 2^64 個(gè)不同元素的基 數(shù)。這和計(jì)算基數(shù)時(shí),元素越多耗費(fèi)內(nèi)存就越多的集合形成鮮明對(duì)比。

注:因?yàn)镠yperLogLog只會(huì)根據(jù)輸入元素來(lái)計(jì)算基數(shù),而不會(huì)存儲(chǔ)輸入元素本身,因此不會(huì)返回輸入的各個(gè)元素。

基數(shù)是什么? 對(duì)于["abc", "abc", "2", "3"],基數(shù)是["abc", "2", "3"],個(gè)數(shù)是3.

HyperLogLog通過(guò)下面三個(gè)命令:

pfadd key ele [ele2 ...]:添加指定元素到HyperLogLog中,

pfcount key: 返回給定HyperLogLog的基數(shù)估算值

pfmerge destkey srckey [srckey2....]:講多個(gè)HyperLogLog合并到一個(gè)第一個(gè)HyperLogLog中

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Redis 數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)介 Redis 可以存儲(chǔ)鍵與5種不同數(shù)據(jù)結(jié)構(gòu)類型之間的映射,這5種數(shù)據(jù)結(jié)構(gòu)類型分別為Stri...
    DreamerRzc閱讀 237,462評(píng)論 26 273
  • PHP-redis中文文檔 phpredis是php的一個(gè)擴(kuò)展,效率是相當(dāng)高有鏈表排序功能,對(duì)創(chuàng)建內(nèi)存級(jí)的模塊業(yè)務(wù)...
    神秘者007閱讀 2,812評(píng)論 0 2
  • phpredis是php的一個(gè)擴(kuò)展,效率是相當(dāng)高有鏈表排序功能,對(duì)創(chuàng)建內(nèi)存級(jí)的模塊業(yè)務(wù)關(guān)系 很有用;以下是redi...
    神秘者007閱讀 1,581評(píng)論 0 1
  • 轉(zhuǎn)自:http://bbs.redis.cn/forum.php?mod=viewthread&tid=481 p...
    木十2036閱讀 1,173評(píng)論 0 7
  • phpredis是php的一個(gè)擴(kuò)展Redis::__construct構(gòu)造函數(shù)$redis = new Redis...
    hello大象閱讀 803評(píng)論 0 2

友情鏈接更多精彩內(nèi)容