REDIS的官方定义
Redis is an open source, BSD licensed, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets. redis是开源,BSD许可,高级的key-value存储系统.
那Redis和MC相比,独特之处是啥:
redis可以用来做存储(storge), 而memcached只能用来做缓存(cache), 这个特点主要因为其有”持久化”的功能.
对于memcached来说,存储的数据,只有1种类型–”字符串”,而redis则可以存储字符串,链表,哈希结构,集合,有序集合
REDIS的安装和下载
我的安装链接方式
到链接下载 http://download.redis.io/releases/redis-5.0.0.tar.gz
下载结束后,解压到英文文件夹中
我的文件加在
打开cmd
在cmd中输入
然后会出现(这是服务端)
再开一个cmd,输入(这是客户端)
链接成功,在客户端敲命令
官方的链接方式
1:官方站点: redis.io 下载最新版或者最新stable版
2:解压源码并进入目录
3:不用configure
4:直接make
5:可选步骤: make test 测试编译情况
(可能出现: need tcl >8.4这种情况, yum install tcl)
6:安装到指定的目录,比如 /usr/local/redis
make PREFIX=/usr/local/redis install
注: PREFIX要大写
7:make install之后, 得到如下几个文件
- redis-benchmark 性能测试工具
- redis-check-aof 日志文件检测工(比如断电造成日志损坏,可以检测并修复)
- redis-check-dump 快照文件检测工具,效果类上
- redis-cli 客户端
- redis-server 服务端
8: 复制配置文件
Cp /path/redis.conf /usr/local/redis
9: 启动与连接
启动
path/to/redis/bin/redis-server ./path/to/conf-file 例:[root@localhost redis]# ./bin/redis-server ./redis.conf
连接
#/path/to/redis/bin/redis-cli [-h localhost -p 6379 ]
-
1#/path/to/redis/bin/redis-cli [-h localhost -p 6379 ]
10:让redis以后台进程的形式运行
编辑conf配置文件,修改如下内容;
daemonize yes
易碰到的问题:时间错误.
原因: 源码是官方configure过的,但官方configure时,生成的文件有时间戳信息,所以如果你的虚拟机的时间不对,比如说是2022年,就可能会出错
解决: date -s ‘yyyy-mm-dd hh:mm:ss’ 重写时间
再 clock -w 写入cmos
redis的常见操作
1. 对于key的所有操作
-
del key1 key2 … keyn
作用:删除1个或者多个键
返回值:不存在的key忽略掉,返回真正删除的key的数量 -
rename key newkey
作用:给key附一个新的key名
注:如果说newkey的值已经存在,则newkey的原值被覆盖 -
renamenx key newkey
作用:把key改名为newkey
返回:发生修改返回1,未发生修改返回0 -
move key db
redis 127.0.0.1:6379[1]> select 2
OK
redis 127.0.0.1:6379[2]> keys
(empty list or set)
redis 127.0.0.1:6379[2]> select 0
OK
redis 127.0.0.1:6379> keys
1) “name”
2) “cc”
3) “a”
4) “b”
redis 127.0.0.1:6379> move cc 2
(integer) 1
redis 127.0.0.1:6379> select 2
OK
redis 127.0.0.1:6379[2]> keys *
1) “cc”
redis 127.0.0.1:6379[2]> get cc
“3”
(注意: 一个redis进程,可以打开不止一个数据库, 默认打开16个数据库,从0到15编号,如果想打开更多数据库,可以从配置文件修改)
-
keys pattern
pattern可选择如下:
: 通配任意多个字符
?: 通配单个字符
[]: 通配括号内的某1个字符
redis 127.0.0.1:6379> flushdb
OK
redis 127.0.0.1:6379> keys
(empty list or set)
redis 127.0.0.1:6379> mset one 1 two 2 three 3 four 4
OK
redis 127.0.0.1:6379> keys o
1) “one”
redis 127.0.0.1:6379> key o
(error) ERR unknown command ‘key’
redis 127.0.0.1:6379> keys *o
1) “two”
redis 127.0.0.1:6379> keys ???
1) “one”
2) “two”
redis 127.0.0.1:6379> keys on?
1) “one”
redis 127.0.0.1:6379> set ons yes
OK
redis 127.0.0.1:6379> keys on[eaw]
1)”one” -
randomkey 返回随机key
-
exists key 判断key是否存在 返回1/0
-
type key 返回key存储的值的类型 有string link set order set hash
-
ttl key 查询key的生命周期
-
expire key 整型值 设置key的生命周期
- pexpire key 毫秒数, 设置生命周期
-
pttl key, 以毫秒返回生命周期
-
persist key 把指定key设置为永久有效
注:对于不存在的key或已过期的key/不过期的key,都返回-1
Redis2.8中,对于不存在的key,返回-2
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1. KEYS/RENAME/DEL/EXISTS/MOVE/RENAMENX: #在Shell命令行下启动Redis客户端工具。 /> redis-cli #清空当前选择的数据库,以便于对后面示例的理解。 redis 127.0.0.1:6379> flushdb OK #添加String类型的模拟数据。 redis 127.0.0.1:6379> set mykey 2 OK redis 127.0.0.1:6379> set mykey2 "hello" OK #添加Set类型的模拟数据。 redis 127.0.0.1:6379> sadd mysetkey 1 2 3 (integer) 3 #添加Hash类型的模拟数据。 redis 127.0.0.1:6379> hset mmtest username "stephen" (integer) 1 #根据参数中的模式,获取当前数据库中符合该模式的所有key,从输出可以看出,该命令在执行时并不区分与Key关联的Value类型。 redis 127.0.0.1:6379> keys my* 1) "mysetkey" 2) "mykey" 3) "mykey2" #删除了两个Keys。 redis 127.0.0.1:6379> del mykey mykey2 (integer) 2 #查看一下刚刚删除的Key是否还存在,从返回结果看,mykey确实已经删除了。 redis 127.0.0.1:6379> exists mykey (integer) 0 #查看一下没有删除的Key,以和上面的命令结果进行比较。 redis 127.0.0.1:6379> exists mysetkey (integer) 1 #将当前数据库中的mysetkey键移入到ID为1的数据库中,从结果可以看出已经移动成功。 redis 127.0.0.1:6379> move mysetkey 1 (integer) 1 #打开ID为1的数据库。 redis 127.0.0.1:6379> select 1 OK #查看一下刚刚移动过来的Key是否存在,从返回结果看已经存在了。 redis 127.0.0.1:6379[1]> exists mysetkey (integer) 1 #在重新打开ID为0的缺省数据库。 redis 127.0.0.1:6379[1]> select 0 OK #查看一下刚刚移走的Key是否已经不存在,从返回结果看已经移走。 redis 127.0.0.1:6379> exists mysetkey (integer) 0 #准备新的测试数据。 redis 127.0.0.1:6379> set mykey "hello" OK #将mykey改名为mykey1 redis 127.0.0.1:6379> rename mykey mykey1 OK #由于mykey已经被重新命名,再次获取将返回nil。 redis 127.0.0.1:6379> get mykey (nil) #通过新的键名获取。 redis 127.0.0.1:6379> get mykey1 "hello" #由于mykey已经不存在了,所以返回错误信息。 redis 127.0.0.1:6379> rename mykey mykey1 (error) ERR no such key #为renamenx准备测试key redis 127.0.0.1:6379> set oldkey "hello" OK redis 127.0.0.1:6379> set newkey "world" OK #由于newkey已经存在,因此该命令未能成功执行。 redis 127.0.0.1:6379> renamenx oldkey newkey (integer) 0 #查看newkey的值,发现它也没有被renamenx覆盖。 redis 127.0.0.1:6379> get newkey "world" 2. PERSIST/EXPIRE/EXPIREAT/TTL: #为后面的示例准备的测试数据。 redis 127.0.0.1:6379> set mykey "hello" OK #将该键的超时设置为100秒。 redis 127.0.0.1:6379> expire mykey 100 (integer) 1 #通过ttl命令查看一下还剩下多少秒。 redis 127.0.0.1:6379> ttl mykey (integer) 97 #立刻执行persist命令,该存在超时的键变成持久化的键,即将该Key的超时去掉。 redis 127.0.0.1:6379> persist mykey (integer) 1 #ttl的返回值告诉我们,该键已经没有超时了。 redis 127.0.0.1:6379> ttl mykey (integer) -1 #为后面的expire命令准备数据。 redis 127.0.0.1:6379> del mykey (integer) 1 redis 127.0.0.1:6379> set mykey "hello" OK #设置该键的超时被100秒。 redis 127.0.0.1:6379> expire mykey 100 (integer) 1 #用ttl命令看一下当前还剩下多少秒,从结果中可以看出还剩下96秒。 redis 127.0.0.1:6379> ttl mykey (integer) 96 #重新更新该键的超时时间为20秒,从返回值可以看出该命令执行成功。 redis 127.0.0.1:6379> expire mykey 20 (integer) 1 #再用ttl确认一下,从结果中可以看出果然被更新了。 redis 127.0.0.1:6379> ttl mykey (integer) 17 #立刻更新该键的值,以使其超时无效。 redis 127.0.0.1:6379> set mykey "world" OK #从ttl的结果可以看出,在上一条修改该键的命令执行后,该键的超时也无效了。 redis 127.0.0.1:6379> ttl mykey (integer) -1 3. TYPE/RANDOMKEY/SORT: #由于mm键在数据库中不存在,因此该命令返回none。 redis 127.0.0.1:6379> type mm none #mykey的值是字符串类型,因此返回string。 redis 127.0.0.1:6379> type mykey string #准备一个值是set类型的键。 redis 127.0.0.1:6379> sadd mysetkey 1 2 (integer) 2 #mysetkey的键是set,因此返回字符串set。 redis 127.0.0.1:6379> type mysetkey set #返回数据库中的任意键。 redis 127.0.0.1:6379> randomkey "oldkey" #清空当前打开的数据库。 redis 127.0.0.1:6379> flushdb OK #由于没有数据了,因此返回nil。 redis 127.0.0.1:6379> randomkey (nil)
2. 字符串操作
set key value [ex 秒数] / [px 毫秒数]
set a 1 ex 10 , 10秒有效 Set a 1 px 9000 , 9秒有效 注: 如果ex,px同时写,以后面的有效期为准 如 set a 1 ex 100 px 9000, 实际有效期是9000毫秒
mset multi set
一次性设置多个键值
mset key1 v1 key2 v2
get key
获取key的值
mget key1 key2 ....keyn
获取多个key的值
getset key newvalue
获取并返回旧值,设置新值
127.0.0.1:6379> set num 100 OK 127.0.0.1:6379> getset num 200 "100" 127.0.0.1:6379> get num "200" 127.0.0.1:6379>
set
设置 字符的值
redis 127.0.0.1:6379> set cnt 0 OK redis 127.0.0.1:6379> getset cnt 1 "0" redis 127.0.0.1:6379> getset cnt 2 "1"
incr key
作用: 指定的key的值加1,并返回加1后的值
127.0.0.1:6379> incr num
(integer) 201
127.0.0.1:6379>
incrby key number
表示自增几 127.0.0.1:6379> incrby num 2 (integer) 203 127.0.0.1:6379>
incrbyfloat key floatnumber
表示小数的自增 redis 127.0.0.1:6379> incrbyfloat age 3.5 "95.5"
dect key
表示自减1 redis 127.0.0.1:6379> set age 20 OK redis 127.0.0.1:6379> decr age (integer) 19
decrby key number
表示自增几 redis 127.0.0.1:6379> decrby age 3 (integer) 16
应用场景
在登录的时候,可以控制频率
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1. SET/GET/APPEND/STRLEN: /> redis-cli #执行Redis客户端工具。 redis 127.0.0.1:6379> exists mykey #判断该键是否存在,存在返回1,否则返回0。 (integer) 0 redis 127.0.0.1:6379> append mykey "hello" #该键并不存在,因此append命令返回当前Value的长度。 (integer) 5 redis 127.0.0.1:6379> append mykey " world" #该键已经存在,因此返回追加后Value的长度。 (integer) 11 redis 127.0.0.1:6379> get mykey #通过get命令获取该键,以判断append的结果。 "hello world" redis 127.0.0.1:6379> set mykey "this is a test" #通过set命令为键设置新值,并覆盖原有值。 OK redis 127.0.0.1:6379> get mykey "this is a test" redis 127.0.0.1:6379> strlen mykey #获取指定Key的字符长度,等效于C库中strlen函数。 (integer) 14 2. INCR/DECR/INCRBY/DECRBY: redis 127.0.0.1:6379> set mykey 20 #设置Key的值为20 OK redis 127.0.0.1:6379> incr mykey #该Key的值递增1 (integer) 21 redis 127.0.0.1:6379> decr mykey #该Key的值递减1 (integer) 20 redis 127.0.0.1:6379> del mykey #删除已有键。 (integer) 1 redis 127.0.0.1:6379> decr mykey #对空值执行递减操作,其原值被设定为0,递减后的值为-1 (integer) -1 redis 127.0.0.1:6379> del mykey (integer) 1 redis 127.0.0.1:6379> incr mykey #对空值执行递增操作,其原值被设定为0,递增后的值为1 (integer) 1 redis 127.0.0.1:6379> set mykey hello #将该键的Value设置为不能转换为整型的普通字符串。 OK redis 127.0.0.1:6379> incr mykey #在该键上再次执行递增操作时,Redis将报告错误信息。 (error) ERR value is not an integer or out of range redis 127.0.0.1:6379> set mykey 10 OK redis 127.0.0.1:6379> decrby mykey 5 (integer) 5 redis 127.0.0.1:6379> incrby mykey 10 (integer) 15 3. GETSET: redis 127.0.0.1:6379> incr mycounter #将计数器的值原子性的递增1 (integer) 1 #在获取计数器原有值的同时,并将其设置为新值,这两个操作原子性的同时完成。 redis 127.0.0.1:6379> getset mycounter 0 "1" redis 127.0.0.1:6379> get mycounter #查看设置后的结果。 "0" 4. SETEX: redis 127.0.0.1:6379> setex mykey 10 "hello" #设置指定Key的过期时间为10秒。 OK #通过ttl命令查看一下指定Key的剩余存活时间(秒数),0表示已经过期,-1表示永不过期。 redis 127.0.0.1:6379> ttl mykey (integer) 4 redis 127.0.0.1:6379> get mykey #在该键的存活期内我们仍然可以获取到它的Value。 "hello" redis 127.0.0.1:6379> ttl mykey #该ttl命令的返回值显示,该Key已经过期。 (integer) 0 redis 127.0.0.1:6379> get mykey #获取已过期的Key将返回nil。 (nil) 5. SETNX: redis 127.0.0.1:6379> del mykey #删除该键,以便于下面的测试验证。 (integer) 1 redis 127.0.0.1:6379> setnx mykey "hello" #该键并不存在,因此该命令执行成功。 (integer) 1 redis 127.0.0.1:6379> setnx mykey "world" #该键已经存在,因此本次设置没有产生任何效果。 (integer) 0 redis 127.0.0.1:6379> get mykey #从结果可以看出,返回的值仍为第一次设置的值。 "hello" 6. SETRANGE/GETRANGE: redis 127.0.0.1:6379> set mykey "hello world" #设定初始值。 OK redis 127.0.0.1:6379> setrange mykey 6 dd #从第六个字节开始替换2个字节(dd只有2个字节) (integer) 11 redis 127.0.0.1:6379> get mykey #查看替换后的值。 "hello ddrld" redis 127.0.0.1:6379> setrange mykey 20 dd #offset已经超过该Key原有值的长度了,该命令将会在末尾补0。 (integer) 22 redis 127.0.0.1:6379> get mykey #查看补0后替换的结果。 "hello ddrld\x00\x00\x00\x00\x00\x00\x00\x00\x00dd" redis 127.0.0.1:6379> del mykey #删除该Key。 (integer) 1 redis 127.0.0.1:6379> setrange mykey 2 dd #替换空值。 (integer) 4 redis 127.0.0.1:6379> get mykey #查看替换空值后的结果。 "\x00\x00dd" redis 127.0.0.1:6379> set mykey "0123456789" #设置新值。 OK redis 127.0.0.1:6379> getrange mykey 1 2 #截取该键的Value,从第一个字节开始,到第二个字节结束。 "12" redis 127.0.0.1:6379> getrange mykey 1 20 #20已经超过Value的总长度,因此将截取第一个字节后面的所有字节。 "123456789" 7. SETBIT/GETBIT: redis 127.0.0.1:6379> del mykey (integer) 1 redis 127.0.0.1:6379> setbit mykey 7 1 #设置从0开始计算的第七位BIT值为1,返回原有BIT值0 (integer) 0 redis 127.0.0.1:6379> get mykey #获取设置的结果,二进制的0000 0001的十六进制值为0x01 "\x01" redis 127.0.0.1:6379> setbit mykey 6 1 #设置从0开始计算的第六位BIT值为1,返回原有BIT值0 (integer) 0 redis 127.0.0.1:6379> get mykey #获取设置的结果,二进制的0000 0011的十六进制值为0x03 "\x03" redis 127.0.0.1:6379> getbit mykey 6 #返回了指定Offset的BIT值。 (integer) 1 redis 127.0.0.1:6379> getbit mykey 10 #Offset已经超出了value的长度,因此返回0。 (integer) 0 8. MSET/MGET/MSETNX: redis 127.0.0.1:6379> mset key1 "hello" key2 "world" #批量设置了key1和key2两个键。 OK redis 127.0.0.1:6379> mget key1 key2 #批量获取了key1和key2两个键的值。 1) "hello" 2) "world" #批量设置了key3和key4两个键,因为之前他们并不存在,所以该命令执行成功并返回1。 redis 127.0.0.1:6379> msetnx key3 "stephen" key4 "liu" (integer) 1 redis 127.0.0.1:6379> mget key3 key4 1) "stephen" 2) "liu" #批量设置了key3和key5两个键,但是key3已经存在,所以该命令执行失败并返回0。 redis 127.0.0.1:6379> msetnx key3 "hello" key5 "world" (integer) 0 #批量获取key3和key5,由于key5没有设置成功,所以返回nil。 redis 127.0.0.1:6379> mget key3 key5 1) "stephen" 2) (nil)
3 链表操作
redis的list类型其实就是一个每个子元素都是string类型的双向链表。我们可以通过push,pop操作从链表的头部或者尾部添加删除元素。这使得list既可以用作栈,也可以用作队列。
list的pop操作还有阻塞版本的。当我们[lr]pop一个list对象是,如果list是空,或者不存在,会立即返回nil。但是阻塞版本的b[lr]pop可以则可以阻塞,当然可以加超时时间,超时后也会返回nil。为什么要阻塞版本的pop呢,主要是为了避免轮询。举个简单的例子如果我们用list来实现一个工作队列。执行任务的thread可以调用阻塞版本的pop去获取任务这样就可以避免轮询去检查是否有任务存在。当任务来时候工作线程可以立即返回,也可以避免轮询带来的延迟。
lpush key value | 把值插入到链表的头部 |
rpop key | 返回并删除链表尾部元素 |
lrange key start stop |
返回链表中的[start,stop]中的元素 规律: 左数从0开始,右数从-1开始 |
ltrim key start stop | 剪切key对应的链接,切[start,stop]一段,并把该段重新赋值给key |
lindex key value | 返回index索引的值 :lindex my andy |
llen key |
计算链表的元素个数 127.0.0.1:6379> llen my |
linsert key after|before search value |
在key 中寻找,'search',并在search值之前|之后,.插入value 一旦找到一个search,命令就结束了,因此不会插入多个value eg: 127.0.0.1:6379> LINSERT my after egon zhangsan |
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
一、概述: 在Redis中,List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,我们可以在其头部(left)和尾部(right)添加新的元素。在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。List中可以包含的最大元素数量是4294967295。 从元素插入和删除的效率视角来看,如果我们是在链表的两头插入或删除元素,这将会是非常高效的操作,即使链表中已经存储了百万条记录,该操作也可以在常量时间内完成。然而需要说明的是,如果元素插入或删除操作是作用于链表中间,那将会是非常低效的。相信对于有良好数据结构基础的开发者而言,这一点并不难理解。 二、相关命令列表: 命令原型 时间复杂度 命令描述 返回值 LPUSH key value [value ...] O(1) 在指定Key所关联的List Value的头部插入参数中给出的所有Values。如果该Key不存在,该命令将在插入之前创建一个与该Key关联的空链表,之后再将数据从链表的头部插入。如果该键的Value不是链表类型,该命令将返回相关的错误信息。 插入后链表中元素的数量。 LPUSHX key value O(1) 仅有当参数中指定的Key存在时,该命令才会在其所关联的List Value的头部插入参数中给出的Value,否则将不会有任何操作发生。 插入后链表中元素的数量。 LRANGE key start stop O(S+N) 时间复杂度中的S为start参数表示的偏移量,N表示元素的数量。该命令的参数start和end都是0-based。即0表示链表头部(leftmost)的第一个元素。其中start的值也可以为负值,-1将表示链表中的最后一个元素,即尾部元素,-2表示倒数第二个并以此类推。该命令在获取元素时,start和end位置上的元素也会被取出。如果start的值大于链表中元素的数量,空链表将会被返回。如果end的值大于元素的数量,该命令则获取从start(包括start)开始,链表中剩余的所有元素。 返回指定范围内元素的列表。 LPOP key O(1) 返回并弹出指定Key关联的链表中的第一个元素,即头部元素,。如果该Key不存,返回nil。 链表头部的元素。 LLEN key O(1) 返回指定Key关联的链表中元素的数量,如果该Key不存在,则返回0。如果与该Key关联的Value的类型不是链表,则返回相关的错误信息。 链表中元素的数量。 LREM key count value O(N) 时间复杂度中N表示链表中元素的数量。在指定Key关联的链表中,删除前count个值等于value的元素。如果count大于0,从头向尾遍历并删除,如果count小于0,则从尾向头遍历并删除。如果count等于0,则删除链表中所有等于value的元素。如果指定的Key不存在,则直接返回0。 返回被删除的元素数量。 LSET key index value O(N) 时间复杂度中N表示链表中元素的数量。但是设定头部或尾部的元素时,其时间复杂度为O(1)。设定链表中指定位置的值为新值,其中0表示第一个元素,即头部元素,-1表示尾部元素。如果索引值Index超出了链表中元素的数量范围,该命令将返回相关的错误信息。 LINDEX key index O(N) 时间复杂度中N表示在找到该元素时需要遍历的元素数量。对于头部或尾部元素,其时间复杂度为O(1)。该命令将返回链表中指定位置(index)的元素,index是0-based,表示头部元素,如果index为-1,表示尾部元素。如果与该Key关联的不是链表,该命令将返回相关的错误信息。 返回请求的元素,如果index超出范围,则返回nil。 LTRIM key start stop O(N) N表示被删除的元素数量。该命令将仅保留指定范围内的元素,从而保证链接中的元素数量相对恒定。start和stop参数都是0-based,0表示头部元素。和其他命令一样,start和stop也可以为负值,-1表示尾部元素。如果start大于链表的尾部,或start大于stop,该命令不错报错,而是返回一个空的链表,与此同时该Key也将被删除。如果stop大于元素的数量,则保留从start开始剩余的所有元素。 LINSERT key BEFORE|AFTER pivot value O(N) 时间复杂度中N表示在找到该元素pivot之前需要遍历的元素数量。这样意味着如果pivot位于链表的头部或尾部时,该命令的时间复杂度为O(1)。该命令的功能是在pivot元素的前面或后面插入参数中的元素value。如果Key不存在,该命令将不执行任何操作。如果与Key关联的Value类型不是链表,相关的错误信息将被返回。 成功插入后链表中元素的数量,如果没有找到pivot,返回-1,如果key不存在,返回0。 RPUSH key value [value ...] O(1) 在指定Key所关联的List Value的尾部插入参数中给出的所有Values。如果该Key不存在,该命令将在插入之前创建一个与该Key关联的空链表,之后再将数据从链表的尾部插入。如果该键的Value不是链表类型,该命令将返回相关的错误信息。 插入后链表中元素的数量。 RPUSHX key value O(1) 仅有当参数中指定的Key存在时,该命令才会在其所关联的List Value的尾部插入参数中给出的Value,否则将不会有任何操作发生。 插入后链表中元素的数量。 RPOP key O(1) 返回并弹出指定Key关联的链表中的最后一个元素,即尾部元素,。如果该Key不存,返回nil。 链表尾部的元素。 RPOPLPUSH source destination O(1) 原子性的从与source键关联的链表尾部弹出一个元素,同时再将弹出的元素插入到与destination键关联的链表的头部。如果source键不存在,该命令将返回nil,同时不再做任何其它的操作了。如果source和destination是同一个键,则相当于原子性的将其关联链表中的尾部元素移到该链表的头部。 返回弹出和插入的元素。 三、命令示例: 1. LPUSH/LPUSHX/LRANGE: /> redis-cli #在Shell提示符下启动redis客户端工具。 redis 127.0.0.1:6379> del mykey (integer) 1 #mykey键并不存在,该命令会创建该键及与其关联的List,之后在将参数中的values从左到右依次插入。 redis 127.0.0.1:6379> lpush mykey a b c d (integer) 4 #取从位置0开始到位置2结束的3个元素。 redis 127.0.0.1:6379> lrange mykey 0 2 1) "d" 2) "c" 3) "b" #取链表中的全部元素,其中0表示第一个元素,-1表示最后一个元素。 redis 127.0.0.1:6379> lrange mykey 0 -1 1) "d" 2) "c" 3) "b" 4) "a" #mykey2键此时并不存在,因此该命令将不会进行任何操作,其返回值为0。 redis 127.0.0.1:6379> lpushx mykey2 e (integer) 0 #可以看到mykey2没有关联任何List Value。 redis 127.0.0.1:6379> lrange mykey2 0 -1 (empty list or set) #mykey键此时已经存在,所以该命令插入成功,并返回链表中当前元素的数量。 redis 127.0.0.1:6379> lpushx mykey e (integer) 5 #获取该键的List Value的头部元素。 redis 127.0.0.1:6379> lrange mykey 0 0 1) "e" 2. LPOP/LLEN: redis 127.0.0.1:6379> lpush mykey a b c d (integer) 4 redis 127.0.0.1:6379> lpop mykey "d" redis 127.0.0.1:6379> lpop mykey "c" #在执行lpop命令两次后,链表头部的两个元素已经被弹出,此时链表中元素的数量是2 redis 127.0.0.1:6379> llen mykey (integer) 2 3. LREM/LSET/LINDEX/LTRIM: #为后面的示例准备测试数据。 redis 127.0.0.1:6379> lpush mykey a b c d a c (integer) 6 #从头部(left)向尾部(right)变量链表,删除2个值等于a的元素,返回值为实际删除的数量。 redis 127.0.0.1:6379> lrem mykey 2 a (integer) 2 #看出删除后链表中的全部元素。 redis 127.0.0.1:6379> lrange mykey 0 -1 1) "c" 2) "d" 3) "c" 4) "b" #获取索引值为1(头部的第二个元素)的元素值。 redis 127.0.0.1:6379> lindex mykey 1 "d" #将索引值为1(头部的第二个元素)的元素值设置为新值e。 redis 127.0.0.1:6379> lset mykey 1 e OK #查看是否设置成功。 redis 127.0.0.1:6379> lindex mykey 1 "e" #索引值6超过了链表中元素的数量,该命令返回nil。 redis 127.0.0.1:6379> lindex mykey 6 (nil) #设置的索引值6超过了链表中元素的数量,设置失败,该命令返回错误信息。 redis 127.0.0.1:6379> lset mykey 6 hh (error) ERR index out of range #仅保留索引值0到2之间的3个元素,注意第0个和第2个元素均被保留。 redis 127.0.0.1:6379> ltrim mykey 0 2 OK #查看trim后的结果。 redis 127.0.0.1:6379> lrange mykey 0 -1 1) "c" 2) "e" 3) "c" 4. LINSERT: #删除该键便于后面的测试。 redis 127.0.0.1:6379> del mykey (integer) 1 #为后面的示例准备测试数据。 redis 127.0.0.1:6379> lpush mykey a b c d e (integer) 5 #在a的前面插入新元素a1。 redis 127.0.0.1:6379> linsert mykey before a a1 (integer) 6 #查看是否插入成功,从结果看已经插入。注意lindex的index值是0-based。 redis 127.0.0.1:6379> lindex mykey 0 "e" #在e的后面插入新元素e2,从返回结果看已经插入成功。 redis 127.0.0.1:6379> linsert mykey after e e2 (integer) 7 #再次查看是否插入成功。 redis 127.0.0.1:6379> lindex mykey 1 "e2" #在不存在的元素之前或之后插入新元素,该命令操作失败,并返回-1。 redis 127.0.0.1:6379> linsert mykey after k a (integer) -1 #为不存在的Key插入新元素,该命令操作失败,返回0。 redis 127.0.0.1:6379> linsert mykey1 after a a2 (integer) 0 5. RPUSH/RPUSHX/RPOP/RPOPLPUSH: #删除该键,以便于后面的测试。 redis 127.0.0.1:6379> del mykey (integer) 1 #从链表的尾部插入参数中给出的values,插入顺序是从左到右依次插入。 redis 127.0.0.1:6379> rpush mykey a b c d (integer) 4 #通过lrange的可以获悉rpush在插入多值时的插入顺序。 redis 127.0.0.1:6379> lrange mykey 0 -1 1) "a" 2) "b" 3) "c" 4) "d" #该键已经存在并且包含4个元素,rpushx命令将执行成功,并将元素e插入到链表的尾部。 redis 127.0.0.1:6379> rpushx mykey e (integer) 5 #通过lindex命令可以看出之前的rpushx命令确实执行成功,因为索引值为4的元素已经是新元素了。 redis 127.0.0.1:6379> lindex mykey 4 "e" #由于mykey2键并不存在,因此该命令不会插入数据,其返回值为0。 redis 127.0.0.1:6379> rpushx mykey2 e (integer) 0 #在执行rpoplpush命令前,先看一下mykey中链表的元素有哪些,注意他们的位置关系。 redis 127.0.0.1:6379> lrange mykey 0 -1 1) "a" 2) "b" 3) "c" 4) "d" 5) "e" #将mykey的尾部元素e弹出,同时再插入到mykey2的头部(原子性的完成这两步操作)。 redis 127.0.0.1:6379> rpoplpush mykey mykey2 "e" #通过lrange命令查看mykey在弹出尾部元素后的结果。 redis 127.0.0.1:6379> lrange mykey 0 -1 1) "a" 2) "b" 3) "c" 4) "d" #通过lrange命令查看mykey2在插入元素后的结果。 redis 127.0.0.1:6379> lrange mykey2 0 -1 1) "e" #将source和destination设为同一键,将mykey中的尾部元素移到其头部。 redis 127.0.0.1:6379> rpoplpush mykey mykey "d" #查看移动结果。 redis 127.0.0.1:6379> lrange mykey 0 -1 1) "d" 2) "a" 3) "b" 4) "c"
集合set操作
代码 | 作用 |
sadd setname value1 value2 | 往集合setname中增加元素 |
srem value1 value2 |
删除集合中值为value1 value2的元素 返回值:忽略不存在的元素后,真正删除掉的元素的个数 |
spop key | 返回并删除集合中key中一个随机元素 |
srandmember key | 返回集合key中随机的一个元素 |
sismember key value |
判断value是否存在key集合中 是的话返回1 不是返回0 |
smembers key | 返回集合中的所有元素 |
scard key | 返回集合中元素的个数 |
smove source dest value |
把source中的value删除,并日安驾到dest集合中 eg:smove setname set1 andy |
sinter s1 s2 s3 |
作用: 求出s1 s2 s3 三个集合中的交集,并返回
redis 127.0.0.1:6379> sadd s1 0 2 4 6
(integer) 4
redis 127.0.0.1:6379> sadd s2 1 2 3 4
(integer) 4
redis 127.0.0.1:6379> sadd s3 4 8 9 12
(integer) 4
redis 127.0.0.1:6379> sinter s1 s2 s3
1) "4"
redis 127.0.0.1:6379> sinter s3 s1 s2
1)"4"
|
sinterstore dest s1 s2 s3 |
求出s1 s2 s3 三个集合中的交际,并赋值给dest
|
suion s1 s2 s3 |
求出s1 s2 s3 的并集,并返回
|
sdiff s1 s2 s3 | 求出s1 与s2 s3 的差集 即:s1-s2-s3 |
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1. SADD/SMEMBERS/SCARD/SISMEMBER: #在Shell命令行下启动Redis的客户端程序。 /> redis-cli #插入测试数据,由于该键myset之前并不存在,因此参数中的三个成员都被正常插入。 redis 127.0.0.1:6379> sadd myset a b c (integer) 3 #由于参数中的a在myset中已经存在,因此本次操作仅仅插入了d和e两个新成员。 redis 127.0.0.1:6379> sadd myset a d e (integer) 2 #判断a是否已经存在,返回值为1表示存在。 redis 127.0.0.1:6379> sismember myset a (integer) 1 #判断f是否已经存在,返回值为0表示不存在。 redis 127.0.0.1:6379> sismember myset f (integer) 0 #通过smembers命令查看插入的结果,从结果可以,输出的顺序和插入顺序无关。 redis 127.0.0.1:6379> smembers myset 1) "c" 2) "d" 3) "a" 4) "b" 5) "e" #获取Set集合中元素的数量。 redis 127.0.0.1:6379> scard myset (integer) 5 2. SPOP/SREM/SRANDMEMBER/SMOVE: #删除该键,便于后面的测试。 redis 127.0.0.1:6379> del myset (integer) 1 #为后面的示例准备测试数据。 redis 127.0.0.1:6379> sadd myset a b c d (integer) 4 #查看Set中成员的位置。 redis 127.0.0.1:6379> smembers myset 1) "c" 2) "d" 3) "a" 4) "b" #从结果可以看出,该命令确实是随机的返回了某一成员。 redis 127.0.0.1:6379> srandmember myset "c" #Set中尾部的成员b被移出并返回,事实上b并不是之前插入的第一个或最后一个成员。 redis 127.0.0.1:6379> spop myset "b" #查看移出后Set的成员信息。 redis 127.0.0.1:6379> smembers myset 1) "c" 2) "d" 3) "a" #从Set中移出a、d和f三个成员,其中f并不存在,因此只有a和d两个成员被移出,返回为2。 redis 127.0.0.1:6379> srem myset a d f (integer) 2 #查看移出后的输出结果。 redis 127.0.0.1:6379> smembers myset 1) "c" #为后面的smove命令准备数据。 redis 127.0.0.1:6379> sadd myset a b (integer) 2 redis 127.0.0.1:6379> sadd myset2 c d (integer) 2 #将a从myset移到myset2,从结果可以看出移动成功。 redis 127.0.0.1:6379> smove myset myset2 a (integer) 1 #再次将a从myset移到myset2,由于此时a已经不是myset的成员了,因此移动失败并返回0。 redis 127.0.0.1:6379> smove myset myset2 a (integer) 0 #分别查看myset和myset2的成员,确认移动是否真的成功。 redis 127.0.0.1:6379> smembers myset 1) "b" redis 127.0.0.1:6379> smembers myset2 1) "c" 2) "d" 3) "a" 3. SDIFF/SDIFFSTORE/SINTER/SINTERSTORE: #为后面的命令准备测试数据。 redis 127.0.0.1:6379> sadd myset a b c d (integer) 4 redis 127.0.0.1:6379> sadd myset2 c (integer) 1 redis 127.0.0.1:6379> sadd myset3 a c e (integer) 3 #myset和myset2相比,a、b和d三个成员是两者之间的差异成员。再用这个结果继续和myset3进行差异比较,b和d是myset3不存在的成员。 redis 127.0.0.1:6379> sdiff myset myset2 myset3 1) "d" 2) "b" #将3个集合的差异成员存在在diffkey关联的Set中,并返回插入的成员数量。 redis 127.0.0.1:6379> sdiffstore diffkey myset myset2 myset3 (integer) 2 #查看一下sdiffstore的操作结果。 redis 127.0.0.1:6379> smembers diffkey 1) "d" 2) "b" #从之前准备的数据就可以看出,这三个Set的成员交集只有c。 redis 127.0.0.1:6379> sinter myset myset2 myset3 1) "c" #将3个集合中的交集成员存储到与interkey关联的Set中,并返回交集成员的数量。 redis 127.0.0.1:6379> sinterstore interkey myset myset2 myset3 (integer) 1 #查看一下sinterstore的操作结果。 redis 127.0.0.1:6379> smembers interkey 1) "c" #获取3个集合中的成员的并集。 redis 127.0.0.1:6379> sunion myset myset2 myset3 1) "b" 2) "c" 3) "d" 4) "e" 5) "a" #将3个集合中成员的并集存储到unionkey关联的set中,并返回并集成员的数量。 redis 127.0.0.1:6379> sunionstore unionkey myset myset2 myset3 (integer) 5 #查看一下suiionstore的操作结果。 redis 127.0.0.1:6379> smembers unionkey 1) "b" 2) "c" 3) "d" 4) "e" 5) "a"
5. 有序集合order set操作
代码 | 作用 |
zadd s1 score1 value1 score2 value2 .. |
添加有序集合 eg: redis 127.0.0.1:6379> zadd stu 18 lily 19 hmm 20 lilei 21 lilei
(integer) 3
|
zrem s1 value1 value2 | 删除集合中的元素 |
zremrangebyscore sname min max |
作用: 按照socre来删除元素,删除score在[min,max]之间的
redis 127.0.0.1:6379> zremrangebyscore stu 4 10
(integer) 2
redis 127.0.0.1:6379> zrange stu 0 -1
1) "f"
|
zremrangebyrank sname start end |
作用: 按排名删除元素,删除名次在[start,end]之间的
redis 127.0.0.1:6379> zremrangebyrank stu 0 1
(integer) 2
redis 127.0.0.1:6379> zrange stu 0 -1
1) "c"
2) "e"
3) "f"
4) "g"
|
zrank key member | 查询member的排名(升序, 0开始) |
zrevrank key memeber | 查询 member的排名(降序 0名开始 |
zrange key start stop[WITHSCORES] |
把集合排序后,返回名次[start,stop]的元素
默认是升续排列
Withscores 是把score也打印出来
|
zrevrange key start stop | 作用:把集合降序排列,取名字[start,stop]之间的元素 |
zrangebyscore key min max [withscores] limit offset N |
作用: 集合(升续)排序后,取score在[min,max]内的元素,
并跳过 offset个, 取出N个
redis 127.0.0.1:6379> zadd stu 1 a 3 b 4 c 9 e 12 f 15 g
(integer) 6
redis 127.0.0.1:6379> zrangebyscore stu 3 12 limit 1 2 withscores
1) "c"
2) "4"
3) "e"
4) "9
|
zcard key | 返回元素个数 |
zcount key min max | 返回[min,max]遇见内元素的数量 |
6. Hash数据结构操作
hset key field value |
把hash表中,field域中的值设为value 如果没有field域,直接添加,如果有,则覆盖field域的值 |
hmset key field1 value1 [field2 value2 field3 value3 ……fieldn valuen] |
作用: 设置field1->N 个域, 对应的值是value1->N
(对应PHP理解为 $key = array(file1=>value1, field2=>value2 ....fieldN=>valueN))
|
hget key field | 返回key中field域的值 |
hmget key field1 field2 fieldN | 返回key中field1 field2 fieldN域中的值 |
hgetall key | 返回key中,所有与与其值 |
hdel key field | 删除key中,field域 |
hlen key | 返回key中元素的数量 |
hexists key field | 判断key中有没有field域 |
hincrby key field value | 是把key中的field域的值增长长整型值value |
hincrby float key field value | 是吧key中的field域的值增长浮点值value |
hkeys key | 返回key中所有的field |
hvals key | 返回key中所有的value |
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1. HSET/HGET/HDEL/HEXISTS/HLEN/HSETNX: #在Shell命令行启动Redis客户端程序 /> redis-cli #给键值为myhash的键设置字段为field1,值为stephen。 redis 127.0.0.1:6379> hset myhash field1 "stephen" (integer) 1 #获取键值为myhash,字段为field1的值。 redis 127.0.0.1:6379> hget myhash field1 "stephen" #myhash键中不存在field2字段,因此返回nil。 redis 127.0.0.1:6379> hget myhash field2 (nil) #给myhash关联的Hashes值添加一个新的字段field2,其值为liu。 redis 127.0.0.1:6379> hset myhash field2 "liu" (integer) 1 #获取myhash键的字段数量。 redis 127.0.0.1:6379> hlen myhash (integer) 2 #判断myhash键中是否存在字段名为field1的字段,由于存在,返回值为1。 redis 127.0.0.1:6379> hexists myhash field1 (integer) 1 #删除myhash键中字段名为field1的字段,删除成功返回1。 redis 127.0.0.1:6379> hdel myhash field1 (integer) 1 #再次删除myhash键中字段名为field1的字段,由于上一条命令已经将其删除,因为没有删除,返回0。 redis 127.0.0.1:6379> hdel myhash field1 (integer) 0 #判断myhash键中是否存在field1字段,由于上一条命令已经将其删除,因为返回0。 redis 127.0.0.1:6379> hexists myhash field1 (integer) 0 #通过hsetnx命令给myhash添加新字段field1,其值为stephen,因为该字段已经被删除,所以该命令添加成功并返回1。 redis 127.0.0.1:6379> hsetnx myhash field1 stephen (integer) 1 #由于myhash的field1字段已经通过上一条命令添加成功,因为本条命令不做任何操作后返回0。 redis 127.0.0.1:6379> hsetnx myhash field1 stephen (integer) 0 2. HINCRBY: #删除该键,便于后面示例的测试。 redis 127.0.0.1:6379> del myhash (integer) 1 #准备测试数据,该myhash的field字段设定值1。 redis 127.0.0.1:6379> hset myhash field 5 (integer) 1 #给myhash的field字段的值加1,返回加后的结果。 redis 127.0.0.1:6379> hincrby myhash field 1 (integer) 6 #给myhash的field字段的值加-1,返回加后的结果。 redis 127.0.0.1:6379> hincrby myhash field -1 (integer) 5 #给myhash的field字段的值加-10,返回加后的结果。 redis 127.0.0.1:6379> hincrby myhash field -10 (integer) -5 3. HGETALL/HKEYS/HVALS/HMGET/HMSET: #删除该键,便于后面示例测试。 redis 127.0.0.1:6379> del myhash (integer) 1 #为该键myhash,一次性设置多个字段,分别是field1 = "hello", field2 = "world"。 redis 127.0.0.1:6379> hmset myhash field1 "hello" field2 "world" OK #获取myhash键的多个字段,其中field3并不存在,因为在返回结果中与该字段对应的值为nil。 redis 127.0.0.1:6379> hmget myhash field1 field2 field3 1) "hello" 2) "world" 3) (nil) #返回myhash键的所有字段及其值,从结果中可以看出,他们是逐对列出的。 redis 127.0.0.1:6379> hgetall myhash 1) "field1" 2) "hello" 3) "field2" 4) "world" #仅获取myhash键中所有字段的名字。 redis 127.0.0.1:6379> hkeys myhash 1) "field1" 2) "field2" #仅获取myhash键中所有字段的值。 redis 127.0.0.1:6379> hvals myhash 1) "hello" 2) "world"
一篇讲的不错的redis文章