Redis:html
- nosql數據庫,非關係型數據庫redis
- 支持5大數據類型 (字符串String,列表list、字典hash,集合set,zset)sql
- 與之類似的有memcache,但memcache只支持string類型數據庫
- 單進程單線程,好處在於不用考慮併發django
Redis經常使用操做數組
from redis import Redis# from redis import ConnectionPool緩存
conn = Redis() # 實例化對象,建立鏈接對象 # conn.set('name','dxx') # 單個插入 # for i in range(1,100): # conn.set("the %s key"%i, 'the %s value'%i,ex=i) # 循環插入 # ret = conn.get("the 80 key") # 取不到是爲None 沒法指定默認值 # # print(ret) # conn.set('name','希希') # 單個插入 中文會自動以utf8編碼轉碼爲bytes類型 # # for i in range(1,100): # conn.set("%skey"%i,'%svalue'%i) from app01.Redis_POOL import POOL # 鏈接池作成單例 conn = Redis(connection_pool=POOL) print(conn.get("name").decode("utf8")) # 字符串操做 conn.set('age',19,ex=10,xx=True) conn.setex('hobby',10,'basketball') # (key,time, value) # 批量添加,傳字典 conn.mset({'k1':'v1','k2':'v2'}) # 批量取值 print([ res.decode("utf8") for res in conn.mget(['k1', 'k2'])]) # 追加 conn.setrange('k1',1,'pp') # 從索引1的位置日後覆蓋 conn.set('k3','10') # conn.setrange('k3',2,'10') # 從索引2的位置日後覆蓋 # # print(conn.get('k3')) # 重點 (網站訪問量) conn.incr('ask_total',amount=1) # 遞增 可指定頻率爲負數,表示遞減 conn.decr('ask_total') # 與上相反 conn.append('ask_total',22) # 向原有值後拼接 #hash操做 conn.hset('hax1','k1','v1') # 存 print(conn.hget("hax1", 'k1')) # 取 #批量存取 conn.hmset('hax1',{'k2':'v2','k3':'v3'}) print(conn.hmget('hax1', ['k1', 'k2',])) print(conn.hmget('hax1', 'k1', 'k2')) # 內部作判斷是否列表 print(conn.hgetall('hax1')) # {b'k1': b'v1', b'k2': b'v2', b'k3': b'v3'} print(conn.hgetall('hax1')[b"k1"]) # b'v1' print(conn.hlen('hax1')) # 3 列表/數組長度 conn.hdel('hax1','k1') # 哈希刪除 print(conn.hget('hax1','k1')) # 再查詢 conn.hset('hax1','k2',22) conn.hincrby('hax1','k2',amount=-10) # 哈希遞增 或者遞減 print(conn.hget('hax1','k2')) # 重點 hscan hscan_iter for i in range(1,1000): conn.hset('hax2','%skey'%i,'%svalue'%i) # match 過濾條件 模糊匹配,只有?和*兩種模式,?表示匹配一個,*表示匹配多個count 取出數據個數 print(conn.hscan('hax2',10,match='350value',count=20)) # (26, {}) print(conn.hscan('hax2',10,match='350',count=20)) # (26, {}) print(conn.hscan('hax2',10,match='350key',count=20)) # (26, {b'350key': b'350value'}) # conn.hscan_iter('hax2',count=10) genrator = conn.hscan_iter('hax2',count=10) # 產生迭代器,迭代器能產生的數據不因count值而變化, # count的做用是限制一次向redis要多少數據,用完了再要 print(genrator) # 打印的生成器內存地址 print('生成器長度:',len(list(genrator))) # 會取完hax2中全部的數據 for i in genrator: print(i) # 因爲上方len(list(genrator))已經將生成器迭代完,故迭代器已經無元素可迭代,無值打印 # redis列表操做 conn.lpush('h1','11') # 列表左追加 conn.rpush('h1','10','9') # 列表右追加 print(conn.linsert('h1','AFTER','11',99)) # 在元素11後面插入99 print(conn.linsert('h1','AFTER','11','99')) # 在元素11前面插入99 #若是列表中有多個'11',那麼插在第一個'11'的前面或者後面 print(conn.llen('h1')) conn.lset('h1',1,'1111') # 將索引爲1的元素用'1111'替換 conn.lrem('h1',-5,11) #lrem(name,count,value) # count的正負表示從頭開始仍是從尾巴開始刪除和value相同的值,0表示刪除全部相同的 #count的數字表示刪除幾個 print(conn.lindex('h1', 3)) # 取列表索引爲3的值 print(conn.lrange('h1', 1, 5)) #切片取值 取列表索引1-5的元素,閉區間 print(conn.lrange('h1',0,conn.llen('h1'))) # 取列表全部元素 #blpop 重點 print(conn.lpop('h1')) print(conn.lpop('h1')) # 從左刪除一個元素 print(conn.rpop('h1')) # 從右刪除一個元素 while True: print(conn.blpop('h1')) # 取完了會在這裏阻塞,等待有下一個值被添加,你會不會想到隊列呢? # 是的,它能夠實現隊列的效果,能夠實現分佈式 # 能夠同時開多個客戶端去blpop,也能夠同時開多個客戶端去新增
# 自定義列表生成器 - 若是列表很是龐大,一次性取出可能會撐爆內存,所以須要自定義列表生成器進行迭代取值 def scan_list(name,count=10): index = 0 while True: data_list = conn.lrange(name,index,count) if not data_list: return index+= count count+=index for item in data_list: yield item sa_list = scan_list('h1',5) for i in sa_list: print(i) conn.delete('name') # 刪除 print(conn.exists('hax2')) # 返回0或1 print(conn.keys('k?')) # 模糊匹配,只有?和*兩種模式,?表示匹配一個,*表示匹配多個 print(conn.keys('k*')) conn.rename('k1','kk') # 重命名 # 利用管道實現事務操做,redis沒有自身事務操做,需藉助管道實現 pipe = conn.pipeline(transaction=True) pipe.multi() pipe.set('name','egon') pipe.lpush('h1','aa') pipe.execute()
應用場景:服務器
1、利用原生redis實現網站流量統計併發
因爲是全局統計,Django中咱們須要自定義中間件來實現app
from redis import Redis from django.middleware.common import MiddlewareMixin Conn = Redis() class CountVisitorMiddle(MiddlewareMixin): def process_request(self,request): num = Conn.hget('count_visitor','number') if num: Conn.hset('count_visitor','number',int(num.decode("utf8"))+1) else: Conn.hset('count_visitor', 'number', 1)
配置文件中配置:
MIDDLEWARE = [ .......其餘中間件......... 'app01.CountCustomerMiddleWare.CountVisitorMiddle', ]
視圖函數中使用:
from django.shortcuts import render # Create your views here. from app01.redis_hander import Conn def index(request): visitor_number = Conn.hget('count_visitor','number').decode('utf8') return render(request,"index.html",locals())
效果:
固然,django有更好的封裝來讓咱們使用基於redis的緩存實現
2、利用Django基於redis的緩存實現網站流量統計
配置文件中配置緩存信息:
CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", # cache存儲引擎爲redis數據庫 "LOCATION": "redis://127.0.0.1:6379", # redis服務器地址 "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 100} # redis數據庫鏈接池大小限制 # "PASSWORD": "123", } } }