用Python來操作redis 以及在Django中使用redis


什么是Redis?  

  Redis是一款開源的、高性能的鍵-值存儲(key-value store)。它常被稱作是一款數據結構服務器(data   structure server)。

  Redis的鍵值可以包括字符串(strings)類型,同時它還包括哈希(hashes)、列表(lists)集合(sets)有序集合(sorted sets)等數據類型。 對於這些數據類型,你可以執行原子操作。例如:對字符串進行附加操作(append);遞增哈希中的值;向列表中增加元素;計算集合的交集、並集與差集等。

redis = {
    'k1':'zrg',    #字符串
    'k2':['z','r','g'],  #列表
    'k3':{1,2,3,4},    #集合
    'k4':{'name':'zrg','age':25},  #字典/哈希表
    'k5':{('zrg',25),('yj',26)}    #有序集合
}

 

  為了獲得優異的性能,Redis采用了內存中(in-memory)數據集(dataset)的方式。同時,Redis支持數據的持久化(可以保存到硬盤上),你可以每隔一段時間將數據集轉存到磁盤上(snapshot),或者在日志尾部追加每一條操作命令(append only file,aof)。

  Redis同樣支持主從復制(master-slave replication),並且具有非常快速的非阻塞首次同步( non-blocking first synchronization)、網絡斷開自動重連等功能。同時Redis還具有其它一些特性,其中包括簡單的事物支持、發布訂閱 ( pub/sub)、管道(pipeline)和虛擬內存(vm)等 。
Redis具有豐富的客戶端,支持現階段流行的大多數編程語言。

 

一、redis 安裝

  windoes 安裝

  一般情況下不是開發人員安裝,而且也不是安裝在Windows平台下,一般來說是安裝在Linux平台下,而且是運維人員來做這個事。

 

二、Redis操作

  Redis的數據類型:

  Keys 
    非二進制安全的字符類型( not binary-safe strings )

  Values
    Strings 
    Lists 
    Sets 
    Sorted sets 
    Hash

  redis本質上一個key-value 數據庫,所以我們首先來看看他的key.首先key也是字符串類型,由於key不是binary safe的字符串,所以像“my key”和“mykey\n”這樣包含空格和換行的key是不允許的。

我們在使用的時候可以自己定義一個Key的格式。例如 object-type:id:field 
Key不要太長。占內存,查詢慢。
Key不要太短。u:1000:pwd 不如 user:1000:password 可讀性好

 

安裝redis模塊:

pip3 install redis

import redis


# 拿到redis鏈接
coon = redis.Redis(host='127.0.0.1',port=6379)

# 朝內存數據庫存放key是name,value是zrg,的字符串
coon.set('name','zrg')

不通過Python也可以通過命令來執行。

 

連接池:

import redis


# 連接池
pool = redis.ConnectionPool(host='127.0.0.1',port=6379)

# 從池子里拿一個連接
coon = redis.Redis(connection_pool=pool)

# 正常情況下pool做成單例!
# 方法1、寫到模塊里,以模塊形式導過來
# 方法2、寫一個類get一個單例的pool,return回來。

 

存儲是Bytes格式

 

  1、字符串操作

  1.1 set(key,value,ex=None,px=None,nx=False,xx=False)

  在redis中設置值,默認,不存在則創建,存在則修改:

  參數:

    ex,過期時間(秒)   

      px,過期時間(毫秒)

            nx,如果設置為True,則只有key不存在時,當前set操作才執行,值存在,就修改不了,執行沒效果。

            xx,如果設置為True,則只有key存在時,當前set操作才執行,值存在才能修改,值不存在,不會設置新值。

 

  1.2 setex(key,time,value)

  1.3 psetex(key,time_ms,value)  或者是timedelta對象。

import datetime
v = datetime.timedelta(seconds=5)
current_time = datetime.datetime.now()
current_time+v  #就是五秒之后的時間

  1.4 mset(*args,**kwargs)   批量設置(存)  跟set區別,set只能放一個。

import redis


# 連接池
pool = redis.ConnectionPool(host='127.0.0.1',port=6379)

# 從池子里拿一個連接
coon = redis.Redis(connection_pool=pool)

coon.mset({'Language':'English','Title':'Python book','Pages':450})

  1.5 mget(key,*args)  接收以位置傳的多個參數。看源碼!---->判斷key值到底是個列表還是單一個值

import redis


# 連接池
pool = redis.ConnectionPool(host='127.0.0.1',port=6379)

# 從池子里拿一個連接
coon = redis.Redis(connection_pool=pool)

values = coon.mget('name','Language','Title','Pages')
print(values)

 

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

  1.7 getrange(key,start,end)  獲取子序列,根據字節取,非字符。

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

  1.9 setbit(key,offset,value) 對key對應值得二進制表示的位進行操作  參數value的值只能是1或0.

  1.20 getbiyt(key,offset,value)

  1.21 bitop

  1.22 strlen(name)  返回字符串的長度

  1.23 incr(self,name,amount=1) 自增  不寫默認1    文章閱讀數用這個,提高網站性能。amount必須是整數

  1.24 append(key,value)朝字符串里追加內容。

  。

  。

  。

 

 

 

  2、列表操作

存值方式:

2.1 lpush(key,values) 

# 在name對應的list中添加元素,每個新的元素都添加到列表的最左邊
 
# 如:
    # r.lpush('oo', 11,22,33)
    # 保存順序為: 33,22,11
 
# 擴展:
    # rpush(name, values) 表示從右向左操作

 

2.2 lpushx

# 在name對應的list中添加元素,只有name已經存在時,值添加到列表的最左邊
 
# 更多:
    # rpushx(name, value) 表示從右向左操作

 

2.3 llen(name)

# name對應的list元素的個數

 

2.4 linsert(name, where, refvalue, value))

# 在name對應的列表的某一個值前或后插入一個新值
 
# 參數:
    # name,redis的name
    # where,BEFORE或AFTER(小寫也可以)
    # refvalue,標桿值,即:在它前后插入數據(如果存在多個標桿值,以找到的第一個為准)
    # value,要插入的數據

 

2.5 lset(name, index, value)

# 對name對應的list中的某一個索引位置重新賦值
 
# 參數:
    # name,redis的name
    # index,list的索引位置
    # value,要設置的值

 

2.6 r.lrem(name, value, num)

# 在name對應的list中刪除指定的值
 
# 參數:
    # name,redis的name
    # value,要刪除的值
    # num,  num=0,刪除列表中所有的指定值;
           # num=2,從前到后,刪除2個;
           # num=-2,從后向前,刪除2個

 

2.7 lpop(name)

# 在name對應的列表的左側獲取第一個元素並在列表中移除,返回值則是第一個元素
 
# 更多:
    # rpop(name) 表示從右向左操作

 

2.8 lindex(name, index)

在name對應的列表中根據索引獲取列表元素

 

2.9 lrange(name, start, end)

# 在name對應的列表分片獲取數據
# 參數:
    # name,redis的name
    # start,索引的起始位置
    # end,索引結束位置  print(re.lrange('aa',0,re.llen('aa'))

 

2.10 ltrim(name, start, end)

# 在name對應的列表中移除沒有在start-end索引之間的值
# 參數:
    # name,redis的name
    # start,索引的起始位置
    # end,索引結束位置(大於列表長度,則代表不移除任何)

 

2.11 rpoplpush(src, dst)

# 從一個列表取出最右邊的元素,同時將其添加至另一個列表的最左邊
# 參數:
    # src,要取數據的列表的name
    # dst,要添加數據的列表的name

 

2.12 blpop(keys, timeout)

# 將多個列表排列,按照從左到右去pop對應列表的元素
 
# 參數:
    # keys,redis的name的集合
    # timeout,超時時間,當元素所有列表的元素獲取完之后,阻塞等待列表內有數據的時間(秒), 0 表示永遠阻塞
 
# 更多:
    # r.brpop(keys, timeout),從右向左獲取數據
爬蟲實現簡單分布式:多個url放到列表里,往里不停放URL,程序循環取值,但是只能一台機器運行取值,可以把url放到redis中,多台機器從redis中取值,爬取數據,實現簡單分布式

 

2.13 brpoplpush(src, dst, timeout=0) 

# 從一個列表的右側移除一個元素並將其添加到另一個列表的左側
 
# 參數:
    # src,取出並要移除元素的列表對應的name
    # dst,要插入元素的列表對應的name
    # timeout,當src對應的列表中沒有數據時,阻塞等待其有數據的超時時間(秒),0 表示永遠阻塞

 

2.14 自定義增量迭代

# 由於redis類庫中沒有提供對列表元素的增量迭代,如果想要循環name對應的列表的所有元素,那么就需要:
    # 1、獲取name對應的所有列表
    # 2、循環列表
# 但是,如果列表非常大,那么就有可能在第一步時就將程序的內容撐爆,所有有必要自定義一個增量迭代的功能:
import redis
conn=redis.Redis(host='127.0.0.1',port=6379)
# conn.lpush('test',*[1,2,3,4,45,5,6,7,7,8,43,5,6,768,89,9,65,4,23,54,6757,8,68])
# conn.flushall()
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('test',5):
    print('---')
    print(item)

 

 

 

  3、字典操作

存儲格式:

只支持一層的物種數據類型

3.1 hset(name,key,value)  name對應的hash中設置一個鍵值對(不存在,則創建,否則,修改)

參數:

name,redis的name

key,name對應的hash中的key

value,name對應的hash中的value

注:hsetnx(name,key,value),當name對應的hash中不存在當前key時則創建(相當於添加)

import redis


# 連接池
pool = redis.ConnectionPool(host='127.0.0.1',port=6379)

# 從池子里拿一個連接
coon = redis.Redis(connection_pool=pool)



coon.hset('people','age','24')
coon.hset('people','name','yangjing')
coon.hset('people','height','158')

 

3.2 hmset(name,mapping)  批量設值

參數:

name,redis中的name

mapping,字典,如:{'k1':'v1','k2':'v2'}

import redis


# 連接池
pool = redis.ConnectionPool(host='127.0.0.1',port=6379)

# 從池子里拿一個連接
coon = redis.Redis(connection_pool=pool)


coon.hmset('book',{'name':'紅樓夢','price':'123','ahthor':'曹雪芹'})

 

3.3 hget(name,key)  在對應的hash中根據key獲取value

3.4 hmget(name,keys,*args) 批量的取值

import redis


# 連接池
pool = redis.ConnectionPool(host='127.0.0.1',port=6379)

# 從池子里拿一個連接
coon = redis.Redis(connection_pool=pool)


# coon.hmset('book',{'name':'紅樓夢','price':'123','ahthor':'曹雪芹'})

# values = coon.hmget('book','name','price','ahthor')
values = coon.hmget('book',['name','price','ahthor'])
print(values)

3.5 hgetall(name)  取出name對應hash的所有鍵值

3.6 hlen(name)獲取對應的hash中鍵值對的個數

3.7 hkeys(name)返回左右key

3.8 hvals(name)返回所有value

3.9 hexisits(name,key)判斷這個hash的key在不在

3.10 hdel(name,*keys)刪除指定的鍵值對

3.11 hinrby(name,key,amount=1)

import redis


# 連接池
pool = redis.ConnectionPool(host='127.0.0.1',port=6379)

# 從池子里拿一個連接
coon = redis.Redis(connection_pool=pool)

# coon.hincrby('people','age',amount=1)
# coon.hincrby('people','age')

 

3.12 hscan(name,cursor=0,match=None,count=None)  增量迭代獲取

增量式迭代獲取,對於數據大的數據非常有用,hscan可以實現分片的獲取數據,並非一次性將數據全部獲取完

參數:

name,redis的name

cursor,游標(基於游標分批次獲取數據)

match,匹配指定key,默認None,表示所有的key

count,每次分片最少獲取個數,默認None表示采用redis的默認分片個數

3.13 hscan_iter(name,match=None,count=None) 

 

 

 

 

三、管道

redis.py 默認在執行每一次請求都會創建(連接池申請連接)和斷開(歸還連接池)一次連續操作,如果想要在一次請求中指定多個命令,則可以使用pipline實現一次請求指定多個命令,並且默認情況下一次()事務pipline都是原子性(都成功或都不成功)操作。

import redis

# 事務
coon = redis.Redis(host='127.0.0.1',port=6379)

# 拿到一個管道,transaction、
pi = coon.pipeline(transaction=True)
# 說明是批量命令
pi.multi()

pi.set('author','作者')
pi.set('publish','出版社')

# 執行
pi.execute()

 

四、Django中使用redis

第一種方式:通用的

  1.先做成單例

    在一個文件夾里寫一個py文件

import redis

POOL = redis.ConnectionPool(host='127.0.0.1',port=6379)

  2. views.py 里使用的時候導過來

import redis
from api.utils import pool


# 從池子里拿一個連接
coon = redis.Redis(connection_pool=pool)

  3. 寫路由

 

第二種方式 django-redis 模塊  但是需要配置,寫到settings.py里

CACHES = {
    "default":{
        "BACKEND":"django_redis.cache.RedisCache",
        "LOCATION":"redis://127.0.0.1:6379",
        "OPTIONS":{
            "CLIENT_CLSAA":"diango_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS":{"max_connections":100},
            # "PASSWORD":'121352',
        }
    }

}

 

views.py

import redis

from django_redis import get_redis_connection


coon = get_redis_connection() 

 

 

 

五、其他操作 

delete(*names)   根據key值刪數據類型

# 根據刪除redis中的任意數據類型

exists(name)

# 檢測redis的name是否存在

keys(pattern='*')

# 根據模型獲取redis的name
 
# 更多:
    # KEYS * 匹配數據庫中所有 key 。
    # KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
    # KEYS h*llo 匹配 hllo 和 heeeeello 等。
    # KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo

expire(name ,time)

# 為某個redis的某個name設置超時時間

rename(src, dst)

# 對redis的name重命名為

move(name, db))

# 將redis的某個值移動到指定的db下

randomkey()

# 隨機獲取一個redis的name(不刪除)

type(name)

# 獲取name對應值的類型

scan(cursor=0, match=None, count=None)
scan_iter(match=None, count=None)

# 同字符串操作,用於增量迭代獲取key

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM