标签: Memcached

  • Python3 Django框架中如何使用cache缓存代码实例

    Python3 Django框架中如何使用cache缓存代码实例

    场景描述

    在Django开发中,我们在 views.py 里用到了很多的sql查询,很多的跨表跨库显示,而且数据量已达到百万级,为了加快速度显示,这边启用了缓存。

    一开始我们想使用 @cache_page() 来达到缓存的目的,但是这样的缓存没有找到清除缓存的方法。

    所以我们只好使用cache的方式来缓存,这里用时间(年-月-日 时:分)md5后作为缓存的key。

    而且百度一下以后发现,关于django的cache讲述得很少。我们这里做一下简单的笔记。需要说明一下的是 cache.get_or_set ,我一开始以为是如果有这个值就自动获取,但是发现页面任然很慢。所以查了一下官方手册。 cache.get_or_set 手册里面写的是默认是设置新值。大家使用时一定要防止踩这个坑。

    cache.get_or_set(key, default, timeout=DEFAULT_TIMEOUT, version=None)

    If you want to get a key’s value or set a value if the key isn’t in the cache, there is the get_or_set() method. It takes the same parameters as get() but the default is set as the new cache value for that key, rather than simply returned:

    Python3 Django框架中的缓存机制

    views.py 代码实例

    from django.core.cache import cache
    @login_required
    def index( request ):
        if request.GET.get('date_joined_0') is None :
            lastDate = SnmpDiff.objects.values('update_time').filter( type = 'computer_room.snmp_95' ).order_by('-id')[1]
            date_joined_0 =  lastDate['update_time'].strftime("%Y-%m-%d")
            date_joined_1 =  lastDate['update_time'].strftime("%H:%M")
        else :
            date_joined_0 = request.GET.get('date_joined_0').replace('/','-')
            date_joined_1 = request.GET.get('date_joined_1')
        date = date_joined_0 + ' ' + date_joined_1
        cache_key = hashlib.md5(('index_'+date).encode(encoding='UTF-8')).hexdigest()
        # result = cache.get_or_set(cache_key, getIndexResult(date),60*60)
        if not cache.get(cache_key) :
            result = cache.get_or_set(cache_key, getIndexResult(date),60*60)
        else:
            result = cache.get(cache_key)

    现在除了第一次打开慢一点之外,其他时间打开飞快。

  • Python3 Django框架中的缓存机制

    Python3 Django框架中的缓存机制

    概述:对于中等流量的网站来说,尽可能的减少开销是非常必要的。缓存数据就是为了保存那些需要很多计算资源的结果,这样的话就不必在下次重复消耗计算资源。获取数据的数据的时候就是去缓存中拿,拿到了直接返回,没拿到就去数据库中查询,筛选,然后缓存到数据库, 然后返回给模板。

    Django自带了一个健壮的缓存系统来保存动态页面,避免每次请求都重新计算。

    Django提供了不同级别的缓存策略,可以缓存特定的视图的输出、可以仅仅缓存那些很难计算出来的部分、或者缓存整个网站

    目的:优化数据结构;优化了对数据的查询;筛选,过滤;减少了对磁盘的IO

    官方文档:https://docs.djangoproject.co…

    设置缓存

    通过设置决定把数据缓存在哪里,是数据库中、文件系统中还是内存中

    默认缓存(内存)

    CACHES={
        'default':{
            'BACKEND':'django.core.cache.backends.locmem.LocMemCache',
            'LOCATION': 'unique-snowflake',
            'TIMEOUT':60
        }
    }

    参数TIMEOUT:缓存的默认过期时间,以秒为单位

    • 默认为300秒
    • 设置为None,表示永不过期
    • 设置为0造成缓存立即失效

    文件缓存

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
            'LOCATION': 'c:/foo/bar',
            'TIMEOUT':300,
        }
    }

    数据库缓存

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
            'LOCATION': 'my_cache_table',
            'TIMEOUT': '60',
            'KEY_PREFIX': 'bbs',
            'VERSION': '1',
            'OPTIONS': {
                'MAX_ENTRIES': '300'
            }
        }
    }

    创建缓存表: python manage.py createcachetable

    drf的缓存

    https://github.com/chibisov/drf-extensions

    这是drf的一个扩展,不止增强了缓存还有其他的。

    pip install drf-extensions
    

    缓存viewset中的retrieve和list 方法是很常见的。这就是为什么CacheResponseMixin存在。

    获取数据的才会用到cache

    from rest_framework_extensions.cache.mixins import CacheResponseMixin

    把这个CacheResponseMixin,放在list之前。尽量放在第一个继承的类

    class GoodsListViewSet(CacheResponseMixin,mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    

    设置过期时间

    REST_FRAMEWORK_EXTENSIONS = {
        'DEFAULT_CACHE_RESPONSE_TIMEOUT': 5
    }
    

    根据自己需求加缓存。目前这个缓存使用的是内存。每次系统重启会丢失。

    redis缓存

    官网: http://django-redis-chs.readt…

    redis操作文档:http://redisdoc.com

    默认使用redis中的1数据库,但可以指定使用哪个db

    安装pip install django-redis

    配置

    # ---配置Session和Cache---
    CACHES={
        'default':{
            'BACKEND': 'django_redis.cache.RedisCache',
            'LOCATION':'127.0.0.1:6379/12', # 指定db12
            'TIMEOUT':60,
            'OPTIONS': {
                'CLIENT_CLASS': 'django_redis.client.DefaultClient',  # 指定连接Redis的客户端类
                # 'PASSWORD': 'mysecret',
                 # "SOCKET_CONNECT_TIMEOUT": 5,  # in seconds
                 # "SOCKET_TIMEOUT": 5,  # in seconds
                 # "CONNECTION_POOL_KWARGS": {"max_connections": 100},
                 # "CONNECTION_POOL_CLASS": "myproj.mypool.MyOwnPool",
            }
        }
    }
    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
    # --结束Session和Cache配置
    参数解释
    SOCKET_CONNECT_TIMEOUTsocket 建立连接超时设置
    SOCKET_TIMEOUT连接建立后的读写操作超时设置
    CONNECTION_POOL_KWARGS设置连接池的最大连接数量
    CONNECTION_POOL_CLASS自己的连接池子类

    连接池

    django-redis 使用 redis-py 的连接池接口, 并提供了简单的配置方式. 除此之外, 你可以为 backend 定制化连接池的产生。redis-py 默认不会关闭连接, 尽可能重用连接。

    连接池概念

    为什么使用连接池?首先Redis也是一种数据库,它基于C/S模式,因此如果需要使用必须建立连接,稍微熟悉网络的人应该都清楚地知道为什么需要建立连接,C/S模式本身就是一种远程通信的交互模式,因此Redis服务器可以单独作为一个数据库服务器来独立存在。假设Redis服务器与客户端分处在异地,虽然基于内存的Redis数据库有着超高的性能,但是底层的网络通信却占用了一次数据请求的大量时间,因为每次数据交互都需要先建立连接,假设一次数据交互总共用时30ms,超高性能的Redis数据库处理数据所花的时间可能不到1ms,也即是说前期的连接占用了29ms,连接池则可以实现在客户端建立多个链接并且不释放,当需要使用连接的时候通过一定的算法获取已经建立的连接,使用完了以后则还给连接池,这就免去了数据库连接所占用的时间。

    配置默认连接池

    配置默认连接池很简单, 你只需要在 CACHES 中使用 CONNECTION_POOL_KWARGS 设置连接池的最大连接数量即可

    你可以得知连接池已经打开多少连接:

    from django.core.cache import get_cache
    from django_redis import get_redis_connection
    r = get_redis_connection("default")  # Use the name you have defined for Redis in settings.CACHES
    connection_pool = r.connection_pool
    print("Created connections so far: %d" % connection_pool._created_connections)

    使用自己的连接池子类

    有时你想使用自己的连接池子类. django-redis 提供了 CONNECTION_POOL_CLASS 来配置连接池子类

    myproj/mypool.py

    from redis.connection import ConnectionPool
    class MyOwnPool(ConnectionPool):
        # Just doing nothing, only for example purpose
        pass

    缓存的用法

    单个view缓存

    django.views.decorators.cache.cache_page装饰器用于对视图 views.py 的输出进行缓存

    from django.views.decorators.cache import cache_page
    @cache_page(60 * 2)
    def index(request):
        # return HttpResponse("sunck is a good man")
        return HttpResponse("sunck is a nice man")
    参数:
    timeout : 有效时长  # we've written it as 60 * 15 for the purpose of readability
    cache: 缓存到哪一个库中;很少使用;针对于系统配置了多个缓存
           如: @cache_page(timeout=60, cache='filecache')
    key_prefix: 前缀      

    模板片段缓存

    cache标签: 参数

    • 缓存时间,以秒为单位
    • 给缓存片段起名字
    {#{% load static from staticfiles %}#}
    {% load static %}
    {% load cache %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>主页</title>
    {#    <link rel="stylesheet" type="text/css" href="/static/css/index.css">#}
        <link rel="stylesheet" type="text/css" href="{% static 'css/index.css' %}">
    </head>
    <body>
        <h1>sunck is a nice man</h1>
        {% cache 120 sunck %}
            <h1>nice man</h1>
            <!--<h1>good man</h1>-->
        {% endcache %}
    </body>
    </html>

    原生cache

    from django.core.cache import cache
    查看所有缓存的key: cache.keys('*')
    设置:cache.set(键, 值, 有效时间)
    获取:cache.get(键)
    删除:cache.delete(键)
    清空:cache.clear()
    >>> cache.set_many({'a': 1, 'b': 2, 'c': 3})
    >>> cache.getmany(['a','b','c'])
    {'a': 1, 'b': 2, 'c': 3}
    cache.delete_pattern("foo_*") # 全局通配符
  • Docker 安装 memcached 出现 can’t run as root without the -u switch

    Docker 安装 memcached 出现 can’t run as root without the -u switch

    出现问题

    can’t run as root without the -u switch

    解决办法

    docker run -d -p 11211:11211 --name jmemcached memcached -u root

    -u root 使用 root来执行,docker容器就不会自动退出。否则可能会出现刚启动容器就会自动退出。

  • Docker 容器中为PHP-FPM 环境安装Memcached扩展 图文教程

    Docker 容器中为PHP-FPM 环境安装Memcached扩展 图文教程

    前面我们写了关于Docker的一些内容,现在我们需要在容器中开启php对Memcached的扩展。网上找了一些资料,下面我们直接贴出命令行。

    进入容器

    docker exec -it jphp-fpm /bin/bash

    jphp-fpm 是我们创建容器时给的容器名。

    注意:我们这里使用的是 bitnami/php-fpm 的套件。

    安装预编译环境

    apt-get update -y && apt-get install -y pkg-config libmemcached-dev autoconf gcc make zlib1g zlib1g-dev vim

    安装php-memcached扩展

    pecl channel-update pecl.php.net && pecl install memcached

    修改php的配置文件php.ini

    通过phpinfo里Loaded Configuration File,我们看到php.ini的位置:/opt/bitnami/php/lib/php.ini

    echo 'extension=memcached.so' >> /opt/bitnami/php/lib/php.ini

    退出容器 ,HOST终端重启php-fpm

    docker restart jphp-fpm
WeChat