contents
如何确定redis是否已经启动
ps -ef | grep redis
lsof -i :6379
查看redis版本:
[root@web-master bin]# ./redis-server --version
install
步骤一:command:[root@localhost redis]# make
步骤二:command:[root@localhost redis]# make install
redis.conf
bind
修改ip绑定
#bind 127.0.0.1
说明:redis.conf配置文件默认没有注释此行,表示redis服务器只允许本机连接redis。
protected-mode
关闭保护模式
protected-mode no
说明:redis.conf配置文件默认此行为protected-mode yes,将yes修改为no。
daemonize
开启后台启动
daemonize yes
说明:redis.conf配置文件默认此行为ademonize no,将no修改为yes。
command
系统级命令
1、启动redis服务:[root@localhost redis]# redis-server redis.conf
2、检查redis服务项:[root@localhost redis]# ps -ef | grep redis
3、进入redis客户端:[root@localhost redis]# redis-cli -p 6379
说明:如果ip与端口是默认值,则可以将ip与端口省略。
4、关闭redis服务:
方法1:command:[root@localhost redis]# redis-cli -p 6379 shutdown
方法2:kill -9 pid号,例如:
command:[root@localhost redis]# kill -9 14515
查看Redis版本:redis-server -v
其他命令
- flushdb
清空当前库。 - flushall
清空全部库。 - dbsize
查看当前库key的数量。 - del (key)
删除key和该key的值。 demo:del username - type (key)
查看某个key的value的数据类型。 demo:type key1 - exists
判断key是否存在。 demo:exists username 说明:返回1表示存在,返回0表示不存在。 - keys
用于查询符合条件的key。 - keys * 查询redis中全部的key。
(2)keys usern?me 使用占位符获取value。
(3)keys usern* 获取以usern开头的value。 - select (0-15)
切换库。 demo:select 1 说明:共有16个库,编号分别为0-15,默认是0号库。 - rename (key) (key)
修改key的名称,第一个key为待修改的key的名称。 - move (key) (0-15)
将当前库中的key移动到另一个库中。
example:
116.62.212.39_9100_test:1>keys *
116.62.212.39_9100_test:1>set key1 value1
"OK"
116.62.212.39_9100_test:1>set key2 value2
"OK"
116.62.212.39_9100_test:1>keys *
1) "key1"
2) "key2"
116.62.212.39_9100_test:1>move key1 2
"1"
116.62.212.39_9100_test:1>keys *
1) "key2"
116.62.212.39_9100_test:1>select 2
"OK"
116.62.212.39_9100_test:2>keys *
1) "key1"
116.62.212.39_9100_test:2>get key1
"value1"
- incr (key) 加1。 demo:incr key
- decr (key) 自动减1。 demo:decr key
- incrby (key) 按指定数值添加。 demo:incrby key 10
- decrby (key) 按指定数值减。 demo:decrby key 10
- expire (key) 指定key的失效时间,单位s。 demo:expire key 20 说明:key在20s后被删除。
- pexpire (key) 指定key的失效时间,单位ms。 demo:pexpire key 2000 说明:key在2000ms后被删除。
- ttl (key) 查看key的剩余存活时间。 demo:ttl key 说明:返回-1表示该数据永不过期,返回-2表示已过期。
- persist (key) 撤销key的失效时间。 demo:persist key
设置key过期时间,默认-1表示永不过期,-2表示已过期。
Redis的过期时间设置有四种形式:
形式 | 说明 |
---|---|
expire | 设置指定的过期时间,以秒为单位,表示的是时间间隔。 |
pexpire | 设置指定的过期时间,以毫秒为单位,表示的是时间间隔。 |
expireat | 时间戳,设置指定的key过期的Unix时间,单位为秒,表示的是时间/时刻。 |
pexpireat | 时间戳,设置指定的key到期的Unix时间,以毫秒为单位,表示的是时间/时刻。 |
expire key seconds [NX|XX|GT|LT]
数据类型
string
- set (key) (value) 添加key和value。 demo:set username Jack
- get (key) 根据key获取value。 demo:get username
- mset (key) (value) [key value …] 赋值多个key和value。 demo:mset key1 value1 key2 value2 key3 value3
- mget (key) [key …] 获取多个key的value。 demo:mget key1 key2
- setnx (key) (value) 设置不存在的key对应的value。
example:
116.62.212.39_9100_test:1>get key1
"value1"
116.62.212.39_9100_test:1>setnx key1 value1a
"0"
116.62.212.39_9100_test:1>get key1
"value1"
116.62.212.39_9100_test:1>set key1 value1a
"OK"
116.62.212.39_9100_test:1>get key1
"value1a"
- getnx (key)
- msetnx (key) (value) [key value …] 设置多个不存在的key的key值和对应的value值。
example:
116.62.212.39_9100_test:1>keys *
116.62.212.39_9100_test:1>msetnx key1 value1 key2 value2
"1"
116.62.212.39_9100_test:1>msetnx key3 value3 key2 value2
"0"
116.62.212.39_9100_test:1>msetnx key3 value3 key4 value4
"1"
116.62.212.39_9100_test:1>keys *
1) "key3"
2) "key1"
3) "key4"
4) "key2"
- setex (key) (seconds) (value) 创建key和对应的value时设置失效时间,失效时间单位为秒。demo:setex key1 5 value1
- getset (key) (value) 设置新值同时返回旧值。
example:
116.62.212.39_9100_test:1>get key1
"value1"
116.62.212.39_9100_test:1>getset key1 aaa
"value1"
116.62.212.39_9100_test:1>get key1
"aaa"
- strlen (key) 根据key获取value的长度。 demo:strlen username
- append (key) (value) 对某个key的value进行追加。 demo:append key1 value
- setrange (key) (offset) (value) 用value覆写key所储存的字符串值,从指定索引开始(索引从0开始),offset代表覆盖的个数。
example:
116.62.212.39_9100_test:1>get key1
"value1value1abcd"
116.62.212.39_9100_test:1>setrange key1 3 one
"16"
116.62.212.39_9100_test:1>get key1
"valonevalue1abcd"
- getrange (key) (start) (end) 获取指定位置的字符串值。
example:
116.62.212.39_9100_test:1>set key1 value1
"OK"
116.62.212.39_9100_test:1>getrange key1 0 -1
"value1"
116.62.212.39_9100_test:1>getrange key1 2 4
"lue"
list
Redis中的List集合是双端循环列表,分别可以从左右两个方向插入数据。
List集合可以当做队列使用,也可以当做栈使用。
队列:存入数据的方向和获取数据的方向相反。
栈:存入数据的方向和获取数据的方向相同。
lpush
lpush (key) (value) [value …]
从队列的左边入队一个或多个元素。
将所有指定的值插入到存于key的列表的头部。如果key不存在,那么在进行push操作前会创建一个空列表。如果key对应的值不是一个list的话,那么会返回一个错误。
可以使用一个命令把多个元素push进入列表,只需在命令末尾加上多个指定的参数。元素是从最左端到最右端、一个接一个被插入到list的头部。所以对于这个命令例子lpush mylist a b c,返回的列表是c为第一个元素,b为第二个元素,a为第三个元素。
返回值:
integer-reply: 在push操作后的list长度。
example:
127.0.0.1:6379> lpush list1 "value1"
(integer) 1
127.0.0.1:6379> lpush list1 "value2"
(integer) 2
127.0.0.1:6379> lrange list1 0 -1
1) "value2"
2) "value1"
127.0.0.1:6379>
rpush
rpush (key) (value) [value …]
从队列的右边入队一个或多个元素。
向存于key的列表的尾部插入所有指定的值。如果key不存在,那么会创建一个空的列表然后再进行push操作。当key保存的不是一个列表,那么会返回一个错误。
可以使用一个命令把多个元素打入队列,只需要在命令后面指定多个参数。元素是从左到右一个接一个从列表尾部插入。 比如命令rpush mylist a b c,会返回一个列表,其第一个元素是a,第二个元素是b,第三个元素是c。
返回值:
integer-reply: 在push操作后的列表长度。
example:
127.0.0.1:6379> rpush list1 "value1"
(integer) 1
127.0.0.1:6379> rpush list1 "value2"
(integer) 2
127.0.0.1:6379> lrange list1 0 -1
1) "value1"
2) "value2"
127.0.0.1:6379>
lpushx
lpushx (key) (value) [value …]
当队列存在时从队列的左侧入队一个元素。
只有当key已经存在并且存着一个list的时候,在这个key下面的list的头部插入value。与lpush相反,当key不存在的时候不会进行任何操作。
返回值:
integer-reply: 在push操作后的list长度。
example:
127.0.0.1:6379> lpush list1 "value1"
(integer) 1
127.0.0.1:6379> lpushx list1 "value2"
(integer) 2
127.0.0.1:6379> lpushx list2 "value3"
(integer) 0
127.0.0.1:6379> lrange list1 0 -1
1) "value2"
2) "value1"
127.0.0.1:6379> lrange list2 0 -1
(empty list or set)
127.0.0.1:6379>
rpushx
rpushx (key) (value) [value …]
当队列存在时从队列的右侧入队一个元素。
将值value插入到列表key的表尾, 当且仅当key存在并且是一个列表。和rpush命令相反, 当key不存在时,rpushx命令什么也不做。
返回值:
integer-reply: rpushx命令执行之后,表的长度。
example:
127.0.0.1:6379> rpush list1 "value1"
(integer) 1
127.0.0.1:6379> rpushx list1 "value2"
(integer) 2
127.0.0.1:6379> rpushx list2 "value3"
(integer) 0
127.0.0.1:6379> lrange list1 0 -1
1) "value1"
2) "value2"
127.0.0.1:6379> lrange list2 0 -1
(empty list or set)
127.0.0.1:6379>
lpop
lpop (key)
从队列的左端出队一个元素。
移除并且返回key对应的list的第一个元素。
返回值:
bulk-string-reply: 返回第一个元素的值,或者当key不存在时返回nil。
example:
127.0.0.1:6379> rpush list1 "value1"
(integer) 1
127.0.0.1:6379> rpush list1 "value2"
(integer) 2
127.0.0.1:6379> rpush list1 "value3"
(integer) 3
127.0.0.1:6379> lpop list1
"value1"
127.0.0.1:6379> lrange list1 0 -1
1) "value2"
2) "value3"
127.0.0.1:6379>
rpop
rpop (key)
从队列的右端出队一个元素。
移除并返回存于key的list的最后一个元素。
返回值:
bulk-string-reply: 最后一个元素的值,或者当key不存在时返回nil。
example:
127.0.0.1:6379> rpush list1 "value1"
(integer) 1
127.0.0.1:6379> rpush list1 "value2"
(integer) 2
127.0.0.1:6379> rpush list1 "value3"
(integer) 3
127.0.0.1:6379> rpop list1
"value3"
127.0.0.1:6379> lrange list1 0 -1
1) "value1"
2) "value2"
127.0.0.1:6379>
lrange
lrange (key) (start) (stop)
从列表中获取指定返回的元素。
1、返回存储在key的列表里指定范围内的元素。start和end偏移量都是基于0的下标,即list的第一个元素下标是0(list的表头),第二个元素下标是1,以此类推。
2、偏移量也可以是负数,表示偏移量是从list尾部开始计数。例如,-1 表示列表的最后一个元素,-2是倒数第二个,以此类推。
3、在不同编程语言里,关于求范围函数的一致性。
需要注意的是,如果你有一个list,里面的元素是从0到100,那么lrange list 0 10这个命令会返回11个元素,即最右边的那个元素也会被包含在内。 在你所使用的编程语言里,这一点可能是也可能不是跟那些求范围有关的函数都是一致的。(像Ruby的Range.new,Array#slice或者Python的range()函数。)
4、超过范围的下标。
当下标超过list范围的时候不会产生error。 如果start比list的尾部下标大的时候,会返回一个空列表。如果stop比list的实际尾部大的时候,Redis会当它是最后一个元素的下标。
example:
127.0.0.1:6379> rpush list1 "value1"
(integer) 1
127.0.0.1:6379> rpush list1 "value2"
(integer) 2
127.0.0.1:6379> rpush list1 "value3"
(integer) 3
127.0.0.1:6379> lrange list1 0 0
1) "value1"
127.0.0.1:6379> lrange list1 -3 2
1) "value1"
2) "value2"
3) "value3"
127.0.0.1:6379> lrange list1 -100 100
1) "value1"
2) "value2"
3) "value3"
127.0.0.1:6379> lrange list1 5 10
(empty list or set)
127.0.0.1:6379>
lrem
lrem (key) (count) (value)
从存于key的列表里移除前count次出现的值为value的元素。这个count参数通过下面几种方式影响这个操作:
1、count>0: 从头往尾移除值为value的元素。
2、count<0: 从尾往头移除值为value的元素。
3、count=0: 移除所有值为value的元素。
比如,lrem list -2 “hello”会从存于list的列表里移除最后两个出现的 “hello”。
需要注意的是,如果list里没有存在key就会被当作空list处理,所以当key不存在的时候,这个命令会返回 0。
返回值:
integer-reply: 被移除的元素个数。
example:
127.0.0.1:6379> rpush list1 "value1"
(integer) 1
127.0.0.1:6379> rpush list1 "value1"
(integer) 2
127.0.0.1:6379> rpush list1 "value2"
(integer) 3
127.0.0.1:6379> rpush list1 "value1"
(integer) 4
127.0.0.1:6379> lrem list1 -2 "value1"
(integer) 2
127.0.0.1:6379> lrange list1 0 -1
1) "value1"
2) "value2"
127.0.0.1:6379>
lset
lset (key) (index) (value)
设置index位置的list元素的值为value。
当index超出范围时会返回一个error。
返回值:
simple-string-reply
example:
127.0.0.1:6379> rpush list1 "value1"
(integer) 1
127.0.0.1:6379> rpush list1 "value2"
(integer) 2
127.0.0.1:6379> rpush list1 "value3"
(integer) 3
127.0.0.1:6379> lset list1 0 "value4"
OK
127.0.0.1:6379> lset list1 -2 "value5"
OK
127.0.0.1:6379> lrange list1 0 -1
1) "value4"
2) "value5"
3) "value3"
127.0.0.1:6379>
lindex
lindex (key) (index)
返回列表里的元素的索引index存储在key里面。下标是从0开始索引的,所以0是表示第一个元素,1 表示第二个元素,并以此类推。
负数索引用于指定从列表尾部开始索引的元素。在这种方法下,-1表示最后一个元素,-2表示倒数第二个元素,并以此往前推。
当key位置的值不是一个列表的时候,会返回一个error。
返回值:
bulk-reply:请求的对应元素,或者当index超过范围的时候返回nil。
example
127.0.0.1:6379> lpush list1 "value1"
(integer) 1
127.0.0.1:6379> lpush list1 "value2"
(integer) 2
127.0.0.1:6379> lindex list1 0
"value2"
127.0.0.1:6379> lindex list1 -1
"value1"
127.0.0.1:6379> lindex list1 3
(nil)
127.0.0.1:6379>
llen
llen (key)
返回存储在key里的list的长度。如果key不存在,那么就被看作是空list,并且返回长度为0。当存储在key里的值不是一个list的话,会返回error。
返回值
integer-reply:key对应的list的长度。
example:
116.62.212.39_9100_test:1>keys *
116.62.212.39_9100_test:1>lpush key1 value11 value12 value13
"3"
116.62.212.39_9100_test:1>llen key1
"3"
116.62.212.39_9100_test:1>
ltrim
ltrim (key) (start) (end)
修剪(trim)一个已存在的list,这样list就会只包含指定范围的指定元素。start和stop都是由0开始计数的, 这里的0是列表里的第一个元素(表头),1是第二个元素,以此类推。
例如: ltrim foobar 0 2 将会对存储在foobar的列表进行修剪,只保留列表里的前3个元素。
start和end也可以用负数来表示与表尾的偏移量,比如-1表示列表里的最后一个元素,-2表示倒数第二个,等等。
超过范围的下标并不会产生错误:如果start超过列表尾部,或者start>end,结果会是列表变成空表(即该key会被移除)。如果end超过列表尾部,Redis会将其当作列表的最后一个元素。
ltrim的一个常见用法是和lpush/rpush一起使用。例如:
lpush mylist someelement
ltrim mylist 0 99
这一对命令会将一个新的元素push进列表里,并保证该列表不会增长到超过100个元素。这个是很有用的,比如当用Redis来存储日志。 需要特别注意的是,当用这种方式来使用ltrim的时候,操作的复杂度是O(1) ,因为平均情况下,每次只有一个元素会被移除。
返回值
simple-string-reply
example:
116.62.212.39_9100_test:1>rpush key1 one two three four
"4"
116.62.212.39_9100_test:1>ltrim key1 1 -1
"OK"
116.62.212.39_9100_test:1>lrange key1 0 -1
1) "two"
2) "three"
3) "four"
116.62.212.39_9100_test:1>
rpoplpush
rpoplpush (source) (destination)
原子性地返回并移除存储在source的列表的最后一个元素(列表尾部元素),并把该元素放入存储在destination的列表的第一个元素位置(列表头部)。
例如:假设source存储着列表 a,b,c。destination存储着列表 x,y,z。执行rpoplpush得到的结果是source保存着列表a,b,而destination保存着列表 c,x,y,z。
如果source不存在,那么会返回nil值,并且不会执行任何操作。如果source和destination是同样的,那么这个操作等同于移除列表最后一个元素并且把该元素放在列表头部, 所以这个命令也可以当作是一个旋转列表的命令。
返回值
bulk-string-reply: 被移除和放入的元素。
example:
116.62.212.39_9100_test:1>flushdb
"OK"
116.62.212.39_9100_test:1>rpush key1 one two three four
"4"
116.62.212.39_9100_test:1>lrange key1 0 -1
1) "one"
2) "two"
3) "three"
4) "four"
116.62.212.39_9100_test:1>rpoplpush key1 key2
"four"
116.62.212.39_9100_test:1>lrange key1 0 -1
1) "one"
2) "two"
3) "three"
116.62.212.39_9100_test:1>lrange key2 0 -1
1) "four"
116.62.212.39_9100_test:1>
linsert
linsert (key) (before|after) (pivot) (value)
把value插入存于key的列表中在基准值pivot的前面或后面。
当key不存在时,这个list会被看作是空list,任何操作都不会发生。
当key存在,但保存的不是一个list的时候,会返回error。
返回值
integer-reply: 经过插入操作后的list长度,或者当pivot值找不到的时候返回-1。
example:
116.62.212.39_9100_test:1>flushdb
"OK"
116.62.212.39_9100_test:1>keys *
116.62.212.39_9100_test:1>rpush key1 one two three four
"4"
116.62.212.39_9100_test:1>lrange key1 0 -1
1) "one"
2) "two"
3) "three"
4) "four"
116.62.212.39_9100_test:1>linsert key1 after two five
"5"
116.62.212.39_9100_test:1>lrange key1 0 -1
1) "one"
2) "two"
3) "five"
4) "three"
5) "four"
116.62.212.39_9100_test:1>linsert key1 before four six
"6"
116.62.212.39_9100_test:1>lrange key1 0 -1
1) "one"
2) "two"
3) "five"
4) "three"
5) "six"
6) "four"
116.62.212.39_9100_test:1>
set
sadd
sadd (key) (member [member …])
添加一个或多个指定的member元素到集合的key中。
1、指定的一个或者多个元素member如果已经在集合key中存在则忽略。
2、如果集合key不存在,则新建集合key,并添加member元素到集合key中。
3、如果key的类型不是集合则返回错误。
返回值:integer-reply:返回新成功添加到集合里元素的数量,不包括已经存在于集合中的元素。
example:
redis> sadd myset "Hello"
(integer) 1
redis> sadd myset "World"
(integer) 1
redis> sadd myset "World"
(integer) 0
redis> smembers myset
1) "World"
2) "Hello"
redis>
scard
scard (key)
返回集合存储的key的基数 (集合元素的数量)。
返回值:integer-reply: 集合的基数(元素的数量),如果key不存在,则返回0。
example:
redis> sadd myset "Hello"
(integer) 1
redis> sadd myset "World"
(integer) 1
redis> scard myset
(integer) 2
redis>
smembers
smembers (key)
返回key集合所有的元素。
该命令的作用与使用一个参数的sinter命令作用相同。
返回值:array-reply:集合中的所有元素。
example:
redis> sadd myset "Hello"
(integer) 1
redis> sadd myset "World"
(integer) 1
redis> smembers myset
1) "World"
2) "Hello"
redis>
sismember
sismember (key) (member)
返回成员member是否是存储的集合key的成员。
返回值:integer-reply,详细说明:
1、如果member元素是集合key的成员,则返回1。
2、如果member元素不是key的成员,或者集合key不存在,则返回0。
example:
redis> sadd myset "one"
(integer) 1
redis> sismember myset "one"
(integer) 1
redis> sismember myset "two"
(integer) 0
redis>
srem
srem (key) (member [member …])
在key集合中移除指定的元素。
1、如果指定的元素不是key集合中的元素则忽略
2、如果key集合不存在则被视为一个空的集合,该命令返回0。
3、如果key的类型不是一个集合,则返回错误。
返回值:
integer-reply:从集合中移除元素的个数,不包括不存在的成员。
example:
redis> sadd myset "one"
(integer) 1
redis> sadd myset "two"
(integer) 1
redis> sadd myset "three"
(integer) 1
redis> srem myset "one"
(integer) 1
redis> srem myset "four"
(integer) 0
redis> smembers myset
1) "three"
2) "two"
redis>
smove
smove (source) (destination) (member)
将member从source集合移动到destination集合中。对于其他的客户端,在特定的时间元素将会作为source或者destination集合的成员出现。
如果source集合不存在或者不包含指定的元素,smove命令不执行任何操作并且返回0。否则对象将会从source集合中移除,并添加到destination集合中去,如果destination集合已经存在该元素,则smove命令仅将该元素从source集合中移除。如果source和destination不是集合类型,则返回错误。
返回值:integer-reply
1、如果该元素成功移除,返回1。
2、如果该元素不是source集合成员,无任何操作,则返回0。
example:
redis> sadd myset "one"
(integer) 1
redis> sadd myset "two"
(integer) 1
redis> sadd myotherset "three"
(integer) 1
redis> smove myset myotherset "two"
(integer) 1
redis> smembers myset
1) "one"
redis> smembers myotherset
1) "three"
2) "two"
redis>
spop
spop (key) (count)
从存储在key的集合中移除并返回一个或多个随机元素。
此操作与srandmember类似,它从一个集合中返回一个或多个随机元素,但不删除元素。
返回值:bulk-string-reply:被删除的元素,或者当key不存在时返回nil。
example:
srandmember
srandmember (key) [count]
仅提供key参数,那么随机返回key集合中的一个元素。
Redis 2.6开始,可以接受count参数,如果count是整数且小于元素的个数,返回含有count个不同的元素的数组,如果count是个整数且大于集合中元素的个数时,仅返回整个集合的所有元素,当count是负数,则会返回一个包含count的绝对值的个数元素的数组,如果count的绝对值大于元素的个数,则返回的结果集里会出现一个元素出现多次的情况。
仅提供key参数时,该命令作用类似于spop命令,不同的是spop命令会将被选择的随机元素从集合中移除,而srandmember仅仅是返回该随机元素,而不做任何操作。
返回值:
bulk-string-reply: 不使用count参数的情况下该命令返回随机的元素,如果key不存在则返回nil。
array-reply: 使用count参数,则返回一个随机的元素数组,如果key不存在则返回一个空的数组。
例子:
redis> sadd myset one two three
(integer) 3
redis> srandmember myset
"one"
redis> srandmember myset 2
1) "three"
2) "one"
redis> spandmember myset -5
1) "one"
2) "one"
3) "one"
4) "one"
5) "one"
redis>
说明:
一、传递count参数时的行为规范。
当传递了一个值为正数的count参数,返回的元素就好像从集合中移除了每个选中的元素一样(就像在宾果游戏中提取数字一样)。但是元素不会从集合中移除。所以基本上:
1、不会返回重复的元素。
2、如果count参数的值大于集合内的元素数量,此命令将会仅返回整个集合,没有额外的元素。
相反,当count参数的值为负数时,此命令的行为将发生改变,并且提取操作就像在每次提取后,重新将取出的元素放回包里一样,因此,可能返回重复的元素,以及总是会返回我们请求的数量的元素,因为我们可以一次又一次地重复相同的元素,除了当集合为空(或者不存在key)的时候,将总是会返回一个空数组。
二、返回元素的分布。
当集合中的元素数量很少时,返回元素分布远不够完美,这是因为我们使用了一个近似随机元素函数,它并不能保证良好的分布。
所使用的算法(在dict.c中实现)对哈希表桶进行采样以找到非空桶。一旦找到非空桶,由于我们在哈希表的实现中使用了链接法,因此会检查桶中的元素数量,并且选出一个随机元素。
这意味着,如果你在整个哈希表中有两个非空桶,其中一个有三个元素,另一个只有一个元素,那么其桶中单独存在的元素将以更高的概率返回。
sdiff
sdiff (key [key …])
返回一个集合与给定集合的差集的元素。不存在的key认为是空集。
返回的集合元素是第一个key的集合与后面所有key的集合的差集。
返回值:array-reply:结果集的元素。
example:
redis> sadd key1 "a"
(integer) 1
redis> sadd key1 "b"
(integer) 1
redis> sadd key1 "c"
(integer) 1
redis> sadd key2 "c"
(integer) 1
redis> sadd key2 "d"
(integer) 1
redis> sadd key2 "e"
(integer) 1
redis> sdiff key1 key2
1) "a"
2) "b"
redis>
sdiffstore
sdiffstore (destination) (key [key …])
该命令类似于sdiff,不同之处在于该命令不返回结果集,而是将结果存放在destination集合中。
如果destination已经存在, 则将其覆盖重写。
返回值:integer-reply: 结果集元素的个数。
example:
redis> sadd key1 "a"
(integer) 1
redis> sadd key1 "b"
(integer) 1
redis> sadd key1 "c"
(integer) 1
redis> sadd key2 "c"
(integer) 1
redis> sadd key2 "d"
(integer) 1
redis> sadd key2 "e"
(integer) 1
redis> sdiffstore key key1 key2
(integer) 2
redis> smembers key
1) "b"
2) "a"
redis>
sinter
sinter (key [key …])
返回指定所有的集合的成员的交集。
返回值:array-reply: 结果集成员的列表。
example:
redis> sadd key1 "a"
(integer) 1
redis> sadd key1 "b"
(integer) 1
redis> sadd key1 "c"
(integer) 1
redis> sadd key2 "c"
(integer) 1
redis> sadd key2 "d"
(integer) 1
redis> sadd key2 "e"
(integer) 1
redis> sinter key1 key2
1) "c"
redis>
sinterstore
sinterstore (destination) (key [key …])
这个命令与sinter命令类似,但是它并不是直接返回结果集,而是将结果保存在destination集合中。
如果destination集合存在,则会被重写。
返回值:integer-reply: 结果集中成员的个数。
example:
redis> sadd key1 "a"
(integer) 1
redis> sadd key1 "b"
(integer) 1
redis> sadd key1 "c"
(integer) 1
redis> sadd key2 "c"
(integer) 1
redis> sadd key2 "d"
(integer) 1
redis> sadd key2 "e"
(integer) 1
redis> sinterstore key key1 key2
(integer) 1
redis> smembers key
1) "c"
redis>
sunion
sunion (key [key …])
返回给定的多个集合的并集中的所有成员。
不存在的key可以认为是空的集合。
返回值:
array-reply:并集的成员列表。
example:
redis> sadd key1 "a"
(integer) 1
redis> sadd key1 "b"
(integer) 1
redis> sadd key1 "c"
(integer) 1
redis> sadd key2 "c"
(integer) 1
redis> sadd key2 "d"
(integer) 1
redis> sadd key2 "e"
(integer) 1
redis> sunion key1 key2
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
redis>
sunionstore
sunionstore (destination) (key [key …])
该命令作用类似于sunion命令,不同的是它并不返回结果集,而是将结果存储在destination集合中。
如果destination已经存在,则将其覆盖。
返回值:
integer-reply:结果集中元素的个数。
例子:
redis> sadd key1 "a"
(integer) 1
redis> sadd key1 "b"
(integer) 1
redis> sadd key1 "c"
(integer) 1
redis> sadd key2 "c"
(integer) 1
redis> sadd key2 "d"
(integer) 1
redis> sadd key2 "e"
(integer) 1
redis> sunionstore key key1 key2
(integer) 5
redis> smembers key
1) "c"
2) "e"
3) "b"
4) "a"
5) "d"
redis>
hash
可以用散列类型保存对象和属性。
example:User对象{id:2, name:小明,age:19}
hset
hset (key) (field) (value)
设置key指定的哈希集中指定字段的值。
如果key指定的哈希集不存在,会创建一个新的哈希集并与key关联。
如果字段在哈希集中存在,它将被重写。
返回值:
integer-reply:含义如下:
1:如果field是一个新的字段。
0:如果field原来在map里面已经存在。
example:
127.0.0.1:6379> hset hash1 field1 "hello"
(integer) 1
127.0.0.1:6379> hget hash1 field1
"hello"
127.0.0.1:6379> type hash1
hash
127.0.0.1:6379>
hget
hget (key) (field)
返回key指定的哈希集中该字段所关联的值。
返回值:
bulk-string-reply:该字段所关联的值。当字段不存在或者key不存在时返回nil。
example:
127.0.0.1:6379> hset hash1 field "hi"
(integer) 1
127.0.0.1:6379> hget hash1 field
"hi"
127.0.0.1:6379> hget hash1 fieldOne
(nil)
127.0.0.1:6379>
hmset
hmset (key) (field) (value) [field value …]
设置key指定的哈希集中指定字段的值。该命令将重写所有在哈希集中存在的字段。如果key指定的哈希集不存在,会创建一个新的哈希集并与key关联。
返回值:
simple-string-reply
example:
127.0.0.1:6379> hmset hash1 field1 value1 field2 value2
OK
127.0.0.1:6379> hget hash1 field1
"value1"
127.0.0.1:6379> hget hash1 field2
"value2"
127.0.0.1:6379>
hmget
hmget (key) (field [field …])
返回key指定的哈希集中指定字段的值。
对于哈希集中不存在的每个字段,返回nil值。因为不存在的keys被认为是一个空的哈希集,对一个不存在的key执行hmget将返回一个只含有nil值的列表
返回值:
array-reply:含有给定字段及其值的列表,并保持与请求相同的顺序。
example:
127.0.0.1:6379> hset hash1 field1 "value1"
(integer) 1
127.0.0.1:6379> hset hash1 field2 "value2"
(integer) 1
127.0.0.1:6379> hmget hash1 field1 field2 field3
1) "value1"
2) "value2"
3) (nil)
127.0.0.1:6379>
hsetnx
hsetnx (key) (field) (value)
只在key指定的哈希集中不存在指定的字段时,设置字段的值。如果key指定的哈希集不存在,会创建一个新的哈希集并与key关联。如果字段已存在,该操作无效果。
返回值:
integer-reply:含义如下
1:如果字段是个新的字段,并成功赋值。
0:如果哈希集中已存在该字段,没有操作被执行。
example:
127.0.0.1:6379> hsetnx hash1 field1 "value1"
(integer) 1
127.0.0.1:6379> hsetnx hash1 field1 "value2"
(integer) 0
127.0.0.1:6379> hget hash1 field1
"value1"
127.0.0.1:6379>
hgetall
hgetall (key)
返回key指定的哈希集中所有的字段和值。返回值中,每个字段名的下一个是它的值,所以返回值的长度是哈希集大小的两倍。
返回值:
array-reply:哈希集中字段和值的列表。当key指定的哈希集不存在时返回空列表。
example:
127.0.0.1:6379> hset hash1 field1 "value1"
(integer) 1
127.0.0.1:6379> hset hash1 field2 "value2"
(integer) 1
127.0.0.1:6379> hgetall hash1
1) "field1"
2) "value1"
3) "field2"
4) "value2"
127.0.0.1:6379>
hexists
hexists (key) (field)
返回hash里面field是否存在。
返回值:
integer-reply, 含义如下:
1:hash里面包含该field。
0:hash里面不包含该field或者key不存在。
example:
127.0.0.1:6379> hset hash1 field1 "value1"
(integer) 1
127.0.0.1:6379> hexists hash1 field1
(integer) 1
127.0.0.1:6379> hexists hash1 field2
(integer) 0
127.0.0.1:6379>
hdel
hdel (key) (field [field …])
从key指定的哈希集中移除指定的域。在哈希集中不存在的域将被忽略。
如果key指定的哈希集不存在,它将被认为是一个空的哈希集,该命令将返回0。
返回值:
integer-reply: 返回从哈希集中成功移除的域的数量,不包括指出但不存在的那些域。
example:
127.0.0.1:6379> hset hash1 field1 "value1"
(integer) 1
127.0.0.1:6379> hdel hash1 field1
(integer) 1
127.0.0.1:6379> hdel hash1 field2
(integer) 0
127.0.0.1:6379>
hkeys
hkeys (key)
返回key指定的哈希集中所有字段的名字。
返回值:
array-reply:哈希集中的字段列表,当key指定的哈希集不存在时返回空列表。
example:
127.0.0.1:6379> hset hash1 field1 "value1"
(integer) 1
127.0.0.1:6379> hset hash1 field2 "value2"
(integer) 1
127.0.0.1:6379> hkeys hash1
1) "field1"
2) "field2"
127.0.0.1:6379>
hvals
hvals (key)
返回key指定的哈希集中所有字段的值。
返回值:
array-reply:哈希集中的值的列表,当key指定的哈希集不存在时返回空列表。
example:
127.0.0.1:6379> hset hash1 field1 "value1"
(integer) 1
127.0.0.1:6379> hset hash1 field2 "value2"
(integer) 1
127.0.0.1:6379> hvals hash1
1) "value1"
2) "value2"
127.0.0.1:6379>
hlen
hlen (key)
返回key指定的哈希集包含的字段的数量。
返回值:
integer-reply:哈希集中字段的数量,当key指定的哈希集不存在时返回0。
example:
127.0.0.1:6379> hset hash1 field1 "value1"
(integer) 1
127.0.0.1:6379> hset hash1 field2 "value2"
(integer) 1
127.0.0.1:6379> hlen hash1
(integer) 2
127.0.0.1:6379>
hstrlen
hstrlen (key) (value)
返回值:
integer-reply:返回hash指定field的value的字符串长度,如果hash或者field不存在,返回0。
example:
127.0.0.1:6379> hmset hash1 field1 HelloWorld field2 99 field3 -256
OK
127.0.0.1:6379> hstrlen hash1 field1
(integer) 10
127.0.0.1:6379> hstrlen hash1 field2
(integer) 2
127.0.0.1:6379> hstrlen hash1 field3
(integer) 4
127.0.0.1:6379>
hincrby
hincrby (key) (field) (increment)
增加key指定的哈希集中指定字段的数值。如果key不存在,会创建一个新的哈希集并与key关联。如果字段不存在,则字段的值在该操作执行前被设置为0。
hincrby支持的值的范围限定在64位有符号整数。
返回值
integer-reply:增值操作执行后的该字段的值。
example:
116.62.212.39_9100_test:1>keys *
116.62.212.39_9100_test:1>hmset user name jack sex male age 18
"OK"
116.62.212.39_9100_test:1>hget user age
"18"
116.62.212.39_9100_test:1>hincrby user age 2
"20"
116.62.212.39_9100_test:1>hget user age
"20"
116.62.212.39_9100_test:1>
hincrbyfloat
hincrbyfloat (key) (field) (increment)
为指定key的hash的field字段值执行float类型的increment加。如果field不存在,则在执行该操作前设置为0。如果出现下列情况之一,则返回错误:
1、field的值包含的类型错误(不是字符串)。
2、当前field或者increment不能解析为一个float类型。
返回值
bulk-string-reply: field执行increment加后的值。
example:
116.62.212.39_9100_test:1>keys *
116.62.212.39_9100_test:1>hmset user name jack age 18 money 100.1
"OK"
116.62.212.39_9100_test:1>hmget user age money
1) "18"
2) "100.1"
116.62.212.39_9100_test:1>hincrbyfloat user age 2.1
"20.100000000000001"
116.62.212.39_9100_test:1>hincrbyfloat user money 2.1
"102.19999999999999"
116.62.212.39_9100_test:1>
zset
有序集合zset是一个没有重复元素的字符串集合。
有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。
集合中的成员是唯一的,但是评分可以是重复的。
key [NX|XX] [CH] [INCR] score member [score member …]
将一个或多个member元素及其score值加入到有序集key当中。
zadd
example:
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>zadd zkey1 -1 zvalue1 0 zvalue2 1 zvalue3 2 zvalue4 3 zvalue5
"5"
116.62.212.39_9100_test:0>zrange zkey1 0 -1
1) "zvalue1"
2) "zvalue2"
3) "zvalue3"
4) "zvalue4"
5) "zvalue5"
116.62.212.39_9100_test:0>zrange zkey1 0 -1 withscores
1) "zvalue1"
2) "-1"
3) "zvalue2"
4) "0"
5) "zvalue3"
6) "1"
7) "zvalue4"
8) "2"
9) "zvalue5"
10) "3"
116.62.212.39_9100_test:0>
zrange
zrange (key) (start) (stop) [withscores]
返回有序集key中,下标在start与stop之间的元素。带withscores,可以让分数和值一起返回到结果集。
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>zadd zkey1 100 c 200 c++ 300 c# 400 java 500 redis
"5"
116.62.212.39_9100_test:0>zrange zkey1 0 -1
1) "c"
2) "c++"
3) "c#"
4) "java"
5) "redis"
116.62.212.39_9100_test:0>zrange zkey1 0 -1 withscores
1) "c"
2) "100"
3) "c++"
4) "200"
5) "c#"
6) "300"
7) "java"
8) "400"
9) "redis"
10) "500"
116.62.212.39_9100_test:0>zrange zkey1 2 4
1) "c#"
2) "java"
3) "redis"
116.62.212.39_9100_test:0>zrange zkey1 2 4 withscores
1) "c#"
2) "300"
3) "java"
4) "400"
5) "redis"
6) "500"
116.62.212.39_9100_test:0>
zrevrange
zrevrange (key) (start) (stop) [withscores]
score:
116.62.212.39_9100_test:0>flushdb
"OK"
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>zadd zkey1 100 c 200 c++ 300 c# 400 java 500 redis
"5"
116.62.212.39_9100_test:0>zrange zkey1 0 -1 withscores
1) "c"
2) "100"
3) "c++"
4) "200"
5) "c#"
6) "300"
7) "java"
8) "400"
9) "redis"
10) "500"
116.62.212.39_9100_test:0>zrevrange zkey1 0 -1 withscores
1) "redis"
2) "500"
3) "java"
4) "400"
5) "c#"
6) "300"
7) "c++"
8) "200"
9) "c"
10) "100"
116.62.212.39_9100_test:0>zrevrange zkey1 2 3
1) "c#"
2) "c++"
116.62.212.39_9100_test:0>zrevrange zkey1 2 3 withscores
1) "c#"
2) "300"
3) "c++"
4) "200"
116.62.212.39_9100_test:0>zrevrange zkey1 -2 -1 withscores
1) "c++"
2) "200"
3) "c"
4) "100"
116.62.212.39_9100_test:0>
zrangebyscore
zrangebyscore (key) (min) (max) [withscores] [limit offset count]
返回有序集key中,所有score值介于[min max]之间的成员。有序集成员按score值递增次序排列。
116.62.212.39_9100_test:0>flushdb
"OK"
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>zadd zkey1 100 c 200 c++ 300 c# 400 java 500 redis
"5"
116.62.212.39_9100_test:0>zrange zkey1 0 -1
1) "c"
2) "c++"
3) "c#"
4) "java"
5) "redis"
116.62.212.39_9100_test:0>zrange zkey1 0 -1 withscores
1) "c"
2) "100"
3) "c++"
4) "200"
5) "c#"
6) "300"
7) "java"
8) "400"
9) "redis"
10) "500"
116.62.212.39_9100_test:0>zrange zkey1 2 4
1) "c#"
2) "java"
3) "redis"
116.62.212.39_9100_test:0>zrange zkey1 2 4 withscores
1) "c#"
2) "300"
3) "java"
4) "400"
5) "redis"
6) "500"
116.62.212.39_9100_test:0>zrange zkey1 0 -1 withscores
1) "c"
2) "100"
3) "c++"
4) "200"
5) "c#"
6) "300"
7) "java"
8) "400"
9) "redis"
10) "500"
116.62.212.39_9100_test:0>zrangebyscore zkey1 200 400
1) "c++"
2) "c#"
3) "java"
116.62.212.39_9100_test:0>zrangebyscore zkey1 (200 400
1) "c#"
2) "java"
116.62.212.39_9100_test:0>zrangebyscore zkey1 (200 (400
1) "c#"
116.62.212.39_9100_test:0>zrangebyscore zkey1 100 500 withscores
1) "c"
2) "100"
3) "c++"
4) "200"
5) "c#"
6) "300"
7) "java"
8) "400"
9) "redis"
10) "500"
116.62.212.39_9100_test:0>zrangebyscore zkey1 100 500 withscores limit 2 2
1) "c#"
2) "300"
3) "java"
4) "400"
116.62.212.39_9100_test:0>
zrevrangebyscore
zrevrangebyscore (key) (max) (min) [withscores] [limit offset count]
116.62.212.39_9100_test:0>flushdb
"OK"
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>zadd zkey1 100 c 200 c++ 300 c# 400 java 500 redis
"5"
116.62.212.39_9100_test:0>zrange zkey1 0 -1
1) "c"
2) "c++"
3) "c#"
4) "java"
5) "redis"
116.62.212.39_9100_test:0>zrange zkey1 0 -1 withscores
1) "c"
2) "100"
3) "c++"
4) "200"
5) "c#"
6) "300"
7) "java"
8) "400"
9) "redis"
10) "500"
116.62.212.39_9100_test:0>zrange zkey1 2 4
1) "c#"
2) "java"
3) "redis"
116.62.212.39_9100_test:0>zrange zkey1 2 4 withscores
1) "c#"
2) "300"
3) "java"
4) "400"
5) "redis"
6) "500"
116.62.212.39_9100_test:0>zrange zkey1 0 -1 withscores
1) "c"
2) "100"
3) "c++"
4) "200"
5) "c#"
6) "300"
7) "java"
8) "400"
9) "redis"
10) "500"
116.62.212.39_9100_test:0>zrangebyscore zkey1 200 400
1) "c++"
2) "c#"
3) "java"
116.62.212.39_9100_test:0>zrangebyscore zkey1 (200 400
1) "c#"
2) "java"
116.62.212.39_9100_test:0>zrangebyscore zkey1 (200 (400
1) "c#"
116.62.212.39_9100_test:0>zrangebyscore zkey1 100 500 withscores
1) "c"
2) "100"
3) "c++"
4) "200"
5) "c#"
6) "300"
7) "java"
8) "400"
9) "redis"
10) "500"
116.62.212.39_9100_test:0>zrangebyscore zkey1 100 500 withscores limit 2 2
1) "c#"
2) "300"
3) "java"
4) "400"
116.62.212.39_9100_test:0>zrevrangebyscore zkey1 100 500
116.62.212.39_9100_test:0>zrevrangebyscore zkey1 500 100
1) "redis"
2) "java"
3) "c#"
4) "c++"
5) "c"
116.62.212.39_9100_test:0>zrevrangebyscore zkey1 500 100 withscores
1) "redis"
2) "500"
3) "java"
4) "400"
5) "c#"
6) "300"
7) "c++"
8) "200"
9) "c"
10) "100"
116.62.212.39_9100_test:0>zrevrangebyscore zkey1 500 100 withscores limit 2 2
1) "c#"
2) "300"
3) "c++"
4) "200"
116.62.212.39_9100_test:0>
zincrby
zincrby key increment member
zrem
zrem (key) (member [member …])
116.62.212.39_9100_test:0>flushdb
"OK"
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>zadd zkey1 100 c 200 c++ 300 c# 400 java 500 redis
"5"
116.62.212.39_9100_test:0>zrange zkey1 0 -1
1) "c"
2) "c++"
3) "c#"
4) "java"
5) "redis"
116.62.212.39_9100_test:0>zrange zkey1 0 -1 withscores
1) "c"
2) "100"
3) "c++"
4) "200"
5) "c#"
6) "300"
7) "java"
8) "400"
9) "redis"
10) "500"
116.62.212.39_9100_test:0>zrem zkey1 java
"1"
116.62.212.39_9100_test:0>zrange zkey1 0 -1
1) "c"
2) "c++"
3) "c#"
4) "redis"
116.62.212.39_9100_test:0>zrange zkey1 0 -1 withscores
1) "c"
2) "100"
3) "c++"
4) "200"
5) "c#"
6) "300"
7) "redis"
8) "500"
116.62.212.39_9100_test:0>
zcard
zcard (key)
返回key对应的value个数。
case:
116.62.212.39_9100_test:0>flushdb
"OK"
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>zadd zkey1 100 c 200 c++ 300 c# 400 java 500 redis
"5"
116.62.212.39_9100_test:0>zcard zkey1
"5"
116.62.212.39_9100_test:0>
zcount
zcount (key) (min) (max)
统计该集合,分数区间内的元素个数.
case:
116.62.212.39_9100_test:0>flushdb
"OK"
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>zadd zkey1 100 c 200 c++ 300 c# 400 java 500 redis
"5"
116.62.212.39_9100_test:0>zcount zkey1 200 400
"3"
116.62.212.39_9100_test:0>
zrank
zrank (key) (member)
返回该值在集合中的排名,从0开始。
case:
116.62.212.39_9100_test:0>flushdb
"OK"
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>zadd zkey1 100 c 200 c++ 300 c# 400 java 500 redis
"5"
116.62.212.39_9100_test:0>zcount zkey1 200 400
"3"
116.62.212.39_9100_test:0>zrank zkey1 c++
"1"
116.62.212.39_9100_test:0>zrank zkey1 java
"3"
116.62.212.39_9100_test:0>zrank zkey1 oracle
null
zrevrank
zrevrank (key) (member)
逆序获得下标值
case:
116.62.212.39_9100_test:0>flushdb
"OK"
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>zadd zkey1 100 c 200 c++ 300 c# 400 java 500 redis
"5"
116.62.212.39_9100_test:0>zrange zkey1 0 -1 withscores
1) "c"
2) "100"
3) "c++"
4) "200"
5) "c#"
6) "300"
7) "java"
8) "400"
9) "redis"
10) "500"
116.62.212.39_9100_test:0>zrevrank zkey1 c==
null
116.62.212.39_9100_test:0>zrevrank zkey1 c++
"3"
116.62.212.39_9100_test:0>zrevrank zkey1 redis
"0"
116.62.212.39_9100_test:0>zrevrank zkey1 java
"1"
116.62.212.39_9100_test:0>
zscore
zscore (key) (value)
case:
116.62.212.39_9100_test:0>flushdb
"OK"
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>zadd zkey1 100 c 200 c++ 300 c# 400 java 500 redis
"5"
116.62.212.39_9100_test:0>zscore zkey1 java
"400"
116.62.212.39_9100_test:0>zscore zkey1 c
"100"
116.62.212.39_9100_test:0>zscore zkey1 oracle
null
116.62.212.39_9100_test:0>
transaction
multi
标记一个事务块的开始。 随后的指令将在执行EXEC时作为一个原子执行。
返回值:
simple-string-reply: 始终为OK
exec
执行所有multi之后发的命令
执行事务中所有在排队等待的指令并将链接状态恢复到正常,当使用watch时,只有当被监视的键没有被修改,且允许检查设定机制时,exec会被执行
返回值:
multi-bulk-reply: 每个元素与原子事务中的指令一一对应,当使用watch时,如果被终止,exec则返回一个空的应答集合
case:
116.62.212.39_9100_test:0>flushdb
"OK"
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>multi
"OK"
116.62.212.39_9100_test:0>set key1 value1
"QUEUED"
116.62.212.39_9100_test:0>set key2 value2
"QUEUED"
116.62.212.39_9100_test:0>get key2
"QUEUED"
116.62.212.39_9100_test:0>set key3 value3
"QUEUED"
116.62.212.39_9100_test:0>exec
1) "OK"
2) "OK"
3) "OK"
4) "OK"
5) "OK"
6) "value2"
7) "OK"
8) "OK"
9) "OK"
116.62.212.39_9100_test:0>
116.62.212.39_9100_test:0>flushdb
"OK"
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>multi
"OK"
116.62.212.39_9100_test:0>set key1 value1
"QUEUED"
116.62.212.39_9100_test:0>set key2 value2
"QUEUED"
116.62.212.39_9100_test:0>set key3 value3
"QUEUED"
116.62.212.39_9100_test:0>set1 key4 value4
"ERR unknown command 'set1'"
116.62.212.39_9100_test:0>exec
"EXECABORT Transaction discarded because of previous errors."
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>
116.62.212.39_9100_test:0>flushdb
"OK"
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>multi
"OK"
116.62.212.39_9100_test:0>set key1 value1
"QUEUED"
116.62.212.39_9100_test:0>set key2 value2
"QUEUED"
116.62.212.39_9100_test:0>incr key2
"QUEUED"
116.62.212.39_9100_test:0>exec
1) "OK"
2) "OK"
3) "OK"
4) "OK"
5) "OK"
6) "ERR value is not an integer or out of range"
7) "OK"
116.62.212.39_9100_test:0>get key1
"value1"
116.62.212.39_9100_test:0>get key2
"value2"
116.62.212.39_9100_test:0>keys *
1) "key1"
2) "key2"
116.62.212.39_9100_test:0>type k1
"none"
116.62.212.39_9100_test:0>type key1
"string"
116.62.212.39_9100_test:0>type key2
"string"
116.62.212.39_9100_test:0>
3.6.3 discard
丢弃所有multi之后发的命令
刷新一个事务中所有在排队等待的指令,并且将连接状态恢复到正常。
如果已使用watch,discard将释放所有被watch的key。
返回值:
status-reply:所有返回都是OK
case:
116.62.212.39_9100_test:0>flushdb
"OK"
116.62.212.39_9100_test:0>keys *
116.62.212.39_9100_test:0>multi
"OK"
116.62.212.39_9100_test:0>set key1 value1
"QUEUED"
116.62.212.39_9100_test:0>set key2 value2
"QUEUED"
116.62.212.39_9100_test:0>set key3 value3
"QUEUED"
116.62.212.39_9100_test:0>exec
1) "OK"
2) "OK"
3) "OK"
4) "OK"
5) "OK"
6) "OK"
7) "OK"
116.62.212.39_9100_test:0>multi
"OK"
116.62.212.39_9100_test:0>set key1 value11
"QUEUED"
116.62.212.39_9100_test:0>set key2 value22
"QUEUED"
116.62.212.39_9100_test:0>set key3 value33
"QUEUED"
116.62.212.39_9100_test:0>discard
"OK"
116.62.212.39_9100_test:0>get key1
"value1"
116.62.212.39_9100_test:0>get key2
"value2"
116.62.212.39_9100_test:0>get key3
"value3"
116.62.212.39_9100_test:0>multi
"OK"
116.62.212.39_9100_test:0>set key1 key11
"QUEUED"
116.62.212.39_9100_test:0>exec
1) "OK"
2) "OK"
3) "OK"
116.62.212.39_9100_test:0>get key1
"key11"
116.62.212.39_9100_test:0>get key2
"value2"
116.62.212.39_9100_test:0>get key3
"value3"
116.62.212.39_9100_test:0>
watch
watch (key [key …])
标记所有指定的key被监视起来,在事务中有条件的执行(乐观锁)。
返回值:
simple-string-reply: 总是OK。
unwatch
刷新一个事务中已被监视的所有key。
如果执行exce或者discard,则不需要手动执行unwatch。
返回值
simple-string-reply: 总是OK。
事务
SpringBoot整合Redis
1、pom
<!--SpringBoot整合Redis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
2、code
package com.jt;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.params.SetParams;
import java.util.List;
import java.util.Map;
import java.util.Set;
//Redis测试
public class TestRedis {
@Test
public void test01(){
Jedis jedis = new Jedis("192.168.126.129", 6379);
jedis.set("2007", "redis入门案例");
System.out.println(jedis.get("2007"));
}
@Test
public void test02(){
Jedis jedis = new Jedis("192.168.126.129", 6379);
if(!jedis.exists("2007")){ //判断是否有key对应的数据,如果没有则新增数据,如果有则放弃新增
jedis.set("2007", "测试案例2222");
}
System.out.println(jedis.get("2007"));
jedis.setnx("2007", "测试高级用法"); //setnx();如果有数据,则不做处理
System.out.println(jedis.get("2007"));
}
/*向Redis中添加数据,添加超时时间100s。
隐藏bug:代码执行过程中,如果报错,则可能删除失败
原子性:要么同时成功,要么同时失败
解决方案:将入库操作与删除操作一起执行;jedis.setex("2007", 100, "测试时间");
*/
@Test
public void test03() throws InterruptedException {
Jedis jedis = new Jedis("192.168.126.129", 6379);
//jedis.set("2007", "测试时间");
//jedis.expire("2007", 100);
//Thread.sleep(3000);
jedis.setex("2007", 100, "测试时间");
System.out.println(jedis.ttl("2007") + "秒");
}
/*service:
1、如果数据存在,则不操作数据;setnx
2、同时设定超时时间,注意原子性;setex
参数说明:
private static final String XX = "xx"; 只有key存在,则进行操作
private static final String NX = "nx"; 没有key,进行写操作
private static final String PX = "px"; 毫秒
private static final String EX = "ex"; 秒
*/
@Test
public void test04() throws InterruptedException {
Jedis jedis = new Jedis("192.168.126.129", 6379);
SetParams setParams = new SetParams();
setParams.nx().ex(100);
jedis.set("2007", "aaa", setParams);
System.out.println("2007");
}
@Test
public void testHash() {
Jedis jedis = new Jedis("192.168.126.129", 6379);
jedis.hset("person", "id", "1");
jedis.hset("person", "name", "宋江");
jedis.hset("person", "age", "18");
String id = jedis.hget("person", "id"); //获取key里面的field的value
System.out.println(id);
Set<String> set = jedis.hkeys("person"); //获取key里面的所有field
System.out.println(set);
Map<String, String> map = jedis.hgetAll("person"); //获取key里面的所有field及对应的value
System.out.println(map);
List<String> list = jedis.hvals("person"); //获取key里面的所有field里面的value
System.out.println(list);
/*print:
1
[name, age, id]
{name=宋江, age=18, id=1}
[1, 宋江, 18]
*/
}
@Test
public void testList() {
Jedis jedis = new Jedis("192.168.126.129", 6379);
jedis.lpush("list", "1", "2", "3", "4", "5");
System.out.println(jedis.rpop("list"));
}
@Test
public void testList01() {
Jedis jedis = new Jedis("192.168.126.129", 6379);
Long count = jedis.lpush("list1", "value1", "value2", "value3"); //返回的是添加的值的个数
System.out.println("获取数据:" + count);
List<String> list = jedis.lrange("list1", 0, -1); //获取集合中全部的值
System.out.println("获取集合中的值" + list);
/*print:
获取数据:3
获取集合中的值[value3, value2, value1]
*/
}
@Test
public void testTransaction() {
Jedis jedis = new Jedis("192.168.126.129", 6379);
//1、开启事务
Transaction transaction = jedis.multi();
try {
transaction.set("a", "a");
transaction.set("b", "b");
transaction.set("c", "c");
transaction.exec(); //提交事务
} catch (Exception e) {
transaction.discard();
}
}
}
Redis集群
为了提高网站响应速度,总是把热点数据保存在内存中而不是直接从后端数据库中读取。
采用Redis集群,可以保证数据的分散存储,同时保证数据存储的一致性,并且在内部实现高可用机制,实现服务故障的自动迁移.
集群搭建
1、创建集群文件夹
linux命令:mkdir
说明:在Redis根目录下创建
[root@localhost redis]# mkdir cluster
2、在cluster文件夹中分别创建7000、7001、7002、7003、7004、7005文件夹
[root@localhost cluster]# mkdir 7000 7001 7002 7003 7004 7005
3、复制配置文件
说明:将redis根目录中的redis.conf文件复制到cluster/7000文件夹中,并以原名保存。
[root@localhost redis]# cp redis.conf cluster/7000
4、编辑配置文件
说明:编辑redis/cluster/7000中的redis.conf文件
(1)注释本地绑定ip地址
#bind 127.0.0.1 在该文件内容的第69行
(2)关闭保护模式
protected-mode no 在该文件内容的第88行
(3)修改端口号
port 7000 在该文件内容的第92行
(4)启动后台启动
daemonize yes 在该文件内容的第136行
(5)修改pid文件
pidfile /usr/local/src/redis/cluster/7000/redis.pid 在该文件内容的第158行
(6)修改持久化文件路径
dir /usr/local/src/redis/cluster/7000 在该文件内容的第263行
(7)设定内存优化策略
maxmemory-policy volatile-lru 在该文件内容的第597行
(8)关闭AOF模式
appendonly no 在该文件内容的第699行
(9)开启集群配置
cluster-enabled yes 在该文件内容的第838行
(10)开启集群配置文件
cluster-config-file nodes.conf 在该文件内容的第846行
(11)设置集群的超时时间
cluster-node-timeout 15000 在该文件内容的第852行
5、复制修改后的配置文件
说明:复制redis/cluster/7000/redis.conf,复制后的文件名不变。
[root@localhost cluster]# cp 7000/redis.conf 7001
[root@localhost cluster]# cp 7000/redis.conf 7002
[root@localhost cluster]# cp 7000/redis.conf 7003
[root@localhost cluster]# cp 7000/redis.conf 7004
[root@localhost cluster]# cp 7000/redis.conf 7005
6、分别修改文件夹7001、7002、7003、7004、7005下的redis.conf文件中的对应的端口号
说明:采用Linux命令中的替换操作。
(1)[root@localhost cluster]# vim 7001/redis.conf
:%s/7000/7001/g
(2)[root@localhost cluster]# vim 7002/redis.conf
:%s/7000/7002/g
(3)[root@localhost cluster]# vim 7003/redis.conf
:%s/7000/7003/g
(4)[root@localhost cluster]# vim 7004/redis.conf
:%s/7000/7004/g
(5)[root@localhost cluster]# vim 7005/redis.conf
:%s/7000/7005/g
7、通过脚本文件启动/关闭对应Redis
(1)创建启动脚本
[root@localhost cluster]# vim start.sh
添加内容如下:
#!/bin/sh
redis-server 7000/redis.conf &
redis-server 7001/redis.conf &
redis-server 7002/redis.conf &
redis-server 7003/redis.conf &
redis-server 7004/redis.conf &
redis-server 7005/redis.conf &
(2)创建关闭脚本
[root@localhost cluster]# vim stop.sh
#!/bin/sh
redis-cli -p 7000 shutdown &
redis-cli -p 7001 shutdown &
redis-cli -p 7002 shutdown &
redis-cli -p 7003 shutdown &
redis-cli -p 7004 shutdown &
redis-cli -p 7005 shutdown &
8、启动Redis节点
[root@localhost cluster]# sh start.sh
9、检查redis节点是否启动正常
[root@localhost cluster]# ps -ef | grep redis
10、检查防火墙是否关闭
[root@localhost cluster]# firewall-cmd --state
11、创建redis集群
redis-cli --cluster create --cluster-replicas 1 192.168.126.129:7000 192.168.126.129:7001 192.168.126.129:7002 192.168.126.129:7003 192.168.126.129:7004 192.168.126.129:7005
12、Redis集群高可用测试
(1)查看7000是否是主机,此时是主机
(2)关闭redis7000主机,检查是否自动实现故障迁移
[root@localhost 7000]# redis-cli -p 7000 shutdown
(3)查看从机7003是否变成了主机。此时7003变成了主机
(4)开启7000并查看7000是否变成了从机,此时7000变成了从机
说明:宕机后的节点重启,可能挂载到其他主节点中(7001、7002)
13、Redis集群原理
redis的所有节点都会保存当前redis集群中的全部主从状态信息,并且每个节点都能够相互通信。当一个节点发生宕机现象,则集群中的其他节点通过ping-pong检测机制检查redis节点是否宕机。当有半数以上的节点认为宕机,则认为主节点宕机。同时由redis剩余的主节点进入选举机制,投票选举链接宕机的主节点的从机,实现故障迁移。
14、redis集群宕机的条件
集群中如果主机宕机,那么从机可以继续提供服务
当主机中没有从机时,则向其它主机借用多余的从机继续提供服务;如果主机宕机时没有从机可用则集群崩溃。
9个redis节点时,节点宕机5-7次时集群才崩溃。
15、redis hash槽存储数据原理
槽算法又叫分区算法
redis cluster采用此分区,所有的键根据哈希函数(CRC16[key]%16384)映射到0-16383槽内,共16384个槽位,每个节点维护部分槽及槽所映射的键值数据,根据主节点的个数,均衡划分区间。
算法:哈希函数: Hash()=CRC16[key]%16384
当向redis集群中插入数据时,首先将key进行计算,之后将计算结果匹配到具体的某一个槽的区间内,之后再将数据set到管理该槽的节点中。
集群代码测试
@Test
public void testCluster() {
Set<HostAndPort> sets = new HashSet<>();
sets.add(new HostAndPort("192.168.126.129", 7000));
sets.add(new HostAndPort("192.168.126.129", 7001));
sets.add(new HostAndPort("192.168.126.129", 7002));
sets.add(new HostAndPort("192.168.126.129", 7003));
sets.add(new HostAndPort("192.168.126.129", 7004));
sets.add(new HostAndPort("192.168.126.129", 7005));
JedisCluster jedisCluster = new JedisCluster(sets);
jedisCluster.set("jedis", "集群赋值");
System.out.println(jedisCluster.get("jedis")); //集群赋值
}