python之路-数据相关

memcached

如今大多数web页面采用的数据库关系型数据库,随着数据量的不断增大、访问的集中,就会出现数据库的负担加重、响应缓慢、 网站显示延迟等重大影响。
这时就该memcached大显身手了。memcached是高性能的分布式内存缓存服务器。 一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、 提高可扩展性。

简单来说就是把第一次访问数据库获取到的值缓存起来,下一次再次请求的时候就不用去访问数据库,通过缓存服务器就可以得到相应的值,这样既减轻了数据库的负担,也加快了访问速度。

memcached的特征

memcached作为高速运行的分布式缓存服务器,具有以下的特点。
1 协议简单
简单的set和get就能设置和获取值,通信简单,使用telnet既可以访问到。
2 基于libevent的事件处理
安装memcached需要安装libevent,就是因为memcached是基于它的事件处理。什么是libevent呢。
libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能 封装成统一的接口。
3 内置内存存储方式
memcache之所以快,是因为它存储在内存之中,如果存储内容超过指定容量就会按照LRU算法删除不使用的缓存,如果断电之后,缓存内容就会消失。
4 memcached不互相通信的分布式
memcached客户端支持多平台,linux下安装的时候,可以直接yum或者apt-get或者用源码安装。

memcached -d -m 10    -u root -l 10.211.55.4 -p 12000 -c 256 -P /tmp/memcached.pid

参数说明:
    -d 是启动一个守护进程
    -m 是分配给Memcache使用的内存数量,单位是MB
    -u 是运行Memcache的用户
    -l 是监听的服务器IP地址
    -p 是设置Memcache监听的端口,最好是1024以上的端口
    -c 选项是最大运行的并发连接数,默认是1024,按照你服务器的负载量来设定
    -P 是设置保存Memcache的pid文件
Memcached命令

存储命令: set/add/replace/append/prepend/cas
获取命令: get/gets
其他命令: delete/stats..

python中的memcache

相关模块python-memcached

import memcache
mc = memcache.Client(['192.168.17.137:12000'], debug=True)
mc.set("name", "hansz")
ret = mc.get('name')
print ret
python实现memcached集群

memcached可以有多个服务,那么就可以用python来实现集群,
实现的方式是在内部维持一个主机列表,集群中的主机的权重和在主机列表出现的次数成正比。
比如a主机出现的次数多,那么调用的时候调用a主机的memcached优先级就比较高。

如果用户根据如果要在内存中创建一个键值对(如:k1 = “v1”),那么要执行一下步骤:
•根据算法将 k1 转换成一个数字
•将数字和主机列表长度求余数,得到一个值 N( 0 <= N < 列表长度 )
•在主机列表中根据 第2步得到的值为索引获取主机,例如:host_list[N]
•连接 将第3步中获取的主机,将 k1 = “v1” 放置在该服务器的内存中

python-memcached实现集群的方式如下。里面的是一个元组,ip后面跟的是权重。debug是要开启日志调试模式。

mc = memcache.Client([('1.1.1.1:12000', 1), ('1.1.1.2:12000', 2), ('1.1.1.3:12000', 1)], debug=True)
mc.set('k1', 'v1')

####################################################
# add 添加如果已经存在key则报错。
mc.add('k1', 'v1')

# replace 替换,如果不存在则报错。
mc.replace('kkkk','999')

####################################################

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

set_multi   
#设置多个键值对,如果key不存在,则创建,如果key存在,则修改
mc.set('key0', 'wupeiqi')
mc.set_multi({'key1': 'val1', 'key2': 'val2'})

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

delete_multi    
#在Memcached中删除指定的多个键值对
mc.delete('key0')
mc.delete_multi(['key1', 'key2'])

####################################################
get            
#获取一个键值对

get_multi   
#获取多一个键值对
val = mc.get('key0')
item_dict = mc.get_multi(["key1", "key2", "key3"])

####################################################
append    
#修改指定key的值,在该值 后面 追加内容

prepend   
#修改指定key的值,在该值 前面 插入内容
# k1 = "v1"

mc.append('k1', 'after')
# k1 = "v1after"

mc.prepend('k1', 'before')
# k1 = "beforev1after"

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

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

mc.set('k1', '777')

mc.incr('k1')
# k1 = 778

mc.incr('k1', 10)
# k1 = 788

mc.decr('k1')
# k1 = 787

mc.decr('k1', 10)
# k1 = 777
####################################################
gets 和 cas
比如使用memcached存储一个实时变化的值,比如说抢购商品的剩余数量。
总共有100台,a抢了1台,那么就应该剩下99台,b取的时候应该是99而不应该是100,每取一次就应该减少相对应的个数。
v = mc.gets('product_count')
mc.cas('product_count', "899")

Redis

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

redis在linux上安装比较简单。使用python操作redis需要安装相关的模块。用easy_install

redis 基本操作
import redis
r = redis.Redis(host='192.168.127.139', port=6379)
r.set('name', 'hansz')
print r.get('name')
redis连接池

每次客户端链接redis,操作完后释放都会耗用一定开销。
每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import redis
pool = redis.ConnectionPool(host='192.168.19.137', port=6379)
r = redis.Redis(connection_pool=pool)
r.set('name', 'hansz')
print r.get('name')
管道

redis每次请求的时候都会创建和断开一次连接操作。如果要想在每次请求中执行多个命令那么就需要pipline.

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import redis
pool = redis.ConnectionPool(host='192.168.17.139', port=6379)
r = redis.Redis(connection_pool=pool)
# pipe = r.pipeline(transaction=False)
pipe = r.pipeline(transaction=True)
r.set('name', 'hansz')
r.set('age', '23')
pipe.execute()
订阅
#订阅端,(比如一个服务器的监控端)
import redis
rc = redis.Redis(host='127.0.0.1')
# ps为订阅端
ps = rc.pubsub()

# 监控两个频道,cpu频道和asterisk_status频道。
ps.subscribe(['cpu', 'asterisk_status']) 

# 如果有消息过来就打印数据。 
for item in ps.listen():
    if item['type'] == 'message':
        print item['data']
#发布端
import redis
rc = redis.Redis(host='127.0.0.1')
# ps为发布端
ps = rc.pubsub()
ps.subscribe(['cpu', 'asterisk_status']) 
# 发布消息
rc.publish('cpu', 'cpu is ok')

SQLAlchemy

一种ORM框架,建立在数据库api之上,可以通过调用api实现对数据库的操作。不用直接执行SQL语句了。
其实原理就是把关系数据库的表结构映射到对象上。
数据库表是二维的,很像一个元组,那么用元组来表示数据库表是非常容易的。只需要转换一下,ORM框架就是用来“转换”的。
SQLAlchemy是python下最著名的ORM框架。

# 导入:
from sqlalchemy import Column, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# 创建对象的基类:
Base = declarative_base()

# 定义User对象:
class User(Base):
    # 表的名字:
    __tablename__ = 'user'

    # 表的结构:
    id = Column(String(20), primary_key=True)
    name = Column(String(20))

# 初始化数据库连接:
engine = create_engine('mysql+mysqlconnector://root:password@localhost:3306/test')
# 创建DBSession类型:
DBSession = sessionmaker(bind=engine)

‘数据库类型+数据库驱动名称://用户名:口令@机器地址:端口号/数据库名’

定义了上面的类,使用方法如下

# 创建session对象:
session = DBSession()
# 创建新User对象:
new_user = User(id='5', name='Bob')
# 添加到session:
session.add(new_user)
# 提交即保存到数据库:
session.commit()
# 关闭session:
session.close()

获取数据库的值

# 创建Session:
session = DBSession()
# 创建Query查询,filter是where条件,最后调用one()返回唯一行,如果调用all()则返回所有行:
user = session.query(User).filter(User.id=='5').one()
# 打印类型和对象的name属性:
print 'type:', type(user)
print 'name:', user.name
# 关闭Session:
session.close()

有些表与表之间还会存在一对多、多对多关系,也可以很轻松的在类定义的时候解决

class User(Base):
    __tablename__ = 'user'

    id = Column(String(20), primary_key=True)
    name = Column(String(20))
    # 一对多:
    books = relationship('Book')

class Book(Base):
    __tablename__ = 'book'

    id = Column(String(20), primary_key=True)
    name = Column(String(20))
    # “多”的一方的book表是通过外键关联到user表的:
    user_id = Column(String(20), ForeignKey('user.id'))

RabbitMQ

MQ消息队列
消息队列是一种进程之间的通信方式,不需要像数据库或者redis等创建链接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值