Redis数据库笔记

1.redis是什么?
  redis(REmote DIctionary Server)是一种使用C语言开发的NOSQL,即非关系数据库;Redis是一个操作数据结构的语言工具是一种内存数据库或者数据结构服务器,将数据直接保存在内存中,但又提供了持久化支持;是一种键值对数据库,保存的是键值对数据,相当于保存了一个变量及变量的值;以字典结构存储数据,并允许其他应用通过TCP协议读写字典中的内容;是Memcached缓存服务器的替代者。
2.redis可以用来做什么?
  数据库、队列、缓存系统,新浪微博大量使用了redis.Key-Value Store 是当下比较流行的话题,尤其在构建诸如搜索引擎、IM、P2P、游戏服务器、SNS等大型互联网应用以及提供云计算服务的时候,保证系统在海量数据环境下的高性能、高可靠性、高扩展性、高可用性、低成本.
适用场合:
a.取最新 N 个数据的操作
b.排行榜应用,取 TOP N 操作
c.需要精准设定过期时间的应用
d.计数器应用 INCR DECR
e.Uniq 操作,获取某段时间所有数据排重值
f.实时系统,反垃圾系统 SET集合
g.Pub/Sub 构建实时消息系统
h.构建队列系统
i.缓存
3.redis与memcashed的优劣
 在性能上Redis是单线程模型,而Memcached支持多线程,所以在多核服务器上后者的性能更高一些。然而,前面已经介绍过,Redis的性能已经足够优异,在绝大部分场合下其性能都不会成为瓶颈。所以在使用时更应该关心的是二者在功能上的区别,如果需要用到高级的数据类型或是持久化等功能,Redis将会是Memcached很好的替代品。
 作为缓存系统,Redis还可以限定数据占用的最大内存空间,在数据达到空间限制后可以按照一定的规则自动淘汰不需要的键。
 除此之外,Redis的列表类型键可以用来实现队列,并且支持阻塞式读取,可以很容易地实现一个高性能的优先级队列。同时在更高层面上,Redis还支持“发布/订阅”的消息模式,可以基于此构建聊天室等系统。
4.redis安装与启动
redis官方只提供了POSIX系统版的redis版本,http://download.redis.io/redis-stable.tar.gz可以下载最新的稳定版。redis没有其它外部依赖。在window中安装,需要使用cygwin环境。
服务器端启动:
>redis-server         :直接启动,默认端口6379
>redis-server --port 6380       :指定端口上启动
>redis-server redis.conf        :启动时使用配置文件初始化,redis.conf 位于安装文件中。
>redis-cli   SHUTDOWN           :安全终止redis服务器
客户端启动:
>redis-cli  -h 127.0.0.1 -p 6379     :客户端启动并连接服务器
5.redis命令执行的返回值(5种)
a.状态回复  回复命令的执行状态,如set和PING的回复
b.错误回复  命令执行错误,回复形式为:(error)...
c.整数回复  redis虽然没有整数类型,但提供了一组用于字符整数操作的命令,这些命令的回复返回整数,如INCR,DBSIZE ,回复形式为:(integer) n
e.字符串回复  当请求一个字符串类型键的键值或一个其他类型键中的某个元素时就会得到一个字符串回复,如GET,回复形式为:“...”
f.多行字符串回复  如KEYS命令,回复时会添加字符串行号。
6.redis的多数据库
如mysql可以建立多个数据库一样,redis可以建立的数据库个数通过redis.conf中的databases来配置,默认为16个,数据库号从0-15,不支持自定义数据库名称。客户端redis-cli与Redis建立连接后会自动选择0号数据库,不过可以随时使用SELECT n命令更换数据库。
7.常用命令
KEYS glob_pattern     :查询当前数据库中所有的键glob_pattern : ?,*,[],\x
EXISTS key   :判断一个键是否存在,存在返回1,否则0
DEL key [key …] :删除一个或多个键
TYPE key  :返回key键的数据类型
EXPIRE key time  :设置一个键的过期时间
PERSIST key  :移除该键的过期时间
MOVE key n  :将当前数据库的key键移动到n号数据库
SELECT n  :选择n号数据库作为当前数据库,0-15
RANDOMKEY  :随机返回当前数据库的一个键
RENAME key newkey :重命名一个key
  服务器相关命令
PING   :测试连接是否存活
ECHO "..."  :在命令行打印一行内容
QUIT   :退出连接
DBSIZE   :返回当前数据库中键的个数
INFO   :返回服务器的信息和统计
MONITOR   :实时转储收到的请求
CONFIG GET dir  :获取服务器配置信息
FLUSHDB   :删除当前数据库中的所有key
FLUSHALL  :删除所有数据库中的key

8.redis的5大数据(键)类型
字符串(string)、散列(hash)、列表(list)、集合(set)、有序集合(zset),每一个键都是这5种数据类型中的一种,根据键的创建方式不同来决定属于哪种类型。Redis不支持数据类型嵌套。列表(list)、集合(set)、有序集合键只能保存字符串类型的数据。
a.字符串类型:一个字符串类型键允许存储的数据的最大容量是512MB。字符串类型是其他4种数据类型的基础,其他数据类型和字符串类型的差别从某种角度来说只是组织字符串的形式不同。例如,列表类型是以列表的形式组织字符串,而集合类型是以集合的形式组织字符串。
命令:
对字符串的操作
SET key value  :创建字符串变量并赋值
GET key   :当键不存在时会返回空结果。
SETNX key value  :如果键key不存在,则设置该键;存在则返回0,不进行设置
SETEX key time value  :设置键key的同时指定该键的有效期为time,可以使用TTL查看
SETRANGE key start jointvalue :将键key从第8个字符起,替换为jointvalue
APPEND key value  :向一个字符串的尾部增加值
STRLEN key   :获取字符串长度
MSET key value [key value …] :同时设置多个键的值
MGET key [key …]  :同时获取多个键的值
MSETNX key value [key value …] :当失败时,一个键也不会被设置
GETSET key value  :设置并返回key的值
GETRANGE key start end  :返回key字符串中从start到end的子窜
对实数字符串的操作
INCR key   :递增数字,对非数字递增将返回错误
INCRBY key increment  :按指定数字增加
DECR key  :递减数字
DECRBY key decrement :按指定数字递减
INCRBYFLOAT key increment :对浮点数加
对字符串进行位操作的4大命令(是内存意义上的二进制位的操作)
GETBIT key offset  :获取字符串中总第offset位的二进制值
SETBIT key offset value  :设置字符串中总第offset位的二进制值
BITCOUNT key [m] [n]  :统一字符串中从第m字节到第n字节中的二进制数中的1的个数
BITOP operation destkey key [key …]:BITOP命令可以对多个字符串类型键进行位运算,并将结果存储在destkey参数指定的键中。BITOP命令支持的运算操作有AND、OR、XOR 和NOT
b.散列类型(python中的字典类型)
散列类型(hash)的键值是一种字典结构,其存储了字段(field)和字段值的映射,但字段值只能是字符串,不支持其他数据类型,一个散列类型键可以包含
至多232-1个字段。
赋值与取值:
HSET key field value   :设置该键指定字段的值
HGET key field    :获取该键指定字段的值
HMSET key field value [field value …] :设置该键多个字段的值
HMGET key field [field …]  :获取该键多个字段的值
HGETALL key    :获取该键所有字段名及域值
HKEYS key    :获取该键所有字段名
HVALS key    :获取该键所有字段的值
HLEN key    :获取该键字段的个数
     
HEXISTS key field   :判断该键中是否存在某个字段
HSETNX key field value   :该字段不存在时赋值
HINCRBY key field increment  :对数字字符串加increment  
HDEL key field [field …]  :删除字段

c.列表类型(双端链表)
向列表两端压入和弹出元素
LPUSH key value [value …]  :向列表左端添加元素
RPUSH key value [value …]  :向列表右端添加元素
LPOP key    :由列表左端弹出元素
RPOP key    :由列表右端弹出元素
LLEN key    :获取列表中元素的个数
LRANGE key start stop   :获得列表片段,-1,最后一个元素,-2倒数第二个元素
LREM key count value   :当count>会从左边删除列表中前count个值为value的元素,返回值是实际删除的元素个数;当count<0从右边起删除;count=0,会删除所有值为value的元素。
LINDEX key index   :获得指定索引的元素值,支持负索引
LSET key index value   :设置指定索引的元素值
LTRIM key start end   :只保留列表指定片段
LINSERT key BEFORE|AFTER pivot value :从左到右查找值为pivot的元素,将value插入到该元素的BEFORE或AFTER
RPOPLPUSH source destination  :将元素从一个列表的右边弹出转到另一个列表的左边

d.集合(存储不相同的字符串)
在集合中的每个元素都是不同的,且没有顺序。一个集合类型(set)键可以存储至多2次方32-1个(相信这个数字对大家来说已经很熟悉了)字符串。集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在等,由于集合类型在Redis内部是使用值为空的散列表(hash table)实现的,所以这些操作的时间复杂度都是0(1)。最方便的是多个集合类型键之间还可以进行并集、交集和差集运算。
SADD key member [member …]  :增加元素
SREM key member [member …]  :删除元素
SMEMBERS key    :获得集合中的所有元素
SISMEMBER key member   :判断元素是否在集合中
SDIFF key [key …]   :差集
SINTER key [key …]   :交集
SUNION key [key …]   :并集
SCARD key    :获得集合中元素个数
SDIFFSTORE destination key [key …] :进行集合运算并将结果存储
SINTERSTORE destination key [key …]
SUNIONSTORE destination key [key …]
SRANDMEMBER key [count]   :随机获得集合中的元素(默认1个)当count为正数时,SRANDMEMBER会随机从集合里获得count个不重复的元素。如果count的值大于集合中的元素个数,则SRANDMEMBER会返回集合中的全部元素;)当count为负数时,SRANDMEMBER会随机从集合里获得|count|个的元素,这些元素有可能相同。
SPOP key    :从集合中弹出一个元素
SMOVE source destination value  :将键source中的value移动到destination中。
e.有序集合类型(sorted set)
在集合类型的基础上有序集合类型为集合中的每个元素都关联了一个分数,这使得我们不仅可以完成插入、删除和判断元素是否存在等集合类型支持的操作,还能够获得分数最高(或最低)的前N个元素、获得指定分数范围内的元素等与分数有关的操作。虽然集合中每个元素都是不同的,但是它们的分数却可以相同。
 有序集合类型在某些方面和列表类型有些相似。
(1)二者都是有序的。
(2)二者都可以获得某一范围的元素。
但是二者有着很大的区别,这使得它们的应用场景也是不同的。
(1)列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会较慢,所以它更加适合实现如“新鲜事”或“日志”这样很少访问中间元素的应用。
(2)有序集合类型是使用散列表和跳跃表(Skip list)实现的,所以即使读取位于中间部分的数据速度也很快(时间复杂度是O(log(N)))。
(3)列表中不能简单地调整某个元素的位置,但是有序集合可以(通过更改这个元素的分数)。
(4)有序集合要比列表类型更耗费内存
有序集合类型算得上是 Redis的5种数据类型中最高级的类型。

ZADD key score member [score member …] :增加元素,score可以是任意实数
ZSCORE key member   :获得指定元素的分数
ZRANGE key start stop [WITHSCORES] :获得排名在某个范围的元素列表(升序),如前三ZRANGE key 0 2 ,[WITHSCORES]返回member的同时返回分数
ZREVRANGE key start stop [WITHSCORES] :按分数降序返回
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] :获得指定分数范围的成员(升序),[LIMIT offset count]从offset成员开始,返回count个成员
例 ZRANGEBYSCORE scoreboard (80 +inf LIMIT 5 3   返回80以上(不包括80)的从第5个人开始的3个人
Z INCRBY key increment member   :增加某个元素的分数,increment可以为负
ZCARD key    :获得集合中元素的个数
ZCOUNT key min max   :获得指定分数范围內的元素个数
ZREM key member [member …]  :删除一个或多个元素
ZREMRANGEBYRANK key start stop  :按照升序排名范围删除元素
ZREMRANGEBYSCORE key min max  :按照分数范围删除元素
ZRANK key member   :获得指定元素的升序排名
ZREVRANK key member   :获得指定元素的降序排名
ZINTERSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGREGATE SUM|MIN|MAX] :计算有序集合的交集,如果权重相同,分数则按[AGREGATE SUM|MIN|MAX]计算
 
9.redis的事务
a.事务语法
redis的事务是需要原子执行的一组命令的集合。事务的原理是先将属于一个事务的命令发送给Redis,然后再让Redis依次执行这些命令。MULTI-EXEC关键字
redis>MULTI
OK
redis>SADD "user:1:following" 2
QUEUED
redis>SADD "user:2:followers" 1
QUEUED
redis>EXEC
1) (integer) 1
2) (integer) 1
在执行过程中如果有语法错误,则离开返回;如果是其它错误(如命令与键值类型不匹配)则不返回,继续执行下面的命令,直到结束。不过由于Redis不支持回滚功能,也使得Redis在事务上可以保持简洁和快速。另外回顾刚才提到的会导致事务执行失败的两种错误,其中语法错误完全可以在开发时找出并解决,另外如果能够很好地规划数据库(保证键名规范等)的使用,是不会出现如命令与数据类型不匹配这样的运行错误的。
b.监控-WATCH key
WATCH命令可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行。监控一直持续到WATCH后面执行的第一个EXEC命令为止(事务中的命令是在EXEC之后才执行的,所以在MULTI命令后可以修改WATCH监控的键值)。
例子:
redis>SET key 1
OK
redis>WATCH key
OK
redis>SET key 2
OK
redis>MULTI
OK
redis>SET key 3
QUEUED
redis>EXEC  //在执行EXEC前,修改了WATCH监控的key值,所以WATCH紧跟的EXEC没有执行。
(nil)
redis>GET key
"2"

c.取消监控-UNWATCH -可以在EXEC之前,认为的取消监控
10.键的生存时间-EXPIRE key seconds  设置某个键的生存时间,时间到达后,键被删除;TTL key查看剩余的时间;PERSIST key取消生存时间
例子:
redis>SET foo bar
OK
redis>EXPIRE foo 20
(integer) 1
redis>TTL foo
(integer) 15
redis>TTL foo
(integer) 7
redis> TTL foo
(integer) -1 //键不存在,或者该键没有生存时间

redis>EXPIRE foo 20
(integer) 1
redis>SET foo bar  //使用SET对键重新赋值,相当于删除该键,然后重新建立了一个新键
OK
redis>TTL foo
(integer) -1
 如果使用WATCH命令监测了一个拥有生存时间的键,该键时间到期自动删除并不会被WATCH命令认为该键被改变。
EXPIREAT  key stamps   时间戳,s单位
PEXPIREAT key stamps   时间戳,ms单位

11.排序
排序可以使用有序集合,也可以使用SORT命令。
SORT命令可以多LIST、SET、ZSET类型的key进行排序。
a.命令格式: SORT key [ALPHA] [DESC] LIMIT start end   :[ALPHA]表示按字母排序;默认是升序;LIMIT start end取排序结果的从start到end结果返回
b.SORT的BY参数:BY 参数的语法为“BY参考键”。其中参考键可以是字符串类型键或者是散列类型键的某个字段(表示为键名->字段名)。如果提供了BY参数,SORT命令将不再依据元素自身的值进行排序,而是对每个元素使用元素的值替换参考键中的第一个“*”并获取其值,然后依据该值对元素排序。参考键可以是散列或字符串类型。
例子:
redis>SORT tag:ruby:posts BY post:*->time DESC
1) "12"
2) "26"
3) "6"
4) "2"

对字符串进行排序:参考键为字符串
redis>LPUSH sortbylist 2 1 3
(integer) 3
redis>SET itemscore:1 50
OK
redis>SET itemscore:2 100
OK
redis>SET itemscore:3 -10
OK
redis>SORT sortbylist BY itemscore:* DESC
1) "2"
2) "1"
3) "3"
例子中anytext是常量键名(甚至anytext键可以不存在),此时SORT的结果与LRANGE的结果相同,没有执行排序操作;如果几个元素的参考键值相同,则SORT命令会再比较元素本身的值来决定元素的顺序。
c.SORT的GET参数:GET参数不影响排序,它的作用是使SORT命令的返回结果不再是元素自身的值,而是GET参数中指定的键值。GET参数的规则和BY参数一样,GET参数也支持字符串类型和散列类型的键,并使用“*”作为占位符。
redis>SORT tag:ruby:posts BY post:*->time DESC GET post:*->title
1) "Windows 8 app designs"
2) "RethinkDB - An open-source distributed database built with love"
3) "Uses for cURL"
4) "The Nature of Ruby"  
排序后返回的不是ID,而是ID对应的文章。(redis是否只能对数字和字母进行排序,不能对字符串进行排序?)
d.SORT的STORE参数:默认情况下SORT会直接返回排序结果,如果希望保存排序结果,可以使用STORE参数。
例子:
SORT some.list STORE cache.sort

12.消息通知
a.任务队列
说到队列很自然就能想到Redis的列表类型。如果要实现任务队列,只需要让生产者将任务使用LPUSH命令加入到某个键中,另一边让消费者不断地使用RPOP命令从该键中取出任务即可。 BRPOP(右边出栈)和BLPOP(左边出栈) 命令就可以实现请求阻塞。
BRPOP命令接收两个参数,第一个是键名,第二个是超时时间,单位是秒。当超过了此时间仍然没有获得新元素的话就会返回nil。上例中超时时间为“0”,表示不限制等待的时间,即如果没有新元素加入列表就会永远阻塞下去。当获得一个元素后BRPOP命令返回两个值,分别是键名和元素值。
例子:(多个客户端实例中实现生产者与消费者模型)
在实例A中:
redis A>BRPOP queue 0
键入回车后实例1会处于阻塞状态,这时在实例B中向queue中加入一个元素:
redis B>LPUSH queue task
(integer) 1
在LPUSH命令执行后实例A马上就返回了结果:
1) "queue"
2) "task"

b.优先级队列
BRPOP命令和BLPOP命令实际上可以同时阻塞的读取多个键,最前面的键优先级最高;如果所有键都没有元素则阻塞;如果都有元素,则先读取第一个键的元素。
BLPOP key [key …] timeout    :最前面的键具有更高的优先级
>LPUSH queue2 task2
1) (integer) 1
>LPUSH queue3 task3
1) (integer) 1
redis>BRPOP queue1 queue2 queue3 0
1) "queue:2"
2) "task2"

c.“发布/订阅”模式
“发布/订阅”模式同样可以实现进程间的消息传递,其原理是这样的:“发布/订阅”模式中包含两种角色,分别是发布者和订阅者。订阅者可以订阅一个或若干
个频道(channel),而发布者可以向指定的频道发送消息,所有订阅此频道的订阅者都会收到此消息。
发布者发布消息的命令是PUBLISH,用法是
PUBLISH channel message,如向channel.1说一声“hi”:
redis>PUBLISH channel.1 hi
(integer) 0
PUBLISH命令的返回值表示接收到这条消息的订阅者数量订阅频道的命令是SUBSCRIBE,可以同时订阅多个频道,用法是
SUBSCRIBEchannel[channel …]  现在新开一个redis-cli实例A,用它来订阅channel.1:
redis A>SUBSCRIBE channel.1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel.1"
3) (integer) 1
执行SUBSCRIBE命令后客户端会进入订阅状态,处于此状态下客户端不能使用除SUBSCRIBE/UNSUBSCRIBE/PSUBSCRIBE/PUNSUBSCRIBE这4个属于“发布/订阅”模式的命令之外的命令(后面3个命令会在下面介绍),否则会报错。相当于阻塞在订阅模式中。UNSUBSCRIBE退订。

按照通配规则订阅:可以使用PSUBSCRIBE命令按照通配规则订阅指定的规则
>PSUBSCRIBE channel.?*
Reading messages... (press Ctrl-C to quit)1) "psubscribe"
2) "channel.?*"
3) (integer) 1
 
redis B>PUBLISH channel.1 hi!
(integer) 2
订阅者返回结果:
1) "pmessage"
2) "channel.?*"
3) "channel.1"
4) "hi!"
 使用PSUBSCRIBE命令可以重复订阅一个频道,如某客户端执行了PSUBSCRIBE channel.? channel.?*,这时向channel.2发布消息后该客户端会收到两条消息,而同时PUBLISH命令返回的值也是2而不是1。
PUNSUBSCRIBE命令可以退订指定的规则,用法是
PUNSUBSCRIBE [pattern[pattern …]]
如果没有参数则会退订所有规则。
UNSUBSCRIBE命令只能退订通过PSUBSCRIBE命令订阅的规则,不会影响直接通过SUBSCRIBE命令订阅的频道;同样UNSUBSCRIBE命令也不会影响通过PSUBSCRIBE命令订阅的规则。另外容易出错的一点是使用PUNSUBSCRIBE命令退订某个规则时不会将其中的通配符展开,而是进行严格的字符串匹配,所以PUNSUBSCRIBE*无法退订channel.*规则,而是必须使用PUNSUBSCRIBE channel.*才能退订。

13.管道
Redis的底层通信协议对管道(pipelining)提供了支持。通过管道可以一次性发送多条命令并在执行完后一次性将结果返回,当一组命令中每条命令都不依赖于之前命令的执行结果时就可以将这组命令一起通过管道发出。管道通过减少客户端与Redis的通信次数来实现降低往返时延累计值的目的。降低TCP消息包的数量。

14.redis与python
Redis官方推荐的Python客户端是redis-py,见https://github.com/andymccurdy/redis-py
a.redis的python客户端在python编程中的使用方法:
import redis   //首先需要引入redis-py:
r=redis.StrictRedis()  //下面的代码将创建一个默认连接到地址127.0.0.1,端口6379的Redis连接:
r=redis.StrictRedis(host=‘127.0.0.1‘, port=6379, db=0)  //也可以显式地指定需要连接的地址:
r.set(‘foo‘, ‘bar‘) # True
a=r.get(‘foo‘) # ‘bar‘
b.HMSET/HGETALL
HMSET支持将字典作为参数存储,同时HGETALL的返回值也是一个字典,搭配使用十分方便:
r.hmset(‘dict‘, {‘name‘: ‘Bob‘})
people=r.hgetall(‘dict‘)
print people # {‘name‘: ‘Bob‘}
c.事务和管道
redis-py的事务使用方式如下:
pipe=r.pipeline()
pipe.set(‘foo‘, ‘bar‘)
pipe.get(‘foo‘)
result=pipe.execute()
print result # [True, ‘bar‘]
管道的使用方式和事务相同,只不过需要在创建时加上参数transaction=False:
pipe=r.pipeline(transaction=False)
事务和管道还支持链式调用:
result=r.pipeline().set(‘foo‘, ‘bar‘).get(‘foo‘).execute()
# [True, ‘bar‘]

15.redis脚本
Redis在2.6版推出了脚本功能,允许开发者使用Lua语言编写脚本传到Redis中执行。在Lua脚本中可以调用大部分的Redis命令
使用脚本的好处如下:
(1)减少网络开销:6.1节中的第一段代码最多需要向Redis发送5次请求,而使用脚本功能完成同样的操作只需要发送一个请求即可,减少了网络往返时延。
(2)原子操作:Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。换句话说在编写脚本的过程中无需担心会出现竞态条件,也就无需使用事务。事务可以完成的所有功能都可以用脚本来实现。
(3)复用:客户端发送的脚本会永久存储在Redis中,这就意味着其他客户端(可以是其他语言开发的项目)可以复用这一脚本而不需要使用代码完成同样的逻辑。
下面是一段lua脚本,名字为a.lua
local times=redis.call(‘incr‘, KEYS[1])
if times==1 then   -- KEYS[1]键刚创建,所以为其设置生存时间
redis.call(‘expire‘, KEYS[1], ARGV[1])
end
if times>tonumber(ARGV[2]) then
return 0
end
return 1
那么,如何测试这个脚本呢?首先把这段代码存为a.lua,然后在命名行中输入:
 redis-cli --eval a.lua rate.limiting:127.0.0.1 , 10 3
 
其中--eval 参数是告诉redis-cli读取并运行后面的Lua脚本,后面跟着的是传给Lua脚本的参数。其中“,”前的
rate.limiting:127.0.0.1是要操作的键,可以在脚本中使用KEYS[1]获取,“,”后面的10和3是参数,在脚本中
能够使用ARGV[1]和ARGV[2]获得。结合脚本的内容可知这行命令的作用就是将访问频率限制为每10秒最多3次,
所以在终端中不断地运行此命令会发现当访问频率在10秒内小于或等于3次时返回1,否则返回0。注意上面
的命令中“,”两边的空格不能省略,否则会出错。
16.redis与lua
a.在脚本中调用Redis命令
在脚本中可以使用redis.call函数调用Redis命令。就像这样:
redis.call(‘set‘, ‘foo‘, ‘bar‘)
local value=redis.call(‘get‘, ‘foo‘) --value的值为bar
redis.call函数的返回值就是Redis命令的执行结果。第2章介绍过Redis命令的返回值有5种
类型,redis.call函数会将这5种类型的回复转换成对应的Lua的数据类型.
Redis还提供了redis.pcall函数,功能与redis.call相同,唯一的区别是当命令执行出错时redis.pcall会记录错误并继续执行,而redis.call会直接返回错误,不会继续执行。
b. 从脚本中返回值 return
在脚本中可以使用return语句将值返回给客户端,如果没有执行return语句则默认返回nil。因为我们可以像调用其他Redis内置命令一样调用我们自己写的脚本
c. 脚本相关命令
EVAL命令:EVAL命令的格式是:EVAL脚本内容key参数的数量[key …] [arg …]
可以通过key和arg这两类参数向脚本传递数据,它们的值可以在脚本中分别使用KEYS和ARGV两个表类型的全局变量访问
例如,我们希望用脚本功能实现一个SET命令(当然现实中我们不会这么干),脚本内容是这样的:
return redis.call(‘SET‘, KEYS[1], ARGV[1])
现在打开redis-cli执行此脚本:
redis>EVAL "return redis.call(‘SET‘, KEYS[1], ARGV[1])" 1 foo bar
OK
redis>GET foo
"bar"
EVALSHA命令:
考虑到在脚本比较长的情况下,如果每次调用脚本都需要将整个脚本传给Redis会占用较
多的带宽。为了解决这个问题,Redis提供了EVALSHA命令允许开发者通过脚本内容的SHA1
摘要来执行脚本,该命令的用法和EVAL一样,只不过是将脚本内容替换成脚本内容的SHA1
摘要.
在程序中使用EVALSHA命令的一般流程如下。
(1)先计算脚本的SHA1摘要,并使用EVALSHA命令执行脚本。
(2)获得返回值,如果返回“NOSCRIPT”错误则使用EVAL命令重新执行脚本。
虽然这一流程略显麻烦,但值得庆幸的是很多编程语言的Redis客户端都会代替开发者完
成这一流程。比如使用node_redis客户端执行EVAL命令时,node_redis会先尝试执行EVALSHA
命令,如果失败了才会执行EVAL命令

时间: 2024-08-15 21:02:02

Redis数据库笔记的相关文章

redis数据库学习笔记

redis数据库 工作需要,简单了解一下redis数据库,供后续参考和复习使用. 一.简介 Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理.它支持字符串.哈希表.列表.集合.有序集合,位图,hyperloglogs等数据类型.内置复制.Lua脚本.LRU收回.事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区 m

Redis学习笔记4-Redis配置具体解释

在Redis中直接启动redis-server服务时, 採用的是默认的配置文件.採用redis-server   xxx.conf 这种方式能够依照指定的配置文件来执行Redis服务. 依照本Redis学习笔记中Redis的依照方式依照后,Redis的配置文件是/etc/redis/6379.conf.以下是Redis2.8.9的配置文件各项的中文解释. #daemonize no 默认情况下, redis 不是在后台运行的.假设须要在后台运行,把该项的值更改为 yes daemonize ye

REDIS基础笔记

Redis基础笔记 资源链接 简介 简介 安装 五种数据类型及相应命令 1. 字符串类型 2. 散列类型 3. 列表类型 4. 集合类型 5. 有序集合 其他 事务 SORT 生存时间 任务队列 发布/订阅模式 Python中使用Redis 实际实例 管理 其他 资源链接 推荐书籍:<Redis入门指南> 资源列表: redis命令速查command | CMD索引-中文 | CMD树-中文 redis源码github 下载地址redis.io The Little Redis book 入口

Redis学习笔记~目录

redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set --有序集合)和hashs(哈希类型).这些数据类型都 支持push/pop.add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的.在此基础上,redis支持各种不同方式的排 序.与memcached一样,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更

redis入门笔记(1)

redis入门笔记(1) 1. Redis 简介 •Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure server).Redis的键值可以包括字符串(strings)类型,同时它还包括哈希(hashes).列表(lists).集合(sets)和 有序集合(sorted sets)等数据类型. 对于这些数据类型,你可以执行原子操作.例如:对字符串进行附加操作(append):递增哈希中的值:向列表中增加元素:

redis入门笔记(2)

redis入门笔记(2) 上篇文章介绍了redis的基本情况和支持的数据类型,本篇文章将介绍redis持久化.主从复制.简单的事务支持及发布订阅功能. 持久化 •redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到磁盘来保证持久化,这是相对memcache来说的一个大的优势.redis支持两种持久化方式,一种是 Snapshotting(快照)也是默认方式,另一种是Append-only file(缩写aof)的方式. Snapshotting        快

Redis学习笔记(简单了解与运行)

Redis学习笔记(简单了解与运行) 开源的非关系型数据库 是REmote Dictionary Server(远程字典服务器)的缩写,以字典结构存储数据 允许其他应用通过TCP协议读写字典中的内容. Redis支持存储的键值数据类型 字符串类型 散列类型 列表类型 集合类型 有序集合类型 Redis的特性 通过一个列子看出Mysql和Redis的存储区别 例如: (存储一篇文章,文章包括:标题(title),正文(content),阅读量(views),标签(tags)) 需求: 把数据存储在

Redis学习笔记4-Redis配置详解

原文:  http://blog.csdn.net/mashangyou/article/details/24555191 在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redis学习笔记中Redis的按照方式按照后,Redis的配置文件是/etc/redis/6379.conf.下面是Redis2.8.9的配置文件各项的中文解释. 1 #daemon

Redis学习笔记(增删查)

Redis学习笔记(增删查) 向数据库中添加一个键 SET key value 获取数据库中的key KEYS pattern pattern支持glob风格通配符格式 " ? " 匹配一个字符 " * " 匹配任意字符 " [] " 匹配括号间的任一字符,可以使用" - "符号表示一个范围,例如:a[a-z]c " \x " 匹配字符x,用于转义字符.如需要匹配"?",就需要用 \?