Redis命令总结

Redis命令总结

Redis提供了丰富的命令(command)对数据库和各种数据类型进行操作,这些command可以在Linux终端使用。在编程时,比如使用Redis 的Java语言包,这些命令都有对应的方法,比如上面例子中使用的sadd方法,就是对集合操作中的SADD命令。下面将Redis提供的命令做一总结。

连接操作相关的命令

Ÿ   quit:关闭连接(connection)

Ÿ   auth:简单密码认证

对value操作的命令

Ÿ   exists(key):确认一个key是否存在

Ÿ   del(key):删除一个key

Ÿ   type(key):返回值的类型

Ÿ   keys(pattern):返回满足给定pattern的所有key

Ÿ   randomkey:随机返回key空间的一个key

Ÿ   rename(oldnamenewname):将key由oldname重命名为newname,若newname存在则删除newname表示的key

Ÿ   dbsize:返回当前数据库中key的数目

Ÿ   expire:设定一个key的活动时间(s)

Ÿ   ttl:获得一个key的活动时间

Ÿ   select(index):按索引查询

Ÿ   move(keydbindex):将当前数据库中的key转移到有dbindex索引的数据库

Ÿ   flushdb:删除当前选择数据库中的所有key

Ÿ   flushall:删除所有数据库中的所有key

对String操作的命令

Ÿ   set(key, value):给数据库中名称为key的string赋予值value

Ÿ   get(key):返回数据库中名称为key的string的value

Ÿ   getset(key, value):给名称为key的string赋予上一次的value

Ÿ   mget(key1, key2,…, key N):返回库中多个string(它们的名称为key1,key2…)的value

Ÿ   setnx(key, value):如果不存在名称为key的string,则向库中添加string,名称为key,值为value

Ÿ   setex(keytimevalue):向库中添加string(名称为key,值为value)同时,设定过期时间time

Ÿ   mset(key1, value1, key2, value2,…key N, value N):同时给多个string赋值,名称为key i的string赋值value i

Ÿ   msetnx(key1, value1, key2, value2,…key N, value N):如果所有名称为keyi的string都不存在,则向库中添加string,名称key i赋值为value i

Ÿ   incr(key):名称为key的string增1操作

Ÿ   incrby(key, integer):名称为key的string增加integer

Ÿ   decr(key):名称为key的string减1操作

Ÿ   decrby(key, integer):名称为key的string减少integer

Ÿ   append(key, value):名称为key的string的值附加value

Ÿ   substr(key, start, end):返回名称为key的string的value的子串

对List操作的命令

Ÿ   rpush(key, value):在名称为key的list尾添加一个值为value的元素

Ÿ   lpush(key, value):在名称为key的list头添加一个值为value的 元素

Ÿ   llen(key):返回名称为key的list的长度

Ÿ   lrange(key, start, end):返回名称为key的list中start至end之间的元素(下标从0开始,下同)

Ÿ   ltrim(key, start, end):截取名称为key的list,保留start至end之间的元素

Ÿ   lindex(key, index):返回名称为key的list中index位置的元素

Ÿ   lset(key, index, value):给名称为key的list中index位置的元素赋值为value

Ÿ   lrem(key, count, value):删除count个名称为key的list中值为value的元素。count为0,删除所有值为value的元素,count>0从头至尾删除count个值为value的元素,count<0从尾到头删除|count|个值为value的元素。

Ÿ   lpop(key):返回并删除名称为key的list中的首元素

Ÿ   rpop(key):返回并删除名称为key的list中的尾元素

Ÿ   blpop(key1, key2,… key N, timeout):lpop命令的block版本。即当timeout为0时,若遇到名称为key i的list不存在或该list为空,则命令结束。如果timeout>0,则遇到上述情况时,等待timeout秒,如果问题没有解决,则对key i+1开始的list执行pop操作。

Ÿ   brpop(key1, key2,… key N, timeout):rpop的block版本。参考上一命令。

Ÿ   rpoplpush(srckey, dstkey):返回并删除名称为srckey的list的尾元素,并将该元素添加到名称为dstkey的list的头部

对Set操作的命令

Ÿ   sadd(key, member):向名称为key的set中添加元素member

Ÿ   srem(key, member:删除名称为key的set中的元素member

Ÿ   spop(key:随机返回并删除名称为key的set中一个元素

Ÿ   smove(srckey, dstkey, member) :将member元素从名称为srckey的集合移到名称为dstkey的集合

Ÿ   scard(key:返回名称为key的set的基数

Ÿ   sismember(key, member) :测试member是否是名称为key的set的元素

Ÿ   sinter(key1, key2,…key N:求交集

Ÿ   sinterstore(dstkey, key1, key2,…key N:求交集并将交集保存到dstkey的集合

Ÿ   sunion(key1, key2,…key N:求并集

Ÿ   sunionstore(dstkey, key1, key2,…key N) :求并集并将并集保存到dstkey的集合

Ÿ   sdiff(key1, key2,…key N:求差集

Ÿ   sdiffstore(dstkey, key1, key2,…key N) :求差集并将差集保存到dstkey的集合

Ÿ   smembers(key) :返回名称为key的set的所有元素

Ÿ   srandmember(key) :随机返回名称为key的set的一个元素

对zset(sorted set)操作的命令

Ÿ   zadd(key, score, member):向名称为key的zset中添加元素member,score用于排序。如果该元素已经存在,则根据score更新该元素的顺序。

Ÿ   zrem(key, member) :删除名称为key的zset中的元素member

Ÿ   zincrby(key, increment, member:如果在名称为key的zset中已经存在元素member,则该元素的score增加increment;否则向集合中添加该元素,其score的值为increment

Ÿ   zrank(key, member:返回名称为key的zset(元素已按score从小到大排序)中member元素的rank(即index,从0开始),若没有member元素,返回"nil"

Ÿ   zrevrank(key, member:返回名称为key的zset(元素已按score从大到小排序)中member元素的rank(即index,从0开始),若没有member元素,返回"nil"

Ÿ   zrange(key, start, end):返回名称为key的zset(元素已按score从小到大排序)中的index从start到end的所有元素

Ÿ   zrevrange(key, start, end):返回名称为key的zset(元素已按score从大到小排序)中的index从start到end的所有元素

Ÿ   zrangebyscore(key, min, max):返回名称为key的zset中score >= min且score <= max的所有元素

Ÿ   zcard(key):返回名称为key的zset的基数

Ÿ   zscore(key, element):返回名称为key的zset中元素element的score

Ÿ   zremrangebyrank(key, min, max):删除名称为key的zset中rank >= min且rank <= max的所有元素

Ÿ   zremrangebyscore(key, min, max) :删除名称为key的zset中score >= min且score <= max的所有元素

Ÿ   zunionstore / zinterstore(dstkeyNkey1,…,keyN, WEIGHTS w1,…wN,AGGREGATE SUM|MIN|MAX):对N个zset求并集和交集,并将最后的集合保存在dstkeyN中。对于集合中每一个元素的score,在进行AGGREGATE运算前,都要乘以对于的WEIGHT参数。如果没有提供WEIGHT,默认为1。默认的AGGREGATE是SUM,即结果集合中元素的score是所有集合对应元素进行SUM运算的值,而MIN和MAX是指,结果集合中元素的score是所有集合对应元素中最小值和最大值。

对Hash操作的命令

Ÿ   hset(key, field, value):向名称为key的hash中添加元素field<—>value

Ÿ   hget(key, field):返回名称为key的hash中field对应的value

Ÿ   hmget(key, field1, …,field N):返回名称为key的hash中field i对应的value

Ÿ   hmset(key, field1, value1,…,field N, value N):向名称为key的hash中添加元素field i<—>value i

Ÿ   hincrby(key, field, integer):将名称为key的hash中field的value增加integer

Ÿ   hexists(key, field):名称为key的hash中是否存在键为field的域

Ÿ   hdel(key, field):删除名称为key的hash中键为field的域

Ÿ   hlen(key):返回名称为key的hash中元素个数

Ÿ   hkeys(key):返回名称为key的hash中所有键

Ÿ   hvals(key):返回名称为key的hash中所有键对应的value

Ÿ   hgetall(key):返回名称为key的hash中所有的键(field)及其对应的value

持久化

Ÿ   save:将数据同步保存到磁盘

Ÿ   bgsave:将数据异步保存到磁盘

Ÿ   lastsave:返回上次成功将数据保存到磁盘的Unix时戳

Ÿ   shundown:将数据同步保存到磁盘,然后关闭服务

远程服务控制

Ÿ   info:提供服务器的信息和统计

Ÿ   monitor:实时转储收到的请求

Ÿ   slaveof:改变复制策略设置

Ÿ   config:在运行时配置Redis服务器

 

 

 

在192.168.134.96 上安装了redis的master

在192.168.134.97 上安装了slave 绑定了192.168.134.96

 

11 redis事务

redis对事务的支持目前还比较简单。redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。由于redis是单线程来处理所有client的请求的所以做到这点是很容易的。一般情况下redis在接受到一个client发来的命令后会立即处理并返回处理结果,但是当一个client在一个连接中发出multi命令有,这个连接会进入一个事务上下文,该连接后续的命令并不是立即执行,而是先放到一个队列中。当从此连接受到exec命令后,redis会顺序的执行队列中的所有命令。并将所有命令的运行结果打包到一起返回给client.然后此连接就结束事务上下文。下面可以看一个例子

redis> multi
OK
redis> incr a
QUEUED
redis> incr b
QUEUED
redis> exec
1. (integer) 1
2. (integer) 1

从这个例子我们可以看到incr a ,incr b命令发出后并没执行而是被放到了队列中。调用exec后俩个命令被连续的执行,最后返回的是两条命令执行后的结果
我们可以调用discard命令来取消一个事务。接着上面例子

redis> multi
OK
redis> incr a
QUEUED
redis> incr b
QUEUED
redis> discard
OK
redis> get a
"1"
redis> get b
"1"

可以发现这次incr a incr b都没被执行。discard命令其实就是清空事务的命令队列并退出事务上下文。
  
虽说redis事务在本质上也相当于序列化隔离级别的了。但是由于事务上下文的命令只排队并不立即执行,所以事务中的写操作不能依赖事务中的读操作结果。看下面例子

redis> multi
OK
redis> get a
QUEUED
redis> get b
QUEUED
redis> exec
1. "1"
2. "1"

发现问题了吧。假如我们想用事务实现incr操作怎么办?可以这样做吗?

redis> get a
"1"
redis> multi
OK
redis> set a 2
QUEUED
redis> exec
1. OK
redis> get a

"2"

结论很明显这样是不行的。这样和 get a 然后直接set a是没区别的。很明显由于get a set a并不能保证两个命令是连续执行的(get操作不在事务上下文中)。很可能有两个client同时做这个操作。结果我们期望是加两次a从原来的1变成3. 但是很有可能两个clientget a,取到都是1,造成最终加两次结果却是2。主要问题我们没有对共享资源a的访问进行任何的同步
也就是说redis没提供任何的加锁机制来同步对a的访问。
还好redis 2.1后添加了watch命令,可以用来实现乐观锁。看个正确实现incr命令的例子,只是在前面加了watch a

redis> watch a
OK
redis> get a
"1"
redis> multi
OK
redis> set a 2
QUEUED
redis> exec
1. OK
redis> get a

"2"

watch 命令会监视给定的key,exec时候如果监视的key从调用watch后发生过变化,则整个事务会失败。也可以调用watch多次监视多个key.样就可以对指定的key加乐观锁了。注意watchkey是对整个连接有效的,事务也一样。如果连接断开,监视和事务都会被自动清除。当然了exec,discard,unwatch命令都会清除连接中的所有监视.
redis
的事务实现是如此简单,当然会存在一些问题。第一个问题是redis只能保证事务的每个命令连续执行,但是如果事务中的一个命令失败了,并不回滚其他命令,比如使用的命令类型不匹配。

redis> set a 5
OK
redis> lpush b 5
(integer) 1
redis> set c 5
OK
redis> multi
OK
redis> incr a
QUEUED
redis> incr b
QUEUED
redis> incr c
QUEUED
redis> exec
1. (integer) 6
2. (error) ERR Operation against a key holding the wrong kind of value
3. (integer) 6

可以看到虽然incr b失败了,但是其他两个命令还是执行了。
后一个十分罕见的问题是当事务的执行过程中,如果redis意外的挂了。很遗憾只有部分命令执行了,后面的也就被丢弃了。当然如果我们使用的append-only file方式持久化,redis会用单个write操作写入整个事务内容。即是是这种方式还是有可能只部分写入了事务到磁盘。发生部分写入事务的情况下,redis重启时会检测到这种情况,然后失败退出。可以使用redis-check-aof工具进行修复,修复会删除部分写入的事务内容。修复完后就能够重新启动了。

12 redis的持久化

redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到磁盘来保证持久化。redis支持两种持久化方式,一种是 Snapshotting(快照)也是默认方式,另一种是Append-only file(缩写aof)的方式。下面分别介绍
Snapshotting
       
快照是默认的持久化方式。这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。可以通过配置设置自动做快照持久化的方式。我们可以配置redisn秒内如果超过mkey被修改就自动做快照,下面是默认的快照保存配置
save 900 1  #900
秒内如果超过1key被修改,则发起快照保存
save 300 10 #300
秒内容如超过10key被修改,则发起快照保存
save 60 10000
下面介绍详细的快照保存过程
1.redis
调用fork,现在有了子进程和父进程。
2. 
父进程继续处理client请求,子进程负责将内存内容写入到临时文件。由于os的写时复制机制(copy on write)父子进程会共享相同的物理页面,当父进程处理写请求时os会为父进程要修改的页面创建副本,而不是写共享的页面。所以子进程的地址空间内的数据是fork时刻整个数据库的一个快照。
3.
当子进程将快照写入临时文件完毕后,用临时文件替换原来的快照文件,然后子进程退出。
client 
也可以使用save或者bgsave命令通知redis做一次快照持久化。save操作是在主线程中保存快照的,由于redis是用一个主线程来处理所有 client的请求,这种方式会阻塞所有client请求。所以不推荐使用。另一点需要注意的是,每次快照持久化都是将内存数据完整写入到磁盘一次,并不是增量的只同步脏数据。如果数据量大的话,而且写操作比较多,必然会引起大量的磁盘io操作,可能会严重影响性能。
另外由于快照方式是在一定间隔时间做一次的,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。如果应用要求不能丢失任何修改的话,可以采用aof持久化方式。下面介绍
Append-only file
aof 
比快照方式有更好的持久化性,是由于在使用aof持久化方式时,redis会将每一个收到的写命令都通过write函数追加到文件中(默认是 appendonly.aof)。当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。当然由于os会在内核中缓存 write做的修改,所以可能不是立即写到磁盘上。这样aof方式的持久化也还是有可能会丢失部分修改。不过我们可以通过配置文件告诉redis我们想要通过fsync函数强制os写入到磁盘的时机。有三种方式如下(默认是:每秒fsync一次)
appendonly yes              //
启用aof持久化方式
# appendfsync always      //
每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
appendfsync everysec     //
每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
# appendfsync no    //
完全依赖os,性能最好,持久化没保证
aof 
的方式也同时带来了另一个问题。持久化文件会变的越来越大。例如我们调用incr test命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的。因为要恢复数据库的状态其实文件中保存一条set test 100就够了。为了压缩aof的持久化文件。redis提供了bgrewriteaof命令。收到此命令redis将使用与快照类似的方式将内存中的数据以命令的方式保存到临时文件中,最后替换原来的文件。具体过程如下
1. redis
调用fork ,现在有父子两个进程
2. 
子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令
3.
父进程继续处理client请求,除了把写命令写入到原来的aof文件中。同时把收到的写命令缓存起来。这样就能保证如果子进程重写失败的话并不会出问题。
4.
当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件。
5.
现在父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加。
需要注意到是重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。

 

 

参照:

http://www.redis.io/

http://cocos.iteye.com/blog/1050291

http://www.cnblogs.com/liping13599168/archive/2011/04/14/2016226.html

知识塑造人生,程序缔造世界。 7年半工作经验,包括2年产品经验,5年半开发经验,半年团队经验。 深知最好的学习资料是官方提供文档以及经验积累。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值