python学习【十三】 Python操作之Redis的介绍及使用
Redis介绍
Redis是一个开源的BSD授权的高级key-value存储。它通常被称为数据结构服务器,因为key可以包含字符串,哈希值,列表,集合和有序集合。
优点
- 性能极高 – Redis能支持超过 100K 每秒的读写频率。
- 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
数据模型
Redis的外层由键、值映射的字典构成。与其他非关系型数据库主要不同在于:Redis中值的类型不仅限于字符串,还支持如下抽象数据类型:
- 字符串列表
- 无序不重复的字符串集合
- 有序不重复的字符串集合
- 键、值都为字符串的哈希表
值的类型决定了值本身支持的操作。Redis支持高层的服务器原子操作,比如交集、并集、差集。
什么是原子操作?
所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。
持久化
大家都知道redis的数据都是存储在内存中的,但是在服务器断电、系统宕机重启后内存中的数据就不存在了。为了解决这一问题,redis提供了持久化技术,将内存中的数据保存在磁盘中。
关于持久化的详细介绍请参考下面链接的内容:
- http://blog.nosqlfan.com/html/4039.html
- http://blog.nosqlfan.com/html/3813.html
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
基本使用
cd redis-3.0.6/src
启动服务端 ./redis-server 启动客户端 ./redis-cli redis> set foo bar OK redis> get foo "bar"
Python操作redis
安装redis模块
sudo pip install redis or sudo easy_install redis or 源码安装 详见:https://github.com/WoLpH/redis-py
简单操作
>>> import redis
>>> r = redis.Redis(host='127.0.0.1')
>>> r.set('foo','shuai')
True
>>> r.get('foo')
'shuai'
>>> r.keys()
['foo']
>>> r.dbsize() #当前数据库包含多少条数据
1L
>>> r.delete('foo')
1
>>> r.save() #执行“检查点”操作,将数据写回磁盘。保存时阻塞
True
>>> r.get('foo');
>>> r.flushdb() #清空r中的所有数据
True
>>> r.exists('foo') #看是否存在这个键值
False
连接池
redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。
import redis
pool = redis.ConnectionPool(host='127.0.0.1', port=6379)
r = redis.Redis(connection_pool=pool)
r.set('foo', 'Bar')
print r.get('foo')
管道pipeline
redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。
import redis
pool = redis.ConnectionPool(host='127.0.0.1', port=6379)
r = redis.Redis(connection_pool=pool)
# pipe = r.pipeline(transaction=False)
pipe = r.pipeline(transaction=True)
r.set('foo', 'aa')
r.set('foo1', 2)
pipe.execute()
发布订阅
发布者:服务器
订阅者:Dashboad和数据处理
代码实例:
工具类
import redis
class RedisHelper:
def __init__(self):
self.__conn = redis.Redis()
self.chan= 'sysinfo' # 频道
def public(self, msg): # 发布消息
self.__conn.publish(self.chan, msg)
return True
def subscribe(self): # 订阅消息
pub = self.__conn.pubsub()
pub.subscribe(self.chan)
pub.parse_response()
return pub
发布者:
import time
import socket
import traceback
from common.monitor import RedisHelper
class LinuxMonitorTemplete(object):
def __init__(self,interval=3):
self.host = socket.gethostbyname(socket.gethostname())
self.interval=interval
self.sysinfo={}
self.sysinfo[self.host]={}
self.obj = RedisHelper()
self.run()
def run(self):
while True:
self.sysinfo[self.host]["Mem"]=self.getmem_use()
# self.sysinfo[self.host]["CPU"] = self.cpu()
print self.sysinfo
self.obj.public(self.sysinfo)
time.sleep(self.interval)
def getmem_use(self):
try:
meminfodict = {}
meminfo_file = open("/proc/meminfo","r")
meminfo = meminfo_file.readlines()
meminfo_file.close()
for memline in meminfo:
memline = memline.replace("\n","")
if memline.split(":")[0] in ["MemTotal","MemFree","Buffers", "Cached","SwapTotal","SwapCached","SwapFree"]:
key = memline.split(":")[0]
value = int(memline.split(":")[1].strip().split(" ")[0])
meminfodict[key] = value / 1024
mem_used = meminfodict["MemTotal"] - meminfodict["MemFree"] - meminfodict["Buffers"] - meminfodict["Cached"]
mem_usage = float(mem_used) / meminfodict["MemTotal"]*100
meminfodict["MemUsed"] = mem_used
meminfodict["MemUsage"] = mem_usage
meminfodict["ts"] = int(time.time())
return meminfodict
except:
exception = traceback.format_exc()
self.exhandle(exception)
def exhandle(self,exception):
Time = time.strftime('%Y-%m-%d-%H:%M:%S', time.localtime(time.time()))
result = Time + " "+exception
print result
if __name__ == '__main__':
LinuxMonitorTemplete()
订阅者:
from common.monitor import RedisHelper
class subscribeClass(object):
def __init__(self):
self.r = RedisHelper()
self.display()
def display(self):
redis_sub = self.r.subscribe()
while True:
msg = redis_sub.parse_response()
print msg[2]
if __name__ == '__main__':
subscribeClass()


浙公网安备 33010602011771号