admin管理员组

文章数量:1026989

Redis的数据类型

string

字符串类型可以是字符类型、数值类型、bitmaps

可以通过help @string 查看string相关命令

set

set  key value [expiration EX seconds|PX milliseconds] [NX|XX]

设置值命令

  • EX seconds:为键设置秒级过期时间
  • PX milliseconds:为键设置毫秒级过期时间
  • NX:键必须不存在,才可以设置成功,用于添加、分布式锁
  • XX:与NX相反,键必须存在,才可以设置成功,用于更新

例:

set name hello EX 10 NX
set name hello1 EX 100 XX

setex

setex key seconds value

将值value关联到key,并将key的生存时间设为seconds(秒级),如果key已经存在,setex命令将覆写旧值

setex name 100 hello1

setnx

setnx key value

将 key 的值设为 value ,当且仅当 key 不存在。若给定的 key 已经存在,则 SETNX 不做任何动作。SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。

127.0.0.1:6379[1]> set name hello
OK
127.0.0.1:6379[1]> setnx name hello1
(integer) 0
127.0.0.1:6379[1]> get name
"hello"

setnx可以作为分布式锁的一种实现方案,如果多个客户端同时执行setnx key value,根据setnx的特性,只有一个客户端能设置成功

get

GET key

获取值,如果值不存在,则返回nil(空)

127.0.0.1:6379[1]> get name
"hello"
127.0.0.1:6379[1]> get name1
(nil)

del

DEL key [key ...]

删除键

127.0.0.1:6379[1]> del name
(integer) 1
127.0.0.1:6379[1]> get name
(nil)

mset

MSET key value [key value ...]

批量设置值

127.0.0.1:6379[1]> mset k1 v1 k2 v2 k3 v3
OK

mget

MGET key [key ...]

批量获取值,如果有些键不存在,那么它的值为nil(空)

127.0.0.1:6379[1]> mget k1 k2 k3 k4
1) "v1"
2) "v2"
3) "v3"
4) (nil)

mget命令时间: n次get时间=1次网络时间+n次命令时间
非mget命令时间:n次get时间=n次网络时间+n次命令时间

批量操作有助于提高业务处理效率,可以节省网络时间开销,但也不是每次批量操作所发送的命令数越大越好,如果数量过多可能会造成Redis阻塞或网络拥塞。

incr、incrby、decrby、incrbyfloat

INCR key

用于对值类型做自增操作

  • 值不是整数,返回错误
  • 值是整数,返回自增后的结果
  • 键不存在,按照值为0自增,返回结果为1
127.0.0.1:6379[1]> incr name
(error) ERR value is not an integer or out of range
127.0.0.1:6379[1]> set num 10
OK
127.0.0.1:6379[1]> incr num
(integer) 11
127.0.0.1:6379[1]> incr num1
(integer) 1
127.0.0.1:6379[1]> get num1
"1"
127.0.0.1:6379[1]> get num
"11"

decr(自减)、incrby(自增指定数字)、decrby(自减指定数字)、incrbyfloat(自增浮点数)

append

APPEND key value

追加值,向字符串尾部追加值

127.0.0.1:6379[1]> set name hello
OK
127.0.0.1:6379[1]> append name world
(integer) 10
127.0.0.1:6379[1]> get name
"helloworld"

strlen

STRLEN key

字符串长度,如果是utf-8编码每个中文占3个字节,如果是gbk每个中文占2个字节

127.0.0.1:6379[1]> strlen name
(integer) 10
127.0.0.1:6379[1]> set name 中国
OK
127.0.0.1:6379[1]> strlen name
(integer) 6

getset

GETSET key value

设置新值并返回原值

127.0.0.1:6379[1]> set name hello
OK
127.0.0.1:6379[1]> getset name hello1
"hello"

setrange

SETRANGE key offset value

设置指定位置的字符

127.0.0.1:6379[1]> set name hello
OK
127.0.0.1:6379[1]> setrange name 1 a
(integer) 5
127.0.0.1:6379[1]> get name
"hallo"

getrange

GETRANGE key start end

start和end分别代表是开始和结束的偏移量,偏移量从0开始,-1表示最后,可以使用正反向索引两种方式

127.0.0.1:6379[1]> set name hello
OK
127.0.0.1:6379[1]> getrange name 3 4
"lo"
127.0.0.1:6379[1]> getrange name 3 -1
"lo"
127.0.0.1:6379[1]> getrange name -2 -1
"lo"

msetnx

MSETNX key value [key value ...]

用于所有给定 key 都不存在时,同时设置一个或多个 key-value 对。

当所有 key 都成功设置,返回 1 。 如果所有给定 key 都设置失败(至少有一个 key 已经存在),那么返回 0 。

127.0.0.1:6379[1]> set k11 v11
OK
127.0.0.1:6379[1]> msetnx k11 v111 k12 v122 k13 v133
(integer) 0
127.0.0.1:6379[1]> mget k11 k12 k13
1) "v11"
2) (nil)
3) (nil)
127.0.0.1:6379[1]> msetnx k12 v122 k13 v133 k14 v144
(integer) 1
127.0.0.1:6379[1]> mget k12 k13 k14
1) "v122"
2) "v133"
3) "v144"

内部编码

object encoding key

字符串类型的内部编码有三种

  • int:8个字节的长整型
  • embstr:小于等于39个字节的字符串
  • raw:大于39个字节的字符串
127.0.0.1:6379[1]> set a 10
OK
127.0.0.1:6379[1]> object encoding a
"int"
127.0.0.1:6379[1]> set b helloworld
OK
127.0.0.1:6379[1]> object encoding b
"embstr"
127.0.0.1:6379[1]> set c LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
OK
127.0.0.1:6379[1]> object encoding c
"raw"

应用

抢购,秒杀,详情页,点赞,评论

规避并发下,对数据库的事务操作完全由redis内存操作代替

共享Session

限速

hash

哈希类型是指键值本身又是一个键值对结构

可以通过help @hash 查看hash相关命令

hset

HSET key field value
summary: Set the string value of a hash field
since: 2.0.0

设置值,如果设置成功会返回1,反之会返回0

127.0.0.1:6379[1]> hset k1 name tom
(integer) 1

hsetnx

HSETNX key field value
summary: Set the value of a hash field, only if the field does not exist
since: 2.0.0

hsetnx命令,当filed值不存在时,可以设置value

127.0.0.1:6379[1]> hsetnx k1 name jerry
(integer) 0
127.0.0.1:6379[1]> hsetnx k1 age 12
(integer) 1

hmset

HMSET key field value [field value ...]
summary: Set multiple hash fields to multiple values
Since: 2.0.0

批量设置filed-value

127.0.0.1:6379[1]> hmset k2 name jack age 12
OK

hget

HGET key field
summary: Get the value of a hash field
since: 2.0.0

获取值,当键或field不存在,返回nil

127.0.0.1:6379[1]> hget k1 name
"tom"
127.0.0.1:6379[1]> hget k1 age
"12"
127.0.0.1:6379[1]> hget k1 birthday
(nil)

hmget

HMGET key field [field ...]
summary: Get the values of all the given hash fields
since: 2.0.0

批量获取filed-value

127.0.0.1:6379[1]> hmget k1 name age
1) "tom"
2) "12"

hdel

HDEL key field [field ...]
summary: Delete one or more hash fields
since: 2.0.0

删除一个或多个field,返回结果为成功删除的field的个数

127.0.0.1:6379[1]> hdel k2 name age
(integer) 2

hlen

HLEN key
summary: Get the number of fields in a hash
since: 2.0.0

计算filed的数量

127.0.0.1:6379[1]> hlen k1
(integer) 2

hexists

HEXISTS key field
summary: Determine if a hash field exists
since: 2.0.0

判断field是否存在

127.0.0.1:6379[1]> hexists k1 name
(integer) 1
127.0.0.1:6379[1]> hexists k1 birthday
(integer) 0
127.0.0.1:6379[1]> hexists k1 age
(integer) 1

hkeys

HKEYS key
summary: Get all the fields in a hash
since: 2.0.0

返回指定key的所有field

127.0.0.1:6379[1]> hkeys k1
1) "name"
2) "age"

hvals

HVALS key
summary: Get all the values in a hash
since: 2.0.0

获取指定key的所有的value

127.0.0.1:6379[1]> hvals k1
1) "tom"
2) "12"

hgetall

HGETALL key
summary: Get all the fields and values in a hash
since: 2.0.0

获取所有的field-value

127.0.0.1:6379[1]> hgetall k1
1) "name"
2) "tom"
3) "age"
4) "12"

hincrby

HINCRBY key field increment
summary: Increment the integer value of a hash field by the given number
since: 2.0.0

对值类型的field 进行自增、自减

127.0.0.1:6379[1]> hincrby k1 age 2
(integer) 14
127.0.0.1:6379[1]> hget k1 age
"14"

hincrbyfloat

HINCRBYFLOAT key field increment
summary: Increment the float value of a hash field by the given amount
since: 2.6.0

对值类型的field 进行浮点数增、减

127.0.0.1:6379[1]> hincrbyfloat k1 age 1.5
"15.5"
127.0.0.1:6379[1]> hget k1 age
"15.5"

hstrlen

HSTRLEN key field
summary: Get the length of the value of a hash field
since: 3.2.0

计算value的字符串长度

127.0.0.1:6379[1]> hstrlen k1 name
(integer) 3

hscan

HSCAN key cursor [MATCH pattern] [COUNT count]
summary: Incrementally iterate hash fields and associated values
since: 2.8.0

cursor - 游标,pattern - 匹配的模式,count - 指定从数据集里返回多少元素,默认值为 10 。

返回的每个元素都是一个元组,每一个元组元素由一个字段(field) 和值(value)组成。

127.0.0.1:6379[1]> hscan k1 0 match "na*" 
1) "0"
2) 1) "name"2) "tom"

内部编码

  • ziplist(压缩编码):当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64字节)时,redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比hsahtable更加优秀。

  • hashtable(哈希表):当哈希类型无法满足ziplist的条件时,redis会使用hashtable作为内部实现,因为此时ziplist的读写效率会下降,而hashtable的读写时间复杂度为O(1)。

当field个数比较少且没有大的value时

127.0.0.1:6379[1]> hset hashkey f1 v1 f1 v1
(integer) 1
127.0.0.1:6379[1]> object encoding hashkey
"ziplist"

当有value大于64字节

127.0.0.1:6379[1]> hset hashkey f3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
(integer) 1
127.0.0.1:6379[1]> object encoding hashkey
"hashtable"

当field个数大于512

127.0.0.1:6379> hmset hashkey f1 v1 f2 v2 ... 忽略 ... f513 v513
127.0.0.1:6379> object encoding hashkey
"hashtable"

应用

用来记录用户信息、点赞、收藏、详情页

list

列表list用来存储多个有序的字符串,如下图所示,a、b、c、d、e五个元素从左到右组成一个有序的列表,列表中的每个字符串称为元素,一个列表可以存储2^32-1个元素

list有两个特点

  • 列表中的元素是有序的,可以通过索引下标获取某个元素或者某个范围的元素列表
  • 列表中的元素是可以重复的

下面看一下list的相关命令 help @list

lpush

LPUSH key value [value ...]
summary: Prepend one or multiple values to a list
since: 1.0.0

从左边插入元素

127.0.0.1:6379[1]> lpush key1 a b c d
(integer) 4

从左边依次插入,最后插入的在最右边

lpushx

LPUSHX key value
summary: Prepend a value to a list, only if the list exists
since: 2.2.0

将一个值插入到已存在的列表头部,列表不存在时操作无效。

127.0.0.1:6379[1]> lpushx key1 aa
(integer) 5
127.0.0.1:6379[1]> lrange key1 0 -1
1) "aa"
2) "d"
3) "c"
4) "b"
5) "a"
127.0.0.1:6379[1]> lpushx key5 aa
(integer) 0
127.0.0.1:6379[1]> lrange key5 0 -1
(empty list or set)

rpush

RPUSH key value [value ...]
summary: Append one or multiple values to a list
since: 1.0.0

从右边插入元素

127.0.0.1:6379[1]> rpush key2 a b c d
(integer) 4

从右边依次插入,最后插入的在最左边

rpushx

RPUSHX key value
summary: Append a value to a list, only if the list exists
since: 2.2.0

将一个值插入到已存在的列表尾部(最右边)。如果列表不存在,操作无效

127.0.0.1:6379[1]> rpushx key2 aa
(integer) 5
127.0.0.1:6379[1]> lrange key2 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "aa"

lrange

LRANGE key start stop
summary: Get a range of elements from a list
since: 1.0.0

获取指定范围内的元素

  • 索引下标从左到右分别是0到N-1,从右到左分别是-1到-N。
  • lrange中的end选项包含了自身
127.0.0.1:6379[1]> lrange key1 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379[1]> lrange key2 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379[1]> lrange key1 2 3
1) "b"
2) "a"

lindex

LINDEX key index
summary: Get an element from a list by its index
since: 1.0.0

获取列表指定索引下标的值

127.0.0.1:6379[1]> lindex key1 1
"c"
127.0.0.1:6379[1]> lindex key1 100
(nil)

llen

LLEN key
summary: Get the length of a list
since: 1.0.0

获取列表长度

127.0.0.1:6379[1]> llen key1
(integer) 4

linsert

LINSERT key BEFORE|AFTER pivot value
summary: Insert an element before or after another element in a list
since: 2.2.0

从列表中找到等于pivot的元素,在其前或后插入一个新的元素value

127.0.0.1:6379[1]> lrange key2 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379[1]> 
127.0.0.1:6379[1]> linsert key2 before c e
(integer) 5
127.0.0.1:6379[1]> lrange key2 0 -1
1) "a"
2) "b"
3) "e"
4) "c"
5) "d"

lpop

LPOP key
summary: Remove and get the first element in a list
since: 1.0.0

从列表左侧弹出元素,最左侧的元素d被弹出

127.0.0.1:6379[1]> lrange key1 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379[1]> lpop key1
"d"
127.0.0.1:6379[1]> lrange key1 0 -1
1) "c"
2) "b"
3) "a"

rpop

RPOP key
summary: Remove and get the last element in a list
since: 1.0.0

从列表右侧弹出元素,最右侧的元素a被弹出

127.0.0.1:6379[1]> lrange key1 0 -1
1) "c"
2) "b"
3) "a"
127.0.0.1:6379[1]> rpop key1
"a"
127.0.0.1:6379[1]> lrange key1 0 -1
1) "c"
2) "b"

lrem

LREM key count value
summary: Remove elements from a list
since: 1.0.0

lrem命令从列表中找到等于value的元素进行删除,根据count的不同分为三种情况

  • count > 0,从左到右,删除最多count个元素
  • count < 0,从右到左,删除最多count绝对值个元素
  • count = 0,删除所有
127.0.0.1:6379[1]> clear
127.0.0.1:6379[1]> lpush key3 a b c d a a c d b a
(integer) 10
127.0.0.1:6379[1]> lrange key3 0 -11) "a"2) "b"3) "d"4) "c"5) "a"6) "a"7) "d"8) "c"9) "b"
10) "a"
127.0.0.1:6379[1]> lrem key3 2 a
(integer) 2
127.0.0.1:6379[1]> lrange key3 0 -1
1) "b"
2) "d"
3) "c"
4) "a"
5) "d"
6) "c"
7) "b"
8) "a"
127.0.0.1:6379[1]> lrem key3 -1 a
(integer) 1
127.0.0.1:6379[1]> lrange key3 0 -1
1) "b"
2) "d"
3) "c"
4) "a"
5) "d"
6) "c"
7) "b"

ltrim

LTRIM key start stop
summary: Trim a list to the specified range
since: 1.0.0

按照索引返回修剪列表,删除范围以外的元素

127.0.0.1:6379[1]> lpush key4 a b c d
(integer) 4
127.0.0.1:6379[1]> lrange key4 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379[1]> ltrim key4 1 2
OK
127.0.0.1:6379[1]> lrange key4 0 -1
1) "c"
2) "b"

lset

LSET key index value
summary: Set the value of an element in a list by its index
since: 1.0.0

修改指定索引下标的值

127.0.0.1:6379[1]> lrange key4 0 -1
1) "c"
2) "b"
127.0.0.1:6379[1]> lset key4 0 aa
OK
127.0.0.1:6379[1]> lrange key4 0 -1
1) "aa"
2) "b"

rpoplpush

RPOPLPUSH source destination
summary: Remove the last element in a list, prepend it to another list and return it
since: 1.2.0

移除列表的最后一个元素,并将该元素添加到另一个列表并返回

127.0.0.1:6379[1]> lpush k1 a b c d
(integer) 4
127.0.0.1:6379[1]> lpush k2 a b c d
(integer) 4
127.0.0.1:6379[1]> lrange k1 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379[1]> rpoplpush k1 k2
"a"
127.0.0.1:6379[1]> lrange k1 0 -1
1) "d"
2) "c"
3) "b"
127.0.0.1:6379[1]> lrange k2 0 -1
1) "a"
2) "d"
3) "c"
4) "b"
5) "a"

blpop brpop

BLPOP key [key ...] timeout
summary: Remove and get the first element in a list, or block until one is available
since: 2.0.0
BRPOP key [key ...] timeout
summary: Remove and get the last element in a list, or block until one is available
since: 2.0.0

blpop和brpop是lpop和rpop的阻塞版本

  1. 列表为空:如果timeout=3,那么客户端要等到三秒后返回,如果timeout=0,那么客户端一直阻塞等下去

    127.0.0.1:6379[1]> del k1
    (integer) 0
    127.0.0.1:6379[1]> blpop k1 3
    (nil)
    (3.00s)
    127.0.0.1:6379[1]> blpop k1 0
    #一直阻塞
    

    这时另起一个客户端端,为k1列表添加数据

    #添加数据
    127.0.0.1:6379[1]> lpush k1 aa
    (integer) 1
    
    #有数据后立即返回
    127.0.0.1:6379[1]> blpop k1 0
    1) "k1"
    2) "aa"
    (73.52s)
    
  2. 列表不为空,客户端会立即返回

    127.0.0.1:6379[1]> lpush k1 a b c d
    (integer) 4
    127.0.0.1:6379[1]> brpop k1 3
    1) "k1"
    2) "a"
    

    在使用brpop时,需要注意两点

    • 如果是多个键,那么brpop会从左至右遍历键,一旦有一个键能弹出元素,客户端就立即返回
    127.0.0.1:6379[1]> del k2 k3 
    (integer) 1
    127.0.0.1:6379[1]> brpop k2 k3 0
    #一直阻塞
    

    另起一个客户端,为k3、k2插入数据

    127.0.0.1:6379[1]> lpush k3 a b c d
    (integer) 4
    127.0.0.1:6379[1]> lpush k2 a b c d
    (integer) 4
    
    127.0.0.1:6379[1]> brpop k2 k3 0
    1) "k3"
    2) "a"
    (41.57s)
    #k3有数据,立即返回
    
    • 如果多个客户端对同一个键执行brpop,那么最先执行brpop命令的客户端可以获取弹出的值

    客户端1:

    127.0.0.1:6379[1]> brpop k2 0
    #.....一直阻塞..........
    

    客户端2:

    127.0.0.1:6379[1]> brpop k2 0
    #.....一直阻塞..........
    

    客户端3:

    127.0.0.1:6379[1]> brpop k2 0
    #.....一直阻塞..........
    

    客户端4:

    127.0.0.1:6379[1]> lpush k2 a
    (integer) 3
    

    只有客户端1最先获取元素,客户端2和客户端3会继续阻塞,直到有元素添加到键k2

    127.0.0.1:6379[1]> brpop k2 0
    1) "k2"
    2) "a"
    (140.33s)
    

内部编码

  • ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使用
  • linkedlist(链表):当列表无法满足ziplist的条件时,使用linkedlist作为列表的内部实现
  • quicklist:3.2版本新编码,废弃list-max-ziplist-entrieslist-max-ziplist-value,使用新配置,list-max-ziplist-size表示最大压缩空间或长度。最大空间使用[-5,-1]范围配置,默认-2表示8KB,list-compress-depth表示最大压缩深度,默认是0不压缩,1表示quicklist两端各有1个节点不压缩,中间的节点压缩。。
    • -5: 每个quicklist节点上的ziplist大小不能超过64 Kb。
    • -4: 每个quicklist节点上的ziplist大小不能超过32 Kb。
    • -3: 每个quicklist节点上的ziplist大小不能超过16 Kb。
    • -2: 每个quicklist节点上的ziplist大小不能超过8 Kb。(默认值)
    • -1: 每个quicklist节点上的ziplist大小不能超过4 Kb。
127.0.0.1:6379[1]> object encoding k1
"quicklist"

应用

lpush+lpop=Stack(栈)

lpush+rpop=Queue(队列)

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

lpush+brpop=Message Queue (消息队列),生产者客户使用lpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的抢列表尾部的元素,多个客户端保证消费的负载均衡和高可用性。

Redis的数据类型

string

字符串类型可以是字符类型、数值类型、bitmaps

可以通过help @string 查看string相关命令

set

set  key value [expiration EX seconds|PX milliseconds] [NX|XX]

设置值命令

  • EX seconds:为键设置秒级过期时间
  • PX milliseconds:为键设置毫秒级过期时间
  • NX:键必须不存在,才可以设置成功,用于添加、分布式锁
  • XX:与NX相反,键必须存在,才可以设置成功,用于更新

例:

set name hello EX 10 NX
set name hello1 EX 100 XX

setex

setex key seconds value

将值value关联到key,并将key的生存时间设为seconds(秒级),如果key已经存在,setex命令将覆写旧值

setex name 100 hello1

setnx

setnx key value

将 key 的值设为 value ,当且仅当 key 不存在。若给定的 key 已经存在,则 SETNX 不做任何动作。SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。

127.0.0.1:6379[1]> set name hello
OK
127.0.0.1:6379[1]> setnx name hello1
(integer) 0
127.0.0.1:6379[1]> get name
"hello"

setnx可以作为分布式锁的一种实现方案,如果多个客户端同时执行setnx key value,根据setnx的特性,只有一个客户端能设置成功

get

GET key

获取值,如果值不存在,则返回nil(空)

127.0.0.1:6379[1]> get name
"hello"
127.0.0.1:6379[1]> get name1
(nil)

del

DEL key [key ...]

删除键

127.0.0.1:6379[1]> del name
(integer) 1
127.0.0.1:6379[1]> get name
(nil)

mset

MSET key value [key value ...]

批量设置值

127.0.0.1:6379[1]> mset k1 v1 k2 v2 k3 v3
OK

mget

MGET key [key ...]

批量获取值,如果有些键不存在,那么它的值为nil(空)

127.0.0.1:6379[1]> mget k1 k2 k3 k4
1) "v1"
2) "v2"
3) "v3"
4) (nil)

mget命令时间: n次get时间=1次网络时间+n次命令时间
非mget命令时间:n次get时间=n次网络时间+n次命令时间

批量操作有助于提高业务处理效率,可以节省网络时间开销,但也不是每次批量操作所发送的命令数越大越好,如果数量过多可能会造成Redis阻塞或网络拥塞。

incr、incrby、decrby、incrbyfloat

INCR key

用于对值类型做自增操作

  • 值不是整数,返回错误
  • 值是整数,返回自增后的结果
  • 键不存在,按照值为0自增,返回结果为1
127.0.0.1:6379[1]> incr name
(error) ERR value is not an integer or out of range
127.0.0.1:6379[1]> set num 10
OK
127.0.0.1:6379[1]> incr num
(integer) 11
127.0.0.1:6379[1]> incr num1
(integer) 1
127.0.0.1:6379[1]> get num1
"1"
127.0.0.1:6379[1]> get num
"11"

decr(自减)、incrby(自增指定数字)、decrby(自减指定数字)、incrbyfloat(自增浮点数)

append

APPEND key value

追加值,向字符串尾部追加值

127.0.0.1:6379[1]> set name hello
OK
127.0.0.1:6379[1]> append name world
(integer) 10
127.0.0.1:6379[1]> get name
"helloworld"

strlen

STRLEN key

字符串长度,如果是utf-8编码每个中文占3个字节,如果是gbk每个中文占2个字节

127.0.0.1:6379[1]> strlen name
(integer) 10
127.0.0.1:6379[1]> set name 中国
OK
127.0.0.1:6379[1]> strlen name
(integer) 6

getset

GETSET key value

设置新值并返回原值

127.0.0.1:6379[1]> set name hello
OK
127.0.0.1:6379[1]> getset name hello1
"hello"

setrange

SETRANGE key offset value

设置指定位置的字符

127.0.0.1:6379[1]> set name hello
OK
127.0.0.1:6379[1]> setrange name 1 a
(integer) 5
127.0.0.1:6379[1]> get name
"hallo"

getrange

GETRANGE key start end

start和end分别代表是开始和结束的偏移量,偏移量从0开始,-1表示最后,可以使用正反向索引两种方式

127.0.0.1:6379[1]> set name hello
OK
127.0.0.1:6379[1]> getrange name 3 4
"lo"
127.0.0.1:6379[1]> getrange name 3 -1
"lo"
127.0.0.1:6379[1]> getrange name -2 -1
"lo"

msetnx

MSETNX key value [key value ...]

用于所有给定 key 都不存在时,同时设置一个或多个 key-value 对。

当所有 key 都成功设置,返回 1 。 如果所有给定 key 都设置失败(至少有一个 key 已经存在),那么返回 0 。

127.0.0.1:6379[1]> set k11 v11
OK
127.0.0.1:6379[1]> msetnx k11 v111 k12 v122 k13 v133
(integer) 0
127.0.0.1:6379[1]> mget k11 k12 k13
1) "v11"
2) (nil)
3) (nil)
127.0.0.1:6379[1]> msetnx k12 v122 k13 v133 k14 v144
(integer) 1
127.0.0.1:6379[1]> mget k12 k13 k14
1) "v122"
2) "v133"
3) "v144"

内部编码

object encoding key

字符串类型的内部编码有三种

  • int:8个字节的长整型
  • embstr:小于等于39个字节的字符串
  • raw:大于39个字节的字符串
127.0.0.1:6379[1]> set a 10
OK
127.0.0.1:6379[1]> object encoding a
"int"
127.0.0.1:6379[1]> set b helloworld
OK
127.0.0.1:6379[1]> object encoding b
"embstr"
127.0.0.1:6379[1]> set c LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
OK
127.0.0.1:6379[1]> object encoding c
"raw"

应用

抢购,秒杀,详情页,点赞,评论

规避并发下,对数据库的事务操作完全由redis内存操作代替

共享Session

限速

hash

哈希类型是指键值本身又是一个键值对结构

可以通过help @hash 查看hash相关命令

hset

HSET key field value
summary: Set the string value of a hash field
since: 2.0.0

设置值,如果设置成功会返回1,反之会返回0

127.0.0.1:6379[1]> hset k1 name tom
(integer) 1

hsetnx

HSETNX key field value
summary: Set the value of a hash field, only if the field does not exist
since: 2.0.0

hsetnx命令,当filed值不存在时,可以设置value

127.0.0.1:6379[1]> hsetnx k1 name jerry
(integer) 0
127.0.0.1:6379[1]> hsetnx k1 age 12
(integer) 1

hmset

HMSET key field value [field value ...]
summary: Set multiple hash fields to multiple values
Since: 2.0.0

批量设置filed-value

127.0.0.1:6379[1]> hmset k2 name jack age 12
OK

hget

HGET key field
summary: Get the value of a hash field
since: 2.0.0

获取值,当键或field不存在,返回nil

127.0.0.1:6379[1]> hget k1 name
"tom"
127.0.0.1:6379[1]> hget k1 age
"12"
127.0.0.1:6379[1]> hget k1 birthday
(nil)

hmget

HMGET key field [field ...]
summary: Get the values of all the given hash fields
since: 2.0.0

批量获取filed-value

127.0.0.1:6379[1]> hmget k1 name age
1) "tom"
2) "12"

hdel

HDEL key field [field ...]
summary: Delete one or more hash fields
since: 2.0.0

删除一个或多个field,返回结果为成功删除的field的个数

127.0.0.1:6379[1]> hdel k2 name age
(integer) 2

hlen

HLEN key
summary: Get the number of fields in a hash
since: 2.0.0

计算filed的数量

127.0.0.1:6379[1]> hlen k1
(integer) 2

hexists

HEXISTS key field
summary: Determine if a hash field exists
since: 2.0.0

判断field是否存在

127.0.0.1:6379[1]> hexists k1 name
(integer) 1
127.0.0.1:6379[1]> hexists k1 birthday
(integer) 0
127.0.0.1:6379[1]> hexists k1 age
(integer) 1

hkeys

HKEYS key
summary: Get all the fields in a hash
since: 2.0.0

返回指定key的所有field

127.0.0.1:6379[1]> hkeys k1
1) "name"
2) "age"

hvals

HVALS key
summary: Get all the values in a hash
since: 2.0.0

获取指定key的所有的value

127.0.0.1:6379[1]> hvals k1
1) "tom"
2) "12"

hgetall

HGETALL key
summary: Get all the fields and values in a hash
since: 2.0.0

获取所有的field-value

127.0.0.1:6379[1]> hgetall k1
1) "name"
2) "tom"
3) "age"
4) "12"

hincrby

HINCRBY key field increment
summary: Increment the integer value of a hash field by the given number
since: 2.0.0

对值类型的field 进行自增、自减

127.0.0.1:6379[1]> hincrby k1 age 2
(integer) 14
127.0.0.1:6379[1]> hget k1 age
"14"

hincrbyfloat

HINCRBYFLOAT key field increment
summary: Increment the float value of a hash field by the given amount
since: 2.6.0

对值类型的field 进行浮点数增、减

127.0.0.1:6379[1]> hincrbyfloat k1 age 1.5
"15.5"
127.0.0.1:6379[1]> hget k1 age
"15.5"

hstrlen

HSTRLEN key field
summary: Get the length of the value of a hash field
since: 3.2.0

计算value的字符串长度

127.0.0.1:6379[1]> hstrlen k1 name
(integer) 3

hscan

HSCAN key cursor [MATCH pattern] [COUNT count]
summary: Incrementally iterate hash fields and associated values
since: 2.8.0

cursor - 游标,pattern - 匹配的模式,count - 指定从数据集里返回多少元素,默认值为 10 。

返回的每个元素都是一个元组,每一个元组元素由一个字段(field) 和值(value)组成。

127.0.0.1:6379[1]> hscan k1 0 match "na*" 
1) "0"
2) 1) "name"2) "tom"

内部编码

  • ziplist(压缩编码):当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64字节)时,redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比hsahtable更加优秀。

  • hashtable(哈希表):当哈希类型无法满足ziplist的条件时,redis会使用hashtable作为内部实现,因为此时ziplist的读写效率会下降,而hashtable的读写时间复杂度为O(1)。

当field个数比较少且没有大的value时

127.0.0.1:6379[1]> hset hashkey f1 v1 f1 v1
(integer) 1
127.0.0.1:6379[1]> object encoding hashkey
"ziplist"

当有value大于64字节

127.0.0.1:6379[1]> hset hashkey f3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
(integer) 1
127.0.0.1:6379[1]> object encoding hashkey
"hashtable"

当field个数大于512

127.0.0.1:6379> hmset hashkey f1 v1 f2 v2 ... 忽略 ... f513 v513
127.0.0.1:6379> object encoding hashkey
"hashtable"

应用

用来记录用户信息、点赞、收藏、详情页

list

列表list用来存储多个有序的字符串,如下图所示,a、b、c、d、e五个元素从左到右组成一个有序的列表,列表中的每个字符串称为元素,一个列表可以存储2^32-1个元素

list有两个特点

  • 列表中的元素是有序的,可以通过索引下标获取某个元素或者某个范围的元素列表
  • 列表中的元素是可以重复的

下面看一下list的相关命令 help @list

lpush

LPUSH key value [value ...]
summary: Prepend one or multiple values to a list
since: 1.0.0

从左边插入元素

127.0.0.1:6379[1]> lpush key1 a b c d
(integer) 4

从左边依次插入,最后插入的在最右边

lpushx

LPUSHX key value
summary: Prepend a value to a list, only if the list exists
since: 2.2.0

将一个值插入到已存在的列表头部,列表不存在时操作无效。

127.0.0.1:6379[1]> lpushx key1 aa
(integer) 5
127.0.0.1:6379[1]> lrange key1 0 -1
1) "aa"
2) "d"
3) "c"
4) "b"
5) "a"
127.0.0.1:6379[1]> lpushx key5 aa
(integer) 0
127.0.0.1:6379[1]> lrange key5 0 -1
(empty list or set)

rpush

RPUSH key value [value ...]
summary: Append one or multiple values to a list
since: 1.0.0

从右边插入元素

127.0.0.1:6379[1]> rpush key2 a b c d
(integer) 4

从右边依次插入,最后插入的在最左边

rpushx

RPUSHX key value
summary: Append a value to a list, only if the list exists
since: 2.2.0

将一个值插入到已存在的列表尾部(最右边)。如果列表不存在,操作无效

127.0.0.1:6379[1]> rpushx key2 aa
(integer) 5
127.0.0.1:6379[1]> lrange key2 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "aa"

lrange

LRANGE key start stop
summary: Get a range of elements from a list
since: 1.0.0

获取指定范围内的元素

  • 索引下标从左到右分别是0到N-1,从右到左分别是-1到-N。
  • lrange中的end选项包含了自身
127.0.0.1:6379[1]> lrange key1 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379[1]> lrange key2 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379[1]> lrange key1 2 3
1) "b"
2) "a"

lindex

LINDEX key index
summary: Get an element from a list by its index
since: 1.0.0

获取列表指定索引下标的值

127.0.0.1:6379[1]> lindex key1 1
"c"
127.0.0.1:6379[1]> lindex key1 100
(nil)

llen

LLEN key
summary: Get the length of a list
since: 1.0.0

获取列表长度

127.0.0.1:6379[1]> llen key1
(integer) 4

linsert

LINSERT key BEFORE|AFTER pivot value
summary: Insert an element before or after another element in a list
since: 2.2.0

从列表中找到等于pivot的元素,在其前或后插入一个新的元素value

127.0.0.1:6379[1]> lrange key2 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379[1]> 
127.0.0.1:6379[1]> linsert key2 before c e
(integer) 5
127.0.0.1:6379[1]> lrange key2 0 -1
1) "a"
2) "b"
3) "e"
4) "c"
5) "d"

lpop

LPOP key
summary: Remove and get the first element in a list
since: 1.0.0

从列表左侧弹出元素,最左侧的元素d被弹出

127.0.0.1:6379[1]> lrange key1 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379[1]> lpop key1
"d"
127.0.0.1:6379[1]> lrange key1 0 -1
1) "c"
2) "b"
3) "a"

rpop

RPOP key
summary: Remove and get the last element in a list
since: 1.0.0

从列表右侧弹出元素,最右侧的元素a被弹出

127.0.0.1:6379[1]> lrange key1 0 -1
1) "c"
2) "b"
3) "a"
127.0.0.1:6379[1]> rpop key1
"a"
127.0.0.1:6379[1]> lrange key1 0 -1
1) "c"
2) "b"

lrem

LREM key count value
summary: Remove elements from a list
since: 1.0.0

lrem命令从列表中找到等于value的元素进行删除,根据count的不同分为三种情况

  • count > 0,从左到右,删除最多count个元素
  • count < 0,从右到左,删除最多count绝对值个元素
  • count = 0,删除所有
127.0.0.1:6379[1]> clear
127.0.0.1:6379[1]> lpush key3 a b c d a a c d b a
(integer) 10
127.0.0.1:6379[1]> lrange key3 0 -11) "a"2) "b"3) "d"4) "c"5) "a"6) "a"7) "d"8) "c"9) "b"
10) "a"
127.0.0.1:6379[1]> lrem key3 2 a
(integer) 2
127.0.0.1:6379[1]> lrange key3 0 -1
1) "b"
2) "d"
3) "c"
4) "a"
5) "d"
6) "c"
7) "b"
8) "a"
127.0.0.1:6379[1]> lrem key3 -1 a
(integer) 1
127.0.0.1:6379[1]> lrange key3 0 -1
1) "b"
2) "d"
3) "c"
4) "a"
5) "d"
6) "c"
7) "b"

ltrim

LTRIM key start stop
summary: Trim a list to the specified range
since: 1.0.0

按照索引返回修剪列表,删除范围以外的元素

127.0.0.1:6379[1]> lpush key4 a b c d
(integer) 4
127.0.0.1:6379[1]> lrange key4 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379[1]> ltrim key4 1 2
OK
127.0.0.1:6379[1]> lrange key4 0 -1
1) "c"
2) "b"

lset

LSET key index value
summary: Set the value of an element in a list by its index
since: 1.0.0

修改指定索引下标的值

127.0.0.1:6379[1]> lrange key4 0 -1
1) "c"
2) "b"
127.0.0.1:6379[1]> lset key4 0 aa
OK
127.0.0.1:6379[1]> lrange key4 0 -1
1) "aa"
2) "b"

rpoplpush

RPOPLPUSH source destination
summary: Remove the last element in a list, prepend it to another list and return it
since: 1.2.0

移除列表的最后一个元素,并将该元素添加到另一个列表并返回

127.0.0.1:6379[1]> lpush k1 a b c d
(integer) 4
127.0.0.1:6379[1]> lpush k2 a b c d
(integer) 4
127.0.0.1:6379[1]> lrange k1 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379[1]> rpoplpush k1 k2
"a"
127.0.0.1:6379[1]> lrange k1 0 -1
1) "d"
2) "c"
3) "b"
127.0.0.1:6379[1]> lrange k2 0 -1
1) "a"
2) "d"
3) "c"
4) "b"
5) "a"

blpop brpop

BLPOP key [key ...] timeout
summary: Remove and get the first element in a list, or block until one is available
since: 2.0.0
BRPOP key [key ...] timeout
summary: Remove and get the last element in a list, or block until one is available
since: 2.0.0

blpop和brpop是lpop和rpop的阻塞版本

  1. 列表为空:如果timeout=3,那么客户端要等到三秒后返回,如果timeout=0,那么客户端一直阻塞等下去

    127.0.0.1:6379[1]> del k1
    (integer) 0
    127.0.0.1:6379[1]> blpop k1 3
    (nil)
    (3.00s)
    127.0.0.1:6379[1]> blpop k1 0
    #一直阻塞
    

    这时另起一个客户端端,为k1列表添加数据

    #添加数据
    127.0.0.1:6379[1]> lpush k1 aa
    (integer) 1
    
    #有数据后立即返回
    127.0.0.1:6379[1]> blpop k1 0
    1) "k1"
    2) "aa"
    (73.52s)
    
  2. 列表不为空,客户端会立即返回

    127.0.0.1:6379[1]> lpush k1 a b c d
    (integer) 4
    127.0.0.1:6379[1]> brpop k1 3
    1) "k1"
    2) "a"
    

    在使用brpop时,需要注意两点

    • 如果是多个键,那么brpop会从左至右遍历键,一旦有一个键能弹出元素,客户端就立即返回
    127.0.0.1:6379[1]> del k2 k3 
    (integer) 1
    127.0.0.1:6379[1]> brpop k2 k3 0
    #一直阻塞
    

    另起一个客户端,为k3、k2插入数据

    127.0.0.1:6379[1]> lpush k3 a b c d
    (integer) 4
    127.0.0.1:6379[1]> lpush k2 a b c d
    (integer) 4
    
    127.0.0.1:6379[1]> brpop k2 k3 0
    1) "k3"
    2) "a"
    (41.57s)
    #k3有数据,立即返回
    
    • 如果多个客户端对同一个键执行brpop,那么最先执行brpop命令的客户端可以获取弹出的值

    客户端1:

    127.0.0.1:6379[1]> brpop k2 0
    #.....一直阻塞..........
    

    客户端2:

    127.0.0.1:6379[1]> brpop k2 0
    #.....一直阻塞..........
    

    客户端3:

    127.0.0.1:6379[1]> brpop k2 0
    #.....一直阻塞..........
    

    客户端4:

    127.0.0.1:6379[1]> lpush k2 a
    (integer) 3
    

    只有客户端1最先获取元素,客户端2和客户端3会继续阻塞,直到有元素添加到键k2

    127.0.0.1:6379[1]> brpop k2 0
    1) "k2"
    2) "a"
    (140.33s)
    

内部编码

  • ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使用
  • linkedlist(链表):当列表无法满足ziplist的条件时,使用linkedlist作为列表的内部实现
  • quicklist:3.2版本新编码,废弃list-max-ziplist-entrieslist-max-ziplist-value,使用新配置,list-max-ziplist-size表示最大压缩空间或长度。最大空间使用[-5,-1]范围配置,默认-2表示8KB,list-compress-depth表示最大压缩深度,默认是0不压缩,1表示quicklist两端各有1个节点不压缩,中间的节点压缩。。
    • -5: 每个quicklist节点上的ziplist大小不能超过64 Kb。
    • -4: 每个quicklist节点上的ziplist大小不能超过32 Kb。
    • -3: 每个quicklist节点上的ziplist大小不能超过16 Kb。
    • -2: 每个quicklist节点上的ziplist大小不能超过8 Kb。(默认值)
    • -1: 每个quicklist节点上的ziplist大小不能超过4 Kb。
127.0.0.1:6379[1]> object encoding k1
"quicklist"

应用

lpush+lpop=Stack(栈)

lpush+rpop=Queue(队列)

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

lpush+brpop=Message Queue (消息队列),生产者客户使用lpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的抢列表尾部的元素,多个客户端保证消费的负载均衡和高可用性。

本文标签: Redis的数据类型