REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。
Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。
一、Redis安装和基本使用
下载安装与编译
1 2 3 4
| wget http://download.redis.io/releases/redis-3.0.6.tar.gz tar xzf redis-3.0.6.tar.gz cd redis-3.0.6 make
|
启动服务端
启动客户端
二、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
|
操作模式
redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。
1 2 3 4 5
| import redis r = 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 2 3 4 5 6 7
| import redis pool = redis.ConnectionPool(host='10.211.55.4', port=6379) r = redis.Redis(connection_pool=pool) r.set('foo', 'Bar') print r.get('foo')
|
操作
String操作
redis中的String在在内存中按照一个name对应一个value来存储。如图:
![img]()
set()
setnx()
setex()
psetex()
mset()
get(name)
mget()
getset()
getrange()
setrange()
setbit()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
source = "foo" for i in source: num = ord(i) print bin(num).replace('b','')
|
getbit()
bitcount()
bitop()
strlen()
incr()
incrbyfloat()
decr()
append()
Hash操作
redis中Hash在内存中的存储格式如下图:
![img]()
hset()
hmset()
hget()
hmget()
hgetall()
hlen()
hkeys()
hvals()
hexists()
hdel()
hincrby()
hincrbyfloat()
hscan()
hscan_iter()
List操作
redis中的List在在内存中按照一个name对应一个List来存储。如图:
![img]()
lpush()
lpushx()
llen()
linsert()
lset()
lrem()
lpop()
lindex()
lrange()
ltrim()
rpoplpush()
blpopbc()
brpoplpush()
自定义增量迭代
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
def list_iter(name): """ 自定义redis列表增量迭代 :param name: redis中的name,即:迭代name对应的列表 :return: yield 返回 列表元素 """ list_count = r.llen(name) for index in xrange(list_count): yield r.lindex(name, index)
for item in list_iter('pp'): print item
|
Set操作
Set集合就是不允许重复的列表
sadd()
scard()
sdiff()
sdiffstore()
sinter()
sinterstore()
sismember()
smembers()
smove()
spop()
srandmember()
srem()
sunion()
sunionstore()
sscan() and sscan_iter()
有序集合
在集合的基础上,为每元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。
zadd()
zcard()
zcount()
zincrby()
zrange()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
|
zrank()
zrangebylex()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
|
zrem()
zremrangebyrank()
zremrangebyscore()
zremrangebylex()
zscore()
zinterstore()
zunionstore()
zscan() 和 zscan_iter()
其他常用操作
delete()
exists()
keys()
expire()
rename()
move()
randomkey()
type()
scan()和scan_iter()
管道
redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
import redis pool = redis.ConnectionPool(host='10.211.55.4', port=6379) r = redis.Redis(connection_pool=pool)
pipe = r.pipeline(transaction=True) pipe.multi() pipe.set('name', 'alex') pipe.set('role', 'sb') pipe.execute()
|
实现计数器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import redis
conn = redis.Redis(host='192.168.1.41',port=6379)
conn.set('count',1000)
with conn.pipeline() as pipe:
conn.watch('count')
pipe.multi() old_count = conn.get('count') count = int(old_count) if count > 0: pipe.set('count', count - 1)
pipe.execute()
|
发布订阅
![img]()
发布者:服务器
订阅者:Dashboad和数据处理
Demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
import redis
class RedisHelper:
def __init__(self): self.__conn = redis.Redis(host='10.211.55.4') 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
RedisHelper
|
订阅者
1 2 3 4 5 6 7 8
| from monitor.RedisHelper import RedisHelper obj = RedisHelper() redis_sub = obj.subscribe() while True: msg= redis_sub.parse_response() print msg
|
发布者
1 2 3 4
| from monitor.RedisHelper import RedisHelper obj = RedisHelper() obj.public('hello')
|
sentinel
redis重的sentinel主要用于在redis主从复制中,如果master顾上,则自动将slave替换成master
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| from redis.sentinel import Sentinel
sentinel = Sentinel([('10.211.55.20', 26379), ('10.211.55.20', 26380), ], socket_timeout=0.5)
|
更多参见:https://github.com/andymccurdy/redis-py/
http://doc.redisfans.com/