Redis
1.非關系型內存數據(nosql;mongodb,redis),key-value的存儲
2.單線程單進程,qps:10w
Mencached:多線程,支持的數據類型少,只支持字符串類型,不支持持久化
redis支持的5大數據類型
k1:'123' 字符串
k2:[1,2,3,4] 列表/數組
k3:{1,2,3,4} 集合:去重,爬蟲去重
k4:{name:mcc,age:18} 字典/哈希表
k5:{('mcc',18),('zl',12)} 有序集合:游戲排行榜
redis支持持久化,兩種持久化方案
python操作 redis
新建一個py文件 --安裝 最新版本
使用
from redis import Redis # 實例化產生對象,就是拿到一個redis鏈接 conn=Redis(host='localhost',posr=6379) 現在都是默認的,不用寫 操作redis(value部分都是以bytes的格式存儲),所以要轉一下 ret=conn.get('name') print(ret) str() bytes()
redis操作只連接池
from redis import Connection # 池子應該寫成單列 寫在模塊中,然后引入直接用就好 pool=ConnectionPool(host='127.0.0.1',port=6379,max_connection=100) conn=Redis(connection_pool=pool) print(conn.get('name'))
redis操作之字符串
conn.set()
四個參數
ex:過期時間(秒)
px:過期時間(毫秒)
nx:默認是False,如果設置為True,則只有name不存在的時候,當前set對象才執行,若值存在,則修改不了,執行沒有效果
xx:默認是False,如果設置為True,只有name存在的時候才會執行,不存在不會執行 -- 存在就會覆蓋
示例
conn.set('name','egon',ex=5,xx=True) print(conn.get('name'))
setnx 默認nx=True
setex 默認ex=True
conn.setex('xxx',5,'ppp') name,time,value
批量設置 重點記憶
conn.mset(mapping) 傳一個字典 conn.mset({'k1':'v1','k2':'v2'})
批量取值
conn.mget(keys,*args) keys是個列表 conn.mget(['k1','k2'])/conn.mget('k1','k2')
其他的一些方法
getrange(key,start,end) 取出字符串的一部分 其他語言不支持字符串取值,只能自己取 setrange 修改字符串內容,從指定的字符串后面開始替換 拿到的結果是字節 setrange(name,offset,value) name 是主鍵,offset 要替換的索引位置,value 替換成什么內容 setrange(egon,1,lxx) --elxx strlen --返回字符串的長度 其他語言計算比較復雜,所以用的多
重點
conn.incr('age') 自增
# 應用場景 文章閱讀數 在線直播人數 conn.incr('age',amount=3) 指定增長為3,每一次 conn.incr('age',amount=-3) 指定自減為3
# 自減
conn.decr('age',amount=3)
追加
conn.append('age','xxx') 18xxx 注意,數字是可以自增和自減的,但是只限制是純數字
redis之字典操作 --hash操作
conn.hset('hash1','k1','v1') hash1--類似表 k1是表中的key值 v1是表中的value值
conn.hsetnx nx:值存在就不修改
批量設值
conn.hmset('hash1',{'name':'mcc','age':18}) conn.hmget('hash1','k1')
批量取值
conn.hmget('hash1',['name','age']) conn.hmget('hash1','name','age')
取值 字典取值 獲取所有
conn.hgetall('hash1',[b'name']) --b'mcc'
獲取鍵值對的長度
conn.hlen('hash1') --就是一個表中有多少條數據 hkeys/hvalue/hexits conn.hdel('hash1','k1') 刪除 conn.hincrby('hash1','k3') 增加值
重點
hscan 參數是游標,count,
hscan_iter 其實拿到的是一個生成器 內部是while 循環嵌套for循環,yidld
只支持一層的5大數據類型,也就是說字典的value只能是字符串,列表的value只能是字符串
redis之列表操作
conn.flushdb() 刪掉所有庫,不要做 conn.lpush('list1',10) 插入多個值,是插到上方,rpush是插入到下方 conn.llen('list1') # 獲取長度 conn.linsert('list1','before',10,100) 對列表list1,在10的前面插入100,如果有多個10,是以第一個10為標准 conn.linsert('list1','after',10,100) conn.lset('list1','4',123) # 從0開始 索引**不是row,value值 row是軟件做的,內部是從0開始 conn.lrem('list1',count,value) count是0代表所有全刪 2代表從前往后刪除2個 -2代表從后往前刪除兩個 conn.lpop() 從左側pop出一個元素 # 如果一值移除,沒有的話會給一個None conn.lrange() 獲取從幾到幾的元素 前后都取,都是閉區間
重點 沒有阻塞住,可以實現分布式
conn.blpop # 基於這個做一個生產者消費者模型 #這個是在取值的時候,如果沒有值會一值在原地等待,所以我們可以起一個新項目,給他push值,這樣就相當於完成了一個生產者消費者模型 print(conn.blpop('list1')) 沒有原地等待 分布式的東西
添加值
conn.push('list1',10) 之后運行會發現 print(conn.blpop('list1')) --(b'list1',b'10')
帶b就是阻塞
獲取列表中所有值
conn.lrange('list1',start,end) for i in range(10000): conn.lpush('list1',i) print(conn.lrange('list1',0,conn,llen('list1'))) # 將所有的值都拿了出來,不太好,需要有一個類似於生成器的東西scan,只能自己寫
自定義生成器
def scan_list(name,count=10): index = 0 while True: # count+index-1 是因為取得是自閉和的值,從0-9就是10條了 data_list = conn.lrange(name,index,count+index-1) if not data_list: return # 這里就是將所有的數據都取出后,列表空了,那就直接結束這個函數 # 下面是正常的邏輯 index = count # 這樣的話下面再取的值的話就是從索引10 開始了 for data in data_list: yield data # 使用生成器直接將data一個一個的給出 print(conn.lrange('list1',0,100)) # 這個就是將100條全部取出 for i in scan_list('list1',5): print i # 和全部取出有了明顯的對比,下面這個更省內存
redis其他操作--不管數據類型,通用操作
conn.delete() 根據key值刪除 conn.exists() 返回0/1 conn.keys() 里面可以傳正則 模糊匹配 expire conn.rename() 給key值重命名 conn.move() 移動數據庫 randomkey() 隨機獲取一個key conn.type() 查看數據類型 scan,scan_iter
django中操作
管道-實現事務 pipe = conn.pipeline(transaction = True) pipe.multi() pipe.set('name','alex') pipe.set('role','sb') pipe.execute() # 這個才是真正的去執行
所有框架都能用的方式
-新建一個py文件,生成一個redis數據庫連接池 from redis import ConnectionPool POOL = ConnectionPool(host='127.0.0.1',port=6379,max_connection=100)
在哪用,導過來
conn = Redis(connection_pool=POOL) conn.set('xxx','yyy') conn.get('name')
django中使用 django-redis
1.安裝
2.在settings中做配置
# 緩存配置:采用redis CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 100} } } }
3.使用:
from django-redis import get_redis_connection def index(request): conn = get_redis_connection() print conn.get('name') conn.set return HttpResponse('ok')