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 :
memcached --10    -u root -192.168.1.50 -12000 -256 -/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')

 

posted @ 2016-07-22 18:59  也敲寡妇门  阅读(345)  评论(0编辑  收藏  举报