Memcache
前戏
Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象减少读取数据库的次数,从而减小数据库的压力,提高动态,数据库网站的速度。Memcached基于一个存储 键/值对的hashmap。其守护进程是用C编写的,但是客户端可以用任何语言来编程,并通过Memcached协议和守护进程通信。
Memcached安装及基本使用
Memcached服务端的安装
#依赖libevent,先安装 yum install libvent-devel* #用wget去http://memcached.org下载最新源码 tar -zxvf memcached-1.4.29.tar.gz #编译安装 ./configure && make && make test && sudo make install
Memcached的启动
memcached -d -m 10 -u root -p 12000 -c 256 -P /tmp/memcached.pid 参数概述: -d 启动一个线程; -m 分配给Memcached使用的内存数量,单位是MB; -u 运行Memcached的用户; -l 监听的服务器IP地址(可选) -p 设置Memcache监听的端口,最好是1024以上的端口; -c 最大运行的并发连接数,默认是1024,按照服务器的负载量来设定 -P 设置保存Memcached的pip文件
Memcached的基本操作命令
memcached的操作分为三类: 存储操作: set add replace append prepend cas 获取操作: get gets 其他命令: delete stats
使用python操作Memcached
在python中使用Memcached,首先安装memcache:install python-memcached
连接使用
import memcache m = memcache.Client(['192.168.12.12:8800'],debug=True) m.set('liu','qingyang') res = m.get('liu') print(res) #打印qingyang
#debug=True表示运行错误时,显示错误信息,生产环境中不需要
集群支持
python-memcached模块支持集群操作。就是在内存维护一个主机列表,而且集群中主机的权重值与主机在列表中出现的次数成正比。
主机 权重 192.0.0.1 1 192.0.0.2 2 192.0.0.3 1 #内存主机列表:HostList = ["192.0.0.1","192.0.0.2","192.0.0.2","192.0.0.3"]
set操作
#set:设置一个键值对,如果key不存在,就创建;如果存在,就更新value; #set_multi:设置多个键值对,如果key不存在,就创建;如果存在,就更新values。 import memcache m = memcache.Client(["192.0.0.1:8800"],debug=True) m.set('liu',111) m.set_mulit({'liu':111,'wu':222})
get操作
#get 获取一个键值对 #get_multi 获取多个键值对 import memcache m = memcache.Client(['192.0.0.1:8800'],debug=True) print(m.get('liu')) print(m.get_multi(['liu','wu']))
add操作
#add 添加一个键值对,如果key已经存在,操作将会报错:MemCached: while expecting 'STORED', got unexpected response 'NOT_STORED' #add 和 set 都是存储操作,但是set可以更新value,add不可以。 import memcache m = memcache.Client(['192.0.0.1:8800'],debug=True) m.set('liu','111') m.add('wu',222) #如果已经存在'wu'的key,会报错
replace操作
#replace 替换,修改key的值,如果key不存在,则报错:MemCached: while expecting 'STORED', got unexpected response 'NOT_STORED' import memcache m=memcache.Client(['192.0.0.1:8800'],debug=True) m.replace('liu',222) m.replace('li',333) #如果不存在'li'的key,会报错
delete操作
#delete 删除指定的一个键值对,如果没有指定的key,不会报错 #delete_multi 删除多个键值对 import memcache m=memcache.Client(['192.0.0.1:8800'],debug=True) m.delete('liu') m.delete('wu') m.delete_multi(['liu','wu'])
append,prepend操作
#append:修改指定key的值,在值的后面追加数据,无指定key会报异常 #prepend:修改指定key的值,在值的前面插入数据 import memcache m=memcache.Client(['192.0.0.1:8800'],debug=True) m.append('cc','dd') m.append('ds','dsdsds') #不存在ds,会报异常 m.prepend('cc','aa')
decr,incr操作
#incr:自增,将Memcached中的某一个值增加N,(N默认为1),如果值非数字,会报错 #decr:自减,将Memcached中的某一个值减少N,(N默认为1),如果值非数字,会报错 import memcache m=memcache.Client(['192.0.0.1:8800'],debug=True) m.incr('liu') m.decr('liu',30)
gets cas使用
#为了避免在生产环境中产生脏数据,使用gets和cas,类似MySQL中的事务 import memcache mc=memcache.Client(['192.0.01:8800'],debug=True) m.set('count',999) print(m.gets('count')) # 如果有人在gets之后和cas之前修改了product_count,那么,下面的设置将会执行失败,抛出异常,从而避免非正常数据的产生 m.cas('count',998) #cas也能创建一个不存在key的键值对 m.cas('w',90) print(m.gets('w')) #每次执行gets时,会从memcache中获取一个自增的数字,通过cas去修改gets的值时,会携带之前获取的自增值和memcache中的自增值进行比较,如果相等,则可以提交,如果不想等,那表示在gets和cas执行之间,又有其他人执行了gets(获取了缓冲的指定值), 如此一来有可能出现非正常数据,则不允许修改。
memcached和redis的区别
1、 Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等。 2、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。 3、虚拟内存–Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘 4、过期策略–memcache在set时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire 设定,例如expire liu 111 5、分布式–设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从 6、存储数据安全–memcache挂掉后,数据没了;redis可以定期持久化 7、灾难恢复–memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复 8、Redis支持数据的备份,即master-slave模式的数据备份。