一、Redis的介紹
redis是業界主流的key-value nosql 數據庫之一。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步。
二、Redis的優點
-
異常快速 : Redis是非常快的,每秒可以執行大約110000設置操作,81000個/每秒的讀取操作。
-
支持豐富的數據類型 : Redis支持最大多數開發人員已經知道如列表,集合,可排序集合,哈希等數據類型。這使得在應用中很容易解決的各種問題,因為我們知道哪些問題處理使用哪種數據類型更好解決。
-
操作都是原子的 : 所有 Redis 的操作都是原子,從而確保當兩個客戶同時訪問 Redis 服務器得到的是更新后的值(最新值)。
-
MultiUtility工具:Redis是一個多功能實用工具,可以在很多如:緩存,消息傳遞隊列中使用(Redis原生支持發布/訂閱),在應用程序中,如:Web應用程序會話,網站頁面點擊數等任何短暫的數據
三、Redis API使用
redis-py 的API的使用可以分類為:
- 連接方式
- 連接池
- 操作
- String 操作
- Hash 操作
- List 操作
- Set 操作
- Sort Set 操作
- 管道
- 發布訂閱
3.1 連接方式
1. 操作模式
redis-py提供兩個類Redis和StrictRedis用於實現Redis的命令,StrictRedis用於實現大部分官方的命令,並使用官方的語法和命令,Redis是StrictRedis的子類,用於向后兼容舊版本的redis-py。
import redis
host = '172.16.200.49'
port = 6379
r = redis.Redis(host=host, port=port)
r.set('foo', 'bar')
print(r.get('foo'))
2. 連接池
redis-py使用connection pool來管理對一個redis server的所有連接,避免每次建立、釋放連接的開銷。默認,每個Redis實例都會維護一個自己的連接池。可以直接建立一個連接池,然后作為參數Redis,這樣就可以實現多個Redis實例共享一個連接池。
import redis
host = '172.16.200.49'
port = 6379
pool = redis.ConnectionPool(host=host, port=port)
r = redis.Redis(connection_pool=pool)
r.set('foo', 'bar')
print(r.get('foo'))
3.1 string操作
redis中的String在在內存中按照一個name對應一個value來存儲。如圖:

1.set(name, value, ex=None, px=None, nx=False, xx=False)
在Redis中設置值,默認,不存在則創建,存在則修改
參數:
ex,過期時間(秒)
px,過期時間(毫秒)
nx,如果設置為True,則只有name不存在時,當前set操作才執行
xx,如果設置為True,則只有name存在時,崗前set操作才執行
操作命令
# 設置一個k-v
r.set('name', 'bigberg')
print(r.get('name'))
#設置過期時間為2秒
# 2 秒后獲取該值為None
r.set('name', 'bigberg', ex=2)
print(r.get('name'))
time.sleep(2)
print(r.get('name'))
2. setnx(name, value)
設置值,只有name不存在時,執行設置操作(添加)
如果是r.setnx('name', 'Tom') 則name的值還是'bigberg'
r.setnx('age', 22)
print(r.get('age'))
3. setex(name, value, time)
# 設置值
# 參數:
# time,過期時間(數字秒 或 timedelta對象)
4. psetex(name, time_ms, value)
# 設置值
# 參數:
# time_ms,過期時間(數字毫秒 或 timedelta對象)
5. mset(*args, **kwargs)
批量設置值
如:
mset({'k1': 'v1', 'k2': 'v2'})
r.mset({'a': 1, 'b': 2})
print(r.get('a'))
print(r.get('b'))
6. get(name)
獲取值
7. mget(keys, *args)
批量獲取
如:
mget('ylr', 'wupeiqi')
或
r.mget(['ylr', 'wupeiqi'])
r.mset({'a': 1, 'b': 2})
print(r.mget('a', 'b'))
8. getset(name, value)
設置新值並獲取原來的值
# 會將原先的值先返回
print(r.getset('name', 'Tom'))
print(r.get('name'))
9. getrange(key, start, end)
如果是中文字符,在utf-8編碼下,一個中文字符占3個字節
r.set('address', '杭州')
res = r.getrange('address', 0, 2)
print(res.decode())
10. setrange(name, offset, value)
# 修改字符串內容,從指定字符串索引開始向后替換(新值太長時,則向后添加)
# 參數:
# offset,字符串的索引,字節(一個漢字三個字節)
# value,要設置的值
r.setrange('address', 0, '蘇')
print(r.get('address').decode())
# 輸出
蘇州
r.setrange('name', 2, 'ol')
print(r.get('name').decode())
# 輸出
Tool
# Tom 變成了 Tool
11. setbit(name, offset, value)
*用途舉例,用最省空間的方式,存儲在線用戶數及分別是哪些用戶在線
# 對name對應值的二進制表示的位進行操作
# 參數:
# name,redis的name
# offset,位的索引(將值變換成二進制后再進行索引)
# value,值只能是 1 或 0
# 注:如果在Redis中有一個對應: n1 = "foo",
那么字符串foo的二進制表示為:01100110 01101111 01101111
所以,如果執行 setbit('n1', 7, 1),則就會將第7位設置為1,
那么最終二進制則變成 01100111 01101111 01101111,即:"goo"
#我們將Tool 改變為 Pool
#則需要將T的ascii值 改為 P 的ASCII值
print(r.get('name'))
r.setbit('name', 5, 0)
print(r.get('name'))
# 輸出
b'Tool'
b'Pool'
12. getbit(name, offset)
# 獲取name對應的值的二進制表示中的某位的值 (0或1)
print(r.getbit('name', 3))
# 輸出
1
13. bitcount(key, start=None, end=None)
# 獲取name對應的值的二進制表示中 1 的個數
# 參數:
# key,Redis的name
# start,位起始位置
# end,位結束位置
print(r.bitcount('name', 0, 20))
# 輸出
18
14. strlen(name)
# 返回name對應值的字節長度(一個漢字3個字節)
print(r.strlen('address'))
# 輸出
6
15. incr(self, name, amount=1)
# 自增 name對應的值,當name不存在時,則創建name=amount,否則,則自增。
# 參數:
# name,Redis的name
# amount,自增數(必須是整數)
for i in range(5):
print(r.incr('login_user'))
#輸出
1
2
3
4
5
16. incrbyfloat(self, name, amount=1.0)
# 自增 name對應的值,當name不存在時,則創建name=amount,否則,則自增。
# 參數:
# name,Redis的name
# amount,自增數(浮點型)
for i in range(5):
print(r.incrbyfloat('num', 1.2))
# 輸出
1.2
2.4
3.6
4.8
6.0
17. decr(self, name, amount=1)
# 自減 name對應的值,當name不存在時,則創建name=amount,否則,則自減。
# 參數:
# name,Redis的name
# amount,自減數(整數)
for i in range(5):
print(r.decr('login_user'))
# 輸出
4
3
2
1
0
18. append(key, value)
# 在redis name對應的值后面追加內容
# 參數:
key, redis的name
value, 要追加的字符串
print(r.get('address').decode())
print(r.append('address', '西湖區'))
print(r.get('address').decode())
# 輸出
杭州
15
杭州西湖區
