设为首页 收藏本站
查看: 1246|回复: 0

[经验分享] python之redis

[复制链接]

尚未签到

发表于 2017-12-20 17:21:24 | 显示全部楼层 |阅读模式
  前言:本来想写redis与rabbitMQ的,但写完redis后感觉有点多,rabbitMQ还是留在下篇博客吧~~
  关于redis与rabbitMQ的下载与安装,可参考redis&rabbitMQ安装

一、redis基本操作-1
  

1 import redis  

2 #建立连接  
3 r=redis.Redis(host="127.0.0.1",port=6379)
  
4
  
5 all_keys=r.keys()#输出所有key,列表[b'age',b'name',b'occupation']
  
6 for k in all_keys:
  
7     print(k,r.get(k))
  
8
  
9 print(r.keys())
  
10
  
11 r.set("sister","yongli",ex=5)     #存入缓存,5秒后清除
  
12
  
13 print(r.get("sister"))
  
14
  
15 r.set("father","jingxian",nx=True)    #只有father不存在时,当前set操作才执行
  
16 print(r.get("father"))
  
17
  
18 r.set("AA","BB",xx=True)           #只有AA存在时,当前set操作才执行
  
19 print(r.get("AA"))
  
20
  
21
  
22 r.mset(k1="v1",k2="v2")        #批量设置值
  
23 print(r.mget("k1","k2"))     #批量获取值
  
24
  
25
  
26 r.set("id","3114007487")
  
27 print(r.getrange("id",3,6))      #获取子序列(切片,0开始)
  
28
  
29 r.setrange("id",3,"AAA")       #修改字符串内容,从指定字符串索引开始向后替换
  
30 print(r.getrange("id",0,-1))   #输出:b'311AAA7487'
  
31
  
32 #"3" 对应ASCII码为51, 二进制为 0011 0011
  
33 print(r.getbit("id",7))
  
34 r.setbit("id",7,0)      #将第7位改为0,第0位开始算 0011 0010 : 50 对应为2
  
35 print(r.getbit("id",7))
  
36 print(r.getbit("id",1000))  #读取位数超过,不爆错
  
37 print(r.get("id"))
  

  运行结果:

DSC0000.gif DSC0001.gif   

1 b'age' b'22'  
2 b'id' b'211AAA7487'
  
3 b'k2' b'v2'
  
4 b'k1' b'v1'
  
5 b'name' b'abc'
  
6 b'occupation' b'student'
  
7 b'father' b'BB'
  
8 [b'age', b'id', b'k2', b'k1', b'name', b'occupation', b'father']
  
9 b'yongli'
  
10 b'BB'
  
11 None
  
12 [b'v1', b'v2']
  
13 b'4007'
  
14 b'311AAA7487'
  
15 1
  
16 0
  
17 0
  
18 b'211AAA7487'
  


View Code  redis基本操作-2(供拓展)

  

getbit(name, offset)  

1    # 获取name对应的值的二进制表示中的某位的值 (0或1)  

  

  
bitcount(key, start=None, end=None)
  
1    # 获取name对应的值的二进制表示中 1 的个数
  
2    # 参数:
  
3        # key,Redis的name
  
4        # start,位起始位置
  
5        # end,位结束位置
  

  

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

  

  
incr(self, name, amount=1)  可用于计算PV
  
1    # 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。
  
2     
  
3    # 参数:
  
4        # name,Redis的name
  
5        # amount,自增数(必须是整数)
  
6
  

  

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

  

  
decr(self, name, amount=1)
  
1    # 自减 name对应的值,当name不存在时,则创建name=amount,否则,则自减。
  
2     
  
3    # 参数:
  
4        # name,Redis的name
  
5        # amount,自减数(整数)
  

  

  
append(key, value)  返回字符的长度
  
1    # 在redis name对应的值后面追加内容
  
2     
  
3    # 参数:
  
4        key, redis的name
  
5        value, 要追加的字符串
  


View Code  上面是redis的基本操作,建议一句句实验下。
  redis是一种no-sql缓存数据库。数据是存在缓存中的。所以你如果重启redis-server,会发现之前存的数据都消失了! 为了解决这个问题,可在存数据后加上save命令, 数据便会存到磁盘,重启后数据不会消失。
DSC0002.png


二、连接池与计算网站UV实例
  1. 连接池
  使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。
  

1 import redis  

2  

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

4 r = redis.Redis(connection_pool=pool)  

  2.计算网站UV实例
  关于PV,UV,IP可以看看我下面的总结,具体也可以参考博客:http://playkid.blog.163.com/blog/static/56287260201361951919690/

  

PV(page view)即页面浏览量或点击量,是衡量一个网站或网页用户访问量。具体的说,PV值就是所有访问者在24小时(0点到24点)内看了某个网站多少个页面或某个网页多少次。PV是指页面刷新的次数,每一次页面刷新,就算做一次PV流量。  

  
UV(unique visitor)即独立访客数,指访问某个站点或点击某个网页的不同IP地址的人数。在同一天内,UV只记录第一次进入网站的具有独立IP的访问者,在同一天内再次访问该网站则不计数。
  

  
IP可以理解为独立IP的访问用户,指1天内使用不同IP地址的用户访问网站的数量,同一IP无论访问了几个页面,独立IP数均为1。
  


View Code  setbit巨流弊的应用场景,想想什么情况下会用到这个功能呢?超大型的应用平台,比如新浪微博,我想查看当前正在登陆的用户,如何实现?当然你会想到,用户登陆后在数据库上的用户信息上做个标记,然后count去统计做标记的用户一共有多少,so,当前用户查看迎刃而解;OK,好好,首先每个用户登录都要设置标记,如果当前用户几个亿,那么得存几个亿的标记位,超级占用库的开销;现在就有一个无敌高效的办法,利用二进制位统计当前在线用户,什么意思呢?看下面的代码就能明白了:

  

1 import redis  

2 #建立连接  
3 pool = redis.ConnectionPool(host='127.0.0.1', port=6379)
  
4 r = redis.Redis(connection_pool=pool)
  
5
  
6 r.setbit("uv_count1", 5,1)  #每来一个连接,则让字节位设为1
  
7 r.setbit("uv_count1", 8,1)
  
8 r.setbit("uv_count1", 3,1)
  
9 r.setbit("uv_count1", 3,1) #重复的不计算
  
10 print("uv_count:", r.bitcount("uv_count1"))
  
11
  
12 输出:uv_count: 3
  


View Code  比如:当前第500位用户在线,则将第500个bit置为1(默认为0)。bitcount统计二级制位中1的个数,setbit和bitcount配合使用,轻松解决当前在线用户数的问题。1字节=8位,那么10m=8000万位,即一个亿的在线用户也就10m多的内存就可搞定,这优化不得了!!

三、redis基本hash,list,set基本操作
  我会直接用运行的截图来讲hash,list,set基本操作,不然有点无聊~~
  Hash操作,redis中Hash在内存中的存储格式如下图:
DSC0003.png

  1. hash基本操作
DSC0004.png

  List操作,redis中的List在在内存中按照一个name对应一个List来存储。如图:
DSC0005.png

  2. list基本操作
  列表的某一个值前或后插入一个新值
DSC0006.png

  r.lpush()  从左边开始放数据
  r.rpush()   从右边开始放数据
DSC0007.png

  3. set基本操作
DSC0008.png


四、redis的16个数据库与有序集合
  1. 16个数据库
  Redis有默认16个数据库,默认在0库,可以切换(eg:切换到15号数据库: select 15);但在python中,出于安全考虑,在python的API没有切换数据库的概念,可以在连接调用时指定调用的数据库,但一连接上了就不能切换了。
  

move(name, db))  

     # 将redis的某个值移动到指定的db下  

  2. 有序集合
  有序集合: 在集合的基础上,为每个元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。
  有序集合的基本操作
DSC0009.png


五、redis发布与订阅
  应用场景:一登陆QQ右上角会有广告。
  发布者:服务器
  订阅者:个人用户
  发布与订阅必须在同一个频道上(类似于收音机),不然发布方发布后,订阅方接收不到!
  redis_helper.py文件(公共类)
  

1 import redis  

2  
3

  
4>  
5
  
6     def __init__(self):
  
7         self.__conn=redis.Redis(host='127.0.0.1')
  
8         self.chan_sub='fm88.7'          #设置两个频道,订阅频道
  
9         self.chan_pub='fm88.7'         #发布频道
  
10     
  
11     def public(self,msg):
  
12         self.__conn.publish(self.chan_pub,msg)        #发布消息
  
13         returnTrue
  
14     
  
15     def subscribe(self):
  
16         pub=self.__conn.pubsub()               #生成实例 打开收音机
  
17         pub.subscribe(self.chan_sub)     #拧到那个台
  
18         m=pub.parse_response()          #准备听,未阻塞,再调用一次就阻塞
  
19         print(m)        #[b'subscribe', b'fm88.7', 1]
  
20         return pub             #返回实例
  

  redis_sub.py
  

1 from redis_helper import RedisHelper  

2  
3 obj=RedisHelper()
  
4 redis_sub=obj.subscribe()        #返回实例
  
5
  
6 while True:7     msg=redis_sub.parse_response()       #听
  
8 print(msg)              #有消息则打印,无消息则阻塞
  

  redis_pub.py
  

from redis_helper importRedisHelper  

  
obj
=RedisHelper()  
return1
=obj.public('love')  

print(return1)  

  运行结果(客户端): 可并发处理多个客户端。
  

[b'subscribe', b'fm88.7', 1]  
[b
'message', b'fm88.7', b'love']  
[b
'message', b'fm88.7', b'love']  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-426136-1-1.html 上篇帖子: spring boot 配置redis 下篇帖子: SpringBoot使用Redis缓存
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

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