python-操作缓存
参考王智刚同学博客
操作Mmecached
1. 安装API
python -m pip install python-memcached
2. 启动memcached
memcached -d -u root -p 12000 -m 50 memcached -d -u root -p 12001 -m 50 memcached -d -u root -p 12002 -m 50[/code]
[code]参数说明:
3. Python Memcached模块对于memcached集群的支持
python-memcached模块原生支持集群操作,其原理是在内存维护一个主机列表,且集群中主机的权重值和主机在列表中重复出现的次数成正比
如果用户根据如果要在内存中创建一个键值对(如:k1 = "v1"),那么要执行一下步骤:
- 根据算法将 k1 转换成一个数字
- 将数字和主机列表长度求余数,得到一个值 N( 0 <= N < 列表长度 )
- 在主机列表中根据 第2步得到的值为索引获取主机,例如:host_list
- 连接 将第3步中获取的主机,将 k1 = "v1" 放置在该服务器的内存中
代码实现如下:
4. add(keyname, value)
add 新增一个key,如果key存在则报错
5. replace(keyname, new_value)
replace 修改某个key的值,如果key不存在,则报错
6. set 和 set_multi
set 设置一个键值对,如果key不存在,则创建,如果key存在,则修改
get 获取一个键值对
set_multi 设置多个键值对,如果key不存在,则创建,如果key存在,则修改
get_multi 获取多个键值对
7. delete 和 delete_multi
8. append 和 prepend
append 修改指定key的值,在该值 后面 追加内容
prepend 修改指定key的值,在该值 前面 插入内容
9. decr 和 incr
incr 自增,将Memcached中的某一个值增加 N ( N默认为1 )
decr 自减,将Memcached中的某一个值减少 N ( N默认为1 )
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 即可,如:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
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(获取了缓冲的指定值), 如此一来有可能出现非正常数据,则不允许修改。
Ps:以上gets cas经过测试无效,或许我测试方法错误,以后修正!
三、操作Redis
redis提供五种数据类型:string,hash,list,set及zset(sorted set)。
1. 安装redis模块
2. redis模块介绍
redis-py 的API的使用可以分类为:
- 连接方式
- 连接池
- 操作
- String 操作
- Hash 操作
- List 操作
- Set 操作
- Sort Set 操作
- 管道
- 发布订阅
3. 操作模式
redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。
4. 连接池
redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。
5. String操作
String操作,redis中的String在在内存中按照一个name对应一个value来存储
5.1 set(name, value, ex=None, px=None, nx=False, xx=False)
在Redis中设置值,默认,不存在则创建,存在则修改
基于这个命令的变种:
setnx(name, value) 设置值,只有name不存在时,执行设置操作(添加)
setex(name, value, time) 设置值, time,过期时间(数字秒 或 timedelta对象)
psetex(name, time_ms, value) 设置值,time_ms,过期时间(数字毫秒 或 timedelta对象)
mset(*args, **kwargs) 批量设置值,mset(k1='v1', k2='v2') 或 mset({'k1': 'v1', 'k2': 'v2'})
getset(name, value)
getrange(key, start, end)
setrange(name, offset, value)
setbit(name, offset, value)
getbit(name, offset)
bitcount(key, start=None, end=None)
bitop(operation, dest, *keys)
strlen(name)
incr(self, name, amount=1)
incrbyfloat(self, name, amount=1.0)
decr(self, name, amount=1)
append(key, value)
6. Hash操作
Hash操作,redis中Hash在内存中的存储格式如下图:
hset(name, key, value)
hmset(name, mapping)
hget(name,key)
hmget(name, keys, *args)
hgetall(name)
hlen(name)
hkeys(name)
hvals(name)
hexists(name, key)
hdel(name,*keys)
hincrby(name, key, amount=1)
hincrbyfloat(name, key, amount=1.0)
hscan(name, cursor=0, match=None, count=None)
hscan_iter(name, match=None, count=None)
7. List操作
List操作,redis中的List在在内存中按照一个name对应一个List来存储。如图:
lpush(name,values)
lpushx(name,value)
llen(name)
linsert(name, where, refvalue, value))
r.lset(name, index, value)
r.lrem(name, value, num)
lpop(name)
lindex(name, index)
lrange(name, start, end)
ltrim(name, start, end)
rpoplpush(src, dst)
blpop(keys, timeout)
brpoplpush(src, dst, timeout=0)
自定义增量迭代
8. Set操作
sadd(name,values)
scard(name)
sdiff(keys, *args)
sdiffstore(dest, keys, *args)
sinter(keys, *args)
sinterstore(dest, keys, *args)
sismember(name, value)
smembers(name)
smove(src, dst, value)
spop(name)
srandmember(name, numbers)
srem(name, values)
sunion(keys, *args)
sunionstore(dest,keys, *args)
sscan(name, cursor=0, match=None, count=None)
sscan_iter(name, match=None, count=None)
9. Zset操作
有序集合,在集合的基础上,为每元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。
zadd(name, *args, **kwargs)
zcard(name)
zcount(name, min, max)
zincrby(name, value, amount)
r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)
zrank(name, value)
zrangebylex(name, min, max, start=None, num=None)
zrem(name, values)
zremrangebyrank(name, min, max)
zremrangebyscore(name, min, max)
zremrangebylex(name, min, max)
zscore(name, value)
zinterstore(dest, keys, aggregate=None)
zunionstore(dest, keys, aggregate=None)
zscan(name, cursor=0, match=None, count=None, score_cast_func=float)
zscan_iter(name, match=None, count=None,score_cast_func=float)
10. 其他常用操作
delete(*names)
exists(name)
keys(pattern='*')
expire(name ,time)
rename(src, dst)
move(name, db))
randomkey()
type(name)
scan(cursor=0, match=None, count=None)
scan_iter(match=None, count=None)
- python-线程池
- python变量
- python变量
- Learning Python 012 函数式编程 1 高阶函数
- Learning Python 012 函数式编程 1 高阶函数
- 纯Python的JSON库性能比较:simplejson vs demjson
- python 常用运算符
- python核心编程学习笔记-2016-07-23-01-习题5-6
- python3.x爬取美团信息
- 基于python3的手机号生成脚本
- python3.x 学习心得
- python set add 导致问题 TypeError: unhashable type: 'list'
- Python线程、进程和协程详解
- Python3.4中的Numpy、SciPy、MatPlotLib安装与配置
- python操作mysql数据库
- Python入门笔记之匿名函数
- Python入门笔记之装饰器decorator
- Python菜鸟之路:Python基础-线程池注释
- 多版本python下,安装pip
- 多版本python共存的解决方案