<div id="cnblogs_post_body" class="blogpost-body">
Memcached
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的。其(daemon )是用写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
Memcached安装和基本使用
<div id="cnblogs_post_body" class="blogpost-body">
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的。其(daemon )是用写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
Memcached安装和基本使用
windows系统安装方法:http://blog.csdn.net/l1028386804/article/details/61417166
安装API
错误时,现实错误信息,上线后移除该参数。
2、天生支持集群
python-memcached模块原生支持集群操作,其原理是在内存维护一个主机列表,且集群中主机的权重值和主机在列表中重复出现的次数成正比
如果用户根据如果要在内存中创建一个键值对(如:k1 = "v1"),那么要执行一下步骤:
代码实现如下:
3、add
添加一条键值对,如果已经存在的 key,重复执行add操作异常
API使用
redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。
redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。
举例
dis
配置文件
String操作,rdis中的String在在内存中按照一个name对应一个value来存储。如图:
set(name,value,ex=None,px=None,nx=False,xx=False)
Highlighter sh-gutter">setnx(name,value)
setex(name,time)
Highlighter sh-gutter">psetex(name,time_ms,value)
mset(*args,**kwargs)
mget(keys,*args)
Highlighter sh-gutter">getset(name,value)
getrange(key,start,end)
Highlighter sh-gutter">setrange(name,offset,value)
setbit(name,value)
Highlighter sh-gutter">getbit(name,offset)
bitcount(key,start=None,end=None)
Highlighter sh-gutter">bitop(operation,dest,*keys)
获取多个值,并将值做位运算,将最后的结果保存至新的name对应的值strlen(name)
Highlighter sh-gutter">incr(self,name,amount=1)
incrbyfloat(self,amount=1.0)
append(key,value)
Highlighter sh-gutter">
5、散列表(Hash)操作
Hash操作,redis中Hash在内存中的存储格式如下图:
hset(name,key,value)
一个键值对(不存在,则创建;否则,修改)dis的name
添加)
hmset(name,mapping)
hmget(name,keys,*args)
Highlighter sh-gutter">hgetall(name)
hlen(name)
Highlighter sh-gutter">hkeys(name)
hvals(name)
hdel(name,*keys)
Highlighter sh-gutter">hincrby(name,amount=1) 把原来的值加1
hincrbyfloat(name,amount=1.0)
Highlighter sh-gutter">hscan(name,cursor=0,match=None,count=None)
hscan_iter(name,count=None)
Highlighter sh-gutter">
6、列表(List)操作
List操作,redis中的List在在内存中按照一个name对应一个List来存储。如图:
lpush(name,values)
添加元素,每个新的元素都添加到列表的最左边lpushx(name,value)
linsert(name,where,refvalue,value))
Highlighter sh-gutter">r.lset(name,index,value)
r.lrem(name,num)
Highlighter sh-gutter">lpop(name)
lindex(name,index)
Highlighter sh-gutter">lrange(name,end)
ltrim(name,end)
Highlighter sh-gutter">rpoplpush(src,dst)
blpop(keys,timeout)
Highlighter sh-gutter">brpoplpush(src,dst,timeout=0)
自定义增量迭代
Highlighter sh-gutter">7、集合(Set)操作
Set操作,Set集合就是不允许重复的列表
sadd(name,values)
添加元素 scard(name)
Highlighter sh-gutter">sdiff(keys,*args)
一个name对应的集合中且不在其他name对应的集合的元素集合 sdiffstore(dest,*args)
Highlighter sh-gutter">sinter(keys,*args)
获取多一个name对应集合的并集 sinterstore(dest,*args)
smembers(name)
Highlighter sh-gutter">smove(src,value)
一个集合中移动到另外一个集合 spop(name)
Highlighter sh-gutter">srandmember(name,numbers)
随机获取 numbers 个元素 srem(name,values)
Highlighter sh-gutter">sunion(keys,*args)
获取多一个name对应的集合的并集 sunionstore(dest,*args)
Highlighter sh-gutter">sscan(name,count=None)
sscan_iter(name,count=None)
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大</td>
</tr>
</table>
8、有序集合(zset)操作
有序集合,在集合的基础上,为每元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。
zadd(name,*args,**kwargs)
Highlighter sh-gutter">Highlighter_664304" class="SyntaxHighlighter python">
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 在name对应的有序集合中添加元素
<div class="line number2 index1 alt1"><code class="python comments"># 如:
<div class="line number3 index2 alt2"><code class="python spaces"><code class="python comments"># zadd('zz','n1',1,'n2',2)
<div class="line number4 index3 alt1"><code class="python spaces"><code class="python comments"># 或
<div class="line number5 index4 alt2"><code class="python spaces"><code class="python comments"># zadd('zz',n1=11,n2=22)</td>
</tr>
</table>
zcard(name)
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 获取name对应的有序集合元素的数量</td>
</tr>
</table>
zcount(name,min,max)
Highlighter sh-gutter">Highlighter_655350" class="SyntaxHighlighter python">
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 获取name对应的有序集合中分数 在 [min,max] 之间的个数</td>
</tr>
</table>
zincrby(name,amount)
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 自增name对应的有序集合的 name 对应的分数</td>
</tr>
</table>
r.zrange( name,end,desc=False,withscores=False,score_cast_func=float)
Highlighter sh-gutter">Highlighter_669465" class="SyntaxHighlighter python">
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 按照索引范围获取name对应的有序集合的元素
<div class="line number2 index1 alt1">
<div class="line number3 index2 alt2"><code class="python comments"># 参数:
<div class="line number4 index3 alt1"><code class="python spaces"><code class="python comments"># name,redis的name
<div class="line number5 index4 alt2"><code class="python spaces"><code class="python comments"># start,有序集合索引起始位置(非分数)
<div class="line number6 index5 alt1"><code class="python spaces"><code class="python comments"># end,有序集合索引结束位置(非分数)
<div class="line number7 index6 alt2"><code class="python spaces"><code class="python comments"># desc,排序规则,默认按照分数从小到大排序
<div class="line number8 index7 alt1"><code class="python spaces"><code class="python comments"># withscores,是否获取元素的分数,默认只获取元素的值
<div class="line number9 index8 alt2"><code class="python spaces"><code class="python comments"># score_cast_func,对分数进行数据转换的函数
<div class="line number10 index9 alt1">
<div class="line number11 index10 alt2"><code class="python comments"># 更多:
<div class="line number12 index11 alt1"><code class="python spaces"><code class="python comments"># 从大到小排序
<div class="line number13 index12 alt2"><code class="python spaces"><code class="python comments"># zrevrange(name,score_cast_func=float)
<div class="line number14 index13 alt1">
<div class="line number15 index14 alt2"><code class="python spaces"><code class="python comments"># 按照分数范围获取name对应的有序集合的元素
<div class="line number16 index15 alt1"><code class="python spaces"><code class="python comments"># zrangebyscore(name,max,num=None,score_cast_func=float)
<div class="line number17 index16 alt2"><code class="python spaces"><code class="python comments"># 从大到小排序
<div class="line number18 index17 alt1"><code class="python spaces"><code class="python comments"># zrevrangebyscore(name,score_cast_func=float)</td>
</tr>
</table>
zrank(name,value)
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 获取某个值在 name对应的有序集合中的排行(从 0 开始)
<div class="line number2 index1 alt1">
<div class="line number3 index2 alt2"><code class="python comments"># 更多:
<div class="line number4 index3 alt1"><code class="python spaces"><code class="python comments"># zrevrank(name,value),从大到小排序</td>
</tr>
</table>
zrangebylex(name,num=None)
Highlighter sh-gutter">Highlighter_505152" class="SyntaxHighlighter python">
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 当有序集合的所有成员都具有相同的分值时,有序集合的元素会根据成员的 值 (lexicographical ordering)来进行排序,而这个命令则可以返回给定的有序集合键 key 中, 元素的值介于 min 和 max 之间的成员
<div class="line number2 index1 alt1"><code class="python comments"># 对集合中的每个成员进行逐个字节的对比(byte-by-byte compare), 并按照从低到高的顺序, 返回排序后的集合成员。 如果两个字符串有一部分内容是相同的话, 那么命令会认为较长的字符串比较短的字符串要大
<div class="line number3 index2 alt2">
<div class="line number4 index3 alt1"><code class="python comments"># 参数:
<div class="line number5 index4 alt2"><code class="python spaces"><code class="python comments"># name,redis的name
<div class="line number6 index5 alt1"><code class="python spaces"><code class="python comments"># min,左区间(值)。 + 表示正无限; - 表示负无限; ( 表示开区间; [ 则表示闭区间
<div class="line number7 index6 alt2"><code class="python spaces"><code class="python comments"># min,右区间(值)
<div class="line number8 index7 alt1"><code class="python spaces"><code class="python comments"># start,对结果进行分片处理,索引位置
<div class="line number9 index8 alt2"><code class="python spaces"><code class="python comments"># num,对结果进行分片处理,索引后面的num个元素
<div class="line number10 index9 alt1">
<div class="line number11 index10 alt2"><code class="python comments"># 如:
<div class="line number12 index11 alt1"><code class="python spaces"><code class="python comments"># ZADD myzset 0 aa 0 ba 0 ca 0 da 0 ea 0 fa 0 ga
<div class="line number13 index12 alt2"><code class="python spaces"><code class="python comments"># r.zrangebylex('myzset',"-","[ca") 结果为:['aa','ba','ca']
<div class="line number14 index13 alt1">
<div class="line number15 index14 alt2"><code class="python comments"># 更多:
<div class="line number16 index15 alt1"><code class="python spaces"><code class="python comments"># 从大到小排序
<div class="line number17 index16 alt2"><code class="python spaces"><code class="python comments"># zrevrangebylex(name,num=None)</td>
</tr>
</table>
zrem(name,values)
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 删除name对应的有序集合中值是values的成员
<div class="line number2 index1 alt1">
<div class="line number3 index2 alt2"><code class="python comments"># 如:zrem('zz',['s1','s2'])</td>
</tr>
</table>
zremrangebyrank(name,max)
Highlighter sh-gutter">Highlighter_814045" class="SyntaxHighlighter python">
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 根据排行范围删除</td>
</tr>
</table>
zremrangebyscore(name,max)
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 根据分数范围删除</td>
</tr>
</table>
zremrangebylex(name,max)
Highlighter sh-gutter">Highlighter_981384" class="SyntaxHighlighter python">
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 根据值返回删除</td>
</tr>
</table>
zscore(name,value)
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 获取name对应有序集合中 value 对应的分数</td>
</tr>
</table>
zinterstore(dest,aggregate=None)
Highlighter sh-gutter">Highlighter_439890" class="SyntaxHighlighter python">
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 获取两个有序集合的交集,如果遇到相同值不同分数,则按照aggregate进行操作
<div class="line number2 index1 alt1"><code class="python comments"># aggregate的值为: SUM MIN MAX</td>
</tr>
</table>
zunionstore(dest,aggregate=None)
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 获取两个有序集合的并集,如果遇到相同值不同分数,则按照aggregate进行操作
<div class="line number2 index1 alt1"><code class="python comments"># aggregate的值为: SUM MIN MAX</td>
</tr>
</table>
zscan(name,count=None,score_cast_func=float)
zscan_iter(name,score_cast_func=float)Highlighter sh-gutter">Highlighter_465697" class="SyntaxHighlighter python">
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 同字符串相似,相较于字符串新增score_cast_func,用来对分数进行操作</td>
</tr>
</table>
9、其他常用操作
delete(*names)
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 根据删除redis中的任意数据类型</td>
</tr>
</table>
exists(name)
Highlighter sh-gutter">Highlighter_567894" class="SyntaxHighlighter python">
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 检测redis的name是否存在</td>
</tr>
</table>
keys(pattern='*')
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 根据模型获取redis的name
<div class="line number2 index1 alt1">
<div class="line number3 index2 alt2"><code class="python comments"># 更多:
<div class="line number4 index3 alt1"><code class="python spaces"><code class="python comments"># KEYS 匹配数据库中所有 key 。
<div class="line number5 index4 alt2"><code class="python spaces"><code class="python comments"># KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
<div class="line number6 index5 alt1"><code class="python spaces"><code class="python comments"># KEYS hllo 匹配 hllo 和 heeeeello 等。
<div class="line number7 index6 alt2"><code class="python spaces"><code class="python comments"># KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo</td>
</tr>
</table>
expire(name,time)
Highlighter sh-gutter">Highlighter_405996" class="SyntaxHighlighter python">
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 为某个redis的某个name设置超时时间</td>
</tr>
</table>
rename(src,dst)
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 对redis的name重命名为</td>
</tr>
</table>
move(name,db))
Highlighter sh-gutter">Highlighter_287582" class="SyntaxHighlighter python">
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 将redis的某个值移动到指定的db下</td>
</tr>
</table>
randomkey()
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 随机获取一个redis的name(不删除)</td>
</tr>
</table>
type(name)
Highlighter sh-gutter">Highlighter_634207" class="SyntaxHighlighter python">
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 获取name对应值的类型</td>
</tr>
</table>
scan(cursor=0,count=None)
scan_iter(match=None,count=None)
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments"># 同字符串操作,用于增量迭代获取key</td>
</tr>
</table>
10、管道
redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。
Highlighter sh-gutter">Highlighter_680823" class="SyntaxHighlighter python">
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python comments">#!/usr/bin/env python
<div class="line number2 index1 alt1"><code class="python comments"># -- coding:utf-8 --
<div class="line number3 index2 alt2">
<div class="line number4 index3 alt1"><code class="python keyword">import <code class="python plain">redis
<div class="line number5 index4 alt2">
<div class="line number6 index5 alt1"><code class="python plain">pool <code class="python keyword">= <code class="python plain">redis.ConnectionPool(host<code class="python keyword">=<code class="python string">'10.211.55.4'<code class="python plain">,port<code class="python keyword">=<code class="python value">6379<code class="python plain">)
<div class="line number7 index6 alt2">
<div class="line number8 index7 alt1"><code class="python plain">r <code class="python keyword">= <code class="python plain">redis.Redis(connection_pool<code class="python keyword">=<code class="python plain">pool)
<div class="line number9 index8 alt2">
<div class="line number10 index9 alt1"><code class="python comments"># pipe = r.pipeline(transaction=False)
<div class="line number11 index10 alt2"><code class="python plain">pipe <code class="python keyword">= <code class="python plain">r.pipeline(transaction<code class="python keyword">=<code class="python color1">True<code class="python plain">)
<div class="line number12 index11 alt1">
<div class="line number13 index12 alt2"><code class="python plain">pipe.<code class="python functions">set<code class="python plain">(<code class="python string">'name'<code class="python plain">,<code class="python string">'alex'<code class="python plain">)
<div class="line number14 index13 alt1"><code class="python plain">pipe.<code class="python functions">set<code class="python plain">(<code class="python string">'role'<code class="python plain">,<code class="python string">'sb'<code class="python plain">)
<div class="line number15 index14 alt2">
<div class="line number16 index15 alt1"><code class="python plain">pipe.execute()</td>
</tr>
</table>
11、发布订阅
发布者:服务器
订阅者:Dashboad和数据处理
Demo如下:
<span style="color: #0000ff;">import
<span style="color: #000000;"> redis <span style="color: #0000ff;">class<span style="color: #000000;"> RedisHelper:</span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__init__</span><span style="color: #000000;">(self): self.</span><span style="color: #800080;">__conn</span> = redis.Redis(host=<span style="color: #800000;">'</span><span style="color: #800000;">10.211.55.4</span><span style="color: #800000;">'</span><span style="color: #000000;">) self.chan_sub </span>= <span style="color: #800000;">'</span><span style="color: #800000;">fm104.5</span><span style="color: #800000;">'</span><span style="color: #000000;"> self.chan_pub </span>= <span style="color: #800000;">'</span><span style="color: #800000;">fm104.5</span><span style="color: #800000;">'</span> <span style="color: #0000ff;">def</span><span style="color: #000000;"> public(self,msg): self.</span><span style="color: #800080;">__conn</span><span style="color: #000000;">.publish(self.chan_pub,msg) </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> True </span><span style="color: #0000ff;">def</span><span style="color: #000000;"> subscribe(self): pub </span>= self.<span style="color: #800080;">__conn</span><span style="color: #000000;">.pubsub() pub.subscribe(self.chan_sub) pub.parse_response() </span><span style="color: #0000ff;">return</span> pub</pre>
订阅者:
发布者:
Highlighter sh-gutter">更多参见:https://github.com/andymccurdy/redis-py/
http://doc.redisfans.com/
三.操作表
<div class="c-markdown">
key操作
在这里主要将Key的一些判断和操作方法做下总结:
方法 作用 参数说明 示例 示例说明 示例结果exists(name) 判断一个key是否存在 name: key名 redis.exists('name') 是否存在name这个key True delete(name) 删除一个key name: key名 redis.delete('name') 删除name这个key 1 type(name) 判断key类型 name: key名 redis.type('name') 判断name这个key类型 b'string' keys(pattern) 获取所有符合规则的key pattern: 匹配规则 redis.keys('n*') 获取所有以n开头的key [b'name'] randomkey() 获取随机的一个key randomkey() 获取随机的一个key b'name' rename(src,dst) 将key重命名 src: 原key名 dst: 新key名 redis.rename('name','nickname') 将name重命名为nickname True dbsize() 获取当前数据库中key的数目 dbsize() 获取当前数据库中key的数目 100 expire(name,time) 设定key的过期时间,单位秒 name: key名 time: 秒数 redis.expire('name',2) 将name这key的过期时间设置2秒 True ttl(name) 获取key的过期时间,单位秒,-1为永久不过期 name: key名 redis.ttl('name') 获取name这key的过期时间 -1 move(name,db) 将key移动到其他数据库 name: key名 db: 数据库代号 move('name',2) 将name移动到2号数据库 True flushdb() 删除当前选择数据库中的所有key flushdb() 删除当前选择数据库中的所有key True flushall() 删除所有数据库中的所有key flushall() 删除所有数据库中的所有key True String操作
方法 作用 参数说明 示例 示例说明 示例结果set(name,value) 给数据库中key为name的string赋予值value name: key名 value: 值 redis.set('name','Bob') 给name这个key的value赋值为Bob True get(name) 返回数据库中key为name的string的value name: key名 redis.get('name') 返回name这个key的value b'Bob' getset(name,value) 给数据库中key为name的string赋予值value并返回上次的value name: key名 value: 新值 redis.getset('name','Mike') 赋值name为Mike并得到上次的value b'Bob' mget(keys,*args) 返回多个key对应的value keys: key的列表 redis.mget(['name','nickname']) 返回name和nickname的value [b'Mike',b'Miker'] setnx(name,value) 如果key不存在才设置value name: key名 redis.setnx('newname','James') 如果newname这key不存在则设置值为James 第一次运行True,第二次False setex(name,time,value) 设置可以对应的值为string类型的value,并指定此键值对应的有效期 name: key名 time: 有效期 value: 值 redis.setex('name','James') 将name这key的值设为James,有效期1秒 True setrange(name,value) 设置指定key的value值的子字符串 name: key名 offset: 偏移量 value: 值 redis.set('name','Hello') redis.setrange('name',6,'World') 设置name为Hello字符串,并在index为6的位置补World 11,修改后的字符串长度 mset(mapping) 批量赋值 mapping: 字典 redis.mset({'name1': 'Durant','name2': 'James'}) 将name1设为Durant,name2设为James True msetnx(mapping) key均不存在时才批量赋值 mapping: 字典 redis.msetnx({'name3': 'Smith','name4': 'Curry'}) 在name3和name4均不存在的情况下才设置二者值 True incr(name,amount=1) key为name的value增值操作,默认1,key不存在则被创建并设为amount name: key名 amount:增长的值 redis.incr('age',1) age对应的值增1,若不存在则会创建并设置为1 1,即修改后的值 decr(name,amount=1) key为name的value减值操作,默认1,key不存在则被创建并设置为-amount name: key名 amount:减少的值 redis.decr('age',1) age对应的值减1,若不存在则会创建并设置为-1 -1,即修改后的值 append(key,value) key为name的string的值附加value key: key名 redis.append('nickname','OK') 向key为nickname的值后追加OK 13,即修改后的字符串长度 substr(name,end=-1) 返回key为name的string的value的子串 name: key名 start: 起始索引 end: 终止索引,默认-1截取到末尾 redis.substr('name',4) 返回key为name的值的字符串,截取索引为1-4的字符 b'ello' getrange(key,end) 获取key的value值从start到end的子字符串 key: key名 start: 起始索引 end: 终止索引 redis.getrange('name',4) 返回key为name的值的字符串,截取索引为1-4的字符 b'ello' List操作
方法 作用 参数说明 示例 示例说明 示例结果rpush(name,*values) 在key为name的list尾添加值为value的元素,可以传多个 name: key名 values: 值 redis.rpush('list',2,3) 给list这个key的list尾添加1、2、3 3,list大小 lpush(name,*values) 在key为name的list头添加值为value的元素,可以传多个 name: key名 values: 值 redis.lpush('list',0) 给list这个key的list头添加0 4,list大小 llen(name) 返回key为name的list的长度 name: key名 redis.llen('list') 返回key为list的列表的长度 4 lrange(name,end) 返回key为name的list中start至end之间的元素 name: key名 start: 起始索引 end: 终止索引 redis.lrange('list',3) 返回起始为1终止为3的索引范围对应的list [b'3',b'2',b'1'] ltrim(name,end) 截取key为name的list,保留索引为start到end的内容 name:key名 start: 起始索引 end: 终止索引 ltrim('list',3) 保留key为list的索引为1到3的元素 True lindex(name,index) 返回key为name的list中index位置的元素 name: key名 index: 索引 redis.lindex('list',1) 返回key为list的列表index为1的元素 b'2' lset(name,value) 给key为name的list中index位置的元素赋值,越界则报错 name: key名 index: 索引位置 value: 值 redis.lset('list',5) 将key为list的list索引1位置赋值为5 True lrem(name,count,value) 删除count个key的list中值为value的元素 name: key名 count: 删除个数 value: 值 redis.lrem('list',3) 将key为list的列表删除2个3 1,即删除的个数 lpop(name) 返回并删除key为name的list中的首元素 name: key名 redis.lpop('list') 返回并删除名为list的list第一个元素 b'5' rpop(name) 返回并删除key为name的list中的尾元素 name: key名 redis.rpop('list') 返回并删除名为list的list最后一个元素 b'2' blpop(keys,timeout=0) 返回并删除名称为在keys中的list中的首元素,如果list为空,则会一直阻塞等待 keys: key列表 timeout: 超时等待时间,0为一直等待 redis.blpop('list') 返回并删除名为list的list的第一个元素 [b'5'] brpop(keys,timeout=0) 返回并删除key为name的list中的尾元素,如果list为空,则会一直阻塞等待 keys: key列表 timeout: 超时等待时间,0为一直等待 redis.brpop('list') 返回并删除名为list的list的最后一个元素 [b'2'] rpoplpush(src,dst) 返回并删除名称为src的list的尾元素,并将该元素添加到名称为dst的list的头部 src: 源list的key dst: 目标list的key redis.rpoplpush('list','list2') 将key为list的list尾元素删除并返回并将其添加到key为list2的list头部 b'2' Set操作
方法 作用 参数说明 示例 示例说明 示例结果sadd(name,*values) 向key为name的set中添加元素 name: key名 values: 值,可为多个 redis.sadd('tags','Book','Tea','Coffee') 向key为tags的set中添加Book、Tea、Coffee三个内容 3,即插入的数据个数 srem(name,*values) 从key为name的set中删除元素 name: key名 values: 值,可为多个 redis.srem('tags','Book') 从key为tags的set中删除Book 1,即删除的数据个数 spop(name) 随机返回并删除key为name的set中一个元素 name: key名 redis.spop('tags') 从key为tags的set中随机删除并返回该元素 b'Tea' smove(src,value) 从src对应的set中移除元素并添加到dst对应的set中 src: 源set dst: 目标set value: 元素值 redis.smove('tags','tags2','Coffee') 从key为tags的set中删除元素Coffee并添加到key为tags2的set True scard(name) 返回key为name的set的元素个数 name: key名 redis.scard('tags') 获取key为tags的set中元素个数 3 sismember(name,value) 测试member是否是key为name的set的元素 name:key值 redis.sismember('tags','Book') 判断Book是否为key为tags的set元素 True sinter(keys,*args) 返回所有给定key的set的交集 keys: key列表 redis.sinter(['tags','tags2']) 返回key为tags的set和key为tags2的set的交集 {b'Coffee'} sinterstore(dest,*args) 求交集并将交集保存到dest的集合 dest:结果集合 keys:key列表 redis.sinterstore('inttag',['tags','tags2']) 求key为tags的set和key为tags2的set的交集并保存为inttag 1 sunion(keys,*args) 返回所有给定key的set的并集 keys: key列表 redis.sunion(['tags','tags2']) 返回key为tags的set和key为tags2的set的并集 {b'Coffee',b'Book',b'Pen'} sunionstore(dest,*args) 求并集并将并集保存到dest的集合 dest:结果集合 keys:key列表 redis.sunionstore('inttag','tags2']) 求key为tags的set和key为tags2的set的并集并保存为inttag 3 sdiff(keys,*args) 返回所有给定key的set的差集 keys: key列表 redis.sdiff(['tags','tags2']) 返回key为tags的set和key为tags2的set的差集 {b'Book',b'Pen'} sdiffstore(dest,*args) 求差集并将差集保存到dest的集合 dest:结果集合 keys:key列表 redis.sdiffstore('inttag','tags2']) 求key为tags的set和key为tags2的set的差集并保存为inttag 3 smembers(name) 返回key为name的set的所有元素 name: key名 redis.smembers('tags') 返回key为tags的set的所有元素 {b'Pen',b'Coffee'} srandmember(name) 随机返回key为name的set的一个元素,但不删除元素 name: key值 redis.srandmember('tags') 随机返回key为tags的set的一个元素 Sorted Set操作
方法 作用 参数说明 示例 示例说明 示例结果zadd(name,args,*kwargs) 向key为name的zset中添加元素member,score用于排序。如果该元素存在,则更新其顺序 name: key名 args: 可变参数 redis.zadd('grade',100,'Bob',98,'Mike') 向key为grade的zset中添加Bob,score为100,添加Mike,score为98 2,即添加的元素个数 zrem(name,*values) 删除key为name的zset中的元素 name: key名 values: 元素 redis.zrem('grade','Mike') 从key为grade的zset中删除Mike 1,即删除的元素个数 zincrby(name,amount=1) 如果在key为name的zset中已经存在元素value,则该元素的score增加amount,否则向该集合中添加该元素,其score的值为amount name: key名 value: 元素 amount: 增长的score值 redis.zincrby('grade',-2) key为grade的zset中Bob的score减2 98.0,即修改后的值 zrank(name,value) 返回key为name的zset中元素的排名(按score从小到大排序)即下标 name: key名 value: 元素值 redis.zrank('grade','Amy') 得到key为grade的zset中Amy的排名 1 zrevrank(name,value) 返回key为name的zset中元素的倒数排名(按score从大到小排序)即下标 name: key名 value: 元素值 redis.zrevrank('grade','Amy') 得到key为grade的zset中Amy的倒数排名 2 zrevrange(name,withscores=False) 返回key为name的zset(按score从大到小排序)中的index从start到end的所有元素 name: key值 start: 开始索引 end: 结束索引 withscores: 是否带score redis.zrevrange('grade',3) 返回key为grade的zset前四名元素 [b'Bob',b'Mike',b'Amy',b'James'] zrangebyscore(name,withscores=False) 返回key为name的zset中score在给定区间的元素 name:key名 min: 最低score max:最高score start: 起始索引 num: 个数 withscores: 是否带score redis.zrangebyscore('grade',80,95) 返回key为grade的zset中score在80和95之间的元素 zcount(name,max) 返回key为name的zset中score在给定区间的数量 name:key名 min: 最低score max: 最高score redis.zcount('grade',95) 返回key为grade的zset中score在80到95的元素个数 2 zcard(name) 返回key为name的zset的元素个数 name: key名 redis.zcard('grade') 获取key为grade的zset中元素个数 3 zremrangebyrank(name,max) 删除key为name的zset中排名在给定区间的元素 name:key名 min: 最低位次 max: 最高位次 redis.zremrangebyrank('grade',0) 删除key为grade的zset中排名第一的元素 1,即删除的元素个数 zremrangebyscore(name,max) 删除key为name的zset中score在给定区间的元素 name:key名 min: 最低score max:最高score redis.zremrangebyscore('grade',90) 删除score在80到90之间的元素 1,即删除的元素个数 Hash操作
方法 作用 参数说明 示例 示例说明 示例结果hset(name,value) 向key为name的hash中添加映射 name: key名 key: 映射键名 value: 映射键值 hset('price','cake',5) 向key为price的hash中添加映射关系,cake的值为5 1,即添加的映射个数 hsetnx(name,value) 向key为name的hash中添加映射,如果映射键名不存在 name: key名 key: 映射键名 value: 映射键值 hsetnx('price','book',6) 向key为price的hash中添加映射关系,book的值为6 1,即添加的映射个数 hget(name,key) 返回key为name的hash中field对应的value name: key名 key: 映射键名 redis.hget('price','cake') 获取key为price的hash中键名为cake的value 5 hmget(name,*args) 返回key为name的hash中各个键对应的value name: key名 keys: 映射键名列表 redis.hmget('price',['apple','orange']) 获取key为price的hash中apple和orange的值 [b'3',b'7'] hmset(name,mapping) 向key为name的hash中批量添加映射 name: key名 mapping: 映射字典 redis.hmset('price',{'banana': 2,'pear': 6}) 向key为price的hash中批量添加映射 True hincrby(name,amount=1) 将key为name的hash中映射的value增加amount name: key名 key: 映射键名 amount: 增长量 redis.hincrby('price','apple',3) key为price的hash中apple的值增加3 6,修改后的值 hexists(name,key) key为namehash中是否存在键名为key的映射 name: key名 key: 映射键名 redis.hexists('price','banana') key为price的hash中banana的值是否存在 True hdel(name,*keys) key为namehash中删除键名为key的映射 name: key名 key: 映射键名 redis.hdel('price','banana') 从key为price的hash中删除键名为banana的映射 True hlen(name) 从key为name的hash中获取映射个数 name: key名 redis.hlen('price') 从key为price的hash中获取映射个数 6 hkeys(name) 从key为name的hash中获取所有映射键名 name: key名 redis.hkeys('price') 从key为price的hash中获取所有映射键名 [b'cake',b'book',b'banana',b'pear'] hvals(name) 从key为name的hash中获取所有映射键值 name: key名 redis.hvals('price') 从key为price的hash中获取所有映射键值 [b'5',b'6',b'6'] hgetall(name) 从key为name的hash中获取所有映射键值对 name: key名 redis.hgetall('price') 从key为price的hash中获取所有映射键值对 {b'cake': b'5',b'book': b'6',b'orange': b'7',b'pear': b'6'}
RabbitMQ
RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统。他遵循Mozilla Public License开源协议。
MQ全称为Message Queue,(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消 息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如的技术。排队指的是应用程序通过 队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。
RabbitMQ安装
注意:service rabbitmq-server start/stop
安装API
Highlighter sh-gutter">使用API操作RabbitMQ
基于Queue实现生产者消费者模型
message = Queue.Queue(10<span style="color: #000000;">) <span style="color: #0000ff;">def<span style="color: #000000;"> producer(i):
<span style="color: #0000ff;">while<span style="color: #000000;"> True:
message.put(i) <span style="color: #0000ff;">def<span style="color: #000000;"> consumer(i):
<span style="color: #0000ff;">while<span style="color: #000000;"> True:
msg =<span style="color: #000000;"> message.get()<span style="color: #0000ff;">for i <span style="color: #0000ff;">in range(12<span style="color: #000000;">):
t = threading.Thread(target=producer,args=<span style="color: #000000;">(i,))
t.start()<span style="color: #0000ff;">for i <span style="color: #0000ff;">in range(10<span style="color: #000000;">):
t = threading.Thread(target=consumer,))
t.start()对于RabbitMQ来说,生产和消费不再针对内存里的一个Queue对象,而是某台服务器上的RabbitMQ Server实现的消息队列。
Highlighter sh-gutter">1、acknowledgment 消息不丢失
no-ack = False,如果消费者遇到情况(its channel is closed,connection is closed,or TCP connection is lost)挂掉了,那么,RabbitMQ会重新将该任务添加到队列中。
connection =<span style="color: #000000;"> pika.BlockingConnection(pika.ConnectionParameters(
host=<span style="color: #800000;">'<span style="color: #800000;">10.211.55.4<span style="color: #800000;">'<span style="color: #000000;">))
channel =<span style="color: #000000;"> connection.channel()channel.queue_declare(queue=<span style="color: #800000;">'<span style="color: #800000;">hello<span style="color: #800000;">'<span style="color: #000000;">)
<span style="color: #0000ff;">def<span style="color: #000000;"> callback(ch,body):
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;"> [x] Received %r<span style="color: #800000;">" %<span style="color: #000000;"> body)
<span style="color: #0000ff;">import<span style="color: #000000;"> time
time.sleep(10<span style="color: #000000;">)
<span style="color: #0000ff;">print <span style="color: #800000;">'<span style="color: #800000;">ok<span style="color: #800000;">'<span style="color: #000000;">
ch.basic_ack(delivery_tag =<span style="color: #000000;"> method.delivery_tag)channel.basic_consume(callback,queue=<span style="color: #800000;">'<span style="color: #800000;">hello<span style="color: #800000;">'<span style="color: #000000;">,no_ack=<span style="color: #000000;">False)
<span style="color: #0000ff;">print(<span style="color: #800000;">'<span style="color: #800000;"> [*] Waiting for messages. To exit press CTRL+C<span style="color: #800000;">'<span style="color: #000000;">)
channel.start_consuming()2、
connection = pika.BlockingConnection(pika.ConnectionParameters(host=<span style="color: #800000;">'<span style="color: #800000;">10.211.55.4<span style="color: #800000;">'<span style="color: #000000;">))
channel =<span style="color: #000000;"> connection.channel()<span style="color: #008000;">#<span style="color: #008000;"> make message persistent
channel.queue_declare(queue=<span style="color: #800000;">'<span style="color: #800000;">hello<span style="color: #800000;">',durable=<span style="color: #000000;">True)channel.basic_publish(exchange=<span style="color: #800000;">''<span style="color: #000000;">,routing_key=<span style="color: #800000;">'<span style="color: #800000;">hello<span style="color: #800000;">'<span style="color: #000000;">,body=<span style="color: #800000;">'<span style="color: #800000;">Hello World!<span style="color: #800000;">'<span style="color: #000000;">,properties=<span style="color: #000000;">pika.BasicProperties(
delivery_mode=2,<span style="color: #008000;">#<span style="color: #008000;"> make message persistent
<span style="color: #000000;"> ))
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;"> [x] Sent 'Hello World!'<span style="color: #800000;">"<span style="color: #000000;">)
connection.close()connection = pika.BlockingConnection(pika.ConnectionParameters(host=<span style="color: #800000;">'<span style="color: #800000;">10.211.55.4<span style="color: #800000;">'<span style="color: #000000;">))
channel =<span style="color: #000000;"> connection.channel() <span style="color: #008000;">#<span style="color: #008000;"> make message persistent
channel.queue_declare(queue=<span style="color: #800000;">'<span style="color: #800000;">hello<span style="color: #800000;">',durable=<span style="color: #000000;">True)<span style="color: #0000ff;">def<span style="color: #000000;"> callback(ch,no_ack=<span style="color: #000000;">False)
<span style="color: #0000ff;">print(<span style="color: #800000;">'<span style="color: #800000;"> [*] Waiting for messages. To exit press CTRL+C<span style="color: #800000;">'<span style="color: #000000;">)
channel.start_consuming()
channel.basic_qos(prefetch_count=1) 表示谁来谁取,不再按照奇偶数排列
connection = pika.BlockingConnection(pika.ConnectionParameters(host=<span style="color: #800000;">'<span style="color: #800000;">10.211.55.4<span style="color: #800000;">'<span style="color: #000000;">))
channel =<span style="color: #000000;"> connection.channel() <span style="color: #008000;">#<span style="color: #008000;"> make message persistent
channel.queue_declare(queue=<span style="color: #800000;">'<span style="color: #800000;">hello<span style="color: #800000;">'<span style="color: #000000;">)<span style="color: #0000ff;">def<span style="color: #000000;"> callback(ch,body):
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;"> [x] Received %r<span style="color: #800000;">" %<span style="color: #000000;"> body)
<span style="color: #0000ff;">import<span style="color: #000000;"> time
time.sleep(10<span style="color: #000000;">)
<span style="color: #0000ff;">print <span style="color: #800000;">'<span style="color: #800000;">ok<span style="color: #800000;">'<span style="color: #000000;">
ch.basic_ack(delivery_tag =<span style="color: #000000;"> method.delivery_tag)channel.basic_qos(prefetch_count=1<span style="color: #000000;">)
channel.basic_consume(callback,no_ack=<span style="color: #000000;">False)
<span style="color: #0000ff;">print(<span style="color: #800000;">'<span style="color: #800000;"> [*] Waiting for messages. To exit press CTRL+C<span style="color: #800000;">'<span style="color: #000000;">)
channel.start_consuming()4、发布订阅
发布订阅和简单的消息队列区别在于,发布订阅会将消息发送给所有的订阅者,而消息队列中的数据被消费一次便消失。所以,RabbitMQ实现发布和订阅时,会为每一个订阅者创建一个队列,而发布者发布消息时,会将消息放置在所有相关队列中。
exchange_type = fanout
connection =<span style="color: #000000;"> pika.BlockingConnection(pika.ConnectionParameters(
host=<span style="color: #800000;">'<span style="color: #800000;">localhost<span style="color: #800000;">'<span style="color: #000000;">))
channel =<span style="color: #000000;"> connection.channel()channel.exchange_declare(exchange=<span style="color: #800000;">'<span style="color: #800000;">logs<span style="color: #800000;">'<span style="color: #000000;">,exchange_type=<span style="color: #800000;">'<span style="color: #800000;">fanout<span style="color: #800000;">'<span style="color: #000000;">)
message = <span style="color: #800000;">' <span style="color: #800000;">'.join(sys.argv[1:]) <span style="color: #0000ff;">or <span style="color: #800000;">"<span style="color: #800000;">info: Hello World!<span style="color: #800000;">"<span style="color: #000000;">
channel.basic_publish(exchange=<span style="color: #800000;">'<span style="color: #800000;">logs<span style="color: #800000;">'<span style="color: #000000;">,routing_key=<span style="color: #800000;">''<span style="color: #000000;">,body=<span style="color: #000000;">message)
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;"> [x] Sent %r<span style="color: #800000;">" %<span style="color: #000000;"> message)
connection.close()connection =<span style="color: #000000;"> pika.BlockingConnection(pika.ConnectionParameters(
host=<span style="color: #800000;">'<span style="color: #800000;">localhost<span style="color: #800000;">'<span style="color: #000000;">))
channel =<span style="color: #000000;"> connection.channel()channel.exchange_declare(exchange=<span style="color: #800000;">'<span style="color: #800000;">logs<span style="color: #800000;">'<span style="color: #000000;">,exchange_type=<span style="color: #800000;">'<span style="color: #800000;">fanout<span style="color: #800000;">'<span style="color: #000000;">)
result = channel.queue_declare(exclusive=<span style="color: #000000;">True)
queue_name =<span style="color: #000000;"> result.method.queuechannel.queue_bind(exchange=<span style="color: #800000;">'<span style="color: #800000;">logs<span style="color: #800000;">'<span style="color: #000000;">,queue=<span style="color: #000000;">queue_name)
<span style="color: #0000ff;">print(<span style="color: #800000;">'<span style="color: #800000;"> [*] Waiting for logs. To exit press CTRL+C<span style="color: #800000;">'<span style="color: #000000;">)
<span style="color: #0000ff;">def<span style="color: #000000;"> callback(ch,body):
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;"> [x] %r<span style="color: #800000;">" %<span style="color: #000000;"> body)channel.basic_consume(callback,queue=<span style="color: #000000;">queue_name,no_ack=<span style="color: #000000;">True)
channel.start_consuming()
5、关键字发送
exchange_type = direct
之前事例,发送消息时明确指定某个队列并向其中发送消息,RabbitMQ还支持根据关键字发送,即:队列绑定关键字,发送者将数据根据关键字发送到消息exchange,exchange根据 关键字 判定应该将数据发送至指定队列。
connection =<span style="color: #000000;"> pika.BlockingConnection(pika.ConnectionParameters(
host=<span style="color: #800000;">'<span style="color: #800000;">localhost<span style="color: #800000;">'<span style="color: #000000;">))
channel =<span style="color: #000000;"> connection.channel()channel.exchange_declare(exchange=<span style="color: #800000;">'<span style="color: #800000;">direct_logs<span style="color: #800000;">'<span style="color: #000000;">,exchange_type=<span style="color: #800000;">'<span style="color: #800000;">direct<span style="color: #800000;">'<span style="color: #000000;">)
result = channel.queue_declare(exclusive=<span style="color: #000000;">True)
queue_name =<span style="color: #000000;"> result.method.queueseverities = sys.argv[1<span style="color: #000000;">:]
<span style="color: #0000ff;">if <span style="color: #0000ff;">not<span style="color: #000000;"> severities:
sys.stderr.write(<span style="color: #800000;">"<span style="color: #800000;">Usage: %s [info] [warning] [error]\n<span style="color: #800000;">" %<span style="color: #000000;"> sys.argv[0])
sys.exit(1<span style="color: #000000;">)<span style="color: #0000ff;">for severity <span style="color: #0000ff;">in<span style="color: #000000;"> severities:
channel.queue_bind(exchange=<span style="color: #800000;">'<span style="color: #800000;">direct_logs<span style="color: #800000;">'<span style="color: #000000;">,routing_key=<span style="color: #000000;">severity)<span style="color: #0000ff;">print(<span style="color: #800000;">'<span style="color: #800000;"> [*] Waiting for logs. To exit press CTRL+C<span style="color: #800000;">'<span style="color: #000000;">)
<span style="color: #0000ff;">def<span style="color: #000000;"> callback(ch,body):
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;"> [x] %r:%r<span style="color: #800000;">" %<span style="color: #000000;"> (method.routing_key,body))channel.basic_consume(callback,no_ack=<span style="color: #000000;">True)
channel.start_consuming()
connection =<span style="color: #000000;"> pika.BlockingConnection(pika.ConnectionParameters(
host=<span style="color: #800000;">'<span style="color: #800000;">localhost<span style="color: #800000;">'<span style="color: #000000;">))
channel =<span style="color: #000000;"> connection.channel()channel.exchange_declare(exchange=<span style="color: #800000;">'<span style="color: #800000;">direct_logs<span style="color: #800000;">'<span style="color: #000000;">,exchange_type=<span style="color: #800000;">'<span style="color: #800000;">direct<span style="color: #800000;">'<span style="color: #000000;">)
severity = sys.argv[1] <span style="color: #0000ff;">if len(sys.argv) > 1 <span style="color: #0000ff;">else <span style="color: #800000;">'<span style="color: #800000;">info<span style="color: #800000;">'<span style="color: #000000;">
message = <span style="color: #800000;">' <span style="color: #800000;">'.join(sys.argv[2:]) <span style="color: #0000ff;">or <span style="color: #800000;">'<span style="color: #800000;">Hello World!<span style="color: #800000;">'<span style="color: #000000;">
channel.basic_publish(exchange=<span style="color: #800000;">'<span style="color: #800000;">direct_logs<span style="color: #800000;">'<span style="color: #000000;">,routing_key=<span style="color: #000000;">severity,body=<span style="color: #000000;">message)
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;"> [x] Sent %r:%r<span style="color: #800000;">" %<span style="color: #000000;"> (severity,message))
connection.close()6、模糊匹配
exchange_type = topic
在topic类型下,可以让队列绑定几个模糊的关键字,之后发送者将数据发送到exchange,exchange将传入”路由值“和 ”关键字“进行匹配,匹配成功,则将数据发送到指定队列。
- # 表示可以匹配 0 个 或 多个 单词
- * 表示只能匹配 一个 单词
pika connection =<span style="color: #000000;"> pika.BlockingConnection(pika.ConnectionParameters(
host=<span style="color: #800000;">'<span style="color: #800000;">localhost<span style="color: #800000;">'<span style="color: #000000;">))
channel =<span style="color: #000000;"> connection.channel()channel.exchange_declare(exchange=<span style="color: #800000;">'<span style="color: #800000;">topic_logs<span style="color: #800000;">'<span style="color: #000000;">,exchange_type=<span style="color: #800000;">'<span style="color: #800000;">topic<span style="color: #800000;">'<span style="color: #000000;">)
result = channel.queue_declare(exclusive=<span style="color: #000000;">True)
queue_name =<span style="color: #000000;"> result.method.queuebinding_keys = sys.argv[1<span style="color: #000000;">:]
<span style="color: #0000ff;">if <span style="color: #0000ff;">not<span style="color: #000000;"> binding_keys:
sys.stderr.write(<span style="color: #800000;">"<span style="color: #800000;">Usage: %s [binding_key]...\n<span style="color: #800000;">" %<span style="color: #000000;"> sys.argv[0])
sys.exit(1<span style="color: #000000;">)<span style="color: #0000ff;">for binding_key <span style="color: #0000ff;">in<span style="color: #000000;"> binding_keys:
channel.queue_bind(exchange=<span style="color: #800000;">'<span style="color: #800000;">topic_logs<span style="color: #800000;">'<span style="color: #000000;">,routing_key=<span style="color: #000000;">binding_key)<span style="color: #0000ff;">print(<span style="color: #800000;">'<span style="color: #800000;"> [*] Waiting for logs. To exit press CTRL+C<span style="color: #800000;">'<span style="color: #000000;">)
<span style="color: #0000ff;">def<span style="color: #000000;"> callback(ch,no_ack=<span style="color: #000000;">True)
channel.start_consuming()
pika connection =<span style="color: #000000;"> pika.BlockingConnection(pika.ConnectionParameters(
host=<span style="color: #800000;">'<span style="color: #800000;">localhost<span style="color: #800000;">'<span style="color: #000000;">))
channel =<span style="color: #000000;"> connection.channel()channel.exchange_declare(exchange=<span style="color: #800000;">'<span style="color: #800000;">topic_logs<span style="color: #800000;">'<span style="color: #000000;">,exchange_type=<span style="color: #800000;">'<span style="color: #800000;">topic<span style="color: #800000;">'<span style="color: #000000;">)
routing_key = sys.argv[1] <span style="color: #0000ff;">if len(sys.argv) > 1 <span style="color: #0000ff;">else <span style="color: #800000;">'<span style="color: #800000;">anonymous.info<span style="color: #800000;">'<span style="color: #000000;">
message = <span style="color: #800000;">' <span style="color: #800000;">'.join(sys.argv[2:]) <span style="color: #0000ff;">or <span style="color: #800000;">'<span style="color: #800000;">Hello World!<span style="color: #800000;">'<span style="color: #000000;">
channel.basic_publish(exchange=<span style="color: #800000;">'<span style="color: #800000;">topic_logs<span style="color: #800000;">'<span style="color: #000000;">,routing_key=<span style="color: #000000;">routing_key,body=<span style="color: #000000;">message)
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;"> [x] Sent %r:%r<span style="color: #800000;">" %<span style="color: #000000;"> (routing_key,message))
connection.close()注意:
<div class="cnblogs_code" onclick="cnblogs_code_show('bb167bb0-526c-4724-8488-4f1b64fe0e82')">
<div id="cnblogs_code_open_bb167bb0-526c-4724-8488-4f1b64fe0e82" class="cnblogs_code_hide">sudo rabbitmqctl add_user alex 123 用户为administrator角色 sudo rabbitmqctl set_permissions -p alex
<span style="color: #008000;">#
<span style="color: #008000;"> 然后重启rabbiMQ服务
sudo /etc/init.d/rabbitmq-<span style="color: #000000;">server restart <span style="color: #008000;">#<span style="color: #008000;"> 然后可以使用刚才的用户远程连接rabbitmq server了。------------------------------<span style="color: #000000;">
= pika.PlainCredentials(<span style="color: #800000;">"<span style="color: #800000;">alex<span style="color: #800000;">",<span style="color: #800000;">"<span style="color: #800000;">123<span style="color: #800000;">"<span style="color: #000000;">)
credentialsconnection
= pika.BlockingConnection(pika.ConnectionParameters(<span style="color: #800000;">'<span style="color: #800000;">192.168.14.47<span style="color: #800000;">',credentials=credentials))sqlAlchemy
sqlAlchemy是编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果。
Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作,如:
MysqL
MysqL
MysqLdb:
:
@ [: ]
MysqLMysqL
MysqL:
:
@
[?
] MysqL
MysqL
MysqLconnector:
:
@ [: ]
dbname[?key
sqlalchemy.org
步骤一:
使用 Engine/ConnectionPooling/Dialect 进行数据库操作,Engine使用ConnectionPooling连接数据库,然后再通过Dialect执行sql语句。
Highlighter sh-gutter"><span style="color: #0000ff;">from
sqlalchemy <span style="color: #0000ff;">import<span style="color: #000000;"> create_engineengine
= create_engine(<span style="color: #800000;">"<span style="color: #800000;">mysql+mysqldb://root:123@127.0.0.1:3306/s11<span style="color: #800000;">",max_overflow=5<span style="color: #000000;">)<span style="color: #008000;">#<span style="color: #008000;"> 事务操作
<span style="color: #000000;">with engine.begin() as conn:
conn.execute(<span style="color: #800000;">"<span style="color: #800000;">insert into table (x,y,z) values (1,3)<span style="color: #800000;">"<span style="color: #000000;">)
conn.execute(<span style="color: #800000;">"<span style="color: #800000;">my_special_procedure(5)<span style="color: #800000;">"<span style="color: #000000;">)conn =<span style="color: #000000;"> engine.connect()
<span style="color: #008000;">#<span style="color: #008000;"> 事务操作
<span style="color: #000000;">with conn.begin():
conn.execute(<span style="color: #800000;">"<span style="color: #800000;">some statement<span style="color: #800000;">",{<span style="color: #800000;">'<span style="color: #800000;">x<span style="color: #800000;">':5,<span style="color: #800000;">'<span style="color: #800000;">y<span style="color: #800000;">':10})
步骤二:
使用 Schema Type/SQL Expression Language/Engine/ConnectionPooling/Dialect 进行数据库操作。Engine使用Schema Type创建一个特定的结构对象,之后通过SQL Expression Language将该对象转换成SQL语句,然后通过ConnectionPooling 连接数据库,再然后通过Dialect 执行SQL,并获取结果。
sqlalchemy
MetaData,ForeignKey
Metadata
MetaData()
Metadata,
MysqL+MysqLdb://root:123@127.0.0.1:3306/s11"
Metadata.create_all(engine)Metadata.clear()Metadata.remove()<span style="color: #0000ff;">from
sqlalchemy <span style="color: #0000ff;">import<span style="color: #000000;"> create_engine,ForeignKeyMetadata
=<span style="color: #000000;"> MetaData()user
= Table(<span style="color: #800000;">'<span style="color: #800000;">user<span style="color: #800000;">'<span style="color: #000000;">,Column(<span style="color: #800000;">'<span style="color: #800000;">id<span style="color: #800000;">',primary_key=<span style="color: #000000;">True),Column(<span style="color: #800000;">'<span style="color: #800000;">name<span style="color: #800000;">',String(20<span style="color: #000000;">)),)color = Table(<span style="color: #800000;">'<span style="color: #800000;">color<span style="color: #800000;">'<span style="color: #000000;">,)
engine = create_engine(<span style="color: #800000;">"<span style="color: #800000;">MysqL+MysqLdb://root:123@127.0.0.1:3306/s11<span style="color: #800000;">",max_overflow=5<span style="color: #000000;">)conn =<span style="color: #000000;"> engine.connect()
<span style="color: #008000;">#<span style="color: #008000;"> 创建sql语句,INSERT INTO "user" (id,name) VALUES (:id,:name)
conn.execute(user.insert(),{<span style="color: #800000;">'<span style="color: #800000;">id<span style="color: #800000;">':7,<span style="color: #800000;">'<span style="color: #800000;">name<span style="color: #800000;">':<span style="color: #800000;">'<span style="color: #800000;">seven<span style="color: #800000;">'<span style="color: #000000;">})
conn.close()<span style="color: #008000;">#<span style="color: #008000;"> sql = user.insert().values(id=123,name='wu')<span style="color: #008000;">
<span style="color: #008000;"> conn.execute(sql)<span style="color: #008000;">
<span style="color: #008000;"> conn.close()
<span style="color: #008000;">#<span style="color: #008000;"> sql = user.delete().where(user.c.id > 1)
<span style="color: #008000;">#<span style="color: #008000;"> sql = user.update().values(fullname=user.c.name)<span style="color: #008000;">
<span style="color: #008000;"> sql = user.update().where(user.c.name == 'jack').values(name='ed')
<span style="color: #008000;">#<span style="color: #008000;"> sql = select([user,])<span style="color: #008000;">
<span style="color: #008000;"> sql = select([user.c.id,])<span style="color: #008000;">
<span style="color: #008000;"> sql = select([user.c.name,color.c.name]).where(user.c.id==color.c.id)<span style="color: #008000;">
<span style="color: #008000;"> sql = select([user.c.name]).order_by(user.c.name)<span style="color: #008000;">
<span style="color: #008000;"> sql = select([user]).group_by(user.c.name)
<span style="color: #008000;">#<span style="color: #008000;"> result = conn.execute(sql)<span style="color: #008000;">
<span style="color: #008000;"> print result.fetchall()<span style="color: #008000;">
<span style="color: #008000;"> conn.close()
更多内容详见:
http://www.jianshu.com/p/e6bba189fcbd
http://docs.sqlalchemy.org/en/latest/core/expression_api.html
注:sqlAlchemy无法修改表结构,如果需要可以使用sqlAlchemy开发者开源的另外一个软件Alembic来完成。
步骤三:
使用 ORM/Schema Type/sql Expression Language/Engine/ConnectionPooling/Dialect 所有组件对数据进行操作。根据类创建对象,对象转换成sql,执行sql。
Highlighter sh-gutter">更多功能参见文档,下载PDF
dis的两种链接方式
相关文章
优化MySQL数据库发布系统存储的方法有:1.mysql库主从读写分...使用mysql的方法:在“我的电脑”→右键→“管理”→“服务”...在mysql中查看root用户权限的方法:1.命令行启动mysql服务;...MySQL主从复制是用来备份一个与主数据库一样环境的从数据库,...运行mysql的方法1.启动mysql服务,在“我的电脑”→右键→“...开启mysql的方法1.可以通过快捷键win+r,输入cmd,打开窗口,...