首页 > 学院 > 开发设计 > 正文

tornado应用中使用memcached

2019-11-08 00:46:58
字体:
来源:转载
供稿:网友

Memcached简介

Memcached是一款开源、高性能、分布式内存对象缓存系统,可应用各种需要缓存的场景,其主要目的是通过降低对Database的访问来加速web应用程序。它是一个基于内存的“键值对”存储,用于存储数据库调用、API调用或页面引用结果的直接数据,如字符串、对象等。

为何要用memcached

许多Web应用都将数据保存到MySQL这样的关系型数据库管理系统中,应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大、访问的集中,就会出现数据库的负担加重、数据库响应恶化、 网站显示延迟等不良影响。memcached通过缓存数据库查询结果,减少数据库访问次数,可以显著提高动态Web应用的速度和可扩展性。

存储方式

为了提高性能,memcached中保存的数据都存储在memcached内置的内存存储空间中。由于数据仅存在于内存中,因此重启memcached、重启操作系统会导致全部数据消失。另外,缓存的内容容量达到指定值之后,就基于LRU(Least Recently Used)算法自动删除不使用的缓存。memcached本身是为缓存而设计的服务,因此并没有过多考虑数据的永久性问题。

管理memcache

安装

$ brew install memcached

memcache 的依赖: openssl 和 libevent 会自动下载并安装。

启动

$ memcached -m 32 -p 11211 -d

memcached将会以守护程序的形式启动 memcached(-d),为其分配32M内存(-m 32),并指定监听 localhost的11211端口。

在tornado项目中使用

python访问memcache

#!/usr/bin/env pythonimport memcachemc = memcache.Client(['127.0.0.1:12000'],debug=0)mc.set("foo","bar")value = mc.get("foo")PRint value

torando应用使用memcache

# coding: utf-8import sysimport tornado.ioloopimport tornado.webimport loggingimport memcacheimport jsonimport urllib# 初始化memcache clientmc = memcache.Client(['127.0.0.1:11211'], debug=0)mc_prefix = 'demo'class BaseHandler(tornado.web.RequestHandler): """ 把缓存处理抽象到BaseHandler基类 """ USE_CACHE = False # 控制是否使用缓存 def format_args(self): arg_list = [] for a in self.request.arguments: for value in self.request.arguments[a]: arg_list.append('%s=%s' % (a, urllib.quote(value.replace(' ', '')))) # 根据请求的URL产生key arg_list.sort() key = '%s?%s' % (self.request.path, '&'.join(arg_list)) if arg_list else self.request.path key = '%s_%s' % (mc_prefix, key) # key太长,不进行缓存处理 if len(key) > 250: logging.error('key out of length: %s', key) return None return key def get(self, *args, **kwargs): if self.USE_CACHE: try: # 根据请求获取key self.key = self.format_args() if self.key: data = mc.get(self.key) # 若缓存命中,则直接返回数据 if data: logging.info('get data from memecahce') self.finish(data) return except Exception, e: logging.exception(e) # 若未命中缓存,调用do_get处理请求,获取数据 data = self.do_get() data_str = json.dumps(data) # 把成功获取到的数据,放入memcache缓存 if self.USE_CACHE and data and data.get('result', -1) == 0 and self.key: try: mc.set(self.key, data_str, 60) except Exception, e: logging.exception(e) self.finish(data_str) def do_get(self): return Noneclass DemoHandler(BaseHandler): USE_CACHE = True def do_get(self): a = self.get_argument('a', 'test') b = self.get_argument('b', 'test') # 访问数据库获取数据,此处略去 data = {'result': 0, 'a': a, 'b': b} return datadef make_app(): return tornado.web.application([ (r"/", DemoHandler), ])if __name__ == "__main__": logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='%(asctime)s %(levelno)s %(message)s', ) app = make_app() app.listen(8888) tornado.ioloop.IOLoop.current().start()

demo测试结果

在浏览器访问http://127.0.0.1:8888/?a=1&b=3,终端打印的log如下:

2017-02-21 22:45:05,987 20 304 GET /?a=1&b=2 (127.0.0.1) 3.11ms2017-02-21 22:45:07,427 20 get data from memecahce2017-02-21 22:45:07,427 20 304 GET /?a=1&b=2 (127.0.0.1) 0.71ms2017-02-21 22:45:10,350 20 200 GET /?a=1&b=3 (127.0.0.1) 0.82ms2017-02-21 22:45:13,586 20 get data from memecahce

从日志可以看到,缓存命中的情况。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表