標籤:
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.gztar xzf redis-3.0.6.tar.gzcd redis-3.0.6makemake 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.gztar -zvxf redis-2.8.0.tar.gzmv redis-2.8.0 python-redis-2.8.0cd python-redis-2.8.0python setup.py install
1.操作模式:
redis-py提供兩個類Redis和StrictRedis用於實現Redis的命令,StrictRedis用於實現大部分官方的命令,並使用官方的文法和命令,Redis是StrictRedis的子類,用於向後相容舊版本的redis-py。
#!/usr/bin/env python# -*- coding:utf-8 -*- import redisr = redis.Redis(host=‘127.0.0.1‘, port=6379)#串連redis伺服器,連接埠是6379r.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 redisclass 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 RedisHelperobj = 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 RedisHelperobj = RedisHelper()obj.public(‘hello‘)
更多參見:https://github.com/andymccurdy/redis-py
Python操作Redis、Memcache、RabbitMQ、SQLAlchemy