一、Memcached
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
Memcached安装和基本使用
Memcached安装:
1 1 sentos 安装步骤: 2 2 wget http://memcached.org/latest 3 3 tar -zxvf memcached-1.x.x.tar.gz 4 4 cd memcached-1.x.x 5 5 ./configure && make && make test && sudo make install 6 6 7 7 PS:依赖libevent 8 8 yum install libevent-devel
启动Memcached
1 memcached -d -m 10 -u root -l 10.211.55.4 -p 12000 -c 256 -P /tmp/memcached.pid
系统下查看:
[root@centos6 ~]# ps -aux | grep memcached
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root 16362 0.0 0.0 57300 820 ? Ssl 05:53 0:00 memcached -d -m 10 -u root -l 192.168.1.7 -p 12000 -c 256 -P /tmp/memcached.pid
root 22733 0.0 0.0 4356 728 pts/0 S+ 07:16 0:00 grep memcached
[root@centos6 ~]# netstat -antlp | grep 12000
tcp 0 0 192.168.1.7:12000 0.0.0.0:* LISTEN 16362/memcached
[root@centos6 ~]#
参数说明: -d 是启动一个守护进程 -m 是分配给Memcache使用的内存数量,单位是MB -u 是运行Memcache的用户 -l 是监听的服务器IP地址 -p 是设置Memcache监听的端口,最好是1024以上的端口 -c 选项是最大运行的并发连接数,默认是1024,按照你服务器的负载量来设定 -P 是设置保存Memcache的pid文件
Memcached命令
存储命令: set/add/replace/append/prepend/cas 获取命令: get/gets 其他命令: delete/stats..
Python操作Memcached
安装API
python操作Memcached使用Python-memcached模块
1 yum install python-memcached
1、python下操作memcache
1 >>> import memcache 2 >>> mc = memcache.Client(['192.168.1.7:12000'], debug=True) 3 >>> mc.set("foo","bar") 4 True 5 >>> ret = mc.get("foo") 6 >>> print ret 7 bar 8 >>>
2、天生支持集群
python-memcached模块原生支持集群操作,其原理是在内存维护一个主机列表,且集群中主机的权重值和主机在列表中重复出现的次数成正比。
主机 权重
1.1.1.1 1
1.1.1.2 2
1.1.1.3 1
那么在内存中主机列表为:
1 >>> host_list = ["1.1.1.1","1.1.1.2","1.1.1.2","1.1.1.3",] 2 >>> print host_list 3 ['1.1.1.1', '1.1.1.2', '1.1.1.2', '1.1.1.3']
如果用户要在内存中创建一个键值对(如:k1 = "v1"),那么要执行一下步骤:
- 根据算法将 k1 转换成一个数字
- 将数字和主机列表长度求余数,得到一个值 N( 0 <= N < 列表长度 )
- 在主机列表中根据 第2步得到的值为索引获取主机,例如:host_list[N]
- 连接 将第3步中获取的主机,将 k1 = "v1" 放置在该服务器的内存中;
实现代码如下:
1 >>> mc = memcache.Client([("1.1.1.1:12000",1),("1.1.1.2:12000",2),("1.1.1.3:12000",1)],debug=True) 2 >>> 3 >>> mc.set("k1","v1")
3、ADD
添加一条键值对,如已经存在key,重复执行add操作异常
1 >>> mc = memcache.Client(["192.168.1.7:12000"],debug=True) 2 >>> mc.add("k1","v1") 3 True 4 >>>
4、replace
replace 修改某个key的值,如果key不存在,则异常。
5、set和set_multi
set 设置一个键值对,如果key不存在,则创建,如果key存在,则修改;
set_multi 设置多个键值对,如果key不存在,则创建,如果key存在,则修改。
1 >>> import memcache 2 >>> mc = memcache.Client(["192.168.1.7:12000"],debug=True) 3 >>> mc.set("key0","jason") 4 True 5 >>> mc.set_multi({"key1":"val1","key2":"val2"}) 6 [] 7 >>>
6、delete 和delete_multi
delete 在memcached中删除指定的一个键值对;
delete_multi 在memcached中删除指定的多个键值对。
1 >>> import memcache 2 >>> mc = memcache.Client(["192.168.1.7:12000"],debug=True) 3 >>> mc.delete("key0") 4 1 5 >>> mc.delete_multi(['key1',"key2"]) 6 1 7 >>>
7、get和get_multi
get 获取一个键值对;
get_multi 获取多个键值对。
>>> import memcache >>> mc = memcache.Client(["192.168.1.7:12000"],debug=True) >>> val = mc.get("key0") >>> item_dict = mc.get_multi(["key1","key2","key3"])
8、append 和prepend
append 修改指定key的值,在该值后面追加内容;
prepend 修改指定key的值,在该值前面插入内容。
1 >>> mc = memcache.Client(["192.168.1.7:12000"],debug=True) 2 >>> mc.append("k1","after") 3 True 4 >>> mc.prepend("k1","before") 5 True 6 >>>
9、decr和incr
decr 自减,将memcached中的某一个值减少N(N默认为1)
incr 自增,将memcached中的某一个值增加N (N默认为1)
1 >>> mc = memcache.Client(["192.168.1.7:12000"],debug=True) 2 >>> mc.set("k1","777") 3 True 4 >>> mc.incr("k1") 5 778 6 >>> mc.incr("k1",10) 7 788 8 >>> mc.decr("k1") 9 787 10 >>> mc.decr("k1",10) 11 777 12 >>>
10、gets和cas
例子:
商城商品剩余个数,假设改值保存在memcache中,product_count = 900
A用户刷新页面从memcache中读取到product_count = 900
B用户刷新页面从memcache中读取到product_count = 900
如果A、B用户均购买商品
A用户修改商品剩余个数 product_count=899
B用户修改商品剩余个数 product_count=899
如此这样做:缓存内的数据便不在正确,两个用户购买商品后,商品剩余还是 899
如果使用python的set和get来操作以上过程,那么程序就会如上述所示情况!
如果想要避免此情况的发生,只要使用 gets 和 cas 即可,如:
import memcache mc = memcache.Client(['10.211.55.4:12000'], debug=True, cache_cas=True) v = mc.gets('product_count') # 如果有人在gets之后和cas之前修改了product_count,那么,下面的设置将会执行失败,剖出异常,从而避免非正常数据的产生 mc.cas('product_count', "899")
Ps:本质上每次执行gets时,会从memcache中获取一个自增的数字,通过cas去修改gets的值时,会携带之前获取的自增值和 memcache中的自增值进行比较,如果相等,则可以提交,如果不相等,那表示在gets和cas执行之间,又有其他人执行了gets(获取了缓冲的指 定值), 如此一来有可能出现非正常数据,则不允许修改。
2、Redis
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集、并集、差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 安装及基本使用:(ubuntu系统)
apt-get install redis-server
3、RabbitMQ
RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统。他遵循Mozilla Public License开源协议。
MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。