首先安裝pipgit
1
2
3
4
5
6
7
8
|
<SHELL># apt-get install python-pip
......
<SHELL># pip install --proxy=http://172.1.2.6:8080 redis
Downloading redis-2.9.1.tar.gz (62kB): 62kB downloaded
Running setup.py (path:/tmp/pip_build_root/redis/setup.py) egg_info for package redis
......
Successfully installed redis
Cleaning up...
|
也能夠使用easy_install的方式來安裝:github
1
|
easy_install redis
|
或者直接編譯安裝:redis
1
2
3
4
|
wget https://pypi.python.org/packages/source/r/redis/redis-2.9.1.tar.gz
tar xvzf redis-2.9.1.tar.gz
cd redis-2.9.1
python setup.py install
|
2 . 簡單的redis操做
redis鏈接實例是線程安全的,能夠直接將redis鏈接實例設置爲一個全局變量,直接使用。若是須要另外一個Redis實例(or Redis數據庫)時,就須要從新建立redis鏈接實例來獲取一個新的鏈接。同理,python的redis沒有實現select命令。數據庫
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
>>> import redis
>>> r = redis.Redis(host='localhost',port=6379,db=0)
>>> r.set('guo','shuai')
True
>>> r.get('guo')
'shuai'
>>> r['guo']
'shuai'
>>> r.keys()
['guo']
>>> r.dbsize() #當前數據庫包含多少條數據
1L
>>> r.delete('guo')
1
>>> r.save() #執行「檢查點」操做,將數據寫回磁盤。保存時阻塞
True
>>> r.get('guo');
>>> r.flushdb() #清空r中的全部數據
True
|
3. pipeline操做
管道(pipeline)是redis在提供單個請求中緩衝多條服務器命令的基類的子類。它經過減小服務器-客戶端之間反覆的TCP數據庫包,從而大大提升了執行批量命令的功能。flask
1
2
3
4
5
6
7
8
|
>>> p = r.pipeline() --建立一個管道
>>> p.set('hello','redis')
>>> p.sadd('faz','baz')
>>> p.incr('num')
>>> p.execute()
[True, 1, 1]
>>> r.get('hello')
'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次)app
1
2
|
>>> r.set("visit:1237:totals",34634)
True
|
每當有一個頁面點擊,則使用INCR增長點擊數便可。網站
1
2
3
4
|
>>> r.incr("visit:1237:totals")
34635
>>> r.incr("visit:1237:totals")
34636
|
頁面載入的時候則可直接獲取這個值
1
2
|
>>> r.get ("visit:1237:totals")
'34636'
|
5. 使用hash類型保存多樣化對象
當有大量類型文檔的對象,文檔的內容都不同時,(即「表」沒有固定的列),能夠使用hash來表達。
1
2
3
4
5
6
7
8
9
10
11
12
|
>>> r.hset('users:jdoe', 'name', "John Doe")
1L
>>> r.hset('users:jdoe', 'email', 'John@test.com')
1L
>>> r.hset('users:jdoe', 'phone', '1555313940')
1L
>>> r.hincrby('users:jdoe', 'visits', 1)
1L
>>> r.hgetall('users:jdoe')
{'phone': '1555313940', 'name': 'John Doe', 'visits': '1', 'email': 'John@test.com'}
>>> r.hkeys('users:jdoe')
['name', 'email', 'phone', 'visits']
|
6. 應用場景 – 社交圈子數據
在社交網站中,每個圈子(circle)都有本身的用戶羣。經過圈子能夠找到有共同特徵(好比某一體育活動、遊戲、電影等愛好者)的人。當一個用戶加入一個或幾個圈子後,系統能夠向這個用戶推薦圈子中的人。
咱們定義這樣兩個圈子,並加入一些圈子成員。
1
2
3
4
5
6
7
8
9
10
11
12
|
>>> r.sadd('circle:game:lol','user:debugo')
1
>>> r.sadd('circle:game:lol','user:leo')
1
>>> r.sadd('circle:game:lol','user:Guo')
1
>>> r.sadd('circle:soccer:InterMilan','user:Guo')
1
>>> r.sadd('circle:soccer:InterMilan','user:Levis')
1
>>> r.sadd('circle:soccer:InterMilan','user:leo')
1
|
#得到某一圈子的成員
1
2
3
|
>>> r.smembers('circle:game:lol')
set(['user:Guo', 'user:debugo', 'user:leo'])
redis> smembers circle:jdoe:family
|
能夠使用集合運算來獲得幾個圈子的共同成員:
1
2
3
4
|
>>> r.sinter('circle:game:lol', 'circle:soccer:InterMilan')
set(['user:Guo', 'user:leo'])
>>> r.sunion('circle:game:lol', 'circle:soccer:InterMilan')
set(['user:Levis', 'user:Guo', 'user:debugo', 'user:leo'])
|
7. 應用場景 – 實時用戶統計
Counting Online Users with Redis介紹了這個方法。當咱們須要在頁面上顯示當前的在線用戶時,就能夠使用Redis來完成了。首先得到當前時間(以Unix timestamps方式)除以60,能夠基於這個值建立一個key。而後添加用戶到這個集合中。當超過你設定的最大的超時時間,則將這個集合設爲過時;而當須要查詢當前在線用戶的時候,則將最後N分鐘的集合交集在一塊兒便可。因爲redis鏈接對象是線程安全的,因此能夠直接使用一個全局變量來表示。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
import time
from redis import Redis
from datetime import datetime
ONLINE_LAST_MINUTES = 5
redis = Redis()
def mark_online(user_id): #將一個用戶標記爲online
now = int(time.time()) #當前的UNIX時間戳
expires = now + (app.config['ONLINE_LAST_MINUTES'] * 60) + 10 #過時的UNIX時間戳
all_users_key = 'online-users/%d' % (now // 60) #集合名,包含分鐘信息
user_key = 'user-activity/%s' % user_id
p = redis.pipeline()
p.sadd(all_users_key, user_id) #將用戶id插入到包含分鐘信息的集合中
p.set(user_key, now) #記錄用戶的標記時間
p.expireat(all_users_key, expires) #設定集合的過時時間爲UNIX的時間戳
p.expireat(user_key, expires)
p.execute()
def get_user_last_activity(user_id): #得到用戶的最後活躍時間
last_active = redis.get('user-activity/%s' % user_id) #若是獲取不到,則返回None
if last_active is None:
return None
return datetime.utcfromtimestamp(int(last_active))
def get_online_users(): #得到當前online用戶的列表
current = int(time.time()) // 60
minutes = xrange(app.config['ONLINE_LAST_MINUTES'])
return redis.sunion(['online-users/%d' % (current - x) #取ONLINE_LAST_MINUTES分鐘對應集合的交集
for x in minutes
|