请选择 进入手机版 | 继续访问电脑版

Redis中国用户组(CRUG)论坛

 找回密码
 立即注册

扫一扫,访问微社区

搜索
热搜: 活动 交友 discuz
查看: 2929|回复: 2

使用Python操作Redis

[复制链接]
  • TA的每日心情
    开心
    2016-9-7 09:37
  • 签到天数: 7 天

    [LV.3]偶尔看看II

    23

    主题

    35

    帖子

    256

    积分

    中级会员

    Rank: 3Rank: 3

    积分
    256
    发表于 2016-3-15 09:50:27 | 显示全部楼层 |阅读模式
    1. 安装pyredis
    首先安装pip
    1. <SHELL># apt-get install python-pip
    2. ......
    3. <SHELL># pip install --proxy=http://172.1.2.6:8080 redis
    4.   Downloading redis-2.9.1.tar.gz (62kB): 62kB downloaded
    5.   Running setup.py (path:/tmp/pip_build_root/redis/setup.py) egg_info for package redis
    6.   ......
    7.   Successfully installed redis
    8.   Cleaning up...
    复制代码


    也可以使用easy_install的方式来安装:
    1. easy_install redis
    复制代码

    或者直接编译安装:
    1. wget https://pypi.python.org/packages/source/r/redis/redis-2.9.1.tar.gz
    2. tar xvzf redis-2.9.1.tar.gz
    3. cd redis-2.9.1
    4. python setup.py install
    复制代码


    2 . 简单的redis操作
    redis连接实例是线程安全的,可以直接将redis连接实例设置为一个全局变量,直接使用。如果需要另一个Redis实例(or Redis数据库)时,就需要重新创建redis连接实例来获取一个新的连接。同理,python的redis没有实现select命令。
    1. >>> import redis
    2. >>> r = redis.Redis(host='localhost',port=6379,db=0)
    3. >>> r.set('guo','shuai')
    4. True
    5. >>> r.get('guo')
    6. 'shuai'
    7. >>> r['guo']            
    8. 'shuai'
    9. >>> r.keys()
    10. ['guo']
    11. >>> r.dbsize()         #当前数据库包含多少条数据      
    12. 1L
    13. >>> r.delete('guo')
    14. 1
    15. >>> r.save()               #执行“检查点”操作,将数据写回磁盘。保存时阻塞
    16. True
    17. >>> r.get('guo');
    18. >>> r.flushdb()        #清空r中的所有数据
    19. True
    复制代码


    3. pipeline操作
    管道(pipeline)是redis在提供单个请求中缓冲多条服务器命令的基类的子类。它通过减少服务器-客户端之间反复的TCP数据库包,从而大大提高了执行批量命令的功能。
    1. >>> p = r.pipeline()        --创建一个管道
    2. >>> p.set('hello','redis')
    3. >>> p.sadd('faz','baz')
    4. >>> p.incr('num')
    5. >>> p.execute()
    6. [True, 1, 1]
    7. >>> r.get('hello')
    8. 'redis'
    复制代码


    管道的命令可以写在一起,如:
    1. >>> p.set('hello','redis').sadd('faz','baz').incr('num').execute()
    复制代码

    默认的情况下,管道里执行的命令可以保证执行的原子性,执行pipe = r.pipeline(transaction=False)可以禁用这一特性。
    4. 应用场景 – 页面点击数
    《Redis Cookbook》对这个经典场景进行详细描述。假定我们对一系列页面需要记录点击次数。例如论坛的每个帖子都要记录点击次数,而点击次数比回帖的次数的多得多。如果使用关系数据库来存储点击,可能存在大量的行级锁争用。所以,点击数的增加使用redis的INCR命令最好不过了。
    当redis服务器启动时,可以从关系数据库读入点击数的初始值(1237这个页面被访问了34634次)
    1. >>> r.set("visit:1237:totals",34634)
    2. True
    复制代码


    每当有一个页面点击,则使用INCR增加点击数即可。
    1. >>> r.incr("visit:1237:totals")
    2. 34635
    3. >>> r.incr("visit:1237:totals")
    4. 34636
    复制代码


    页面载入的时候则可直接获取这个值
    1. >>> r.get ("visit:1237:totals")
    2. '34636'
    复制代码


    5. 使用hash类型保存多样化对象
    当有大量类型文档的对象,文档的内容都不一样时,(即“表”没有固定的列),可以使用hash来表达。
    1. >>> r.hset('users:jdoe',  'name', "John Doe")
    2. 1L
    3. >>> r.hset('users:jdoe', 'email', 'John@test.com')
    4. 1L
    5. >>> r.hset('users:jdoe',  'phone', '1555313940')
    6. 1L
    7. >>> r.hincrby('users:jdoe', 'visits', 1)
    8. 1L
    9. >>> r.hgetall('users:jdoe')
    10. {'phone': '1555313940', 'name': 'John Doe', 'visits': '1', 'email': 'John@test.com'}
    11. >>> r.hkeys('users:jdoe')
    12. ['name', 'email', 'phone', 'visits']
    复制代码


    6. 应用场景 – 社交圈子数据
    在社交网站中,每一个圈子(circle)都有自己的用户群。通过圈子可以找到有共同特征(比如某一体育活动、游戏、电影等爱好者)的人。当一个用户加入一个或几个圈子后,系统可以向这个用户推荐圈子中的人。
    我们定义这样两个圈子,并加入一些圈子成员。
    1. >>> r.sadd('circle:game:lol','user:debugo')
    2. 1
    3. >>> r.sadd('circle:game:lol','user:leo')
    4. 1
    5. >>> r.sadd('circle:game:lol','user:Guo')
    6. 1
    7. >>> r.sadd('circle:soccer:InterMilan','user:Guo')
    8. 1
    9. >>> r.sadd('circle:soccer:InterMilan','user:Levis')
    10. 1
    11. >>> r.sadd('circle:soccer:InterMilan','user:leo')
    12. 1
    复制代码


    #获得某一圈子的成员
    1. >>> r.smembers('circle:game:lol')
    2. set(['user:Guo', 'user:debugo', 'user:leo'])
    3. redis> smembers circle:jdoe:family
    复制代码

    可以使用集合运算来得到几个圈子的共同成员:
    1. >>> r.sinter('circle:game:lol', 'circle:soccer:InterMilan')
    2. set(['user:Guo', 'user:leo'])
    3. >>> r.sunion('circle:game:lol', 'circle:soccer:InterMilan')
    4. set(['user:Levis', 'user:Guo', 'user:debugo', 'user:leo'])
    复制代码


    7. 应用场景 – 实时用户统计
    Counting Online Users with Redis介绍了这个方法。当我们需要在页面上显示当前的在线用户时,就可以使用Redis来完成了。首先获得当前时间(以Unix timestamps方式)除以60,可以基于这个值创建一个key。然后添加用户到这个集合中。当超过你设定的最大的超时时间,则将这个集合设为过期;而当需要查询当前在线用户的时候,则将最后N分钟的集合交集在一起即可。由于redis连接对象是线程安全的,所以可以直接使用一个全局变量来表示。
    1. import time
    2. from redis import Redis
    3. from datetime import datetime
    4. ONLINE_LAST_MINUTES = 5
    5. redis = Redis()

    6. def mark_online(user_id):         #将一个用户标记为online
    7.     now = int(time.time())        #当前的UNIX时间戳
    8.     expires = now + (app.config['ONLINE_LAST_MINUTES'] * 60) + 10    #过期的UNIX时间戳
    9.     all_users_key = 'online-users/%d' % (now // 60)        #集合名,包含分钟信息
    10.     user_key = 'user-activity/%s' % user_id               
    11.     p = redis.pipeline()
    12.     p.sadd(all_users_key, user_id)                         #将用户id插入到包含分钟信息的集合中
    13.     p.set(user_key, now)                                   #记录用户的标记时间
    14.     p.expireat(all_users_key, expires)                     #设定集合的过期时间为UNIX的时间戳
    15.     p.expireat(user_key, expires)
    16.     p.execute()

    17. def get_user_last_activity(user_id):        #获得用户的最后活跃时间
    18.     last_active = redis.get('user-activity/%s' % user_id)  #如果获取不到,则返回None
    19.     if last_active is None:
    20.         return None
    21.     return datetime.utcfromtimestamp(int(last_active))

    22. def get_online_users():                     #获得当前online用户的列表
    23.     current = int(time.time()) // 60        
    24.     minutes = xrange(app.config['ONLINE_LAST_MINUTES'])
    25.     return redis.sunion(['online-users/%d' % (current - x)        #取ONLINE_LAST_MINUTES分钟对应集合的交集
    26.                          for x in minutes])
    复制代码


    References:
    http://blog.csdn.net/vv_demon/article/details/7676384
    tigerfish NoSQL和NewSQL数据库引航
    《Redis Cookbook》
    Redis-Python https://pypi.python.org/pypi/redis/2.9.1

  • TA的每日心情
    开心
    2016-6-3 13:11
  • 签到天数: 1 天

    [LV.1]初来乍到

    1

    主题

    3

    帖子

    37

    积分

    新手上路

    Rank: 1

    积分
    37
    发表于 2016-6-3 13:16:58 | 显示全部楼层
    谢谢分享
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2016-7-25 17:39
  • 签到天数: 1 天

    [LV.1]初来乍到

    0

    主题

    2

    帖子

    37

    积分

    新手上路

    Rank: 1

    积分
    37
    发表于 2016-7-25 17:41:00 | 显示全部楼层
    多谢分享
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    Archiver|手机版|小黑屋|Redis中国用户组 ( 京ICP备15003959号

    GMT+8, 2019-10-16 08:11 , Processed in 0.087713 second(s), 25 queries .

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表