标签:connect back com conf htm amp utf-8 https 设计
Memcached是一个自由开源的,高性能,分布式内存对象缓存系统。
Memcached是以LiveJournal旗下Danga Interactive公司的Brad Fitzpatric为首开发的一款软件。现在已成为mixi、hatena、Facebook、Vox、LiveJournal等众多服务中提高Web应用扩展性的重要因素。
Memcached是一种基于内存的key-value存储,用来存储小块的任意数据(字符串、对象)。这些数据可以是数据库调用、API调用或者是页面渲染的结果。
Memcached简洁而强大。它的简洁设计便于快速开发,减轻开发难度,解决了大数据量缓存的很多问题。它的API兼容大部分流行的开发语言。
本质上,它是一个简洁的key-value存储系统。通过socket连接和发送命令
一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。
协议简单
基于libevent的事件处理
内置内存存储方式
memcached不互相通信的分布式
参考安装链接地址:http://www.runoob.com/memcached/window-install-memcached.html
当前安装方法:
[root@centos6 ~]# yum install memcached -y [root@centos6 ~]# memcached -d -m 10 -u root -l 172.1.1.7 -p 11211 –P /tmp/memcached.pid #启动
参数说明:
-
d 是启动一个守护进程
-
m 是分配给Memcache使用的内存数量,单位是MB
-
u 是运行Memcache的用户
-
l 是监听的服务器IP地址
-
p 是设置Memcache监听的端口,最好是
1024
以上的端口
-
c 选项是最大运行的并发连接数,默认是
1024
,按照你服务器的负载量来设定
-
P 是设置保存Memcache的pid文件
python操作Memcached使用Python-memcached模块 下载安装:https://pypi.python.org/pypi/python-memcached
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache memc=memcache.Client([‘172.1.1.7:11211‘],debug=True) #连接远程mencache memc.set(‘key1‘,‘value1‘) #写入键值对 rec=memc.get(‘key1‘) #按照key读取参数 print(rec)
- 连接memcached集群
memc=memcache.Client([(‘172.1.1.6:11211’,1),(‘172.1.1.2:11211’,2)],debug=True)
权重的计算:
python-memcached模块原生支持集群操作,其原理是在内存维护一个主机列表,且集群中主机的权重值和主机在列表中重复出现的次数成正比;
如果用户根据如果要在内存中创建一个键值对(如:k1 = "v1"),那么要执行一下步骤:
- 根据算法将 k1 转换成一个数字
- 将数字和主机列表长度求余数,得到一个值 N( 0 <= N < 列表长度 )
- 在主机列表中根据 第2步得到的值为索引获取主机,例如:host_list[N]
- 连接 将第3步中获取的主机,将 k1 = "v1" 放置在该服务器的内存中
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache #添加一条键值对,如果已经存在的 key,重复执行add操作异常 memc = memcache.Client([‘172.1.1.7:11211‘],debug=True) #连接memcache服务端 memc.add(‘k1‘,‘v1‘) #添加参数 # memc.add(‘k1‘,‘v2‘)
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache #replace 修改某个key的值,如果key不存在,则异常 memc=memcache.Client([‘172.1.1.7:11211‘],debug=True) memc.replace(‘k1‘,‘vvvv‘) kk=memc.get(‘k1‘) print(kk)
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache memc=memcache.Client([‘172.1.1.7:11211‘],debug=True) #memc.set(‘s1‘,‘t1‘) memc.set_multi({‘s2‘:‘k2‘,‘s3‘:‘k3‘}) #千万要记住此处是引号
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache memc = memcache.Client([‘172.1.1.7:11211‘],debug=True) #memc.delete(‘s1‘)
memc.delete_multi([‘s2‘,‘s3‘])
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache memc=memcache.Client([‘172.1.1.7:11211‘],debug=True) val1 = memc.get(‘s1‘) #取的值不存在就为None print(val1) val2 = memc.get_multi([‘s1‘,‘s2‘,‘s3‘]) print(val2)
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache memc = memcache.Client([‘172.1.1.7:11211‘],debug=True) memc.append(‘s7‘,‘after‘) memc.prepend(‘s7‘,‘before‘) t=memc.get(‘s7‘) print(t)
decr&incr
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache memc=memcache.Client([‘172.1.1.7:11211‘],debug=True) memc.set(‘k1‘,‘789‘) t1=memc.incr(‘k1‘) print(t1) t2=memc.decr(‘k1‘) print(t2)
如商城商品剩余个数,假设改值保存在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 即可,如:
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache memc=memcache.Client([‘172.1.1.7:11211‘],debug=True) v=memc.gets(‘product_count‘) memc.cas(‘product_count‘,‘211‘) #再次修改则会出错 print(v) memc.cas(‘product_count‘,‘122‘) #设定值
本质上每次执行gets时,会从memcache中获取一个自增的数字,通过cas去修改gets的值时,会携带之前获取的自增值和memcache中的自增值进行比较,如果相等,则可以提交,如果不想等,那表示在gets和cas执行之间,又有其他人执行了gets(获取了缓冲的指定值), 如此一来有可能出现非正常数据,则不允许修改。
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
[root@centos6 opt]# tar xf redis-3.0.3.tar.gz [root@centos6 opt]# mv redis-3.0.3 redis [root@centos6 opt]# cd redis [root@centos6 redis]# make && make install
[root@centos6 redis]# /opt/redis/src/redis-server /opt/redis/redis.conf & #启动服务
[root@centos6 ~]# /opt/redis/src/redis-cli #客户端连接 127.0.0.1:6379> set ‘foo‘ ‘bar‘ #设定键值对 OK 127.0.0.1:6379> get ‘foo‘ #按照key取出值 "bar"
redis-py 的API的使用可以分类为:
连接方式
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis red=redis.Redis(host=‘172.1.1.7‘,port=6379) #创建连接 red.set(‘foo‘,‘bar‘) #存入键值对 print(red.get(‘foo‘)) #按照key取出值
连接池
redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis red=redis.ConnectionPool(host=‘172.1.1.7‘,port=6379) #创建连接池 poo=redis.Redis(connection_pool=red) #创建连接 poo.set(‘hello‘,‘nimei‘) print(poo.get(‘hello‘))
操作
set(name, value, ex=None, px=None, nx=False, xx=False)
在Redis中设置值,默认,不存在则创建,存在则修改
参数:
ex,过期时间(秒)
px,过期时间(毫秒)
nx,如果设置为True,则只有name不存在时,当前set操作才执行
xx,如果设置为True,则只有name存在时,当前set操作才执行
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis red = redis.Redis(host=‘172.1.1.7‘,port=6379) r=red.setnx(‘kk‘,‘vv‘) #setnx设置值,只有name不存在时,执行设置操作(添加) print(red.get(‘kk‘)) #打印key对应的值
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis import time red = redis.Redis(host=‘172.1.1.7‘,port=6379) red.setex(‘kk1‘,‘vv1‘,2) #设置有效时长为2 print(red.get(‘kk1‘)) time.sleep(3) #3秒超时 print(red.get(‘kk1‘)) #返回值为空
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis red=redis.Redis(host=‘172.1.1.7‘,port=6379) red.set(‘k6‘,‘v7‘) #单个设值 red.mset(k1=‘v1‘,k2=‘v2‘,k3=‘v3‘) #第一种方法设值 red.mset({‘k4‘:‘v4‘,‘k5‘:‘v5‘}) #第二种方法 print(red.mget(‘k1‘,‘k2‘)) #多个取值 print(red.get(‘k3‘)) #单个取值
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis red = redis.Redis(host=‘172.1.1.7‘,port=6379) red.set(‘k1‘,‘vvv‘) print(red.getset(‘k1‘,‘afternew‘)) #设置新值,返回旧值 print(red.get(‘k1‘)) #此时是新值
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis red=redis.Redis(host=‘172.1.1.7‘,port=6379) red.set(‘k1‘,‘我爱北京天安门‘) tt=red.getrange(‘k1‘,0,3) print(red.getrange(‘k1‘,0,3)) #汉子的话是每三个字节算一个汉子
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis red=redis.Redis(host=‘172.1.1.7‘,port=6379) red.set(‘k1‘,‘我爱北京天安门‘) print(red.setrange(‘k1‘,3,‘hah‘))
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis red=redis.Redis(host=‘172.1.1.7‘,port=6379) red.set(‘k1‘,‘vava‘) red.setbit(‘k1‘,7,1) #将第七位设置成一 print(red.get(‘k1‘))
source = "哈哈哈" for i in source: num=ord(i) print(bin(num).replace(‘b‘,‘‘)) #打印二进制格式字符串
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis red=redis.Redis(host=‘172.1.1.7‘,port=6379) red.set(‘k1‘,‘abc‘) print(red.getbit(‘k1‘,2))
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis red=redis.Redis(host=‘172.1.1.7‘,port=6379) red.set(‘k1‘,‘abc‘) print(red.bitcount(‘k1‘,0,8))
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis red=redis.Redis(host=‘172.1.1.7‘,port=6379) red.set(‘k1‘,‘abc‘) print(red.bitop(‘AND‘,‘kk‘,‘k1‘))
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis red=redis.Redis(host=‘172.1.1.7‘,port=6379) red.set(‘k1‘,‘abc‘) print(red.strlen(‘k1‘))
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis red=redis.Redis(host=‘172.1.1.7‘,port=6379) red.set(‘k1‘,‘12345‘) #确保value是整数 print(red.incr(‘k1‘,amount=1))
day13 memcache,redis,myqlachemy
标签:connect back com conf htm amp utf-8 https 设计
原文地址:http://www.cnblogs.com/wanghui1991/p/6273891.html