redis总结和补充

参考博客

http://www.cnblogs.com/wupeiqi/articles/5132791.html

- 基本操作

    - 连接
        - 直接连接:
            import redis 
            r = redis.Redis(host='10.211.55.4', port=6379)
            r.set('foo', 'Bar')
            print r.get('foo')
        - 连接池:
            import redis
            pool = redis.ConnectionPool(host='10.211.55.4', port=6379)
             
            r = redis.Redis(connection_pool=pool)
            r.set('foo', 'Bar')
            print r.get('foo')
    
    - 5大数据类型
        - 字符串 "sadf"
            - set('k1','123',ex=10)
            - get 
            - mset
            - mget
            - incr
            - 超时时间:
                import redis 
                r = redis.Redis(host='10.211.55.4', port=6379)
                r.set('foo', 'Bar',ex=10)
        - 字典 {'k1':'v1'}
            - hset(name, key, value)
            - hmset(name, mapping)
            - hget(name,key)
            - 超时时间(字典,列表、集合、有序结合相同):
                import redis 
                conn = redis.Redis(host='10.211.55.4', port=6379)
                conn.hset('n1', 'k1','123123')
                conn.expire('n1',10)
            - 如果一个字典在redis中保存了10w个值,我需要将所有值全部循环并显示,请问如何实现?
                
                for item in r.hscan_iter('k2',count=100):
                    print item
                    
        - 列表 [11,11,22,33]
            - lpush
            - rpush
            - lpop
            - blpop
            - rpop
            - brpop
            - llen
            - lrange
            - 如果一个列表在redis中保存了10w个值,我需要将所有值全部循环并显示,请问如何实现?
                def list_scan_iter(name,count=3):
                    start = 0
                    while True:
                        result = conn.lrange(name, start, start+count-1)
                        start += count
                        if not result:
                            break
                        for item in result:
                            yield item

                for val in list_scan_iter('num_list'):
                    print(val)
                
        - 集合 {'alex','oldboy','日天'}
            
        - 有序集合 {('alex',59),('oldboy',100),('日天',1)}
    
    - 公共操作:
        - delete(*names)
        - keys(pattern='*')
        expire(name ,time)
        ...

- 事务 
    import redis

    pool = redis.ConnectionPool(host='10.211.55.4', port=6379)

    conn = redis.Redis(connection_pool=pool)

    # pipe = r.pipeline(transaction=False)
    pipe = conn.pipeline(transaction=True)
    # 开始事务
    pipe.multi()

    pipe.set('name', 'alex')
    pipe.set('role', 'sb')
    pipe.lpush('roless', 'sb')

    # 提交
    pipe.execute()
    
    注意:咨询是否当前分布式redis是否支持事务

- 检测,watch
    面试题:你如何控制剩余的数量不会出问题?
        - 通过redis的watch实现
            import redis
            conn = redis.Redis(host='127.0.0.1',port=6379)

            # conn.set('count',1000)
            val = conn.get('count')
            print(val)

            with conn.pipeline(transaction=True) as pipe:

                # 先监视,自己的值没有被修改过
                conn.watch('count')

                # 事务开始
                pipe.multi()
                old_count = conn.get('count')
                count = int(old_count)
                print('现在剩余的商品有:%s',count)
                input("问媳妇让不让买?")
                pipe.set('count', count - 1)

                # 执行,把所有命令一次性推送过去
                pipe.execute()
        - 数据库的锁 
        
- 发布和订阅,只要有任务就所有订阅者每人一份。
    发布者:
        import redis

        conn = redis.Redis(host='127.0.0.1',port=6379)
        conn.publish('104.9MH', "hahahahahaha")
    订阅者:
        import redis

        conn = redis.Redis(host='127.0.0.1',port=6379)
        pub = conn.pubsub()
        pub.subscribe('104.9MH')

        while True:
            msg= pub.parse_response()
            print(msg)
                
- 主从复制
    优势:
        - 高可用
        - 分担主压力
    注意: 
        - slave设置只读
    
    
    从的配置文件添加以下记录,即可:
        slaveof 1.1.1.1 3306 

- sentinel,哨兵
    启动主redis:
        redis-server /etc/redis-6379.conf  启动主redis
        redis-server /etc/redis-6380.conf  启动从redis
        
    在linux中:
        找到 /etc/redis-sentinel-8001.conf  配置文件,在内部:
            - 哨兵的端口 port = 8001
            - 主redis的IP,哨兵个数的一半/1
        
        找到 /etc/redis-sentinel-8002.conf  配置文件,在内部:
            - 哨兵的端口 port = 8002
            - 主redis的IP, 1 
    
        启动两个哨兵
        

- redis-cluster

   redis集群、分片、分布式redis        
   redis-py-cluster

问题:
    目前你们公司项目1000用户,QPS=1000 ,如果用户猛增10000w?
    项目如何提高的并发?
    
    1. 数据库读写分离
    2. 设置缓存
    3. 负载均衡

 

redis的cluster是什么?
    集群方案:
        - redis cluster 官方提供的集群方案。
        - codis,豌豆荚技术团队。
        - tweproxy,Twiter技术团队。
    redis cluster的原理?
        - 基于分片来完成。
        - redis将所有能放置数据的地方创建了 16384 个哈希槽。
        - 如果设置集群的话,就可以为每个实例分配哈希槽:
            - 192.168.1.20【0-5000- 192.168.1.21【5001-10000- 192.168.1.22【10001-16384- 以后想要在redis中写值时,
            set k1 123 
          将k1通过crc16的算法,将k1转换成一个数字。然后再将该数字和16384求余,如果得到的余数 3000,那么就将该值写入到 192.168.1.20 实例中。
            
redis是否可以做持久化?
    RDB:每隔一段时间对redis进行一次持久化。
         - 缺点:数据不完整
         - 优点:速度快
    AOF:把所有命令保存起来,如果想到重新生成到redis,那么就要把命令重新执行一次。
         - 缺点:速度慢,文件比较大
         - 优点:数据完整
        
redis的过期策略。
    voltile-lru:    从已设置过期时间的数据集(server.db[i].expires)中挑选最近频率最少数据淘汰
    volatile-ttl:   从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
    volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

    
    allkeys-lru:       从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
    allkeys-random:    从数据集(server.db[i].dict)中任意选择数据淘汰
    no-enviction(驱逐):禁止驱逐数据
                
redis的分布式锁实现。
    - 写值并设置超时时间
    - 超过一半的redis实例设置成功,就表示加锁完成。
    - 使用:安装redlock-py 
        from redlock import Redlock

        dlm = Redlock(
            [
                {"host": "localhost", "port": 6379, "db": 0},
                {"host": "localhost", "port": 6379, "db": 0},
                {"host": "localhost", "port": 6379, "db": 0},
            ]
        )

        # 加锁,acquire
        my_lock = dlm.lock("my_resource_name",10000)
        if  my_lock:
            # J进行操作
            # 解锁,release
            dlm.unlock(my_lock)
        else:
            print('获取锁失败')
    
http://www.redis.cn/

 

posted on 2018-05-21 18:45  杨小天  阅读(132)  评论(0)    收藏  举报