redis缓存,rabbitMQ队列

2019年12月11日 阅读数:252
这篇文章主要向大家介绍redis缓存,rabbitMQ队列,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

缓存数据库介绍

 NoSQL(NoSQL = Not Only SQL ),意即“不只仅是SQL”,泛指非关系型的数据库,随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了不少难以克服的问题,而非关系型的数据库则因为其自己的特色获得了很是迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤为是大数据应用难题。javascript

NoSQL数据库的四大分类

键值(Key-Value)存储数据库html

这一类数据库主要会使用到一个 哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来讲的优点在于简单、易部署。可是若是 DBA只对部分值进行查询或更新的时候,Key/value就显得效率低下了。[3]   举例如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB.
 
列存储数据库。
这部分数据库一般是用来应对分布式存储的海量数据。键仍然存在,可是它们的特色是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase, Riak.
 
文档型数据库
文档型数据库的灵感是来自于Lotus Notes办公软件的,并且它同第一种键值存储相相似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,好比JSON。文档型数据库可 以看做是键值数据库的升级版,容许之间嵌套键值。并且文档型数据库比键值数据库的查询效率更高。如:CouchDB, MongoDb. 国内也有文档型数据库SequoiaDB,已经开源。
 
图形(Graph)数据库
图形结构的数据库同其余行列以及刚性结构的SQL数据库不一样,它是使用灵活的图形模型,而且可以扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),所以进行数据库查询须要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。[2]   如:Neo4J, InfoGrid, Infinite Graph.
所以,咱们总结NoSQL数据库在如下的这几种状况下比较适用:一、数据模型比较简单;二、须要灵活性更强的IT系统;三、对数据库性能要求较高;四、不须要高度的数据一致性;五、对于给定key,比较容易映射复杂值的环境。
 

NoSQL数据库的四大分类表格分析

分类 Examples举例 典型应用场景 数据模型 优势 缺点
键值(key-value)[3]  Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB 内容缓存,主要用于处理大量数据的高访问负载,也用于一些日志系统等等。[3]  Key 指向 Value 的键值对,一般用hash table来实现[3]  查找速度快 数据无结构化,一般只被看成字符串或者二进制数据[3] 
列存储数据库[3]  Cassandra, HBase, Riak 分布式的文件系统 以列簇式存储,将同一列数据存在一块儿 查找速度快,可扩展性强,更容易进行分布式扩展 功能相对局限
文档型数据库[3]  CouchDB, MongoDb Web应用(与Key-Value相似,Value是结构化的,不一样的是数据库可以了解Value的内容) Key-Value对应的键值对,Value为结构化数据 数据结构要求不严格,表结构可变,不须要像关系型数据库同样须要预先定义表结构 查询性能不高,并且缺少统一的查询语法。
图形(Graph)数据库[3]  Neo4J, InfoGrid, Infinite Graph 社交网络,推荐系统等。专一于构建关系图谱 图结构 利用图结构相关算法。好比最短路径寻址,N度关系查找等 不少时候须要对整个图作计算才能得出须要的信息,并且这种结构不太好作分布式的集群方案。[3] 

 

 

 

redis

介绍

redis是业界主流的key-value nosql 数据库之一。和Memcached相似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操做,并且这些操做都是原子性的。在此基础上,redis支持各类不一样方式的排序。与memcached同样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操做写入追加的记录文件,而且在此基础上实现了master-slave(主从)同步。java

Redis优势

  • 异常快速 : Redis是很是快的,每秒能够执行大约110000设置操做,81000个/每秒的读取操做。node

  • 支持丰富的数据类型 : Redis支持最大多数开发人员已经知道如列表,集合,可排序集合,哈希等数据类型。python

    这使得在应用中很容易解决的各类问题,由于咱们知道哪些问题处理使用哪一种数据类型更好解决。
  • 操做都是原子的 : 全部 Redis 的操做都是原子,从而确保当两个客户同时访问 Redis 服务器获得的是更新后的值(最新值)。git

  • MultiUtility工具:Redis是一个多功能实用工具,能够在不少如:缓存,消息传递队列中使用(Redis原生支持发布/订阅),在应用程序中,如:Web应用程序会话,网站页面点击数等任何短暂的数据;

安装Redis环境

要在 Ubuntu 上安装 Redis,打开终端,而后输入如下命令:
$sudo apt-get update
$sudo apt-get install redis-server
这将在您的计算机上安装Redis

启动 Redis程序员

$redis-server

查看 redis 是否还在运行github

$redis-cli
这将打开一个 Redis 提示符,以下图所示:
redis 127.0.0.1:6379>
在上面的提示信息中:127.0.0.1 是本机的IP地址,6379是 Redis 服务器运行的端口。如今输入 PING 命令,以下图所示:
redis 127.0.0.1:6379> ping
PONG
这说明如今你已经成功地在计算机上安装了 Redis。
 

Python操做Redis

1
2
3
4
5
6
7
sudo pip install redis
or
sudo easy_install redis
or
源码安装
  
详见:https: / / github.com / WoLpH / redis - py

  

在Ubuntu上安装Redis桌面管理器

要在Ubuntu 上安装 Redis桌面管理,能够从 http://redisdesktop.com/download 下载包并安装它。web

Redis 桌面管理器会给你用户界面来管理 Redis 键和数据。
 
 

Redis API使用

redis-py 的API的使用能够分类为:redis

  • 链接方式
  • 链接池
  • 操做
    • String 操做
    • Hash 操做
    • List 操做
    • Set 操做
    • Sort Set 操做
  • 管道
  • 发布订阅

 

链接方式

一、操做模式

redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。

1
2
3
4
5
import  redis
  
=  redis.Redis(host = '10.211.55.4' , port = 6379 )
r. set ( 'foo' 'Bar' )
print  r.get( 'foo' )

 

二、链接池

redis-py使用connection pool来管理对一个redis server的全部链接,避免每次创建、释放链接的开销。默认,每一个Redis实例都会维护一个本身的链接池。能够直接创建一个链接池,而后做为参数Redis,这样就能够实现多个Redis实例共享一个链接池。

 

操做

 

1. String操做

redis中的String在在内存中按照一个name对应一个value来存储。如图:

set(name, value, ex=None, px=None, nx=False, xx=False)

1
2
3
4
5
6
在Redis中设置值,默认,不存在则建立,存在则修改
参数:
      ex,过时时间(秒)
      px,过时时间(毫秒)
      nx,若是设置为True,则只有name不存在时,当前set操做才执行
      xx,若是设置为True,则只有name存在时,岗前set操做才执行
# EX 和 PX 能够同时出现,但后面给出的选项会覆盖前面给出的选项

redis 127.0.0.1:6379> SET key "value" EX 1000 PX 5000000
OK

redis 127.0.0.1:6379> TTL key
(integer) 4993  # 这是 PX 参数设置的值

redis 127.0.0.1:6379> SET another-key "value" PX 5000000 EX 1000
OK

redis 127.0.0.1:6379> TTL another-key
(integer) 997   # 这是 EX 参数设置的值
get(name)

返回 key 所关联的字符串值。

若是 key 不存在那么返回特殊值 nil 。


setnx (name, value)
将  key  的值设为  value  ,当且仅当  key  不存在。

若给定的 key 已经存在,则 SETNX 不作任何动做。

redis> EXISTS job                # job 不存在
(integer) 0

redis> SETNX job "programmer"    # job 设置成功
(integer) 1

redis> SETNX job "code-farmer"   # 尝试覆盖 job ,失败
(integer) 0

redis> GET job                   # 没有被覆盖
"programmer"
setex(name, time,value)

将值 value 关联到 key ,并将 key 的生存时间设为 seconds (以秒为单位)。

若是 key 已经存在, SETEX 命令将覆写旧值。

# key 已经存在时,SETEX 覆盖旧值

redis> SET cd "timeless"
OK

redis> SETEX cd 3000 "goodbye my love"
OK
psetex (name, time_ms, value)
这个命令和 SETEX 命令类似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。
redis> PSETEX mykey 1000 "Hello"
OK

redis> PTTL mykey
(integer) 999

redis> GET mykey
"Hello"

mset(*args, **kwargs)

批量设置值
MSET key value [key value ...]

同时设置一个或多个 key-value 对。

redis> MSET date "2012.3.30" time "11:00 a.m." weather "sunny"
OK

redis> MGET date time weather
1) "2012.3.30"
2) "11:00 a.m."
3) "sunny"
mget(keys, *args)
返回全部(一个或多个)给定 key 的值。
redis> MGET redis mongodb
getrange(key, start, end)

返回 key 中字符串值的子字符串,字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内)。

负数偏移量表示从字符串最后开始计数, -1 表示最后一个字符, -2 表示倒数第二个,以此类推

redis> SET greeting "hello, my friend"
OK

redis> GETRANGE greeting 0 4          # 返回索引0-4的字符,包括4。
"hello"

redis> GETRANGE greeting -1 -5        # 不支持回绕操做
""

redis> GETRANGE greeting -3 -1        # 负数索引
"end"

redis> GETRANGE greeting 0 -1         # 从第一个到最后一个
"hello, my friend"

redis> GETRANGE greeting 0 1008611    # 值域范围不超过实际字符串,超过部分自动被符略
"hello, my friend"
setrange(name, offset, value)
1
2
3
4
# 修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)
# 参数:
     # offset,字符串的索引,字节(一个汉字三个字节)
     # value,要设置的值


redis> SET greeting "hello world"
OK

redis> SETRANGE greeting 6 "Redis"
(integer) 11

redis> GET greeting
"hello Redis"


# 对空字符串/不存在的 key 进行 SETRANGE

redis> EXISTS empty_string
(integer) 0

redis> SETRANGE empty_string 5 "Redis!"   # 对不存在的 key 使用 SETRANGE
(integer) 11

redis> GET empty_string                   # 空白处被"\x00"填充
"\x00\x00\x00\x00\x00Redis!"
redis> SET greeting "hello world"
OK

redis> SETRANGE greeting 6 "Redis"
(integer) 11

redis> GET greeting
"hello Redis"


# 对空字符串/不存在的 key 进行 SETRANGE

redis> EXISTS empty_string
(integer) 0

redis> SETRANGE empty_string 5 "Redis!"   # 对不存在的 key 使用 SETRANGE
(integer) 11

redis> GET empty_string                   # 空白处被"\x00"填充
"\x00\x00\x00\x00\x00Redis!"
setbit(name, offset, value)
redis> SET greeting "hello world"
OK

redis> SETRANGE greeting 6 "Redis"
(integer) 11

redis> GET greeting
"hello Redis"


# 对空字符串/不存在的 key 进行 SETRANGE

redis> EXISTS empty_string
(integer) 0

redis> SETRANGE empty_string 5 "Redis!"   # 对不存在的 key 使用 SETRANGE
(integer) 11

redis> GET empty_string                   # 空白处被"\x00"填充
"\x00\x00\x00\x00\x00Redis!"
# 对name对应值的二进制表示的位进行操做
 
# 参数:
     # name,redis的name
     # offset,位的索引(将值变换成二进制后再进行索引)
     # value,值只能是 1 或 0
 
# 注:若是在Redis中有一个对应: n1 = "foo",
         那么字符串foo的二进制表示为: 01100110  01101111  01101111
     因此,若是执行 setbit( 'n1' 7 1 ),则就会将第 7 位设置为 1
         那么最终二进制则变成  01100111  01101111  01101111 ,即: "goo"
 
# 扩展,转换二进制表示:
 
     # source = "萨德"
     source  =  "foo"
 
     for  in  source:
         num  =  ord (i)
         print  bin (num).replace( 'b' ,'')
 
     特别的,若是source是汉字  "萨德" 怎么办?
     答:对于utf - 8 ,每个汉字占  3  个字节,那么  "萨德"  则有  9 个字节
        对于汉字, for 循环时候会按照 字节 迭代,那么在迭代时,将每个字节转换 十进制数,而后再将十进制数转换成二进制
         11100110  10101101  10100110  11100110  10110010  10011011  11101001  10111101  10010000
         - - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                   

getbit(name, offset)

1
# 获取name对应的值的二进制表示中的某位的值 (0或1)
redis> SET greeting "hello world"
OK

redis> SETRANGE greeting 6 "Redis"
(integer) 11

redis> GET greeting
"hello Redis"


# 对空字符串/不存在的 key 进行 SETRANGE

redis> EXISTS empty_string
(integer) 0

redis> SETRANGE empty_string 5 "Redis!"   # 对不存在的 key 使用 SETRANGE
(integer) 11

redis> GET empty_string                   # 空白处被"\x00"填充
"\x00\x00\x00\x00\x00Redis!"

bitcount(key, start=None, end=None)

1
2
3
4
5
# 获取name对应的值的二进制表示中 1 的个数
# 参数:
     # key,Redis的name
     # start,位起始位置
     # end,位结束位置

strlen(name)

1
# 返回name对应值的字节长度(一个汉字3个字节)
# 获取字符串的长度

redis> SET mykey "Hello world"
OK

redis> STRLEN mykey
(integer) 11

incr(self, name, amount=1)

1
2
3
4
5
6
7
# 自增 name对应的值,当name不存在时,则建立name=amount,不然,则自增。
 
# 参数:
     # name,Redis的name
     # amount,自增数(必须是整数)
 
# 注:同incrby
redis> SET page_view 20
OK

redis> INCR page_view
(integer) 21

redis> GET page_view    # 数字值在 Redis 中以字符串的形式保存
"21"

incrbyfloat(self, name, amount=1.0)

1
2
3
4
5
# 自增 name对应的值,当name不存在时,则建立name=amount,不然,则自增。
 
# 参数:
     # name,Redis的name
     # amount,自增数(浮点型
redis> SET mykey 10.50
OK

redis> INCRBYFLOAT mykey 0.1
"10.6"

decr(self, name, amount=1)

1
2
3
4
5
# 自减 name对应的值,当name不存在时,则建立name=amount,不然,则自减。
 
# 参数:
     # name,Redis的name
     # amount,自减数(整数)
redis> SET failure_times 10
OK

redis> DECR failure_times
(integer) 9

append(key, value)

1
2
3
4
5
# 在redis name对应的值后面追加内容
 
# 参数:
     key, redis的name
     value, 要追加的字符串
redis> EXISTS myphone               # 确保 myphone 不存在
(integer) 0

redis> APPEND myphone "nokia"       # 对不存在的 key 进行 APPEND ,等同于 SET myphone "nokia"
(integer) 5                         # 字符长度

2. Hash操做

hash表现形式上有些像pyhton中的dict,能够存储一组关联性较强的数据 , redis中Hash在内存中的存储格式以下图:  

hset(name, key, value)

1
2
3
4
5
6
7
8
9
# name对应的hash中设置一个键值对(不存在,则建立;不然,修改)
 
# 参数:
     # name,redis的name
     # key,name对应的hash中的key
     # value,name对应的hash中的value
 
# 注:
     # hsetnx(name, key, value),当name对应的hash中不存在当前key时则建立(至关于添加)
redis> HSET website google "www.g.cn"       # 设置一个新域
(integer) 1

redis> HSET website google "www.google.com" # 覆盖一个旧域
(integer) 0

hmset(name, mapping)

1
2
3
4
5
6
7
8
# 在name对应的hash中批量设置键值对
 
# 参数:
     # name,redis的name
     # mapping,字典,如:{'k1':'v1', 'k2': 'v2'}
 
# 如:
     # r.hmset('xx', {'k1':'v1', 'k2': 'v2'})
127.0.0.1:6379> hmset go k1 2 k2 3
OK
127.0.0.1:6379> hget go k1
"2"

hget(name,key)

1
# 在name对应的hash中获取根据key获取value

hmget(name, keys, *args)

1
2
3
4
5
6
7
8
9
10
11
# 在name对应的hash中获取多个key的值
 
# 参数:
     # name,reids对应的name
     # keys,要获取key集合,如:['k1', 'k2', 'k3']
     # *args,要获取的key,如:k1,k2,k3
 
# 如:
     # r.mget('xx', ['k1', 'k2'])
     # 或
     # print r.hmget('xx', 'k1', 'k2')
hmget go k1 k2

hgetall(name)

1
获取name对应 hash 的全部键值

hlen(name)

1
# 获取name对应的hash中键值对的个数

hkeys(name)

1
# 获取name对应的hash中全部的key的值

hvals(name)

1
# 获取name对应的hash中全部的value的值

hexists(name, key)

1
# 检查name对应的hash是否存在当前传入的key

hdel(name,*keys)

1
# 将name对应的hash中指定key的键值对删除

hincrby(name, key, amount=1)

1
2
3
4
5
# 自增name对应的hash中的指定key的值,不存在则建立key=amount
# 参数:
     # name,redis中的name
     # key, hash对应的key
     # amount,自增数(整数)

127.0.0.1:6379> hincrby count page 200 (integer) 200 127.0.0.1:6379> hget count page "200" 127.0.0.1:6379> hincrby count var 200 (integer) 200 127.0.0.1:6379> hget count var "200" 127.0.0.1:6379> hincrby count var -50 (integer) 150 127.0.0.1:6379> hget count var "150"

hincrbyfloat(name, key, amount=1.0)

1
2
3
4
5
6
7
8
# 自增name对应的hash中的指定key的值,不存在则建立key=amount
 
# 参数:
     # name,redis中的name
     # key, hash对应的key
     # amount,自增数(浮点数)
 
# 自增name对应的hash中的指定key的值,不存在则建立key=amount
# 值和增量都是普通小数
redis> HSET mykey field 10.50
(integer) 1
redis> HINCRBYFLOAT mykey field 0.1
"10.6"
# 值和增量都是指数符号
redis> HSET mykey field 5.0e3
(integer) 0
redis> HINCRBYFLOAT mykey field 2.0e2
"5200"
# 对不存在的键执行 HINCRBYFLOAT
redis> EXISTS price
(integer) 0
redis> HINCRBYFLOAT price milk 3.5
"3.5"
redis> HGETALL price
1) "milk"
2) "3.5"
# 对不存在的域进行 HINCRBYFLOAT
redis> HGETALL price
1) "milk"
2) "3.5"
redis> HINCRBYFLOAT price coffee 4.5   # 新增 coffee 域
"4.5"
redis> HGETALL price
1) "milk"
2) "3.5"
3) "coffee"
4) "4.5"
hscan(name, cursor=0, match=None, count=None)

1
2
3
4
5
6
7
8
9
10
11
12
13
# 增量式迭代获取,对于数据大的数据很是有用,hscan能够实现分片的获取数据,并不是一次性将数据所有获取完,从而放置内存被撑爆
 
# 参数:
     # name,redis的name
     # cursor,游标(基于游标分批取获取数据)
     # match,匹配指定key,默认None 表示全部的key
     # count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数
 
# 如:
     # 第一次:cursor1, data1 = r.hscan('xx', cursor=0, match=None, count=None)
     # 第二次:cursor2, data1 = r.hscan('xx', cursor=cursor1, match=None, count=None)
     # ...
     # 直到返回值cursor的值为0时,表示数据已经经过分片获取完毕

hscan_iter(name, match=None, count=None)

1
2
3
4
5
6
7
8
9
# 利用yield封装hscan建立生成器,实现分批去redis中获取数据
  
# 参数:
     # match,匹配指定key,默认None 表示全部的key
     # count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数
  
# 如:
     # for item in r.hscan_iter('xx'):
     #     print item

3. list

List操做,redis中的List在在内存中按照一个name对应一个List来存储。如图:  

lpush(name,values)

1
2
3
4
5
6
7
8
# 在name对应的list中添加元素,每一个新的元素都添加到列表的最左边
 
# 如:
     # r.lpush('oo', 11,22,33)
     # 保存顺序为: 33,22,11
 
# 扩展:
     # rpush(name, values) 表示从右向左操做
redis> LPUSH languages python
(integer) 1
# 加入重复元素
redis> LPUSH languages python
(integer) 2
redis> LRANGE languages 0 -1     # 列表容许重复元素
1) "python"
2) "python"
# 加入多个元素
redis> LPUSH mylist a b c
(integer) 3
redis> LRANGE mylist 0 -1
1) "c"
2) "b"
3) "a"

lpushx(name,value)

1
2
3
4
# 在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边
 
# 更多:
     # rpushx(name, value) 表示从右向左操做

llen(name)

1
# name对应的list元素的个数

linsert(name, where, refvalue, value))

1
2
3
4
5
6
7
# 在name对应的列表的某一个值前或后插入一个新值
 
# 参数:
     # name,redis的name
     # where,BEFORE或AFTER
     # refvalue,标杆值,即:在它先后插入数据
     # value,要插入的数据

lset(name, index, value)

1
2
3
4
5
6
# 对name对应的list中的某一个索引位置从新赋值
 
# 参数:
     # name,redis的name
     # index,list的索引位置
     # value,要设置的值
>>lset my 0 3

lrem(name, value, num)

1
2
3
4
5
6
7
8
# 在name对应的list中删除指定的值
 
# 参数:
     # name,redis的name
     # value,要删除的值
     # num,  num=0,删除列表中全部的指定值;
            # num=2,从前到后,删除2个;
            # num=-2,从后向前,删除2个
redis> LRANGE greet 0 4         # 查看全部元素
1) "morning"
2) "hello"
3) "morning"
4) "hello"
5) "morning"
redis> LREM greet 2 morning     # 移除从表头到表尾,最早发现的两个 morning
(integer) 2                     # 两个元素被移除

lpop(name)

1
2
3
4
# 在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是第一个元素
 
# 更多:
     # rpop(name) 表示从右向左操做

lindex(name, index)

1
在name对应的列表中根据索引获取列表元素

lrange(name, start, end)

1
2
3
4
5
# 在name对应的列表分片获取数据
# 参数:
     # name,redis的name
     # start,索引的起始位置
     # end,索引结束位置
>>rpush var ship a b c 1 2 3
>>lrange var 0 2
>>1) "lisp"
>>2) "a"
>>3) "b"

ltrim(name, start, end)

1
2
3
4
5
# 在name对应的列表中移除没有在start-end索引之间的值
# 参数:
     # name,redis的name
     # start,索引的起始位置
     # end,索引结束位置

rpoplpush(src, dst)

1
2
3
4
# 从一个列表取出最右边的元素,同时将其添加至另外一个列表的最左边
# 参数:
     # src,要取数据的列表的name
     # dst,要添加数据的列表的name

blpop(keys, timeout)

1
2
3
4
5
6
7
8
# 将多个列表排列,按照从左到右去pop对应列表的元素
 
# 参数:
     # keys,redis的name的集合
     # timeout,超时时间,当元素全部列表的元素获取完以后,阻塞等待列表内有数据的时间(秒), 0 表示永远阻塞
 
# 更多:
     # r.brpop(keys, timeout),从右向左获取数据
redis> LPUSH command "update system..."  # 为command列表增长一个值
(integer) 1

redis> LPUSH request "visit page"        # 为request列表增长一个值
(integer) 1

redis> BLPOP job command  0       # job 列表为空,被跳过,紧接着 command 列表的第一个元素被弹出。
1) "command"                             # 弹出元素所属的列表
2) "update system..."                    # 弹出元素所属的值

brpoplpush(src, dst, timeout=0)

1
2
3
4
5
6
# 从一个列表的右侧移除一个元素并将其添加到另外一个列表的左侧
 
# 参数:
     # src,取出并要移除元素的列表对应的name
     # dst,要插入元素的列表对应的name
     # timeout,当src对应的列表中没有数据时,阻塞等待其有数据的超时时间(秒),0 表示永远阻塞

4.set集合操做

Set操做,Set集合就是不容许重复的列表

sadd(name,values)

1
# name对应的集合中添加元素
# 添加单个元素
redis> SADD bbs "discuz.net"
(integer) 1
# 添加剧复元素
redis> SADD bbs "discuz.net"
(integer) 0
# 添加多个元素
redis> SADD bbs "tianya.cn" "groups.google.com"
(integer) 2
redis> SMEMBERS bbs
1) "discuz.net"
2) "groups.google.com"
3) "tianya.cn"

scard(name)

1
获取name对应的集合中元素个数

sdiff(keys, *args)

1
在第一个name对应的集合中且不在其余name对应的集合的元素集合
redis> SMEMBERS peter's_movies
1) "bet man"
2) "start war"
3) "2012"

redis> SMEMBERS joe's_movies
1) "hi, lady"
2) "Fast Five"
3) "2012"

redis> SDIFF peter's_movies joe's_movies
1) "bet man"
2) "start war"

sdiffstore(dest, keys, *args)

1
# 获取第一个name对应的集合中且不在其余name对应的集合,再将其新加入到dest对应的集合中

sinter(keys, *args)

1
# 获取多一个name对应集合的并集

sinterstore(dest, keys, *args)

1
# 获取多一个name对应集合的并集,再讲其加入到dest对应的集合中

sismember(name, value)

1
# 检查value是不是name对应的集合的成员

smembers(name)

1
# 获取name对应的集合的全部成员

smove(src, dst, value)

1
# 将某个成员从一个集合中移动到另一个集合
redis> SMEMBERS songs
1) "Billie Jean"
2) "Believe Me"

redis> SMEMBERS my_songs
(empty list or set)

redis> SMOVE songs my_songs "Believe Me"
(integer) 1

redis> SMEMBERS songs
1) "Billie Jean"

redis> SMEMBERS my_songs
1) "Believe Me"

spop(name)

1
# 从集合的右侧(尾部)移除一个成员,并将其返回

srandmember(name, numbers)

1
# 从name对应的集合中随机获取 numbers 个元素

srem(name, values)

1
# 在name对应的集合中删除某些值
# 移除多个元素

redis> SREM languages lisp python c
(integer) 3

sunion(keys, *args)

1
# 获取多一个name对应的集合的并集
redis> SMEMBERS songs
1) "Billie Jean"

redis> SMEMBERS my_songs
1) "Believe Me"

redis> SUNION songs my_songs
1) "Billie Jean"
2) "Believe Me"

sunionstore(dest,keys, *args)

1
# 获取多一个name对应的集合的并集,并将结果保存到dest对应的集合中
redis> SMEMBERS NoSQL
1) "MongoDB"
2) "Redis"

redis> SMEMBERS SQL
1) "sqlite"
2) "MySQL"

redis> SUNIONSTORE db NoSQL SQL
(integer) 4

redis> SMEMBERS db
1) "MySQL"
2) "sqlite"
3) "MongoDB"
4) "Redis"

sscan(name, cursor=0, match=None, count=None)
sscan_iter(name, match=None, count=None)

1
# 同字符串的操做,用于增量迭代分批获取元素,避免内存消耗太大
SortedSet(有序集合)

有序集合,在集合的基础上,为每元素排序;元素的排序须要根据另一个值来进行比较,因此,对于有序集合,每个元素有两个值,即:值和分数,分数专门用来作排序。

zadd(name, *args, **kwargs)

1
2
3
4
5
# 在name对应的有序集合中添加元素
# 如:
      # zadd('zz', 'n1', 1, 'n2', 2)
      # 或
      # zadd('zz', n1=11, n2=22)
# 添加单个元素

redis> ZADD page_rank 10 google.com
(integer) 1


# 添加多个元素

redis> ZADD page_rank 9 baidu.com 8 bing.com
(integer) 2

redis> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"

zcard(name)

1
# 获取name对应的有序集合元素的数量

zcount(name, min, max)

1
# 获取name对应的有序集合中分数 在 [min,max] 之间的个数

zincrby(name, value, amount)

1
# 自增name对应的有序集合的 name 对应的分数
redis> ZSCORE salary tom
"2000"

redis> ZINCRBY salary 2000 tom   # tom 加薪啦!
"4000"

zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 按照索引范围获取name对应的有序集合的元素
 
# 参数:
     # name,redis的name
     # start,有序集合索引发始位置(非分数)
     # end,有序集合索引结束位置(非分数)
     # desc,排序规则,默认按照分数从小到大排序
     # withscores,是否获取元素的分数,默认只获取元素的值
     # score_cast_func,对分数进行数据转换的函数
 
# 更多:
     # 从大到小排序
     # zrevrange(name, start, end, withscores=False, score_cast_func=float)
 
     # 按照分数范围获取name对应的有序集合的元素
     # zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)
     # 从大到小排序
     # zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)
redis > ZRANGE salary 0 -1 WITHSCORES             # 显示整个有序集成员
1) "jack"
2) "3500"
3) "tom"
4) "5000"
5) "boss"
6) "10086"

redis > ZRANGE salary 1 2 WITHSCORES              # 显示有序集下标区间 1 至 2 的成员
1) "tom"
2) "5000"
3) "boss"
4) "10086"

redis > ZRANGE salary 0 200000 WITHSCORES         # 测试 end 下标超出最大下标时的状况
1) "jack"
2) "3500"
3) "tom"
4) "5000"
5) "boss"
6) "10086"

redis > ZRANGE salary 200000 3000000 WITHSCORES   # 测试当给定区间不存在于有序集时的状况
(empty list or set)

zrank(name, value)

1
2
3
4
# 获取某个值在 name对应的有序集合中的排行(从 0 开始)
 
# 更多:
     # zrevrank(name, value),从大到小排序
redis> ZRANGE salary 0 -1 WITHSCORES        # 显示全部成员及其 score 值
1) "peter"
2) "3500"
3) "tom"
4) "4000"
5) "jack"
6) "5000"

redis> ZRANK salary tom                     # 显示 tom 的薪水排名,第二
(integer) 1

zrem(name, values)

1
2
3
# 删除name对应的有序集合中值是values的成员
 
# 如:zrem('zz', ['s1', 's2'])
redis> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"
# 移除单个元素

redis> ZREM page_rank google.com
(integer) 1

redis> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
# 移除多个元素

redis> ZREM page_rank baidu.com bing.com

zremrangebyrank(name, min, max)

1
# 根据排行范围删除
redis> ZADD salary 2500 jack                        # 测试数据
(integer) 0
redis> ZADD salary 5000 tom
(integer) 0
redis> ZADD salary 12000 peter
(integer) 0

redis> ZRANGEBYSCORE salary -inf +inf               # 显示整个有序集
1) "jack"
2) "tom"
3) "peter"

redis> ZRANGEBYSCORE salary -inf +inf WITHSCORES    # 显示整个有序集及成员的 score 值
1) "jack"
2) "2500"
3) "tom"
4) "5000"
5) "peter"
6) "12000"

redis> ZRANGEBYSCORE salary -inf 5000 WITHSCORES    # 显示工资 <=5000 的全部成员
1) "jack"
2) "2500"
3) "tom"
4) "5000"

redis> ZRANGEBYSCORE salary (5000 400000            # 显示工资大于 5000 小于等于 400000 的成员
1) "peter"

zremrangebyscore(name, min, max)

1
# 根据分数范围删除

redis> ZRANGE salary 0 -1 WITHSCORES          # 显示有序集内全部成员及其 score 值
1) "tom"
2) "2000"
3) "peter"
4) "3500"
5) "jack"
6) "5000"

redis> ZREMRANGEBYSCORE salary 1500 3500      # 移除全部薪水在 1500 到 3500 内的员工
(integer) 2

redis> ZRANGE salary 0 -1 WITHSCORES          # 剩下的有序集成员
1) "jack"
2) "5000"

zscore(name, value)

1
# 获取name对应有序集合中 value 对应的分数
redis> ZRANGE salary 0 -1 WITHSCORES    # 测试数据
1) "tom"
2) "2000"
3) "peter"
4) "3500"
5) "jack"
6) "5000"

redis> ZSCORE salary peter              # 注意返回值是字符串
"3500"

zinterstore(dest, keys, aggregate=None)

1
2
# 获取两个有序集合的交集,若是遇到相同值不一样分数,则按照aggregate进行操做
# aggregate的值为:  SUM  MIN  MAX
redis > ZADD mid_test 70 "Li Lei"
(integer) 1
redis > ZADD mid_test 70 "Han Meimei"
(integer) 1
redis > ZADD mid_test 99.5 "Tom"
(integer) 1

redis > ZADD fin_test 88 "Li Lei"
(integer) 1
redis > ZADD fin_test 75 "Han Meimei"
(integer) 1
redis > ZADD fin_test 99.5 "Tom"
(integer) 1

redis > ZINTERSTORE sum_point 2 mid_test fin_test
(integer) 3

redis > ZRANGE sum_point 0 -1 WITHSCORES     # 显示有序集内全部成员及其 score 值
1) "Han Meimei"
2) "145"
3) "Li Lei"
4) "158"
5) "Tom"
6) "199"

zunionstore(dest, keys, aggregate=None)

1
2
# 获取两个有序集合的并集,若是遇到相同值不一样分数,则按照aggregate进行操做
# aggregate的值为:  SUM  MIN  MAX
redis> ZRANGE programmer 0 -1 WITHSCORES
1) "peter"
2) "2000"
3) "jack"
4) "3500"
5) "tom"
6) "5000"

redis> ZRANGE manager 0 -1 WITHSCORES
1) "herry"
2) "2000"
3) "mary"
4) "3500"
5) "bob"
6) "4000"

redis> ZUNIONSTORE salary 2 programmer manager WEIGHTS 1 3   # 公司决定加薪。。。除了程序员。。。
(integer) 6

redis> ZRANGE salary 0 -1 WITHSCORES
1) "peter"
2) "2000"
3) "jack"
4) "3500"
5) "tom"
6) "5000"
7) "herry"
8) "6000"
9) "mary"
10) "10500"
11) "bob"
12) "12000"

zscan(name, cursor=0, match=None, count=None, score_cast_func=float)
zscan_iter(name, match=None, count=None,score_cast_func=float)

1
# 同字符串类似,相较于字符串新增score_cast_func,用来对分数进行操做

其余经常使用操做

delete(*names)