Python操作 Redis、Memcache、RabbitMQ、SQLAlchemy
redis介绍:
redis是一个开源的,先进的KEY-VALUE存储,它通常被称为数据结构服务器,因为键可以包含string(字符串)、hash(哈希)、list(链表)、set(集合)和zset(有序集合),这些数据类型都支持push/pop、add/remove及取交集和并集及更丰富的操作,redis支持各种不同方式的排序。为了保证效率,数据都是缓存在内存中,它也可以周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件.并且在此基础上实现了master-slave(主从)同步。
Redis安装和基本使用:
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 make install #make PREFIX=/usr/local/redis install #这种可以直接指定redis安装目录 cd src mkdir -p /usr/local/redis/bin cp redis-server redis-cli redis-benchmark redis-check-aof redischeckdump /usr/local/redis/bin/ mkdir -p /usr/local/redis/etc #将源码中的 redis.conf 复制到 /usr/local/redis/etc/ redis-3.0.6]# cp redis.conf /usr/local/redis/etc/
启动服务端
/usr/local/redis/bin/redis-server #后台启动加&
启动客户端
/usr/local/redis/bin/redis-cli
Python操作Redis
安装API
pip install redis 或者源码安装 wget --no-check-certificate https://pypi.python.org/packages/source/r/redis/redis-2.8.0.tar.gz tar -zvxf redis-2.8.0.tar.gz mv redis-2.8.0 python-redis-2.8.0 cd python-redis-2.8.0 python setup.py install
1.操作模式:
redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis r = redis.Redis(host=‘127.0.0.1‘, port=6379) #连接redis服务器,端口是6379 r.set(‘name‘, ‘saneri‘) #创建一个键值对 print r.get(‘name‘) #打印键值对name的值
2、连接池
redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis pool = redis.ConnectionPool(host=‘127.0.0.1‘, port=6379) r = redis.Redis(connection_pool=pool) r.set(‘name‘, ‘rain‘) print r.get(‘name‘)
class ConnectionPool(object): ........... def __init__(self, connection_class=Connection, max_connections=None, **connection_kwargs): #类初始化时调用构造函数 max_connections = max_connections or 2 ** 31 if not isinstance(max_connections, (int, long)) or max_connections < 0: #判断输入的max_connections是否合法 raise ValueError(‘"max_connections" must be a positive integer‘) self.connection_class = connection_class #设置对应的参数 self.connection_kwargs = connection_kwargs self.max_connections = max_connections self.reset() #初始化ConnectionPool 时的reset操作 def reset(self): self.pid = os.getpid() self._created_connections = 0 #已经创建的连接的计数器 self._available_connections = [] #声明一个空的数组,用来存放可用的连接 self._in_use_connections = set() #声明一个空的集合,用来存放已经在用的连接 self._check_lock = threading.Lock() ....... def get_connection(self, command_name, *keys, **options): #在连接池中获取连接的方法 "Get a connection from the pool" self._checkpid() try: connection = self._available_connections.pop() #获取并删除代表连接的元素,在第一次获取connectiong时,因为_available_connections是一个空的数组, 会直接调用make_connection方法 except IndexError: connection = self.make_connection() self._in_use_connections.add(connection) #向代表正在使用的连接的集合中添加元素 return connection def make_connection(self): #在_available_connections数组为空时获取连接调用的方法 "Create a new connection" if self._created_connections >= self.max_connections: #判断创建的连接是否已经达到最大限制,max_connections可以通过参数初始化 raise ConnectionError("Too many connections") self._created_connections += 1 #把代表已经创建的连接的数值+1 return self.connection_class(**self.connection_kwargs) #返回有效的连接,默认为Connection(**self.connection_kwargs) def release(self, connection): #释放连接,链接并没有断开,只是存在链接池中 "Releases the connection back to the pool" self._checkpid() if connection.pid != self.pid: return self._in_use_connections.remove(connection) #从集合中删除元素 self._available_connections.append(connection) #并添加到_available_connections 的数组中 def disconnect(self): #断开所有连接池中的链接 "Disconnects all connections in the pool" all_conns = chain(self._available_connections, self._in_use_connections) for connection in all_conns: connection.disconnect()
ConnectionPool类
3、管道
redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis pool = redis.ConnectionPool(host=‘127.0.0.1‘, port=6379) #建立连接,用pool来管理避免断开 r = redis.Redis(connection_pool=pool) #redis共享连接池 # pipe = r.pipeline(transaction=False) pipe = r.pipeline(transaction=True) #连接池申请连接 r.set(‘name‘, ‘Lisi‘) #插入键值对 r.set(‘role‘, ‘male‘) pipe.execute() #申请断开
发布订阅模型:
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis class RedisHelper: def __init__(self): self.__conn = redis.Redis(host=‘127.0.0.1‘) #连接redis服务器 self.chan_sub = ‘fm104.5‘ #订阅频道 self.chan_pub = ‘fm104.5‘ #发布频道 def public(self, msg): #定义发布函数,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
redis_demo
订阅者:
#!/usr/bin/env python # -*- coding:utf-8 -*- from redis_demo import RedisHelper obj = RedisHelper() #实例化对象 redis_sub = obj.subscribe() while True: msg= redis_sub.parse_response() print msg
发布者:
#!/usr/bin/env python # -*- coding:utf-8 -*- from redis_demo import RedisHelper obj = RedisHelper() obj.public(‘hello‘)
更多参见:https://github.com/andymccurdy/redis-py