- memcached::
- 代码的简单实现
- mc = memcache.Client([('1.1.1.1:12000',1),('1.1.1.2:12000',2),('1.1.1.3:12000',3)],debug=True)
mc .set('k1','v1') - 权重为1代表创建1份1.1.1.1:12000,权重为2代表创建2份1.1.1.2:12000,权重为3代表创建3份1.1.1.3:12000
- 当用户要在内存中创建一个键对应的值,就是 mc.set('k1'='v1') 时
- 它会根据自己的算法,把K1转换成一个值,如 set('ha'=1)
- 它会把 h 转换成一个数字,把 a 转换成一个数字,合在一起
- 然后用合起来的数字和主机列表(1+2+3=6台)求余数,得到一个值N(0<=N<列表长度)
- 如N=3,就会在第三台主机上,把 'ha'=1 放在该服务器的内存中
- mc = memcache.Client([('1.1.1.1:12000',1),('1.1.1.2:12000',2),('1.1.1.3:12000',3)],debug=True)
- gets和cas(感觉跟互斥锁差不多)
- mc.gets('xx') mc.cas('xx',1) ,如果有人在cas前修改了xx,就会报错,避免非正常数据的产生
- mc.gets('xx') mc.cas('xx',1) ,如果有人在cas前修改了xx,就会报错,避免非正常数据的产生
- 代码的简单实现
- redis:
- 代码的简单实现
- 创建连接:
import redis r = redis.Redis(host='10.211.55.4',port=6379) r.set('foo','bar') print(r.get('foo'))
当然还是使用连接池快,不然创建连接的时间,可能比查询还长
- 创建连接池
import redis pool = redis.ConnectionPool(host='10.211.55.4,port=6379') r = redis.Redis(connection_poll=pool) r.set('foo','bar') print(r.get('foo'))
- 操作
- set(name,value,ex=None,px=None,nx=False,xx=False)
1 参数: 2 ex,过期时间(秒) 3 px,过期时间(毫秒) 4 nx,如果设置为True,则只有name不存在时,当前set才操作 5 xx,如果设置为True,则只有name存在时, 当前set才执行
- setnx(name,value) 单独设置nx
- setex(name,value,time) 单独设置ex (秒级别的)
- psetex(name,time_ms,value) 单独设置ex(毫秒级别)
- mset(*args,**kwargs) 批量设置
1 如: 2 mset(k1='v1',k2='v2') 3 或 4 mget({'k1':'v1','k2':'v2'})
- 获取与批量获取
get(name) #批量获取# mget('k1','k2') 或 r.mget(['k1','k2'])
- getset(name,value) # 获取原来的值,并设置一个新值
- getrange(key,start,end) # 获取值的位置
- 存到redis里,是存入2进制的
setbit(name,offset,value) # 设置二进制的位数的值
如:setbit('k1',7,1) # 把二进制的第七位设置成1
getbit(name,offset) # 获得二进制的位数的值 - bitcount(key,start=None,end=None) # 获得二进制位1的个数
- bitop(operation,dest,*keys)
# 获取多个值的二进制,对值进行按位操作,把最后的结果保存到新的name对应的值里面 # 参数 # operation AND,RO,NOT,XOR(异或) # dest 新的redis的name # *keys,要查找的redis的name #如 bitop('AND','new_name','k1','k2','k3')
- strlen(name)
# 返回name对应值的字节长度(一个汉字3个字节)
- appen(key,value)
# 在redis name 对应的值后面追加内容
- 自定义增量迭代
# 由于redis类库中没有提供对列表元素的增量迭代 # 所以如果想要循环name对应的列表元素,就要 # 1.获取name对应的所有元素 # 2.循环列表 # 但是如果列表太大,就可能把内存撑爆,所以我们应该用迭代器 def list_iter(name): """自定义redis列表增量迭代 :param name :redis中的name,即迭代name对应的列表 :return yield 返回列表元素 """ list_count = r.llen(name) # 拿长度再去取,比数据小非常多 for index in range(list_count): yield r.lindex(name,index) # 使用 for item in list_iter('name'): print(item)
- 管道
redis-py 默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline是原子性操作
import redis pool = redis.ConnetctionPool(host='1.1.1.1',port=6379) r = redis.Redis(connection_pool=pool) pip = r.pipline(transaction=True/False) # True是事务开始,False是结束 r.set('name','alex') r.set('role','sb') pipe.execute()
- 订阅
import redis class RedisHelper: def __init__(self): self.__connect = redis.Redis(host='127.0.0.1') # 私密变量,外部不能取 def public(self,msg,chan): self.__connect.publish(chan,msg) return True def subscribe(self,chan): pub = self.__connect.pubsub() pub.subscribe(chan) pub.parse_response() return pub 发布者对象 = RedisHelper() 发布者对象.public('内容','频道') 订阅者对象1 = RedisHelper() 订阅者对象1.subscribe('频道') 订阅者对象2 = RedisHelper() 订阅者对象2.subscribe('频道')
- 还有hash,list.....操作命令都不同
- set(name,value,ex=None,px=None,nx=False,xx=False)
- 创建连接:
- 代码的简单实现