NoSQL(NoSQL = Not Only SQL ),意即“不只仅是SQL”,泛指非关系型的数据库,随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,php
特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了不少难以克服的问题,而非关系型的数据库则因为其自己的特色获得了很是迅速的发展。html
NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤为是大数据应用难题。node
这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来讲的优点在于简单、易部署。mysql
可是若是DBA只对部分值进行查询或更新的时候,Key/value就显得效率低下了。[3] 举例如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB.linux
列存储数据库:nginx
这部分数据库一般是用来应对分布式存储的海量数据。键仍然存在,可是它们的特色是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase, Riak.
git
文档型数据库:github
文档型数据库的灵感是来自于Lotus Notes办公软件的,并且它同第一种键值存储相相似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,好比JSON。web
文档型数据库可 以看做是键值数据库的升级版,容许之间嵌套键值。并且文档型数据库比键值数据库的查询效率更高。如:CouchDB, MongoDb. 国内也有文档型数据库SequoiaDB,已经开源。
图形(Graph)数据库:
redis是业界主流的key-value nosql 数据库之一。和Memcached相似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、
zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操做,并且这些操做都是原子性的。
在此基础上,redis支持各类不一样方式的排序。与memcached同样,为了保证效率,
数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操做写入追加的记录文件,而且在此基础上实现了master-slave(主从)同步。
异常快速 : Redis是很是快的,每秒能够执行大约110000设置操做,81000个/每秒的读取操做。
支持丰富的数据类型 : Redis支持最大多数开发人员已经知道如列表,集合,可排序集合,哈希等数据类型。
操做都是原子的 : 全部 Redis 的操做都是原子,从而确保当两个客户同时访问 Redis 服务器获得的是更新后的值(最新值)。
1.yum安装
#前提得配置好阿里云yum源,epel源 #查看是否有redis包 yum list redis #安装redis yum install redis -y #安装好,启动redis systemctl start redis 复制代码
redis-cli #redis 客户端工具 #进入交互式环境后,执行ping,返回pong表示安装成功 127.0.0.1:6379> ping PONG
编译安装的优点是:
1.下载redis源码 wget http://download.redis.io/releases/redis-4.0.10.tar.gz 2.解压缩 tar -zxf redis-4.0.10.tar.gz 3.切换redis源码目录 cd redis-4.0.10.tar.gz 4.编译源文件 make 5.编译好后,src/目录下有编译好的redis指令 6.make install 安装到指定目录,默认在/usr/local/bin
./redis-benchmark //用于进行redis性能测试的工具 ./redis-check-dump //用于修复出问题的dump.rdb文件 ./redis-cli //redis的客户端 ./redis-server //redis的服务端 ./redis-check-aof //用于修复出问题的AOF文件 ./redis-sentinel //用于集群管理
redis配置文件名为
redis.conf
这个文件能够自定义
绑定ip,如须要远程访问,须要填写服务器ip bind 127.0.0.1 端口,redis启动端口 port 守护进程方式运行 daemonize yes rdb数据文件 dbfilename dump.rdb 数据文件存放路径 dir /var/lib/redis/ 日志文件 logfile /var/log/redis/redis-server.log 主从复制 slaveof
启动redis很是简单,直接./redis-server就能够启动服务端了,还能够用下面的方法指定要加载的配置文件: ./redis-server ../redis.conf 默认状况下,redis-server会以非daemon的方式来运行,且默认服务端口为6379。
使用redis客户端
#执行客户端命令便可进入 ./redis-cli #测试是否链接上redis 127.0.0.1:6379 > ping 返回pong表明链接上了 //用set来设置key、value 127.0.0.1:6379 > set name "luban" OK //get获取name的值 127.0.0.1:6379 > get name "luban"
为咱们的redis数据库加层防御,防止被黑客攻击
http://www.javashuo.com/article/p-spojasgo-ba.html
redis是一种高级的key:value存储系统,其中value支持五种数据类型
字符串(strings)
散列(hashes)
列表(lists)
集合(sets)
有序集合(sorted sets)
keys * 查看全部key type key 查看key类型 expire key seconds 过时时间 ttl key 查看key过时剩余时间 -2表示key已经不存在了 persist 取消key的过时时间 -1表示key存在,没有过时时间 exists key 判断key存在 存在返回1 不然0 del keys 删除key 能够删除多个 dbsize 计算key的数量
sudo pip install redis
一、操做模式
redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,
Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。
import redis r = redis.Redis(host='localhost', port=6379) r.set('foo', 'Bar') print r.get('foo')
二、链接池
redis-py使用connection pool来管理对一个redis server的全部链接,避免每次创建、释放链接的开销。默认,每一个Redis实例都会维护一个本身的链接池。
能够直接创建一个链接池,而后做为参数Redis,这样就能够实现多个Redis实例共享一个链接池。
链接池code:
#Author:Yun
import redis pool = redis.ConnectionPool(host='localhost',port = 6379) r = redis.Redis(connection_pool=pool) r.set('foo2','Bar2') print(r.get('foo2'))
set(name, value, ex=None, px=None, nx=False, xx=False)
在Redis中设置值,默认,不存在则建立,存在则修改 参数: ex,过时时间(秒) px,过时时间(毫秒) nx,若是设置为True,则只有name不存在时,当前set操做才执行 xx,若是设置为True,则只有name存在时,岗前set操做才执行
127.0.0.1:6379> set name luban OK 127.0.0.1:6379> set age 22 OK 127.0.0.1:6379> keys * #获取全部的key 1) "age" 2) "name"
127.0.0.1:6379> set name hehe ex 2#ex 2是指只存活两秒钟 OK 127.0.0.1:6379> get name (nil)
setnx(name, value)
设置值,只有name不存在时,执行设置操做(添加)
get(name)
获取值
127.0.0.1:6379> get name "luban" 127.0.0.1:6379> get age "22"
setex(name, value, time)
设置值 参数: time,过时时间(数字秒 或 timedelta对象)
mget(keys, *args)
批量获取
127.0.0.1:6379> mget n1 n2#批量获取Value
1) "1"
2) "2"
getset(name, value)
1 设置新值并获取原来的值
127.0.0.1:6379> set n3 3
OK
127.0.0.1:6379> get n3
"3"
127.0.0.1:6379> getset n3 hehe#设置新值并获取原来的值
"3"
getrange(key, start, end)
获取子序列(根据字节获取,非字符) # 参数:
# name,Redis 的 name
# start,起始位置(字节)
# end,结束位置(字节) # 如: "武沛齐" ,0-3表示 "武"
127.0.0.1:6379> set n1 luban
OK
127.0.0.1:6379> getrange n1 0 2#切片
"lub"
setrange(name, offset, value)
修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加) # 参数: # offset,字符串的索引,字节(一个汉字三个字节) # value,要设置的值
127.0.0.1:6379> set n2 houyi
OK
127.0.0.1:6379> setrange n2 1 ee#替换
(integer) 5
127.0.0.1:6379> get n2
"heeyi"
# 对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 i in source: num = ord(i) print(bin(num).replace('b','')) 特别的,若是source是汉字 "鲁班"怎么办?
>>> ord('鲁')
40065
>>> bin(40065)
'0b1001110010000001'
>>> 答:对于utf-8,每个汉字占 3 个字节,那么 "鲁班" 则有 6个字节 对于汉字,for循环时候会按照 字节 迭代,那么在迭代时,将每个字节转换 十进制数,而后再将十进制数转换成二进制
------------------------鲁班-------------------------------------------------------- 00000000 10011100 10000001 00000000 01110011 11101101
应用场景:
*用途举例,用最省空间的方式,存储在线用户数及分别是哪些用户在线
setbit n5 100 1#设置用户登陆状态位,n5是用户名,100是用户id
127.0.0.1:6379> setbit bb 1000 1#来一个用户标记一下
(integer) 0
127.0.0.1:6379> setbit bb 100 1#来一个在标记一个
(integer) 0
127.0.0.1:6379> setbit bb 230 1
(integer) 0
获取name对应的值的二进制表示中的某位的值 (0或1)
应用场景:
getbit n5 100 #检测用户登陆状态位,是否在线,1-在线;0-不在线
127.0.0.1:6379> getbit bb 230#检测用户230 是否在线
(integer) 1 #在线
127.0.0.1:6379> getbit bb 233#检测用户233是否在线
(integer) 0 #不在线
127.0.0.1:6379>
应用:能够将10亿用户的的登录状态和在线人数存储到10MB空间中去
bitcount(key, start=None, end=None)
获取name对应的值的二进制表示中 1 的个数 # 参数:
# key,Redis的name
# start,位起始位置
# end,位结束位置
127.0.0.1:6379> bitcount bb#统计上线用户数量
(integer) 3
strlen(name)
127.0.0.1:6379> set hh '你好' OK 127.0.0.1:6379> strlen hh (integer) 6
127.0.0.1:6379> 返回name对应值的字节长度(一个汉字3个字节)
incr(self, name, amount=1)
自增 name对应的值,当name不存在时,则建立name=amount,不然,则自增。
参数:
name,Redis的name
amount,自增数(必须是整数)
127.0.0.1:6379> incr login_users#统计在线计数器
(integer) 1
127.0.0.1:6379> incr login_users (integer) 2
127.0.0.1:6379> incr login_users (integer) 3
127.0.0.1:6379> incr login_users (integer) 4
127.0.0.1:6379> incr login_users (integer) 5
127.0.0.1:6379> decr login_users (integer) 4
127.0.0.1:6379> decr login_users (integer) 3
127.0.0.1:6379>
incrbyfloat(self, name, amount=1.0)
自增 name对应的值,当name不存在时,则建立name=amount,不然,则自增。 参数: name,Redis的name amount,自增数(浮点型)
127.0.0.1:6379> INCRBYFLOAT 2 1.2
"1.2"
127.0.0.1:6379> INCRBYFLOAT 2 1.2
"2.4"
127.0.0.1:6379> INCRBYFLOAT 2 1.2
"3.6"
# 自减 name对应的值,当name不存在时,则建立name=amount,不然,则自减。 # 参数: # name,Redis的name # amount,自减数(整数)
# 在redis name对应的值后面追加内容
# 参数:
key, redis的name value, 要追加的字符串
127.0.0.1:6379> set s1 sea
OK
127.0.0.1:6379> append s1 blue
(integer) 7
127.0.0.1:6379> get s1
"seablue"
127.0.0.1:6379>
hash表现形式上有些像pyhton中的dict,能够存储一组关联性较强的数据 , redis中Hash在内存中的存储格式以下图:
hset(name, key, value)
# name对应的hash中设置一个键值对(不存在,则建立;不然,修改) # 参数: # name,redis的name # key,name对应的hash中的key # value,name对应的hash中的value # 注: # hsetnx(name, key, value),当name对应的hash中不存在当前key时则建立(至关于添加)
127.0.0.1:6379> hset info name luban
(integer) 1
127.0.0.1:6379> hset info age 22
(integer) 1
127.0.0.1:6379> hset info id 8848
(integer) 1
127.0.0.1:6379> hgetall info#获取info下的全部key-value
1) "name"
2) "luban"
3) "age"
4) "22"
5) "id"
6) "8848"
# 在name对应的hash中批量设置键值对 # 参数: # name,redis的name # mapping,字典,如:{'k1':'v1', 'k2': 'v2'} # 如: # r.hmset('xx', {'k1':'v1', 'k2': 'v2'})
127.0.0.1:6379> hmset info2 k1 2 k2 3#批量设置
OK
127.0.0.1:6379> hkeys info2
1) "k1"
2) "k2"
# 在name对应的hash中获取根据key获取value
# 在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')
127.0.0.1:6379> hmget info3 n1 n2
1) "1"
2) "2"
获取name对应hash的全部键值对
127.0.0.1:6379> hgetall info2
1) "k1"
2) "2"
3) "k2"
4) "3"
# 获取name对应的hash中键值对的个数
127.0.0.1:6379> hlen info2#获取info2中有几个key
(integer) 2
获取name对应的hash中全部的key的值
127.0.0.1:6379> hkeys info2
1) "k1"
2) "k2"
# 获取name对应的hash中全部的value的值
127.0.0.1:6379> hvals info#获取info下的全部value
1) "luban"
2) "22"
3) "8848"
# 检查name对应的hash是否存在当前传入的key
127.0.0.1:6379> hexists info2 k1#检查info2下的k1这个key是否存在,存在返回1,不然0
(integer) 1
127.0.0.1:6379> hexists info2 k3
(integer) 0
# 将name对应的hash中指定key的键值对删除
127.0.0.1:6379> hdel info2 k2#删除info2下的k2及其value
(integer) 1
127.0.0.1:6379> hget info2 k2
(nil)
# 自增name对应的hash中的指定key的值,不存在则建立key=amount # 参数: # name,redis中的name # key, hash对应的key # amount,自增数(整数)
127.0.0.1:6379> hincrby info2 k2 1#自增name对应的hash中指定key的值,不存在则建立,value=amount
(integer) 1
127.0.0.1:6379> hincrby info2 k2 1
(integer) 2
127.0.0.1:6379> hincrby info2 k2 1
(integer) 3
127.0.0.1:6379> hincrby info2 k2 1
(integer) 4
127.0.0.1:6379> hincrby info2 k2 1
(integer) 5
# 自增name对应的hash中的指定key的值,不存在则建立key=amount # 参数: # name,redis中的name # key, hash对应的key # amount,自增数(浮点数) # 自增name对应的hash中的指定key的值,不存在则建立key=amount
127.0.0.1:6379> HINCRBYFLOAT info5 n2 1.2
"1.2"
127.0.0.1:6379> HINCRBYFLOAT info5 n2 1.2
"2.4"
127.0.0.1:6379> HINCRBYFLOAT info5 n2 1.2
"3.6"
127.0.0.1:6379> hget info5 n2
"3.6"
127.0.0.1:6379>
使用如下命令启动完整哈希扫描 HSCAN myhash 0 使用与模式匹配的字段开始哈希扫描: HSCAN myhash 0 MATCH order_* 使用与模式匹配的字段启动哈希扫描,并强制扫描命令执行更多操做 扫描: HSCAN myhash 0 MATCH order_* COUNT 1000 # 增量式迭代获取,对于数据大的数据很是有用,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时,表示数据已经经过分片获取完毕 127.0.0.1:6379> HSCAN info 0
1) "0"
2) 1) "name"
2) "luban"
3) "age"
4) "22"
5) "id"
6) "8848"
127.0.0.1:6379> hscan info2 0 match k*#过滤以k开头的key 1) "0" 2) 1) "k1" 2) "2" 3) "k2" 4) "6" 127.0.0.1:6379>
# 利用yield封装hscan建立生成器,实现分批去redis中获取数据
# 参数:
# match,匹配指定key,默认None 表示全部的key
# count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数
# 如:
# for item in r.hscan_iter('xx'):
# print(item)
# 在name对应的list中添加元素,每一个新的元素都添加到列表的最左边
# 如:
# r.lpush('oo', 11,22,33)
# 保存顺序为: 33,22,11
# 扩展:
# rpush(name, values) 表示从右向左操做
127.0.0.1:6379> lpush names luban houyi daji#先入后出建立列表
(integer) 3
# 在name对应的列表分片获取数据 # 参数: # name,redis的name # start,索引的起始位置 # end,索引结束位置
127.0.0.1:6379> lrange names 0 -1
1) "daji"
2) "houyi"
3) "luban"
#在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边 # 更多: # rpushx(name, value) 表示从右向左操做
127.0.0.1:6379> lpushx l5 hehe
(integer) 0
127.0.0.1:6379> lrange l5 0 -1
(empty list or set)
127.0.0.1:6379> lpush L5 1 2 3 4
(integer) 4
127.0.0.1:6379> lrange L5 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379> lpushx L5 hehe
(integer) 5
127.0.0.1:6379> lrange L5 0 -1
1) "hehe"
2) "4"
3) "3"
4) "2"
5) "1"
127.0.0.1:6379>
# name对应的list元素的个数
127.0.0.1:6379> lrange L5 0 -1
1) "hehe"
2) "4"
3) "3"
4) "2"
5) "1"
127.0.0.1:6379> llen L5
(integer) 5
# 在name对应的列表的某一个值前或后插入一个新值 # 参数: # name,redis的name # where,BEFORE或AFTER # refvalue,标杆值,即:在它先后插入数据 # value,要插入的数据
127.0.0.1:6379> linsert names before luban houzi#在luban 前面插入数据
(integer) 6
127.0.0.1:6379> lrange names 0 -1
1) "daji"
2) "houyi"
3) "houzi"
4) "luban"
5) "hanxin"
6) "laofuzi"
127.0.0.1:6379> linsert names after luban kai#在luban 后面插入数据
(integer) 7
127.0.0.1:6379> lrange names 0 -1
1) "daji"
2) "houyi"
3) "houzi"
4) "luban"
5) "kai"
6) "hanxin"
7) "laofuzi"
# 对name对应的list中的某一个索引位置从新赋值 # 参数: # name,redis的name # index,list的索引位置 # value,要设置的值
127.0.0.1:6379> lrange names 0 -1
1) "daji"
2) "houyi"
3) "houzi"
4) "luban"
5) "kai"
6) "hanxin"
7) "laofuzi"
127.0.0.1:6379> lset names 3 LuBan#从新给names列表中 索引为3的位置赋值
OK
127.0.0.1:6379> lrange names 0 -1
1) "daji"
2) "houyi"
3) "houzi"
4) "LuBan"
5) "kai"
6) "hanxin"
7) "laofuzi"
# 在name对应的list中删除指定的值 # 参数: # name,redis的name # value,要删除的值 # num, num=0,删除列表中全部的指定值; # num=2,从前到后,删除2个; # num=-2,从后向前,删除2个
127.0.0.1:6379> lrem names 1 houzi #删除指定的值
(integer) 1
127.0.0.1:6379> lrange names 0 -1
1) "daji"
2) "houyi"
3) "LuBan"
4) "kai"
5) "hanxin"
6) "laofuzi"
# 在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是第一个元素 # 更多: # rpop(name) 表示从右向左操做
127.0.0.1:6379> lpop names#从列表最左边取出一个元素删除,相似于队列
"daji"
127.0.0.1:6379> lrange names 0 -1
1) "houyi"
2) "LuBan"
3) "kai"
4) "hanxin"
5) "laofuzi"
127.0.0.1:6379>
在name对应的列表中根据索引获取列表元素
127.0.0.1:6379> lindex L5 1
"4"
127.0.0.1:6379> lindex L5 0
"hehe"
127.0.0.1:6379> lindex L5 2
"3"
127.0.0.1:6379>
# 在name对应的列表中移除没有在start-end索引之间的值 # 参数: # name,redis的name # start,索引的起始位置 # end,索引结束位置
127.0.0.1:6379> lrange names 0 -1
1) "houyi"
2) "LuBan"
3) "kai"
4) "hanxin"
5) "laofuzi"
127.0.0.1:6379> ltrim names 1 2#只保留列表names 索引为 1 -2 的元素
OK
127.0.0.1:6379> lrange names 0 -1
1) "LuBan"
2) "kai"
# 从一个列表取出最右边的元素,同时将其添加至另外一个列表的最左边 # 参数: # src,要取数据的列表的name # dst,要添加数据的列表的name
127.0.0.1:6379> lrange names 0 -1
1) "LuBan"
2) "kai"
127.0.0.1:6379> lrange names2 0 -1
1) "hehe"
127.0.0.1:6379> rpoplpush names names2#移除names最右边的元素,同时添加到names2的最左边
"kai"
127.0.0.1:6379> lrange names2 0 -1
1) "kai"
2) "hehe"
127.0.0.1:6379> lrange names 0 -1
1) "LuBan"
# 将多个列表排列,按照从左到右去pop对应列表的元素 # 参数: # keys,redis的name的集合 # timeout,超时时间,当元素全部列表的元素获取完以后,阻塞等待列表内有数据的时间(秒), 0 表示永远阻塞 # 更多: # r.brpop(keys, timeout),从右向左获取数据
# 从一个列表的右侧移除一个元素并将其添加到另外一个列表的左侧 # 参数: # src,取出并要移除元素的列表对应的name # dst,要插入元素的列表对应的name # timeout,当src对应的列表中没有数据时,阻塞等待其有数据的超时时间(秒),0 表示永远阻塞
127.0.0.1:6379> brpoplpush names names2 40
#从列表names的最右端移除一个元素并添加到另外一个列表names2的左侧
#当列表中没有数据阻塞等待40s
"hehhe"
(12.69s)
127.0.0.1:6379> lrange names2 0 -1
1) "hehhe"
2) "LuBan"
3) "kai"
4) "hehe"
应用场景:
两个进程,一个进程放数据,另外一个进程取数据;
保证数据一致性,同步放数据,同步取数据并删除,双方不影响
# name对应的集合中添加元素
127.0.0.1:6379> sadd names3 luban luban hehe hehe 2323#集合天生去重
(integer) 3
# 获取name对应的集合的全部成员
127.0.0.1:6379> smembers names3
1) "2323"
2) "luban"
3) "hehe
获取name对应的集合中元素个数
127.0.0.1:6379> scard names3#获取names3集合中的元素个数
(integer) 3
在第一个name对应的集合中且不在其余name对应的集合的元素集合
127.0.0.1:6379> sadd names4 hanxin houzi kai 2323 hehe
127.0.0.1:6379> sdiff names3 names4#返回names3有的而names4中没有的元素
1) "luban"
sdiffstore(dest, keys, *args)
# 获取第一个name对应的集合中且不在其余name对应的集合,再将其新加入到dest对应的集合中
127.0.0.1:6379> sdiffstore n5 names3 names4
#将names3有的而names4中没有的元素从新加入到集合n5中
(integer) 1
127.0.0.1:6379> smembers n5
1) "luban"
# 获取多一个name对应集合的交集
127.0.0.1:6379> sinter names3 names4#返回呢两个集合的交集
1) "2323"
2) "hehe"
# 获取多一个name对应集合的交集,再讲其加入到dest对应的集合中
127.0.0.1:6379> SINTERSTORE names34 names3 names4
(integer) 2
127.0.0.1:6379> SMEMBERS names34
1) "hehe"
2) "2323"
# 检查value是不是name对应的集合的成员
127.0.0.1:6379> SISMEMBER names34 'hehe'#是返回1
(integer) 1
127.0.0.1:6379> SISMEMBER names34 123#不是返回0
(integer) 0
# 将某个成员从一个集合中移动到另一个集合
127.0.0.1:6379> sadd s2 1 2 3
(integer) 3
127.0.0.1:6379> sadd s3 4 5 6
(integer) 3
127.0.0.1:6379> SMOVE s2 s3 1
(integer) 1
127.0.0.1:6379> smembers s2
1) "2"
2) "3"
127.0.0.1:6379> smembers s3
# 从集合的右侧(尾部)移除一个成员,并将其返回
127.0.0.1:6379> smembers s3
1) "1"
2) "4"
3) "5"
4) "6"
127.0.0.1:6379> spop s3
"6"
# 从name对应的集合中随机获取 numbers 个元素
127.0.0.1:6379> SRANDMEMBER s3 2
1) "5"
2) "4"
127.0.0.1:6379> SRANDMEMBER s3 2
1) "1"
2) "4"
127.0.0.1:6379> SRANDMEMBER s3 2
1) "5"
2) "4"
# 在name对应的集合中删除某些值
127.0.0.1:6379> smembers s3
1) "1"
2) "4"
3) "5"
127.0.0.1:6379> srem s3 1#删除s3集合中的成员1
(integer) 1
127.0.0.1:6379> smembers s3
1) "4"
2) "5"
# 获取多个或一个name对应的集合的并集
127.0.0.1:6379> sunion s2
1) "2"
2) "3"
127.0.0.1:6379> sunion s2 s3
1) "2"
2) "3"
3) "4"
4) "5"
# 获取多一个name对应的集合的并集,并将结果保存到dest对应的集合中
127.0.0.1:6379> sunionstore s23_union s2 s3
(integer) 4
127.0.0.1:6379> smembers s23_union
1) "2"
2) "3"
3) "4"
4) "5"
# 同字符串的操做,用于增量迭代分批获取元素,避免内存消耗太大
# 在name对应的有序集合中添加元素 # 如: # zadd('zz', 'n1', 1, 'n2', 2) # 或 # zadd('zz', n1=11, n2=22)
127.0.0.1:6379> zadd z1 10 he 3 hehe 6 hehe
(integer) 2
127.0.0.1:6379> zadd z1 10 he 3 hehe 6 hehehe
(integer) 1
127.0.0.1:6379> ZRANGE z1 0 -1 withscores
1) "hehe"
2) "3"
3) "hehehe"
4) "6"
5) "he"
6) "10"
# 按照索引范围获取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)
# 获取name对应的有序集合元素的数量
127.0.0.1:6379> ZRANGE z1 0 -1 withscores
1) "daji"
2) "3"
3) "hehe"
4) "3"
5) "houyi"
6) "7"
7) "luban"
8) "10"
127.0.0.1:6379> zcard z1
(integer) 4
# 获取name对应的有序集合中分数 在 [min,max] 之间的个数
127.0.0.1:6379> ZRANGE z1 0 -1 withscores
1) "daji"
2) "3"
3) "hehe"
4) "3"
5) "houyi"
6) "7"
7) "luban"
8) "10"
127.0.0.1:6379> zcount z1 3 4
(integer) 2
# 自增name对应的有序集合的 name 对应的分数
127.0.0.1:6379> zincrby z3 3 num
"3"
127.0.0.1:6379> zincrby z3 3 num
"6"
127.0.0.1:6379> zincrby z3 3 num
"9"
127.0.0.1:6379> zincrby z3 3 num
"12"
127.0.0.1:6379> zrange z3 0 -1 withscores
1) "hehe"
2) "6"
3) "daji"
4) "8"
5) "num"
6) "12"
# 获取某个值在 name对应的有序集合中的排行(从 0 开始) # 更多: # zrevrank(name, value),从大到小排序
127.0.0.1:6379> zrange z3 0 -1 withscores
1) "hehe"
2) "6"
3) "daji"
4) "8"
5) "num"
6) "12"
127.0.0.1:6379> zrank z3 daji
(integer) 1
# 删除name对应的有序集合中值是values的成员 # 如:zrem('zz', ['s1', 's2'])
127.0.0.1:6379> zrem z3 'daji'
(integer) 1
127.0.0.1:6379> zrange z3 0 -1 withscores
1) "hehe"
2) "6"
3) "num"
4) "12"
# 根据排行范围删除
127.0.0.1:6379> zrange z1 0 -1 withscores
1) "daji"
2) "3"
3) "hehe"
4) "3"
5) "houyi"
6) "7"
7) "luban"
8) "10"
127.0.0.1:6379> zremrangebyrank z1 0 1
(integer) 2
127.0.0.1:6379> zrange z1 0 -1 withscores
1) "houyi"
2) "7"
3) "luban"
4) "10"
# 根据分数范围删除
127.0.0.1:6379> zrange z4 0 -1 withscores
1) "luban"
2) "2"
3) "wangzhaojun"
4) "3"
5) "daji"
6) "6"
7) "diaochan"
8) "9"
9) "zhenji"
10) "10"
127.0.0.1:6379> zremrangebyscore z4 3 6#删除成绩在[3,6]
(integer) 2
127.0.0.1:6379> zrange z4 0 -1 withscores
1) "luban"
2) "2"
3) "diaochan"
4) "9"
5) "zhenji"
6) "10"
# 获取name对应有序集合中 value 对应的分数
127.0.0.1:6379> zrange z4 0 -1 withscores
1) "luban"
2) "2"
3) "diaochan"
4) "9"
5) "zhenji"
6) "10"
127.0.0.1:6379> zscore z4 'zhenji'
"10"
# 获取两个有序集合的交集,若是遇到相同值,则按照aggregate进行操做 # aggregate的值为: SUM MIN MAX
127.0.0.1:6379> zadd z5 3 luban
(integer) 1
127.0.0.1:6379> zrange z5 0 -1 withscores
1) "luban"
2) "3"
127.0.0.1:6379> zrange z4 0 -1 withscores
1) "luban"
2) "2"
3) "diaochan"
4) "9"
5) "zhenji"
6) "10"
127.0.0.1:6379> zinterstore z45_sum 2 z4 z5
(integer) 1
127.0.0.1:6379> zrange z45_sum 0 -1 withscores
1) "luban"
2) "5"
# 获取两个有序集合的并集,若是遇到相同值不一样分数,则按照aggregate进行操做 # aggregate的值为: SUM MIN MAX
127.0.0.1:6379> zrange z6 0 -1 withscores
1) "luban"
2) "2"
127.0.0.1:6379> zrange z4 0 -1 withscores
1) "luban"
2) "2"
3) "diaochan"
4) "9"
5) "zhenji"
6) "10"
127.0.0.1:6379> zunionstore z46_union 2 z4 z6
(integer) 3
127.0.0.1:6379> zrange z46_union 0 -1 withscores
1) "luban"
2) "4"
3) "diaochan"
4) "9"
5) "zhenji"
6) "10"
# 同字符串类似,相较于字符串新增score_cast_func,用来对分数进行操做
delete(*names)
# 根据删除redis中的任意数据类型
redis 默认有16个db 0-15,select 5切换db
# 检测redis的name是否存在
# 根据模型获取redis的name # 更多: # KEYS * 匹配数据库中全部 key 。 # KEYS h?llo 匹配 hello , hallo 和 hxllo 等。 # KEYS h*llo 匹配 hllo 和 heeeeello 等。 # KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo
# 为某个redis的某个name设置超时时间
# 对redis的name重命名为
# 将redis的某个值移动到指定的db下
# 随机获取一个redis的name(不删除)
# 获取name对应值的类型
# 同字符串操做,用于增量迭代获取key
import redis from time import time pool = redis.ConnectionPool(db=2,) r = redis.Redis(connection_pool=pool,) start_time = time() for i in range(100000): r.set('{}'.format(i), '{}'.format(i)) end_time = time() print('读写10W条数据,共耗时(ms):', (end_time-start_time)*1000)
import redis from time import time pool = redis.ConnectionPool(host='localhost', port=6379, db=4,) r = redis.Redis( connection_pool=pool,) pipe = r.pipeline(transaction=True) start_time = time() pipe.multi() for i in range(100000): pipe.set(i, i) pipe.execute() end_time = time() print('读写10W条数据,共耗时(ms):', (end_time-start_time)*1000)
发布者:服务器
订阅者:Dashboad和数据处理
Demo以下:
#Author:Yun import redis class RedisHelper: def __init__(self): self.__conn = redis.Redis(host='localhost',port=6379,db=0) self.chan_sub = 'fm104.5' self.chan_pub = 'fm104.5' def public(self, msg): self.__conn.publish(self.chan_pub, msg) return True def subscribe(self): pub = self.__conn.pubsub()#打开收音机 pub.subscribe(self.chan_sub)#调频 pub.parse_response()#准备接收 return pub
#发布方 from redishelper import RedisHelper obj = RedisHelper() obj.public('hello') ''' 命令行发布: PUBLISH fm104.5 hello '''
#订阅方 from redishelper import RedisHelper obj = RedisHelper() redis_sub = obj.subscribe() while True: msg = redis_sub.parse_response() print(msg)
django项目中配置redis做为cache缓存,须要先安装django-redis模块
pip install django-redis
在settings.py中,按以下配置CACHE链接的redis信息:
CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 100}, # "PASSWORD": "密码",
"DECODE_RESPONSES":True } }, }
先获取redis链接:
import django_redis CACHE = django_redis.get_redis_connection()
在视图中
...
CACHE.set(key, value)
...