redis

作者: 222AblackA | 来源:发表于2018-12-28 21:34 被阅读0次

    一.redis:非关系型数据库,kv存储系统(REmote Dictinoary server)

    提高高速缓存服务 -- 缓存热点数据(访问量大,数据量不大),缓解了数据库的压力(高频访问数据不用直接访问数据库)

    a.在linux服务器安装redis:

        在linux系统中输入以下命令:
            在官网下载redis的安装包
        wget http://download.redis.io/releases/redis-5.0.3.tar.gz
            解压文件
        gunzip redis-5.0.0.tat.gz
            解归档文件
        tar -xvf redis-5.0.3.tar
        进入redis文件
        cd redis-5.0.3
            查看是否安装有gun编译器套件
        gcc --version 
            编译并且安装
        make && make install
    

    b.redis基本操作:

    redis的客户端、服务器和哨兵等快捷方式默认放在/usr/local/bin文件夹下

        redis提供了两种数据持久化的方案:
        1.RDB -- 默认开启
        2.AOF -- (每两秒保存一次)--默认关闭状态--appendonly yes (打开AOF)
    
    redis-benchmark -a 密码:查看服务器每秒钟能刚处理多好个redis命令
    redis-server --requirepass 123123 --appendonly yes > redis.log 2> redis-error.log & :启动redis服务器,密码设为123123,启动后加载文档放在redis.log,错误信息文档放在error.log, &符号表示启动后自动在后台运行
    redis-cli : 启动redis客户端并且连接自己
    redis-cli -h ip地址 -p 端口号:连接服务器
    auth 密码 : 验证身份
    ping -- 心跳事件(检查是否脸上服务器)
    set -- 设置键值对
    get -- 获取值
    expire -- 设置超时时间
    del -- 删除键
    keys -- 查看键
    exists -- 判断键是否存在
    
    
    
    flushdb -- 清除当前数据库中的键值对
    flushall -- 清除所有数据库中的所有键值对
    dbsize 数据库编号-- 查看当前数据库的存储键值对的个数
    
    select 数据库编号-- 切换至指定的数据库
    shutdown -- 关闭数据库服务器
    save -- 保存数据
    bgsave -- 后台去保存数据(不会占用当前线程,影响当前控制台)
    

    二.redis五中常用value类型:

    a.字符串--String:value值类型是字符串

    append myphone 'nookia' : 如果myphone已经存在数据库中,就把值添加在那个值后面,不存在就创建并赋值
    incr tt: 如果tt存在,将它的值加1,如果不存在就创建,值为1
    incrby num 100 : 如果num是int类型,就给它的值加100,不是就报错
    decr
    decrby
    incrbyfloat key 0.1 : 增加浮点数(小数)
    getrange key 0 8 :获取key的值中下标0到8的值
    set 
    mset
    mget
    get
    getset key value:将key的值改为value,返回出旧值
    

    b.哈希表--Hash:value值类型是对象(字典)

    hset dict1 key1 value1 key2 value2 : 在redis数据库中存储dict={'key1':'value1','key2':'value2'}
    
         域存在
        redis> hset dict1 key1 value1 key2 value2
        (integer) 1
        redis> hget dict1 key1
        "value1"
    
         域不存在
        redis> hget dict1 mysql
        (nil) 
    
                hset
                hget
                hkeys
                hvals
                hmset
                hmget
                hexists
                hincrby
                hincrbyfloat
    

    c.列表--list

        lpush list1 100 200 300 400 : 从左边依次放入元素:list1=[400,300,200,100]
    
        rpush list2 100 200 300 400 : 从右边依次放入元素:list2=[100,200,300,400]
    
        lrange list1 0 3 : 获取list1下标从0到3的元素
    
        rpop list1: 从右边取list1元素
    
        lpop : 从左边取元素
    
        brpop list1 60 : list1中有元素直接获取,60s内还是没有,就返回空
        blpop
        lindex list1 3 : 取出list1中下标为3的元素
    
        
        redis的list类型可以实现两种经典的数据存储结构:
        栈(stack) -- FILO -- 先进后出 -- lpush +lpop / rpush + rpop
        队列(queue) -- FIFO -- 先进先出 -- lpush +rpop / rpush + lpop
        
        函数直接或者间接的调用自己:函数的递归调用 (底层用到了栈结构)
    

    d.集合--set

        sadd set1 100 : 将100添加到set1中 
    
        smembers set1 : 查看set1中所有元素
    
        sinter set1 set2 : 求set1和set2的交集
    
        sunion set1 set2 : 求set1和set2的并集
    
        sdiff set1 set2 : 求set1和set2的差集 
    
        srem set1 100 : 去除集合中的100
    
        sismember set1 100 : 判断集合中是否存在100
    
        scard set1 : 查看集合中有多少个元素
    
        spop set1: 移出并返回集合set1中的一个随机元素
    
        srandmember set1: 获取set1中一个随机元素,但不移出该元素
    
        smove set1 set2 value : 将value从set1中移动到set2中
    

    e有序集合:sortedset

    zadd / zcard / zcount / zincrby / zrange / zrem / zscore

    三.主从复制,读写分离(master -- salve)

    一台服务器做master,可以读写修改等所有操作;一台服务器做slave,只能访问master数据库,读取数据

    redis缓存数据,mysql保存数据,

       用mysql建表(联动型数据)
    
            """
            序列化 - 把对象转换成字符或字节序列 - 串行化/腌咸菜
            反序列化 - 把字符或者字节序列还原成对象 - 反串行化
            Python中要实现对象的序列化和反序列有3种方案:
            - json - load / loads / dump / dumps - 字符序列
            - pickle - load / loads / dump / dumps - 字节序列
            """
            import pickle
            import time
            
            import pymysql
            import redis
            
            
            class District(object):
                """行政区域"""
            
                def __init__(self, distid, name):
                    self.distid = distid
                    self.name = name
            
                def __str__(self):
                    return self.name
            
                def __repr__(self):
                    return self.name
            
            
            def main():
                begin = time.time()
                cli = redis.StrictRedis(host='120.78.202.21',
                                        port=6379,
                                        password='123123')
                # 优先从缓存中读取数据 如果缓存没有命中 才连接数据库进行查询
                if cli.exists('provinces'):
                    # 直接从缓存中通过键获取数据并反序列化成Python中的对象
                    provinces = pickle.loads(cli.get('provinces'))
                else:
                    provinces = []
                    con = pymysql.connect(host='120.78.202.21', port=3306,
                                          database='hrs', charset='utf8',
                                          user='root', password='123456')
                    try:
                        with con.cursor() as cursor:
                            # 查询省级行政区域
                            cursor.execute(
                                'select `distid`, `name` from `tb_district` where `pid` is null')
                            # 将查询结果放入列表容器
                            for dist_tuple in cursor.fetchall():
                                dist = District(*dist_tuple)
                                provinces.append(dist)
                            # 将列表序列化(pickle)然后放入Redis中缓存
                            cli.set('provinces', pickle.dumps(provinces))
                    finally:
                        con.close()
                end = time.time()
                print(f'执行时间: {end - begin}秒')
                print(provinces)
            
            
            if __name__ == '__main__':
                main()
    

    互亿无线发送短信代码:

        import io
        import json
        import logging
        import random
        
        from http.client import HTTPConnection
        from urllib.error import URLError
        from urllib.parse import urlencode
        from redis import StrictRedis
        
        def gen_code(length=8):
            result = io.StringIO()
            for _ in range(length):
                result.write(str(random.randint(0, 9)))
            return result.getvalue()
        
        SMS_SERVER = '106.ihuyi.com'
        SMS_URL = '/webservice/sms.php?method=Submit'
        SMS_ACCOUNT = 'C10419651'
        SMS_PASSWORD = 'a3ecaed032868ea37e612082566cc6ac'
        MSG_TEMPLATE = '您的验证码是:%s。请不要把验证码泄露给其他人。'
        def send_short_message(tel, code):
            """发送短信验证码(互亿无线)"""
            params = urlencode({
                'account': SMS_ACCOUNT,
                'password': SMS_PASSWORD,
                'content': MSG_TEMPLATE % code,
                'mobile': tel,
                'format': 'json'
            })
            headers = {
                'Content-Type': 'application/x-www-form-urlencoded',
                'Accept': 'text/plain'
            }
            conn = HTTPConnection(SMS_SERVER, port=80, timeout=10)
            try:
                conn.request('POST', SMS_URL, params, headers)
                json_str = conn.getresponse().read().decode('utf-8')
                return json.loads(json_str)
            except URLError or KeyError as e:
                logging.error(e)
                return json.dumps({
                    'code': 500,
                    'msg': '短信服务暂时无法使用'
                })
            finally:
                conn.close()
        def main():
            tel = input('请输入手机号:')
            cli = StrictRedis(host='120.78.202.21',
                              port=6379,
                              password='123123')
            mass = gen_code()
            if not cli.exists(tel):
                result = send_short_message(tel, mass)
                print(result)
                if result['code'] == 2:
                    print(result)
                    cli.set(tel, 1, ex=3600)
            elif int(cli.get(tel)) < 3:
                result = send_short_message(tel, mass)
                if result['code'] == 2:
                    print(result)
                    cli.set(tel, 1, ex=3600)
                cli.incr(tel)
            else:
                print('请不要一直发,一小时三次,oj8k?')
        if __name__ == '__main__':
                main()
    

    做短信业务的平台:

    又拍云、luosimao、云片短信、SendCloud、互亿无线

    相关文章

      网友评论

          本文标题:redis

          本文链接:https://www.haomeiwen.com/subject/oxqylqtx.html