python网络篇【第十一篇】Memcache、Redis
一、Memcached
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
分布式对于互联网应用来讲,按照用途可划分为三种方式:
- 分布式计算
- 分布式存储
- 两者兼而有之
安装memcache:
编译安装:
wget http:
/
/
memcached.org
/
latest
tar
-
zxvf memcached
-
1.x
.x.tar.gz
cd memcached
-
1.x
.x
.
/
configure && make && make test && sudo make install
PS:依赖libevent
yum install libevent
-
devel
apt
-
get install libevent
-
dev
memcached
-
d
-
m
10
-
u root
-
l
192.168.1.50
-
p
12000
-
c
256
-
P
/
tmp
/
memcached.pid
参数说明:
-
d 是启动一个守护进程
-
m 是分配给Memcache使用的内存数量,单位是MB
-
u 是运行Memcache的用户
-
l 是监听的服务器IP地址
-
p 是设置Memcache监听的端口,最好是
1024
以上的端口
-
c 选项是最大运行的并发连接数,默认是
1024
,按照你服务器的负载量来设定
-
P 是设置保存Memcache的pid文件
Python操作memcached
安装APIpython操作Memcached使用Python
-
memcached模块,下载地址:
https:
/
/
pypi.python.org
/
pypi
/
python
-
memcached
#解压缩安装:
tar xf python-memcached-1.58.tar.gz && cd python-memcached-1.58
python3 setup.py install
操作memcach:
import memcache mc = memcache.Client(['192.168.1.50:12000'],debug=True) #debug=True 表示出现错误时,显示错误信息,线上环境应移除该参数. mc.set('k1','v1') #设置一个k1, 值为v1 result = mc.get('k1') #获取k1值 print(result)
具体参数实际用法:
add
添加一条键值对,如果已经纯在key,重复执行add操作会抛异常
import memcache mc = memcache.Client(['192.168.1.50:12000'],debug=True) #debug=True 表示出现错误时,显示错误信息,线上环境应移除该参数. mc.add('k','v') result = mc.get('k') #获取k1值 print(result) #执行结果: v #如果再次执行,由于k已经存在,抛异常: MemCached: while expecting 'STORED', got unexpected response 'NOT_STORED' v
set 和 set_multi
set 设置一个键值对,如果key不存在,则创建,如果key已经存在,则更新key值
set_multi 设置多个键值对,如果key不存在,则创建,如果key已经存在,则更新key值
import memcache mc = memcache.Client(['192.168.1.50:12000'],debug=True) #debug=True 表示出现错误时,显示错误信息,线上环境应移除该参数. mc.set('k','v1') result = mc.get('k') #获取k1值 print(result) #执行结果: v1 #设置多个key mc.set_multi({'k1':'v1','k2':'v2','k3':'v3'}) result = mc.get_multi(['k','k1','k2','k3']) #获取k1值 print(result) #结果如下: {'k1': 'v1', 'k2': 'v2', 'k': 'v1', 'k3': 'v3'}
replace
修改某个key的值,如果key不存在,则抛出异常
import memcache mc = memcache.Client(['192.168.1.50:12000'],debug=True) #debug=True 表示出现错误时,显示错误信息,线上环境应移除该参数. mc.replace('k','v1') result = mc.get('k') #获取k1值 print(result) #执行结果 v1 #如果修改一个不存在的key,则抛异常: mc.replace('k3','v1') MemCached: while expecting 'STORED', got unexpected response 'NOT_STORED'
delete和delete_multi
delete 删除指定的一个key/value
delete_multi 删除指定的多个键值对
import memcache mc = memcache.Client(['192.1681.50:12000'],debug=True) #debug=True 表示出现错误时,显示错误信息,线上环境应移除该参数. mc.delete('k') #删除指定的k result = mc.get_multi(['k1','k2','k3']) #获取k1值 print(result) #删除指定的多个键值对 mc.delete_multi(['k1','k2'])
如果删除的时候不存在键值对,则抛出异常:
MemCached: while expecting 'DELETED', got unexpected response 'NOT_FOUND' MemCached: while expecting 'DELETED', got unexpected response 'NOT_FOUND'
get 和 get_multi
get 获取一个key/value
get_multi 获取多个键值对
import memcache mc = memcache.Client(['192.168.1.50:12000'],debug=True) #debug=True 表示出现错误时,显示错误信息,线上环境应移除该参数. # mc.delete('k') # mc.delete_multi(['k1','k2']) res = mc.get('k1') #获取一个key,如果不存在则返回None print(res) result = mc.get_multi(['k1','k2','k3']) #获取多个key print(result) 执行结果: None {'k3': 'v3'}
append 和 prepend
append 修改指定的key的值,在value后面追加内容
prepend 修改key的值,在value前面 插入内容
import memcache mc = memcache.Client(['172.16.30.162:11211'],debug=True) #debug=True 表示出现错误时,显示错误信息,线上环境应移除该参数. mc.append('k1','back') #在原来的v1值后面追加back,结果为 v1back mc.prepend('k1','before') #在原来的v1值前面追加before,结果为: beforev1back result = mc.get_multi(['k1','k2','k3']) #获取k1值 print(result)
decr 和 incr
incr 自增,将Memcached中的某一个值增加 N ( N默认为1 )
decr 自减,将Memcached中的某一个值减少 N ( N默认为1 )
import memcache mc = memcache.Client(['192.168.1.50:12000'], debug=True) mc.set('k1', '777') mc.incr('k1') #k1自增一 # k1 = 778 mc.incr('k1', 10) #在自增10 # k1 = 788 mc.decr('k1') #自减一 # k1 = 787 mc.decr('k1', 10) # k1 = 777
统计命令
stats
用于返回统计信息,如PID、版本号、连接数等:
stats items
用于显示各个slab中item的数目和存储时长(最后一次访问距离到现在的秒数).
stats slabs
显示各个slab的信息,包括chunk的大小、数目、使用情况等。
stats sizes
显示所有item和的大小和个数
返回两列,第一列是item大小,第二列是item的个数
flush_all
该命令用于清空缓存中的所有 key/value, 提供了一个可选参数 time, 用于在指定的时间后执行清理缓存操作。
二、redis
安装:
#下载解压并make,此处以3.0.5为版本. # wget http://download.redis.io/releases/redis-3.0.5.tar.gz # tar xzf redis-3.0.5.tar.gz # cd redis-3.0.5 # make #添加环境变量: # vim /etc/profile.d/redis.sh export PATH=/usr/local/redis-3.0.5/src:$PATH # . /etc/profile.d/redis.sh #编辑配置文件: # cp redis.conf /etc/redis/ #启动redis: [root@localhost redis-3.0.5]# redis-server /etc/redis/redis.conf &
安装api:
pip3 install redis
使用:
import redis rd = redis.Redis(host='192.168.1.50',port=6379) #连接redis-server rd.set('k1','v1') #设置一个k1,值为v1 res = rd.get('k1') #获取k1 print(res) #执行结果: b'v1'
连接池:
import redis rd_pool = redis.ConnectionPool(host='192.168.1.50',port=6379) rd = redis.Redis(connection_pool=rd_pool) rd.set('k1','v1') res = rd.get('k1') print(res)
管道
redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。
import redis rd_pool = redis.ConnectionPool(host='172.16.30.162',port=6379) rd = redis.Redis(connection_pool=rd_pool) rd.set('k1','v1',ex=10) #设置超时时间为10秒,十秒之内可以get到值,10秒之后get到的值就是 None res = rd.get('k1') print(res) # rd.set('k1','v',ex=10) #设置超时时间为10秒,十秒之内可以get到值,10秒之后get到的值就是 None rd.set('k1','v1',nx=True) #设置nx为true,如果不存在k1的话,才会set,现在是已经存在了,因此打印出的结果的值,还是上一步设置的: b'v'
发布订阅
发布者:服务器
订阅者:Dashboad和数据处理
Demo如下:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Author: DBQ(Du Baoqiang) import redis class RedisHelper: def __init__(self): self.__conn = redis.Redis(host='172.16.30.162') 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 monitor.RedisHelper import RedisHelper obj = RedisHelper() redis_sub = obj.subscribe() while True: msg= redis_sub.parse_response() print msg
发布者:
from monitor.RedisHelper import RedisHelper obj = RedisHelper() obj.public('hello')