python之redis


前言:本來想寫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"))

運行結果:

 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命令, 數據便會存到磁盤,重啟后數據不會消失

 

二、連接池與計算網站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在內存中的存儲格式如下圖:

 

1. hash基本操作

 

List操作,redis中的List在在內存中按照一個name對應一個List來存儲。如圖:

 

2. list基本操作

列表的某一個值前或后插入一個新值

r.lpush()  從左邊開始放數據
r.rpush()   從右邊開始放數據

 

 3. set基本操作

 

四、redis的16個數據庫與有序集合

1. 16個數據庫

Redis有默認16個數據庫,默認在0庫,可以切換(eg:切換到15號數據庫: select 15);但在python中,出於安全考慮,在python的API沒有切換數據庫的概念,可以在連接調用時指定調用的數據庫,但一連接上了就不能切換了

move(name, db))
     # 將redis的某個值移動到指定的db下

 

2. 有序集合

有序集合: 在集合的基礎上,為每個元素排序;元素的排序需要根據另外一個值來進行比較,所以,對於有序集合,每一個元素有兩個值,即:值和分數,分數專門用來做排序

 

有序集合的基本操作

 

 

 五、redis發布與訂閱


應用場景:一登陸QQ右上角會有廣告。
發布者:服務器
訂閱者:個人用戶

發布與訂閱必須在同一個頻道上(類似於收音機),不然發布方發布后,訂閱方接收不到!

redis_helper.py文件(公共類)

 1 import redis
 2 
 3 
 4 class RedisHelper(object):
 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']

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM