Python- redis緩存 可達到瞬間併發量10W+

redis是什麼?

mysql是一個軟件,幫助開發者對一臺機器的硬盤進行操做。
redis是一個軟件,幫助開發者對一臺機器的內存進行操做。html

redis緩存 可達到瞬間併發量10W+python

高併發架構系列:Redis爲何是單線程、及高併發快的3大緣由詳解mysql

http://m.sohu.com/a/282430394_99994950?qq-pf-to=pcqq.groupredis

https://www.cnblogs.com/liuqingzheng/p/9833534.htmlsql

 


特色
- 能夠作持久化:
- AOF
- RDB
- 單進程單線程
- 至關因而大字典,5大數據類型

redis={
k1:'123', 字符串
k2:[1,2,3,4,4,2,1], 列表
k3:{1,2,3,4}, 集合
k4:{name:123,age:666}, 字典
k5:{('alex',60),('eva-j',80),('rt',70),},有序集合
}
使用字典:
- 基本操做
- 慎重使用hgetall, 優先使用 hscan_iter
- 計數器

注意事項:redis操做時,只有第一層value支持:list,dict ....數據庫

關鍵字:緩存

緩存,優先去redis中獲取,若是沒有就是數據庫。django

redis的應用場景


1. top 列表
產品運營總會讓你展現最近、最熱、點擊率最高、活躍度最高等等條件的top list。不少更新較頻繁的列表若是使用MC+MySQL維護的話緩存失效的可能性會比較大,鑑於佔用內存較小的狀況,使用Redis作存儲也是至關不錯的。緩存

2.最後的訪問session

用戶最近訪問記錄也是redis list的很好應用場景,lpush lpop自動過時老的登錄記錄,對於開發來講仍是很是友好的架構

3.手機驗證碼的,有效時間

4.限制用戶登陸的次數,好比一天錯誤登陸次數10次。

5.投票系統 ,投票結果排序。 排行榜等等

6.存儲社交信息,set的並集和交集。比較兩個用戶的共同粉絲

7.各類計數:商品維度計數(點贊數,評論數,瀏覽數)

8.發佈訂閱,聊天室等

安裝

- redis軟件
- yum install redis
redis-server /etc/redis.conf
-
wget http://download.redis.io/releases/redis-3.0.6.tar.gz
tar xzf redis-3.0.6.tar.gz
cd redis-3.0.6
make

/src/redis-server redis.conf


默認端口:6379

配置文件:
bind 0.0.0.0
port 6379
requirepass dskjfsdf


- python鏈接redis的模塊

pip3 install redis

Redis Pttl 命令 - 以毫秒爲單位返回 key 的剩餘的過時時間

 

基本使用

a.
import redis
# 建立鏈接
# conn = redis.Redis(host='47.94.172.250',port=6379,password='luffy1234')
# conn.set('x1','wanghuaqiang',ex=5)
# val = conn.get('x1')
# print(val)
b.
# 鏈接池
# import redis
#
# pool = redis.ConnectionPool(host='10.211.55.4', port=6379,password='luffy1234',max_connections=1000)
# conn = redis.Redis(connection_pool=pool)
#
# conn.set('foo', 'Bar')

鏈接池注意:鏈接池只建立一次
wupeiqi/articles/5132791.html

使用字典
基本操做
慎用hgetall,優先使用hscan_iter
計數器

注意事項:redis操做時,只有第一次value支持:list,dict...
session就是經過數據庫,序列化到緩存裏的和反序列化拿來用

 

redis字符串操做總結:

set(name, value, ex=None, px=None, nx=False, xx=False)
在Redis中設置值,默認,不存在則建立,存在則修改
參數:
ex,過時時間(秒)
px,過時時間(毫秒)
nx,若是設置爲True,則只有name不存在時,當前set操做才執行,值存在,就修改不了,執行沒效果
xx,若是設置爲True,則只有name存在時,當前set操做才執行,值存在才能修改,值不存在,不會 
設置新值

get(name)
獲取值

mget(keys, *args)
批量獲取
如:
mget('k1', 'k2')

r.mget(['k3', 'k4'])

getset(name, value)
設置新值並獲取原來的值

getrange(key, start, end)
# 獲取子序列(根據字節獲取,非字符)
# 參數:
# name,Redis 的 name
# start,起始位置(字節)
# end,結束位置(字節)
# 如: "劉清政" ,0-3表示 "劉"

setrange(name, offset, value)
# 修改字符串內容,從指定字符串索引開始向後替換(新值太長時,則向後添加)
# 參數:
# offset,字符串的索引,字節(一個漢字三個字節)
# value,要設置的值


strlen(name)
# 返回name對應值的字節長度(一個漢字3個字節)

incr(self, name, amount=1) #如點贊,提升性能
# 自增 name對應的值,當name不存在時,則建立name=amount,不然,則自增。
# 參數:
# name,Redis的name
# amount,自增數(必須是整數)
# 注:同incrby

append(key, value)
# 在redis name對應的值後面追加內容
# 參數:
key, redis的name
value, 要追加的字符串

 

# 字符串操做
# conn.set('yyy', 'egon', nx=True)
# conn.set('ttt', 'egon', xx=True)
# import datetime
# v=datetime.timedelta(weeks=2)
# ctime=datetime.datetime.now()
# ctime+v
# conn.setex('ttt', 5,'xxx')

# conn.mset({"k1": 'v1', "k2": 'v12', "k3": 'v3'})
# value=conn.mget('name','k1','k2')
# value=conn.mget(['name','k1','k2'])
# print(value)
# print(conn.getset('name','xxxxxx'))
# conn.setrange('name', 1, 'eerrrrrrrrrrrrrrrr')

# print(conn.strlen('name'))
# conn.set('age',"19")
# 文章閱讀數
# conn.incr('age',-4)
# conn.append('name','0000000')

redis字典操做總結:

hscan_iter(name, match=None, count=None)
# 利用yield封裝hscan建立生成器,實現分批去redis中獲取數據

# 參數:
# match,匹配指定key,默認None 表示全部的key
# count,每次分片最少獲取個數,默認None表示採用Redis的默認分片個數

# 如:
# for item in r.hscan_iter('xx'):
# print item

 

# 字典操做

# conn.hset('person','age','18')
# conn.hset('person','name','lqz')
# conn.hset('person','height','180')
# conn.hmset('person2',{'age':'19','name':'egon','xx':'xx'})
# print(conn.hget('person','name'))
# print(conn.hmget('person','age','name','height'))
# print(conn.hmget('person',['age','name','height']))
# 之後用這個要慎用
# print(conn.hgetall('person'))
# print(conn.hlen('person'))
# print(conn.hkeys('person'))

# print(conn.hexists('person','nameee'))
# conn.hdel('person2','name','age')

# conn.hincrby('person','age')
# for i in range(1000000):
# conn.hmset('person2',{'eeeeee%s'%i:i})
# 若是數據量不大,自動全取出來
# cour, data = conn.hscan('person2', cursor=0, match=None, count=3000)
# cour2, data2 = conn.hscan('person2', cursor=cour, match=None, count=3000)
#
# print(cour)
# print(len(data))
#
# print('-------')
# print(cour2)
# print(len(data2))

# cour2 = 0
# count = 1
# while True:
# cour2, data2 = conn.hscan('person2', cursor=cour2, match=None, count=3000)
# count += len(data2)
# if cour2 == 0:
# break
#
# print(count)
# 不用getall的方式取,用這種方式取,也能把全部數據取出來,可是不會吧內存撐爆
# data=conn.hscan_iter('person2', match=None, count=100)
# # 內部有915371條數據
# # 先去取100條
# # 作成了生成器
# # 取值的時候,100之內,沒有再去查,用的是生成器
# # 當超過一百,再去取100條.作成了生成器
# for i in data:
# print(i)

redis列表操做總結:

 

# 列表操做

# conn.lpush('list','2')
# conn.rpush('list','3')
# conn.lpushx('list2','3')
# print(conn.llen('list'))

# conn.linsert('list', 'after', "3", '444444')
# conn.linsert('list', 'before', "3", '5555555')
# 從0開始
# conn.lset('list',4,'66666666')
# conn.lrem('list',0,"3")
# print(conn.lpop('list'))
# print(conn.rpop('list'))
# 按索引取值,支持負索引
# print(conn.lindex('list',-2))

# 簡單的分佈式爬蟲
# print(conn.blpop('list'))
# 取出列表的全部值

# conn.lpush('list',*[1,2,3,4,45,5,6,7,7,8,43,5,6,768,89,9,65,4,23,54,6757,8,68])
# print(conn.lrange('list',0,-1))
# 自定義列表的增量迭代
# def scan_list(name,count=2):
# index=0
# while True:
# data_list=conn.lrange(name,index,count+index-1)
# if not data_list:
# return
# index+=count
# for item in data_list:
# yield item
# # print(conn.lrange('test',0,100))
# for item in scan_list('list',5):
# print('---')
# print(item)

 

# 其它操做

# 事務(不支持事務,可是經過管道模擬)
# conn=redis.Redis(host='127.0.0.1', port=6379)
# # 拿到一個管道,transaction=True表示管道內部都是原子性
# pi=conn.pipeline(transaction=True)
# # 說明是批量命令
# pi.multi()
#
#
# pi.set('xx','xxx')
# pi.set('yy','yyy')
#
# pi.execute()

# 其它操做
# conn.delete('name1')
# 用的比較多
# print(conn.keys('k*'))

# print(conn.type('person'))
# django中使用redis

 

 

 redis 管道(模擬事務)

import redis
 
pool = redis.ConnectionPool(host='10.211.55.4', port=6379)
 
r = redis.Redis(connection_pool=pool)
 
# pipe = r.pipeline(transaction=False)
pipe = r.pipeline(transaction=True)
pipe.multi()
pipe.set('name', 'alex')
pipe.set('role', 'sb')
 
pipe.execute()

  

應用(django):

方式一:

utils文件夾下,創建redis_pool.py

import redis
POOL = redis.ConnectionPool(host='127.0.0.1', port=6379,password='1234',max_connections=1000)

視圖函數中使用:

複製代碼
import redis
from django.shortcuts import render,HttpResponse
from utils.redis_pool import POOL

def index(request):
    conn = redis.Redis(connection_pool=POOL)
    conn.hset('kkk','age',18)

    return HttpResponse('設置成功')
def order(request):
    conn = redis.Redis(connection_pool=POOL)
    conn.hget('kkk','age')

    return HttpResponse('獲取成功')
複製代碼

方式二:

安裝django-redis模塊

pip3 install django-redis

setting裏配置:

複製代碼
# 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}
            # "PASSWORD": "123",
        }
    }
}
複製代碼

視圖函數:

from django_redis import get_redis_connection
conn = get_redis_connection('default')
print(conn.hgetall('xxx'))

 

高級使用: (memachach 不能作持久化)1. 全站緩存(經過中間件)wupeiqi/articles/5246483.html2. 單視圖3. 局部頁面

相關文章
相關標籤/搜索