redis入门指南第二版读书笔记

redis入门指南第二版读书笔记

作者:李子骅

读者:张剑

Redis是以高性能著称的内存数据库,通常用来做缓存服务器。通常人们把它当作memcached的替代品。

同时围绕Redis也形成了很多产品工具链,Redis的命令也成了一种协议,有些模仿者使用同样的命令但是在某些方面有所侧重。

通过replication/persistentce和client-side sharding等特性,用户可以很方便地将Redis扩展成数百GB数据每秒处理上百次请求的系统。

Redis的5种数据结构

我们把Redis归类为内存NOSQL Key—Value数据库。

Redis可以存储key与五种不同类型的value。

Value的五种类型分别是String,List,Set,HashSet,Zset。

特别说明:

String    中存放的是一个元素,可改变或追加其内容(json对象可以压缩为二进制字符串保存)

List Set  中存放的是一组元素,List以双向链表方式存储元素,Set是无序不可重复的元素集合

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

Sorted Set 中存放的是一组元素,不同的是每个元素都会关联一个double类型的score

1.简单类型  String

get,set,del

2.链表类型  List  可重复 有序

lpush和rpush  加入到list的头和尾

lpop和rpop    从list的头和尾出栈

lindex        根据指定位置获取item

lrange        获取某个范围内的items

eg:

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

利用List可以有几种变化,比如可以当作堆栈先进后出,也可以当作队列先进先出

lpush和lpop结合使用就是堆栈

lpush和rpop结合使用就是队列

3.Set类型  Set    不可重复 无序

sadd          添加元素

smembers      返回所有元素

sismember      查看元素是否在set中

srem          如果存在,则删除该元素

说明:

以上3种类型存放的都是元素

4.Hash 类型  HashSet  存放 key-value 组

hset          在Hash表中存放key-value

hget          在Hash表中根据指定key获取value

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

hdel          如果存在,根据key删除value

eg:

可以一次性设置多个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          添加一个元素到zset中

zrange        从zset中获取排序之后的多个元素

zrangebyscore  获得按分数排序后的元素

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的核心内容

1.  5种数据类型的核心命令

String类型

存放3种类型的value

字节(数组)值

整数

浮点数

说明:

整数有自增和自减操作

incr/decr  整数自加1(自减1)

incrby/decrby key byNum  整数自增(自减)指定值byNum

incrbyfloat key amount    浮点数自增指定值amount

List类型  栈和队列类型,允许两头进行出栈和入栈

lpush和rpush  加入到list的头和尾

lpop和rpop    从list的头和尾出栈

lindex        根据指定位置获取item

lrange key start end      获取某个范围内的items

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

Set类型    存放无序不可重复的元素

sadd key item  添加元素

srem key item  删除元素

sismember key item  查看item是否在set中

scard key      返回set中元素数量

smembers      返回set中所有元素

srandmember  key [count]  从set中返回一个或count个随机元素

spop key      从set中删除并返回一个随机元素

smove  source-key dest-key  item  将item元素从source-key 移到dest-key

两个set类型的操作

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

sdiffstore

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

sinterstore

sunion key1 [key2...]  返回多个key中的并集

sunionstore

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

hmget hash key [key...]    从hash中根据多个key获取对应的value

hmset hash key value [key value ...]  在hash中设置多个key及其对应的value

hdel  hash key [key...]    从hash中根据key删除

hlen  hash key              返回hash中的map元素数量

hexists  hash key    对应的key是否存在hash中

hkeys  hash          获取hash中所有的key

hvals  hash          获取hash中所有的value

hgetall hash          获取hash中所有的key-value键值对

hincrby hash key      如果key中存储的value是int,则value+1

Sorted Set类型    zset  存放排序的元素

zadd key-name score member [score member ...] 增加一个元素,并给元素一个对应的score

zrem key-name member [member ...]  删除一个或多个元素

zcard key-name  返回zset中元素数量

zincrby key-name incrment member

zcount key-name min max 返回score在min与max之间的元素,保护member 与其 对应的 value

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

zscore key-name        返回zset中所有元素数量

zrange key-name start stop  返回score在min与max之间的元素

2.  事务

和一般的关系数据库类似,redis也支持事务。

但是redis的事务还是有所区别:

a.不能回滚,

b.即使其中一个命令有了运行错误(非语法错误),也不会影响到同一事务中其他命令的执行。

c.事务中的每个命令的执行结果都是最后一起返回的,所以无法将前一条命令的结果作为下一条命令的参数

结合WATCH命令

WATCH 命令可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行。监控一直持续到 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.过期时间

过期时间经常在访问频率控制和实现缓存中使用

EXPIRE session:29e3d 900

4.消息通知

利用消息通知,可以实现任务队列,优先级队列,发布/订阅模式

这里就用到了list的阻塞弹出命令,不过下面没有提到在消息通知和任务队列里面常用的弹出推入命令(RPOPLPUSH)。

a.任务队列

BRPOP命令和RPOP命令相似,唯一的区别是当列表中没有元素时BRPOP命令会一直阻塞住连接,直到有新元素加入。

示例代码:

loop

# 如果任务队列中没有新任务,BRPOP 命令会一直阻塞,不会执行 execute()。

$task = BRPOP queue, 0

# 返回值是一个数组(见下介绍),数组第二个元素是我们需要的任务。

execute($task[1])

b.优先级队列

BRPOP 命令可以同时接收多个键,其完整的命令格式为 BLPOP key [key …] timeout,如 BLPOP queue:1 queue:2 0。意义是同时检测多个键,如果所有键都没有元素则阻塞,如果其中有一个键有元素则会从该键中弹出元素。

示例代码:

loop

$task =BRPOP queue:confirmation.email,

queue:notification.email, 0

execute($task[1])

这时一旦发送确认邮件的任务被加入到 queue:confirmation.email 队列中,无论queue: notification.email还有多少任务,消费者都会优先完成发送确认邮件的任务。

c.发布/订阅模式

通过两个命令实现发布/订阅模式

PUBLISH

SUBSCRIBE

5.管道pipeline

管道和事务类似,不过管道的主要目的是为了减少来回通信次数,也就节省了来回的通信时间。

Redis 的底层通信协议对管道(pipelining)提供了支持。通过管道可以一次性发送多条命令并在执行完后一次性将结果返回,当一组命令中每条命令都不依赖于之前命令的执行结果时就可以将这组命令一起通过管道发出。管道通过减少客户端与 Redis 的通信次数来实现降低往返时延累计值的目的

6.排序

ALPHA参数

LIMIT参数

DESC/ASC参数

by参数

get参数

下面是sort在各种数据结构的使用实例

$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.节省空间

a.命名简化

b.内部编码优化

本书里面没有的内容

1.Redis HyperLogLog起始版本:2.8.9

Redis HyperLogLog是用来做基数统计的算法。优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

注:因为HyperLogLog只会根据输入元素来计算基数,而不会存储输入元素本身,因此不会返回输入的各个元素。

基数是什么? 对于["abc", "abc", "2", "3"],基数是["abc", "2", "3"],个数是3.

HyperLogLog通过下面三个命令:

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

pfcount key: 返回给定HyperLogLog的基数估算值

pfmerge destkey srckey [srckey2....]:讲多个HyperLogLog合并到一个第一个HyperLogLog中

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容