zoukankan      html  css  js  c++  java
  • Python- redis缓存 可达到瞬间并发量10W+

    redis是什么?

    mysql是一个软件,帮助开发者对一台机器的硬盘进行操作。
    redis是一个软件,帮助开发者对一台机器的内存进行操作。

    redis缓存 可达到瞬间并发量10W+

    高并发架构系列:Redis为什么是单线程、及高并发快的3大原因详解

    http://m.sohu.com/a/282430394_99994950?qq-pf-to=pcqq.group

    https://www.cnblogs.com/liuqingzheng/p/9833534.html


    特点
    - 可以做持久化:
    - AOF
    - RDB
    - 单进程单线程
    - 相当于是大字典,5大数据类型

    redis={
    k1:'123', 字符串
    k2:[1,2,3,4,4,2,1], 列表
    k3:{1,2,3,4}, 集合
    k4:{name:123,age:666}, 字典
    k5:{('alex',60),('eva-j',80),('rt',70),},有序集合
    }
    使用字典:
    - 基本操作
    - 慎重使用hgetall, 优先使用 hscan_iter
    - 计数器

    注意事项:redis操作时,只有第一层value支持:list,dict ....

    关键字:缓存

    缓存,优先去redis中获取,如果没有就是数据库。

    redis的应用场景


    1. top 列表
    产品运营总会让你展示最近、最热、点击率最高、活跃度最高等等条件的top list。很多更新较频繁的列表如果使用MC+MySQL维护的话缓存失效的可能性会比较大,鉴于占用内存较小的情况,使用Redis做存储也是相当不错的。

    2.最后的访问

    用户最近访问记录也是redis list的很好应用场景,lpush lpop自动过期老的登陆记录,对于开发来说还是非常友好的

    3.手机验证码的,有效时间

    4.限制用户登录的次数,比如一天错误登录次数10次。

    5.投票系统 ,投票结果排序。 排行榜等等

    6.存储社交信息,set的并集和交集。比较两个用户的共同粉丝

    7.各种计数:商品维度计数(点赞数,评论数,浏览数)

    8.发布订阅,聊天室等

    安装

    - redis软件
    - yum install redis
    redis-server /etc/redis.conf
    -
    wget http://download.redis.io/releases/redis-3.0.6.tar.gz
    tar xzf redis-3.0.6.tar.gz
    cd redis-3.0.6
    make

    /src/redis-server redis.conf


    默认端口:6379

    配置文件:
    bind 0.0.0.0
    port 6379
    requirepass dskjfsdf


    - python连接redis的模块

    pip3 install redis

    Redis Pttl 命令 - 以毫秒为单位返回 key 的剩余的过期时间

    基本使用

    a.
    import redis
    # 创建连接
    # conn = redis.Redis(host='47.94.172.250',port=6379,password='luffy1234')
    # conn.set('x1','wanghuaqiang',ex=5)
    # val = conn.get('x1')
    # print(val)
    b.
    # 连接池
    # import redis
    #
    # pool = redis.ConnectionPool(host='10.211.55.4', port=6379,password='luffy1234',max_connections=1000)
    # conn = redis.Redis(connection_pool=pool)
    #
    # conn.set('foo', 'Bar')

    连接池注意:连接池只创建一次
    wupeiqi/articles/5132791.html

    使用字典
    基本操作
    慎用hgetall,优先使用hscan_iter
    计数器

    注意事项:redis操作时,只有第一次value支持:list,dict...
    session就是通过数据库,序列化到缓存里的和反序列化拿来用

     

    redis字符串操作总结:

    set(name, value, ex=None, px=None, nx=False, xx=False)
    在Redis中设置值,默认,不存在则创建,存在则修改
    参数:
    ex,过期时间(秒)
    px,过期时间(毫秒)
    nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果
    xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会 
    设置新值

    get(name)
    获取值

    mget(keys, *args)
    批量获取
    如:
    mget('k1', 'k2')

    r.mget(['k3', 'k4'])

    getset(name, value)
    设置新值并获取原来的值

    getrange(key, start, end)
    # 获取子序列(根据字节获取,非字符)
    # 参数:
    # name,Redis 的 name
    # start,起始位置(字节)
    # end,结束位置(字节)
    # 如: "刘清政" ,0-3表示 "刘"

    setrange(name, offset, value)
    # 修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)
    # 参数:
    # offset,字符串的索引,字节(一个汉字三个字节)
    # value,要设置的值


    strlen(name)
    # 返回name对应值的字节长度(一个汉字3个字节)

    incr(self, name, amount=1) #如点赞,提高性能
    # 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。
    # 参数:
    # name,Redis的name
    # amount,自增数(必须是整数)
    # 注:同incrby

    append(key, value)
    # 在redis name对应的值后面追加内容
    # 参数:
    key, redis的name
    value, 要追加的字符串

    # 字符串操作
    # conn.set('yyy', 'egon', nx=True)
    # conn.set('ttt', 'egon', xx=True)
    # import datetime
    # v=datetime.timedelta(weeks=2)
    # ctime=datetime.datetime.now()
    # ctime+v
    # conn.setex('ttt', 5,'xxx')

    # conn.mset({"k1": 'v1', "k2": 'v12', "k3": 'v3'})
    # value=conn.mget('name','k1','k2')
    # value=conn.mget(['name','k1','k2'])
    # print(value)
    # print(conn.getset('name','xxxxxx'))
    # conn.setrange('name', 1, 'eerrrrrrrrrrrrrrrr')

    # print(conn.strlen('name'))
    # conn.set('age',"19")
    # 文章阅读数
    # conn.incr('age',-4)
    # conn.append('name','0000000')

    redis字典操作总结:

    hscan_iter(name, match=None, count=None)
    # 利用yield封装hscan创建生成器,实现分批去redis中获取数据

    # 参数:
    # match,匹配指定key,默认None 表示所有的key
    # count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数

    # 如:
    # for item in r.hscan_iter('xx'):
    # print item

    # 字典操作

    # conn.hset('person','age','18')
    # conn.hset('person','name','lqz')
    # conn.hset('person','height','180')
    # conn.hmset('person2',{'age':'19','name':'egon','xx':'xx'})
    # print(conn.hget('person','name'))
    # print(conn.hmget('person','age','name','height'))
    # print(conn.hmget('person',['age','name','height']))
    # 以后用这个要慎用
    # print(conn.hgetall('person'))
    # print(conn.hlen('person'))
    # print(conn.hkeys('person'))

    # print(conn.hexists('person','nameee'))
    # conn.hdel('person2','name','age')

    # conn.hincrby('person','age')
    # for i in range(1000000):
    # conn.hmset('person2',{'eeeeee%s'%i:i})
    # 如果数据量不大,自动全取出来
    # cour, data = conn.hscan('person2', cursor=0, match=None, count=3000)
    # cour2, data2 = conn.hscan('person2', cursor=cour, match=None, count=3000)
    #
    # print(cour)
    # print(len(data))
    #
    # print('-------')
    # print(cour2)
    # print(len(data2))

    # cour2 = 0
    # count = 1
    # while True:
    # cour2, data2 = conn.hscan('person2', cursor=cour2, match=None, count=3000)
    # count += len(data2)
    # if cour2 == 0:
    # break
    #
    # print(count)
    # 不用getall的方式取,用这种方式取,也能把所有数据取出来,但是不会吧内存撑爆
    # data=conn.hscan_iter('person2', match=None, count=100)
    # # 内部有915371条数据
    # # 先去取100条
    # # 做成了生成器
    # # 取值的时候,100以内,没有再去查,用的是生成器
    # # 当超过一百,再去取100条.做成了生成器
    # for i in data:
    # print(i)

    redis列表操作总结:

    # 列表操作

    # conn.lpush('list','2')
    # conn.rpush('list','3')
    # conn.lpushx('list2','3')
    # print(conn.llen('list'))

    # conn.linsert('list', 'after', "3", '444444')
    # conn.linsert('list', 'before', "3", '5555555')
    # 从0开始
    # conn.lset('list',4,'66666666')
    # conn.lrem('list',0,"3")
    # print(conn.lpop('list'))
    # print(conn.rpop('list'))
    # 按索引取值,支持负索引
    # print(conn.lindex('list',-2))

    # 简单的分布式爬虫
    # print(conn.blpop('list'))
    # 取出列表的所有值

    # conn.lpush('list',*[1,2,3,4,45,5,6,7,7,8,43,5,6,768,89,9,65,4,23,54,6757,8,68])
    # print(conn.lrange('list',0,-1))
    # 自定义列表的增量迭代
    # def scan_list(name,count=2):
    # index=0
    # while True:
    # data_list=conn.lrange(name,index,count+index-1)
    # if not data_list:
    # return
    # index+=count
    # for item in data_list:
    # yield item
    # # print(conn.lrange('test',0,100))
    # for item in scan_list('list',5):
    # print('---')
    # print(item)

    # 其它操作

    # 事务(不支持事务,但是通过管道模拟)
    # conn=redis.Redis(host='127.0.0.1', port=6379)
    # # 拿到一个管道,transaction=True表示管道内部都是原子性
    # pi=conn.pipeline(transaction=True)
    # # 说明是批量命令
    # pi.multi()
    #
    #
    # pi.set('xx','xxx')
    # pi.set('yy','yyy')
    #
    # pi.execute()

    # 其它操作
    # conn.delete('name1')
    # 用的比较多
    # print(conn.keys('k*'))

    # print(conn.type('person'))
    # django中使用redis

     

     redis 管道(模拟事务)

    import redis
     
    pool = redis.ConnectionPool(host='10.211.55.4', port=6379)
     
    r = redis.Redis(connection_pool=pool)
     
    # pipe = r.pipeline(transaction=False)
    pipe = r.pipeline(transaction=True)
    pipe.multi()
    pipe.set('name', 'alex')
    pipe.set('role', 'sb')
     
    pipe.execute()
    

      

    应用(django):

    方式一:

    utils文件夹下,建立redis_pool.py

    import redis
    POOL = redis.ConnectionPool(host='127.0.0.1', port=6379,password='1234',max_connections=1000)

    视图函数中使用:

    复制代码
    import redis
    from django.shortcuts import render,HttpResponse
    from utils.redis_pool import POOL
    
    def index(request):
        conn = redis.Redis(connection_pool=POOL)
        conn.hset('kkk','age',18)
    
        return HttpResponse('设置成功')
    def order(request):
        conn = redis.Redis(connection_pool=POOL)
        conn.hget('kkk','age')
    
        return HttpResponse('获取成功')
    复制代码

    方式二:

    安装django-redis模块

    pip3 install django-redis

    setting里配置:

    复制代码
    # redis配置
    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
                "CONNECTION_POOL_KWARGS": {"max_connections": 100}
                # "PASSWORD": "123",
            }
        }
    }
    复制代码

    视图函数:

    from django_redis import get_redis_connection
    conn = get_redis_connection('default')
    print(conn.hgetall('xxx'))

    高级使用: (memachach 不能做持久化)
    1. 全站缓存(通过中间件)
    wupeiqi/articles/5246483.html

    2. 单视图

    3. 局部页面

  • 相关阅读:
    解析大型.NET ERP系统 权限模块设计与实现
    Enterprise Solution 开源项目资源汇总 Visual Studio Online 源代码托管 企业管理软件开发框架
    解析大型.NET ERP系统 单据编码功能实现
    解析大型.NET ERP系统 单据标准(新增,修改,删除,复制,打印)功能程序设计
    Windows 10 部署Enterprise Solution 5.5
    解析大型.NET ERP系统 设计异常处理模块
    解析大型.NET ERP系统 业务逻辑设计与实现
    解析大型.NET ERP系统 多国语言实现
    Enterprise Solution 管理软件开发框架流程实战
    解析大型.NET ERP系统 数据审计功能
  • 原文地址:https://www.cnblogs.com/du-jun/p/10408576.html
Copyright © 2011-2022 走看看