加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy

发布时间:2020-12-12 00:03:17 所属栏目:MySql教程 来源:网络整理
导读:div id="cnblogs_post_body" class="blogpost-body" Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基

</table>

4、replace
replace 修改某个key的值,如果key不存在,则异常

</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"><code class="python keyword">import <code class="python plain">memcache
<div class="line number4 index3 alt1">
<div class="line number5 index4 alt2"><code class="python plain">mc <code class="python keyword">= <code class="python plain">memcache.Client([<code class="python string">'10.211.55.4:12000'<code class="python plain">],debug<code class="python keyword">=<code class="python color1">True<code class="python plain">)
<div class="line number6 index5 alt1"><code class="python comments"># 如果memcache中存在kkkk,则替换成功,否则一场
<div class="line number7 index6 alt2"><code class="python plain">mc.replace(<code class="python string">'kkkk'<code class="python plain">,<code class="python string">'999'<code class="python plain">)

</td>

</tr>

</table>

5、set 和 set_multi

set 设置一个键值对,如果key不存在,则创建,如果key存在,则修改
set_multi 设置多个键值对,如果key不存在,则创建,如果key存在,则修改

</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"><code class="python keyword">import <code class="python plain">memcache
<div class="line number4 index3 alt1">
<div class="line number5 index4 alt2"><code class="python plain">mc <code class="python keyword">= <code class="python plain">memcache.Client([<code class="python string">'10.211.55.4:12000'<code class="python plain">],debug<code class="python keyword">=<code class="python color1">True<code class="python plain">)
<div class="line number6 index5 alt1">
<div class="line number7 index6 alt2"><code class="python plain">mc.<code class="python functions">set<code class="python plain">(<code class="python string">'key0'<code class="python plain">,<code class="python string">'wupeiqi'<code class="python plain">)
<div class="line number8 index7 alt1">
<div class="line number9 index8 alt2"><code class="python plain">mc.set_multi({<code class="python string">'key1'<code class="python plain">: <code class="python string">'val1'<code class="python plain">,<code class="python string">'key2'<code class="python plain">: <code class="python string">'val2'<code class="python plain">})

</td>

</tr>

</table>

6、delete 和 delete_multi

delete 在Memcached中删除指定的一个键值对
delete_multi 在Memcached中删除指定的多个键值对

</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"><code class="python keyword">import <code class="python plain">memcache
<div class="line number4 index3 alt1">
<div class="line number5 index4 alt2"><code class="python plain">mc <code class="python keyword">= <code class="python plain">memcache.Client([<code class="python string">'10.211.55.4:12000'<code class="python plain">],debug<code class="python keyword">=<code class="python color1">True<code class="python plain">)
<div class="line number6 index5 alt1">
<div class="line number7 index6 alt2"><code class="python plain">mc.delete(<code class="python string">'key0'<code class="python plain">)
<div class="line number8 index7 alt1"><code class="python plain">mc.delete_multi([<code class="python string">'key1'<code class="python plain">,<code class="python string">'key2'<code class="python plain">])

</td>

</tr>

</table>

7、get 和 get_multi

get 获取一个键值对
get_multi 获取多一个键值对

</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"><code class="python keyword">import <code class="python plain">memcache
<div class="line number4 index3 alt1">
<div class="line number5 index4 alt2"><code class="python plain">mc <code class="python keyword">= <code class="python plain">memcache.Client([<code class="python string">'10.211.55.4:12000'<code class="python plain">],debug<code class="python keyword">=<code class="python color1">True<code class="python plain">)
<div class="line number6 index5 alt1">
<div class="line number7 index6 alt2"><code class="python plain">val <code class="python keyword">= <code class="python plain">mc.get(<code class="python string">'key0'<code class="python plain">)
<div class="line number8 index7 alt1"><code class="python plain">item_dict <code class="python keyword">= <code class="python plain">mc.get_multi([<code class="python string">"key1"<code class="python plain">,<code class="python string">"key2"<code class="python plain">,<code class="python string">"key3"<code class="python plain">])

</td>

</tr>

</table>

8、append 和 prepend

append 修改指定key的值,在该值 后面 追加内容
prepend 修改指定key的值,在该值 前面 插入内容

</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"><code class="python keyword">import <code class="python plain">memcache
<div class="line number4 index3 alt1">
<div class="line number5 index4 alt2"><code class="python plain">mc <code class="python keyword">= <code class="python plain">memcache.Client([<code class="python string">'10.211.55.4:12000'<code class="python plain">],debug<code class="python keyword">=<code class="python color1">True<code class="python plain">)
<div class="line number6 index5 alt1"><code class="python comments"># k1 = "v1"
<div class="line number7 index6 alt2">
<div class="line number8 index7 alt1"><code class="python plain">mc.append(<code class="python string">'k1'<code class="python plain">,<code class="python string">'after'<code class="python plain">)
<div class="line number9 index8 alt2"><code class="python comments"># k1 = "v1after"
<div class="line number10 index9 alt1">
<div class="line number11 index10 alt2"><code class="python plain">mc.prepend(<code class="python string">'k1'<code class="python plain">,<code class="python string">'before'<code class="python plain">)
<div class="line number12 index11 alt1"><code class="python comments"># k1 = "beforev1after"

</td>

</tr>

</table>

9、decr 和 incr  

incr 自增,将Memcached中的某一个值增加 N ( N默认为1 )
decr 自减,将Memcached中的某一个值减少 N ( N默认为1 )

</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"><code class="python keyword">import <code class="python plain">memcache
<div class="line number4 index3 alt1">
<div class="line number5 index4 alt2"><code class="python plain">mc <code class="python keyword">= <code class="python plain">memcache.Client([<code class="python string">'10.211.55.4:12000'<code class="python plain">],debug<code class="python keyword">=<code class="python color1">True<code class="python plain">)
<div class="line number6 index5 alt1"><code class="python plain">mc.<code class="python functions">set<code class="python plain">(<code class="python string">'k1'<code class="python plain">,<code class="python string">'777'<code class="python plain">)
<div class="line number7 index6 alt2">
<div class="line number8 index7 alt1"><code class="python plain">mc.incr(<code class="python string">'k1'<code class="python plain">)
<div class="line number9 index8 alt2"><code class="python comments"># k1 = 778
<div class="line number10 index9 alt1">
<div class="line number11 index10 alt2"><code class="python plain">mc.incr(<code class="python string">'k1'<code class="python plain">,<code class="python value">10<code class="python plain">)
<div class="line number12 index11 alt1"><code class="python comments"># k1 = 788
<div class="line number13 index12 alt2">
<div class="line number14 index13 alt1"><code class="python plain">mc.decr(<code class="python string">'k1'<code class="python plain">)
<div class="line number15 index14 alt2"><code class="python comments"># k1 = 787
<div class="line number16 index15 alt1">
<div class="line number17 index16 alt2"><code class="python plain">mc.decr(<code class="python string">'k1'<code class="python plain">,<code class="python value">10<code class="python plain">)
<div class="line number18 index17 alt1"><code class="python comments"># k1 = 777

</td>

</tr>

</table>

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 即可,如:

</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"><code class="python keyword">import <code class="python plain">memcache
<div class="line number4 index3 alt1"><code class="python plain">mc <code class="python keyword">= <code class="python plain">memcache.Client([<code class="python string">'10.211.55.4:12000'<code class="python plain">],debug<code class="python keyword">=<code class="python color1">True<code class="python plain">,cache_cas<code class="python keyword">=<code class="python color1">True<code class="python plain">)
<div class="line number5 index4 alt2">
<div class="line number6 index5 alt1"><code class="python plain">v <code class="python keyword">= <code class="python plain">mc.gets(<code class="python string">'product_count'<code class="python plain">)
<div class="line number7 index6 alt2"><code class="python comments"># ...
<div class="line number8 index7 alt1"><code class="python comments"># 如果有人在gets之后和cas之前修改了product_count,那么,下面的设置将会执行失败,剖出异常,从而避免非正常数据的产生
<div class="line number9 index8 alt2"><code class="python plain">mc.cas(<code class="python string">'product_count'<code class="python plain">,<code class="python string">"899"<code class="python plain">)

</td>

</tr>

</table>

Ps:本质上每次执行gets时,会从memcache中获取一个自增的数字,通过cas去修改gets的值时,会携带之前获取的自增值和memcache中的自增值进行比较,如果相等,则可以提交,如果不想等,那表示在gets和cas执行之间,又有其他人执行了gets(获取了缓冲的指定值), 如此一来有可能出现非正常数据,则不允许修改。

Redis

redis是一个key-value。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list()、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

1(1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1<span style="color: #000000;">)

(2<span style="color: #000000;">) 支持丰富数据类型,支持string,list,set,sorted set,hash

(3<span style="color: #000000;">) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行

(4<span style="color: #000000;">) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

2<span style="color: #000000;">. redis相比memcached有哪些优势?

(1<span style="color: #000000;">) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型

(2<span style="color: #000000;">) redis的速度比memcached快很多

(3<span style="color: #000000;">) redis可以持久化其数据

3<span style="color: #000000;">. redis常见性能问题和解决方案:

(1<span style="color: #000000;">) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件

(2<span style="color: #000000;">) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次

(3<span style="color: #000000;">) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内

(4<span style="color: #000000;">) 尽量避免在压力很大的主库上增加从库

(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <-<span style="color: #000000;"> Slave3...

这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。

4<span style="color: #000000;">. MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据

相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:

voltile-<span style="color: #000000;">lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

volatile-<span style="color: #000000;">ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

volatile-<span style="color: #000000;">random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

allkeys-<span style="color: #000000;">lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

allkeys-<span style="color: #000000;">random:从数据集(server.db[i].dict)中任意选择数据淘汰

no-<span style="color: #000000;">enviction(驱逐):禁止驱逐数据

5<span style="color: #000000;">. Memcache与Redis的区别都有哪些?

1<span style="color: #000000;">)、存储方式

Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。

Redis有部份存在硬盘上,这样能保证数据的持久性。

2<span style="color: #000000;">)、数据支持类型

Memcache对数据类型支持相对简单。

Redis有复杂的数据类型。

3<span style="color: #000000;">),value大小

redis最大可以达到1GB,而memcache只有1MB

6<span style="color: #000000;">. Redis 常见的性能问题都有哪些?如何解决?

1<span style="color: #000000;">).Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。

2<span style="color: #000000;">).Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。

3<span style="color: #000000;">).Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。

4<span style="color: #000000;">). Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内

7<span style="color: #000000;">,redis 最适合的场景

Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-<span style="color: #000000;">backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用Memcached,何时使用Redis呢?

   如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:

 </span>1 、Redis不仅仅支持简单的k/<span style="color: #000000;"&gt;v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
 </span>2 、Redis支持数据的备份,即master-<span style="color: #000000;"&gt;slave模式的数据备份。
 </span>3<span style="color: #000000;"&gt; 、Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

(1<span style="color: #000000;">)、会话缓存(Session Cache)

最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗?

幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。

(2<span style="color: #000000;">)、全页缓存(FPC)

除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。

再次以Magento为例,Magento提供一个插件来使用Redis作为全页缓存后端。

此外,对WordPress的用户来说,Pantheon有一个非常好的插件 wp-<span style="color: #000000;">redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。

(3<span style="color: #000000;">)、队列

Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/<span style="color: #000000;">pop 操作。

如果你快速的在Google中搜索“Redis queues”,你马上就能找到大量的开源项目,这些项目的目的就是利用Redis创建非常好的后端工具,以满足各种队列需求。例如,Celery有一个后台就是使用Redis作为broker,你可以从这里去查看。

(4),排行榜/<span style="color: #000000;">计数器

Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可:

当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行:

ZRANGE user_scores 0 10<span style="color: #000000;"> WITHSCORES

Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的,你可以在这里看到。

(5)、发布/<span style="color: #000000;">订阅

最后(但肯定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/<span style="color: #000000;">订阅功能来建立聊天系统!(不,这是真的,你可以去核实)。

Redis提供的所有特性中,我感觉这个是喜欢的人最少的一个,虽然它为用户提供如果此多功能。

一、Redis安装和基本使用

启动服务端

启动客户端

get foo 二、Python操作Redis API使用

redis-py 的API的使用可以分类为:

  • 连接方式
  • 连接池
  • 操作
    • String 操作
    • Hash 操作
    • List 操作
    • Set 操作
    • Sort Set 操作
  • 管道
  • 发布订阅

1、操作模式

redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。

2、连接池

redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。

举例

= redis.ConnectionPool(host=,port=6379)

django.shortcuts app01.pool = redis.Redis(connection_pool=POOL) HttpResponse(<span style="color: #0000ff;">def<span style="color: #000000;"> home(request):
pool
= redis.Redis(connection_pool=<span style="color: #000000;">POOL)
<span style="color: #0000ff;">return
HttpResponse(<span style="color: #800000;">'
<span style="color: #800000;">ok
<span style="color: #800000;">'
)

3、Django-redis组件

CACHES =: : :

django.core.cache ] = conn =<span style="color: #000000;"> django_redis.get_redis_connection()
conn.set(
<span style="color: #800000;">'
<span style="color: #800000;">b
<span style="color: #800000;">'
,<span style="color: #800000;">'
<span style="color: #800000;">666
<span style="color: #800000;">'
)

4、字符串(Srting)操作

String操作,r

set(name,value,ex=None,px=None,nx=False,xx=False)

setnx(name,value)

setex(name,time)

psetex(name,time_ms,value)

mset(*args,**kwargs)

get(name)

mget(keys,*args)

getset(name,value)

getrange(key,start,end)

setrange(name,offset,value)

setbit(name,value)

getbit(name,offset)

bitcount(key,start=None,end=None)

bitop(operation,dest,*keys)

strlen(name)

incr(self,name,amount=1)

incrbyfloat(self,amount=1.0)

decr(self,amount=1)

append(key,value)

  

5、散列表(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,amount=1) 把原来的值加1

hincrbyfloat(name,amount=1.0)

hscan(name,cursor=0,match=None,count=None)

hscan_iter(name,count=None)

  

6、列表(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,num)

lpop(name)

lindex(name,index)

lrange(name,end)

ltrim(name,end)

rpoplpush(src,dst)

blpop(keys,timeout)

brpoplpush(src,dst,timeout=0)

自定义增量迭代

7、集合(Set)操作

Set操作,Set集合就是不允许重复的列表

sadd(name,values)

scard(name)

sdiff(keys,*args)

sdiffstore(dest,*args)

sinter(keys,*args)

sinterstore(dest,*args)

sismember(name,value)

smembers(name)

smove(src,value)

spop(name)

srandmember(name,numbers)

srem(name,values)

sunion(keys,*args)

sunionstore(dest,*args)

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)

</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)

</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)

</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)

</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)

</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)

</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)

</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)

</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)

</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)

</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))

</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)

</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 是原子性操作。

</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;"&gt;def</span> <span style="color: #800080;"&gt;__init__</span><span style="color: #000000;"&gt;(self):
    self.</span><span style="color: #800080;"&gt;__conn</span> = redis.Redis(host=<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;10.211.55.4</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;)
    self.chan_sub </span>= <span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;fm104.5</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;
    self.chan_pub </span>= <span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;fm104.5</span><span style="color: #800000;"&gt;'</span>

<span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; public(self,msg):
    self.</span><span style="color: #800080;"&gt;__conn</span><span style="color: #000000;"&gt;.publish(self.chan_pub,msg)
    </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; True

</span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; subscribe(self):
    pub </span>= self.<span style="color: #800080;"&gt;__conn</span><span style="color: #000000;"&gt;.pubsub()
    pub.subscribe(self.chan_sub)
    pub.parse_response()
    </span><span style="color: #0000ff;"&gt;return</span> pub</pre>

订阅者:

发布者:

更多参见:https://github.com/andymccurdy/redis-py/

http://doc.redisfans.com/

三.操作表

<div class="c-markdown">

key操作

在这里主要将Key的一些判断和操作方法做下总结:

方法

exists(name)

String操作 方法

set(name,value)

List操作 方法

rpush(name,*values)

Set操作 方法

sadd(name,*values)

Sorted Set操作 方法

zadd(name,args,*kwargs)

Hash操作 方法

hset(name,value)

RabbitMQ

RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统。他遵循Mozilla Public License开源协议。

MQ全称为Message Queue,(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消 息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如的技术。排队指的是应用程序通过 队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。

RabbitMQ安装

注意:service rabbitmq-server start/stop

安装API

使用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实现的消息队列。

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.queue

channel.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.queue

severities = 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 个 或 多个 单词
  • * 表示只能匹配 一个 单词

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.queue

binding_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()

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


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;">
credentials = 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;">)

connection = 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,从而实现对数据库的操作,如:

:@[:] :@[?] :@[:] 步骤一:

使用 Engine/ConnectionPooling/Dialect 进行数据库操作,Engine使用ConnectionPooling连接数据库,然后再通过Dialect执行SQL语句。

<span style="color: #0000ff;">from sqlalchemy <span style="color: #0000ff;">import<span style="color: #000000;"> create_engine

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;">)

<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,并获取结果。

<span style="color: #0000ff;">from sqlalchemy <span style="color: #0000ff;">import<span style="color: #000000;"> create_engine,ForeignKey

metadata =<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。

2).delete() 2).update({'cluster_id' : 0}) 更多功能参见文档,下载PDF

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

<div id="cnblogs_post_body" class="blogpost-body">

Memcached

Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的。其(daemon )是用写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。

Memcached安装和基本使用

Memcached安装:

windows系统安装方法:http://blog.csdn.net/l1028386804/article/details/61417166

启动Memcached

Memcached命令 Python操作Memcached

安装API

1、第一次操作

2、天生支持集群

python-memcached模块原生支持集群操作,其原理是在内存维护一个主机列表,且集群中主机的权重值和主机在列表中重复出现的次数成正比

如果用户根据如果要在内存中创建一个键值对(如:k1 = "v1"),那么要执行一下步骤:

  • 根据算法将 k1 转换成一个数字
  • 将数字和主机列表长度求余数,得到一个值 N( 0 <= N < 列表长度 )
  • 在主机列表中根据 第2步得到的值为索引获取主机,例如:host_list[N]
  • 连接 将第3步中获取的主机,将 k1 = "v1" 放置在该服务器的内存中

代码实现如下:

3、add
添加一条键值对,如果已经存在的 key,重复执行add操作异常

</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"><code class="python keyword">import
<code class="python plain">memcache

<div class="line number4 index3 alt1">
<div class="line number5 index4 alt2"><code class="python plain">mc
<code class="python keyword">=
<code class="python plain">memcache.Client([
<code class="python string">'10.211.55.4:12000'
<code class="python plain">],debug
<code class="python keyword">=
<code class="python color1">True
<code class="python plain">)

<div class="line number6 index5 alt1"><code class="python plain">mc.add(
<code class="python string">'k1'
<code class="python plain">,
<code class="python string">'v1'
<code class="python plain">)

<div class="line number7 index6 alt2"><code class="python comments"># mc.add('k1','v2') # 报错,对已经存在的key重复添加,失败!!!

</td>

</tr>

作用

参数说明

示例

示例说明

示例结果

作用

参数说明

示例

示例说明

示例结果

作用

参数说明

示例

示例说明

示例结果

作用

参数说明

示例

示例说明

示例结果

作用

参数说明

示例

示例说明

示例结果

作用

参数说明

示例

示例说明

示例结果