Redis学习之5种数据类型操作、实现原理及应用场景

  • 格式:pdf
  • 大小:236.69 KB
  • 文档页数:7

Redis学习之5种数据类型操作、实现原理及应⽤场景

Redis可以存储可以存储键与5种不同数据结构类型之间的映射。五种数据类型为:STRING(字符串)、LIST(列表)、SET(集合)、HASH(散

列)、ZSET(有序集合)。

⼀、字符串类型String

1、类型定义

String 数据结构是简单的 key-value 类型,使⽤string时,redis(⼤多数情况下)并不会理解或者解析其含义,⽆论使⽤json、xml还是纯

⽂本在redis看来都是⼀样的,只是⼀个字符串,只能进⾏strlen、append等对字符串通⽤的操作,⽆法针对其内容进⼀步操作。

其基本操作命令有set、get、strlen、getrange、append:在⼤多数情况之外,就是string中存储的为纯数字的情况,redis可以将字符串

当做数字进⾏进⼀步操作,这些操作包括decr、decrby、incr、incrby和incrbyfloat。

1)赋值:SET key value。如set hello world

2)取值:GET key。如get hello。返回是world

3)⾃增:INCR key。就是Mysql的AUTO_INCREMENT。每次执⾏INCR key时,该key的值都会+1.若key不存在,则先建⽴⼀个0,然后+1,返回1。

如果值不是整数则报错。该操作是原⼦操作。 4)⾃减:DECR key。将指定key的值减少1.如DECR num,就是num-1

5)⾃增N:INCRBY key increment⽤来给指定key的值加increment。如INCRBY num 5就是num+5

6)⾃减N:DECRBY key increment⽤来给指定key的值减increment。如DECRBY num 5就是num-5

7)增加浮点数:INCRBYFLOAT key increment。

8)向尾部追加:APPEND key value。如set test:key 123 append test:key 456 get test:key就是123456

9)获取长度:STRLEN key。

10)同时给多个key 赋值:MSET title 这是标题 description 这是描述 content 这是内容。

11)同时获取多个key的值:MGET title description content

12)位操作之获取:GETBIT key offset。如字符a在redis中的存储为01100001(ASCII为98),那么GETBIT key 2就是1,GET key 0就是0。

13)位操作之设置:SETBIT key offset value。如字符a在redis中的存储为01100001(ASCII为98),那么SETBIT key 6 0,SETBIT key 5 1

那么get key得到的是b。因为取出的⼆进制为01100010。 14)位操作之统计:BITCOUNT key [start] [end]:BITCOUNT key⽤来获取key的值中⼆进制是1的个数。⽽BITCOUNT key start end则是⽤来

统计key的值中在第start和end之间的⼦字符串的⼆进制是1的个数(好绕啊)。 15)位操作之位运算:BITOP operation resultKey key1 key2。operation是位运算的操作,有AND,OR,XOR,NOT。resultKey是把运算结构

存储在这个key中,key1和key2是参与运算的key,参与运算的key可以指定多个。

2、应⽤场景

缓存功能:字符串最经典的使⽤场景,redis最为缓存层,Mysql作为储存层,绝⼤部分请求数据都是redis中获取,由于redis具有⽀撑

⾼并发特性,所以缓存通常能起到加速读写和降低 后端压⼒的作⽤。

计数器:许多运⽤都会使⽤redis作为计数的基础⼯具,他可以实现快速计数、查询缓存的功能,同时数据可以⼀步落地到其他的数据

源。如:视频播放数、粉丝数、微博数就是使⽤redis作为计数的基础组件。

共享session:出于负载均衡的考虑,分布式服务会将⽤户信息的访问均衡到不同服务器上,⽤户刷新⼀次访问可能会需要重新登录,

为避免这个问题可以⽤redis将⽤户session集中管理,在这种模式下只要保证redis的⾼可⽤和扩展性的,每次获取⽤户更新或查询登

录信息都直接从redis中集中获取。

限速:处于安全考虑,每次进⾏登录时让⽤户输⼊⼿机验证码,为了短信接⼝不被频繁访问,会限制⽤户每分钟获取验证码的频率。

3、实现原理

通过 int、SDS(simple dynamic string)作为结构存储

int⽤来存放整型数据,sds存放字节/字符串和浮点型数据

redis3.2分⽀引⼊了五种sdshdr类型,

⽬的是为了满⾜不同长度字符串可以使⽤不同⼤⼩的Header,从⽽节省内存

具体请可以参考:

⼆、列表类型List

1、类型定义

Redis对链表(Linked-list)结构的⽀持使得其在键值存储的世界独树⼀帜,⼀个列表结构可以有序地存储多个字符串。

使⽤list时,value就是⼀个string数组,操作这组string时,可以像对待栈⼀样使⽤pop和push操作,但是这个栈两端都能进⾏操作;也

可以像对待数组⼀样使⽤⼀个index参数来操作。list的操作命令略杂,主要分为两类:L开头的和R开头的,L代表LEFT或者LIST,进⾏⼀些

从列表左端进⾏的操作,或者⼀些与端⽆关的操作;R代表RIGHT,进⾏⼀些从列表右端进⾏的操作。

1)向头部插⼊:LPUSH key value1 value2...。返回增加后的列表长度。

2)向尾部插⼊:RPUSH key value1 value2...。返回增加后的列表长度。

3)从头部弹出:LPOP key。返回被弹出的元素值。该操作先删除key列表的第⼀个元素,再将它返回。

4)从尾部弹出:RPOP key。返回被弹出的元素值。

5)列表元素个数:LLEN key。key不存在返回0。

6)获取列表的⼦列表:LRANGE start end。返回第start个到第end个元素的列表。包含start和end。⽀持负数索引。-1表⽰最后⼀个元素,-2表⽰倒数

第⼆个元素。7)删除列表中指定值:LREM key count value。删除key这个列表中,所有值为value的元素,只删除count。如果有count+1个,那么就保留最后⼀个。

count不存在或者为0,则删除所有的。如果count⼤于0,则删除从头到尾的count个,如果count⼩于0,则删除从尾到头的count个。8)获取指定索引值:LINDEX key index。如LINDEX key 0就是列表的第⼀个元素。index可以是负数。

9)设置索引和值:LSET key index value。这个操作只是修改指定key且指定index的值。如果index不存在,则报错。

10)保留⽚段,删除其它:LTRIM key start end。保留start到end之间的所有元素,含start和end。其他全部删除。

11)向列表插⼊元素:LINSERT key BEFORE/AFTER value1 value2。从列表头开始遍历,发现值为value1时停⽌,将value2插⼊,根据BEFORE

或者AFTER插⼊到value1的前⾯还是后⾯。12)把⼀个列表的⼀个元素转到另⼀个列表:RPOPLPUSH list1 list2。将列表list1的右边元素删除,并把该与元素插⼊到列表list2的左边。原⼦操作。

2、应⽤场景

消息队列: redis的lpush+brpop命令组合即可实现阻塞队列,⽣产者客户端是⽤lupsh从列表左侧插⼊元素,多个消费者客户端使⽤

brpop命令阻塞时的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和⾼可⽤性。

⽂章列表:每个⽤户都有属于⾃⼰的⽂章列表,现在需要分页展⽰⽂章列表,此时可以考虑使⽤列表,列表不但有序同时⽀持按照索

引范围获取元素。

使⽤列表技巧:

lpush+lpop=Stack(栈)

lpush+rpop=Queue(队列)

lpush+ltrim=Capped Collection(有限集合)

lpush+brpop=Message Queue(消息队列)

3、实现原理

列表类型内部使⽤双向链表实现。

其内部数据结构为:

value对象内部以linkedlist或者ziplist来实现:

当list的元素个数和单个元素的长度⽐较⼩的时候,Redis会采⽤ziplist(压缩列表)来实现来减少内存占⽤。

否则就会采⽤linkedlist(双向链表)结构。

redis3.2之后,采⽤的⼀种叫quicklist的数据结构,实现ziplist和双向链表的⼆者结合,quicklist仍然是⼀个双向链表,只是列表的每个

节点都是⼀个ziplist。

三、集合Set

1、类型定义

Redis的集合Set和列表List都可以存储多个字符串,但是列表可以存储多个相同的字符串,⽽集合则通过使⽤散列表来保证⾃⼰存储的

每个字符串都是不相同的。Redis使⽤⽆序的⽅式存储元素。

集合类型是为了⽅便对多个集合进⾏操作和运算。集合中每个元素不同且没有顺序的概念,每个元素都是且只能是⼀个字符串。常⽤操

作是对集合插⼊、删除、判断等操作。时间复杂度尾O(1)。可以进⾏交集、并集、差集运算。集合类型在redis中的存储是⼀个值为空的散列

表(这些散列表只有键,但是没有与键相关的值)。

1)增加:SADD key value。

2)删除:SREM key value。

3)获取指定集合的所有元素:SMEMBERS key。

4)判断某个元素是否存在:SISMEMBER key value。

5)差集运算:SDIFF key1 key2...。对多个集合进⾏差集运算。

6)交集运算:SINNER key1 key2...。对多个集合进⾏交集运算。

7)并集运算:SUNION key1 key2...。对多个集合进⾏并集运算。

8)获取集合中元素个数:SCARD key。返回集合中元素的总个数。

9)对差集、交集、并集运算的结果存放在⼀个指定的key中:SDIFFSTORE storekey key1 key2。对key1和key2求差集,结果存放在key为storekey的

集合中。SINNERSTORE和SUNIONSTORE类似。10)获取集合中的随即元素:SRANDMEMBER key [count]。参数count可选,如果count不存在,则随即⼀个。count⼤于0,则是不重复的count个元素。

count⼩于0,则是⼀共|count|个元素,可以重复。11)随即弹出⼀个元素:SPOP key。随即从集合中弹出⼀个元素并删除,将该元素的值返回。