python 操做redis

python 操做redis

redis 定義 python

 redis是一個key-value存儲系統。和Memcached相似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操做,並且這些操做都是原子性的。在此基礎上,redis支持各類不一樣方式的排序。與memcached同樣,爲了保證效率,數據都是緩存在內存中。區別的是redis會週期性的把更新的數據寫入磁盤或者把修改操做寫入追加的記錄文件,而且在此基礎上實現了master-slave(主從)同步。mysql

redis 定義
redis是一個key-value存儲系統。和Memcached相似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操做,並且這些操做都是原子性的。在此基礎上,redis支持各類不一樣方式的排序。與memcached同樣,爲了保證效率,數據都是緩存在內存中。區別的是redis會週期性的把更新的數據寫入磁盤或者把修改操做寫入追加的記錄文件,而且在此基礎上實現了master-slave(主從)同步。
Redis 是一個高性能的key-value數據庫。 redis的出現,很大程度補償了memcached這類key/value存儲的不足,在部 分場合能夠對關係數據庫起到很好的補充做用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客戶端,使用很方便。[1] 
Redis支持主從同步。數據能夠從主服務器向任意數量的從服務器上同步,從服務器能夠是關聯其餘從服務器的主服務器。這使得Redis可執行單層樹複製。存盤能夠有意無心的對數據進行寫操做。因爲徹底實現了發佈/訂閱機制,使得從數據庫在任何地方同步樹時,可訂閱一個頻道並接收主服務器完整的消息發佈記錄。同步對讀取操做的可擴展性和數據冗餘頗有幫助。

數據模型編輯
Redis的外圍由一個鍵、值映射的字典構成。與其餘非關係型數據庫主要不一樣在於:Redis中值的類型[1]  不只限於字符串,還支持以下抽象數據類型:
字符串列表
無序不重複的字符串集合
有序不重複的字符串集合
鍵、值都爲字符串的哈希表[1] 
值的類型決定了值自己支持的操做。Redis支持不一樣無序、有序的列表,無序、有序的集合間的交集、並集等高級服務器端原子操做。
數據結構編輯
redis提供五種數據類型:string,hash,list,set及zset(sorted set)。
string(字符串)
string是最簡單的類型,你能夠理解成與Memcached如出一轍的類型,一個key對應一個value,其上支持的操做與Memcached的操做相似。但它的功能更豐富。
redis採用結構sdshdr和sds封裝了字符串,字符串相關的操做實如今源文件sds.h/sds.c中。
數據結構定義以下:

typedefchar*sds;
structsdshdr{
longlen;
longfree;
charbuf[];
};
list(雙向鏈表)
list是一個鏈表結構,主要功能是push、pop、獲取一個範圍的全部值等等。操做中key理解爲鏈表的名字。
對list的定義和實如今源文件adlist.h/adlist.c,相關的數據結構定義以下:

//list迭代器
typedefstructlistIter{
listNode*next;
intdirection;
}listIter;
//list數據結構
typedefstructlist{
listNode*head;
listNode*tail;
void*(*dup)(void*ptr);
void(*free)(void*ptr);
int(*match)(void*ptr,void*key);
unsignedintlen;
listIteriter;
}list;
dict(hash表)
set是集合,和咱們數學中的集合概念類似,對集合的操做有添加刪除元素,有對多個集合求交併差等操做。操做中key理解爲集合的名字。
在源文件dict.h/dict.c中實現了hashtable的操做,數據結構的定義以下:

//dict中的元素項
typedefstructdictEntry{
void*key;
void*val;
structdictEntry*next;
}dictEntry;
//dict相關配置函數
typedefstructdictType{
unsignedint(*hashFunction)(constvoid*key);
void*(*keyDup)(void*privdata,constvoid*key);
void*(*valDup)(void*privdata,constvoid*obj);
int(*keyCompare)(void*privdata,constvoid*key1,constvoid*key2);
void(*keyDestructor)(void*privdata,void*key);
void(*valDestructor)(void*privdata,void*obj);
}dictType;
//dict定義
typedefstructdict{
dictEntry**table;
dictType*type;
unsignedlongsize;
unsignedlongsizemask;
unsignedlongused;
void*privdata;
}dict;
//dict迭代器
typedefstructdictIterator{
dict*ht;
intindex;
dictEntry*entry,*nextEntry;
}dictIterator;
dict中table爲dictEntry指針的數組,數組中每一個成員爲hash值相同元素的單向鏈表。set是在dict的基礎上實現的,指定了key的比較函數爲dictEncObjKeyCompare,若key相等則再也不插入。
zset(排序set)
zset是set的一個升級版本,他在set的基礎上增長了一個順序屬性,這一屬性在添加修改元素的時候能夠指定,每次指定後,zset會自動從新按新的值調整順序。能夠理解了有兩列的mysql表,一列存value,一列存順序。操做中key理解爲zset的名字。

typedefstructzskiplistNode{
structzskiplistNode**forward;
structzskiplistNode*backward;
doublescore;
robj*obj;
}zskiplistNode;
typedefstructzskiplist{
structzskiplistNode*header,*tail;
unsignedlonglength;
intlevel;
}zskiplist;
typedefstructzset{
dict*dict;
zskiplist*zsl;
}zset;
zset利用dict維護key -> value的映射關係,用zsl(zskiplist)保存value的有序關係。zsl實際是叉數
不穩定的多叉樹,每條鏈上的元素從根節點到葉子節點保持升序排序。
redis 基礎概念

1、Redis安裝和基本使用git

1、檢查配置環境
檢查gcc是否安裝,若是沒有安裝:yum -y install gcc
 
2、下載安裝Redis
cd /opt/
wget http://download.redis.io/releases/redis-3.0.4.tar.gz
#這裏下載能夠登陸官網查看最新的Redis
tar -xvf redis-3.0.4.tar.gz
make
make install
cd /opt/redis-3.0.4/src/
make test
 
 
安裝中可能遇到的問題:
zmalloc.h:50:31: error: jemalloc/jemalloc.h: No such file or directory
zmalloc.h:55:2: error: #error "Newer version of jemalloc required"
 
Allocator
---------------------------------------------------------------------------------------------------------
Selecting a non-default memory allocator when building Redis is done by setting
the `MALLOC` environment variable. Redis is compiled and linked against libc
malloc by default, with the exception of jemalloc being the default on Linux
systems. This default was picked because jemalloc has proven to have fewer
fragmentation problems than libc malloc.
To force compiling against libc malloc, use:
% make MALLOC=libc
To compile against jemalloc on Mac OS X systems, use:
% make MALLOC=jemalloc
 
allocator(分配算符),若是有MALLOC這個環境變量,會有用這個環境變量的 去創建Redis。
並且libc 並非默認的分配器,默認的是jemalloc!
由於jemalloc被證實有更少的fragmentation problems比libc。
 
可是若是你又沒有jemalloc 而只有 libc 固然 make 出錯。 因此加這麼一個參數。
make MALLOC=libc
---------------------------------------------------------------------------------------------------------
 
3、配置redis
cp /opt/redis-3.0.4/utils/redis_init_script /etc/init.d/redis    #複製管理腳本
chmod +x /etc/init.d/redis
mkdir /etc/redis
cp /opt/redis-3.0.4/redis.conf /etc/redis/6379.conf
 
4、修改redis啓動模式
默認Redis啓動的時候是啓動在前臺的,把他改成啓動在後臺
vim /etc/redis/6379.conf
daemonize no  改成 daemonize yes
 
5、Redis加入到系統服務並設置爲開機啓動
首先修改Redis啓動腳本:
vim /etc/init.d/redis
#chkconfig: 35 95 95  在第三行加上便可
 
添加系統服務:chkconfig --add redis
設置開機啓動:chkconfig redis on
檢查服務狀態:chkconfig --list redis
 
六、指定日誌存放位置&PID文件&數據庫文件存放位置(下一邊寫持久化)
vim /etc/redis/6379.conf
 
logfile "/var/log/redis.log"  指定日誌文件若是不指定就會在控制檯輸出
pidfile /var/run/redis_6379.pid
dir ./   這個是指默認的持久化配置文件放在那裏!建議修改下!
 
pidfile若是不修改使用默認的話就會報錯:
緣由是在/etc/init.d/redis裏指定的默認PID是:PIDFILE=/var/run/redis_${REDISPORT}.pid 
可是默認配置文件:/etc/redis/6379.conf(我們本身從解壓包裏複製的裏的默認是:pidfile /var/run/redis.pid) 
redis 安裝細節
SET 設置Key
GET 判斷Key的值
EXISTS 判斷Key是否存在
KEYS * 顯示全部的Key
DEL 刪除指定Key
TYPE 獲取Key類型

注:Redis是不區分大小寫的,命令最好使用大寫這樣能區分是命令仍是參數!

1、set的例子:
192.168.0.201:6379> SET hello hehe
OK
192.168.0.201:6379> GET hello
"hehe"
 
二、設置多個key value 而後使用使用keys * 去查看全部
192.168.0.201:6379> SET hello1 hehe1
OK
192.168.0.201:6379> SET hello2 hehe2
OK
 
192.168.0.201:6379> KEYS  *
1) "hello1"
2) "hello"
3) "hello2"
 
KEY匹配方式:
?匹配單個
 *匹配全部
 
3、判斷key是否存在
判斷Key是否存在使用:EXISTS   他返回的是整形:0不存在,1存在
192.168.0.201:6379> EXISTS hello
(integer) 1
192.168.0.201:6379> EXISTS hehe
(integer) 0
 
4、刪除KEY
192.168.0.201:6379> DEL hello
(integer) 1   #這裏的1是數量
刪除多個測試下:
192.168.0.201:6379> DEL hello1 hello2
(integer) 2
 
5、查看類型TYPE
只要用set類型就是字符串。查看類型命令用TYPE
192.168.0.201:6379> TYPE hello
string
 
6、Keyspace
redis是支持多個實例的默認最多16個,能夠修改配置文件來支持更多!
使用INFO命令查看!
# Keyspace
db0:keys=1,expires=0,avg_ttl=0
 
db0 :這個能夠理解爲命名空間。最多支持16個,使用SELECT 去切換
192.168.0.201:6379> SELECT 1
OK
嘗試添加一個key-value
SET db1 hehe
而後在使用INFO看下
# Keyspace
db0:keys=1,expires=0,avg_ttl=0
db1:keys=1,expires=0,avg_ttl=0
redis 操做詳情
安裝redis
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/src
make
# 修改redis啓動模式
默認Redis啓動的時候是啓動在前臺的,把他改成啓動在後臺
vim /etc/redis/6379.conf
daemonize no  改成 daemonize yes

# 啓動redis-server
cd /redis/redis-3.0.2/src
./redis-server
# 啓動redis-client
cd /redis/redis-3.0.2/src
./redis-cli

 2、Python操做Redisgithub

sudo pip3 install redis
or
sudo easy_install redis
or
源碼安裝
 
詳見:https://github.com/WoLpH/redis-py

API使用redis

redis-py 的API的使用能夠分類爲:sql

  • 鏈接方式
  • 鏈接池
  • 操做
    • String 操做
    • Hash 操做
    • List 操做
    • Set 操做
    • Sort Set 操做
  • 管道
  • 發佈訂閱

3、經常使用操做數據庫

一、操做模式vim

redis-py提供兩個類Redis和StrictRedis用於實現Redis的命令,StrictRedis用於實現大部分官方的命令,並使用官方的語法和命令,Redis是StrictRedis的子類,用於向後兼容舊版本的redis-py。數組

#!/usr/bin/env python
#-*- coding:utf-8 -*-

# 導入模塊
import redis
# 設置鏈接的主機和端口
r = redis.Redis(host='127.0.0.1',port=6379) 
# 添加一條記錄
r.set('name','rain')
# 獲取一條記錄
print r.get('name')

二、鏈接池:緩存

redis-py使用connection pool來管理對一個redis server的全部鏈接,避免每次創建、釋放鏈接的開銷。默認,每一個Redis實例都會維護一個本身的鏈接池。能夠直接創建一個鏈接池,而後做爲參數 Redis,這樣就能夠實現多個Redis實例共享一個鏈接池。

#!/usr/bin/env python
# -*- coding:utf-8 -*-

# 建立鏈接池鏈接對象
rpool = redis.ConnectionPool(host='192.168.17.15',port=6379) 

# 把建立的對象賦值給connection_pool
r = redis.Redis(connection_pool=rpool)
# 添加一條記錄
r.set('username','luotianshuai') 
# 獲取一條記錄
print r.get('username')

三、操做

String操做,redis中的String在在內存中按照一個name對應一個value來存儲。

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

在Redis中設置值,默認,不存在則建立,存在則修改
參數:
     ex,過時時間(秒)
     px,過時時間(毫秒)
     nx,若是設置爲True,則只有name不存在時,當前set操做才執行
     xx,若是設置爲True,則只有name存在時,崗前set操做才執行

setnx(name, value)

# 設置值,只有name不存在時,執行設置操做(添加)
import
redis r = redis.Redis(host='127.0.0.1', port=6379) r.set('foo', 'Bar') print(r.get('foo')) r.setnx('foo','Bar123') print(r.get('foo'))

setex(name, value, time)

# 設置值
# 參數:
    # time,過時時間(數字秒 或 timedelta對象)

psetex(name, time_ms, value)

# 設置值
# 參數:
    # time_ms,過時時間(數字毫秒 或 timedelta對象)

mset(*args, **kwargs)

# /usr/bin/env python
# -*- coding:utf8 -*-
# auth rain

批量設置值
如:
    mset(k1='v1', k2='v2')
    或
    mget({'k1': 'v1', 'k2': 'v2'})

import redis

r = redis.Redis(host='127.0.0.1', port=6379)
r.set('foo', 'Bar')
print(r.get('foo'))
# b'Bar'

r.mset(k1='v1',k2='v2')
print(r.mget(['k1','k2']))
# [b'v1', b'v2']

get(name)

import redis

r = redis.Redis(host='127.0.0.1', port=6379)
r.set('foo', 'Bar')
print(r.get('foo'))   # 獲取值

mget(keys, *args)

批量獲取
如:
    r.mset(k1='v1',k2='v2')
    print(r.mget(['k1','k2']))
    # [b'v1', b'v2']

getset(name, value)

設置新值並獲取原來的值

 getrange(key, start, end)

import redis

r = redis.Redis(host='127.0.0.1', port=6379)
r.set('foo', 'Bar')
print(r.get('foo'))
# b'Bar'

print(r.getrange('foo',0,1))
# b'Ba'

# 獲取子序列(根據字節獲取,非字符)
# 參數:
    # name,Redis 的 name
    # start,起始位置(字節)
    # end,結束位置(字節) 

setrange(name, offset, value)

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

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"
 
# 擴展,轉換二進制表示:
 
    # source = "rain"
    source = "foo"
 
    for i in source:
        num = ord(i)
        print bin(num).replace('b','')
 

getbit(name, offset)

# 獲取name對應的值的二進制表示中的某位的值 (0或1)

bitcount(key, start=None, end=None)

# 獲取name對應的值的二進制表示中 1 的個數
# 參數:
    # key,Redis的name
    # start,位起始位置
    # end,位結束位置

bitop(operation, dest, *keys)

# 獲取多個值,並將值作位運算,將最後的結果保存至新的name對應的值
 
# 參數:
    # operation,AND(並) 、 OR(或) 、 NOT(非) 、 XOR(異或)
    # dest, 新的Redis的name
    # *keys,要查找的Redis的name
 
# 如:
    bitop("AND", 'new_name', 'n1', 'n2', 'n3')
    # 獲取Redis中n1,n2,n3對應的值,而後講全部的值作位運算(求並集),而後將結果保存 new_name 對應的值中

strlen(name)

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

incr(self, name, amount=1)

# 自增 name對應的值,當name不存在時,則建立name=amount,不然,則自增。
 
# 參數:
    # name,Redis的name
    # amount,自增數(必須是整數)
 
# 注:同incrby

incrbyfloat(self, name, amount=1.0)

# 自增 name對應的值,當name不存在時,則建立name=amount,不然,則自增。
 
# 參數:
    # name,Redis的name
    # amount,自增數(浮點型)

decr(self, name, amount=1)

# 自減 name對應的值,當name不存在時,則建立name=amount,不然,則自減。
 
# 參數:
    # name,Redis的name
    # amount,自減數(整數)

append(key, value)

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

Hash操做,redis中Hash在內存中的存儲格式以下圖:

hset(name, key, value)

1
2
3
4
5
6
7
8
9
# name對應的hash中設置一個鍵值對(不存在,則建立;不然,修改)
 
# 參數:
     # name,redis的name
     # key,name對應的hash中的key
     # value,name對應的hash中的value
 
# 注:
     # hsetnx(name, key, value),當name對應的hash中不存在當前key時則建立(至關於添加)

hmset(name, mapping)

1
2
3
4
5
6
7
8
# 在name對應的hash中批量設置鍵值對
 
# 參數:
     # name,redis的name
     # mapping,字典,如:{'k1':'v1', 'k2': 'v2'}
 
# 如:
     # r.hmset('xx', {'k1':'v1', 'k2': 'v2'})

hget(name,key)

1
# 在name對應的hash中獲取根據key獲取value

hmget(name, keys, *args)

1
2
3
4
5
6
7
8
9
10
11
# 在name對應的hash中獲取多個key的值
 
# 參數:
     # name,reids對應的name
     # keys,要獲取key集合,如:['k1', 'k2', 'k3']
     # *args,要獲取的key,如:k1,k2,k3
 
# 如:
     # r.mget('xx', ['k1', 'k2'])
     # 或
     # print r.hmget('xx', 'k1', 'k2')

hgetall(name)

1
獲取name對應 hash 的全部鍵值

hlen(name)

1
# 獲取name對應的hash中鍵值對的個數

hkeys(name)

1
# 獲取name對應的hash中全部的key的值

hvals(name)

1
# 獲取name對應的hash中全部的value的值

hexists(name, key)

1
# 檢查name對應的hash是否存在當前傳入的key

hdel(name,*keys)

1
# 將name對應的hash中指定key的鍵值對刪除

hincrby(name, key, amount=1)

1
2
3
4
5
# 自增name對應的hash中的指定key的值,不存在則建立key=amount
# 參數:
     # name,redis中的name
     # key, hash對應的key
     # amount,自增數(整數)

hincrbyfloat(name, key, amount=1.0)

1
2
3
4
5
6
7
8
# 自增name對應的hash中的指定key的值,不存在則建立key=amount
 
# 參數:
     # name,redis中的name
     # key, hash對應的key
     # amount,自增數(浮點數)
 
# 自增name對應的hash中的指定key的值,不存在則建立key=amount

hscan(name, cursor=0, match=None, count=None)

1
2
3
4
5
6
7
8
9
10
11
12
13
# 增量式迭代獲取,對於數據大的數據很是有用,hscan能夠實現分片的獲取數據,並不是一次性將數據所有獲取完,從而放置內存被撐爆
 
# 參數:
     # name,redis的name
     # cursor,遊標(基於遊標分批取獲取數據)
     # match,匹配指定key,默認None 表示全部的key
     # count,每次分片最少獲取個數,默認None表示採用Redis的默認分片個數
 
# 如:
     # 第一次:cursor1, data1 = r.hscan('xx', cursor=0, match=None, count=None)
     # 第二次:cursor2, data1 = r.hscan('xx', cursor=cursor1, match=None, count=None)
     # ...
     # 直到返回值cursor的值爲0時,表示數據已經經過分片獲取完畢

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

1
2
3
4
5
6
7
8
9
# 利用yield封裝hscan建立生成器,實現分批去redis中獲取數據
 
# 參數:
     # match,匹配指定key,默認None 表示全部的key
     # count,每次分片最少獲取個數,默認None表示採用Redis的默認分片個數
 
# 如:
     # for item in r.hscan_iter('xx'):
     #     print item

List操做,redis中的List在在內存中按照一個name對應一個List來存儲。如圖:

lpush(name,values)

1
2
3
4
5
6
7
8
# 在name對應的list中添加元素,每一個新的元素都添加到列表的最左邊
 
# 如:
     # r.lpush('oo', 11,22,33)
     # 保存順序爲: 33,22,11
 
# 擴展:
     # rpush(name, values) 表示從右向左操做

lpushx(name,value)

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

llen(name)

1
# name對應的list元素的個數

linsert(name, where, refvalue, value))

1
2
3
4
5
6
7
# 在name對應的列表的某一個值前或後插入一個新值
 
# 參數:
     # name,redis的name
     # where,BEFORE或AFTER
     # refvalue,標杆值,即:在它先後插入數據
     # value,要插入的數據

r.lset(name, index, value)

1
2
3
4
5
6
# 對name對應的list中的某一個索引位置從新賦值
 
# 參數:
     # name,redis的name
     # index,list的索引位置
     # value,要設置的值

r.lrem(name, value, num)

1
2
3
4
5
6
7
8
# 在name對應的list中刪除指定的值
 
# 參數:
     # name,redis的name
     # value,要刪除的值
     # num,  num=0,刪除列表中全部的指定值;
            # num=2,從前到後,刪除2個;
            # num=-2,從後向前,刪除2個

lpop(name)

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

lindex(name, index)

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

lrange(name, start, end)

1
2
3
4
5
# 在name對應的列表分片獲取數據
# 參數:
     # name,redis的name
     # start,索引的起始位置
     # end,索引結束位置

ltrim(name, start, end)

1
2
3
4
5
# 在name對應的列表中移除沒有在start-end索引之間的值
# 參數:
     # name,redis的name
     # start,索引的起始位置
     # end,索引結束位置

rpoplpush(src, dst)

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

blpop(keys, timeout)

1
2
3
4
5
6
7
8
# 將多個列表排列,按照從左到右去pop對應列表的元素
 
# 參數:
     # keys,redis的name的集合
     # timeout,超時時間,當元素全部列表的元素獲取完以後,阻塞等待列表內有數據的時間(秒), 0 表示永遠阻塞
 
# 更多:
     # r.brpop(keys, timeout),從右向左獲取數據

brpoplpush(src, dst, timeout=0)

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

自定義增量迭代

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 因爲redis類庫中沒有提供對列表元素的增量迭代,若是想要循環name對應的列表的全部元素,那麼就須要:
     # 一、獲取name對應的全部列表
     # 二、循環列表
# 可是,若是列表很是大,那麼就有可能在第一步時就將程序的內容撐爆,全部有必要自定義一個增量迭代的功能:
 
def list_iter(name):
     """
     自定義redis列表增量迭代
     :param name: redis中的name,即:迭代name對應的列表
     :return: yield 返回 列表元素
     """
     list_count = r.llen(name)
     for index in xrange (list_count):
         yield r.lindex(name, index)
 
# 使用
for item in list_iter( 'pp' ):
     print item

Set操做,Set集合就是不容許重複的列表

sadd(name,values)

1
# name對應的集合中添加元素

scard(name)

1
獲取name對應的集合中元素個數

sdiff(keys, *args)

1
在第一個name對應的集合中且不在其餘name對應的集合的元素集合

sdiffstore(dest, keys, *args)

1
# 獲取第一個name對應的集合中且不在其餘name對應的集合,再將其新加入到dest對應的集合中

sinter(keys, *args)

1
# 獲取多一個name對應集合的並集

sinterstore(dest, keys, *args)

1
# 獲取多一個name對應集合的並集,再講其加入到dest對應的集合中

sismember(name, value)

1
# 檢查value是不是name對應的集合的成員

smembers(name)

1
# 獲取name對應的集合的全部成員

smove(src, dst, value)

1
# 將某個成員從一個集合中移動到另一個集合

spop(name)

1
# 從集合的右側(尾部)移除一個成員,並將其返回

srandmember(name, numbers)

1
# 從name對應的集合中隨機獲取 numbers 個元素

srem(name, values)

1
# 在name對應的集合中刪除某些值

sunion(keys, *args)

1
# 獲取多一個name對應的集合的並集

sunionstore(dest,keys, *args)

1
# 獲取多一個name對應的集合的並集,並將結果保存到dest對應的集合中

sscan(name, cursor=0, match=None, count=None)
sscan_iter(name, match=None, count=None)

1
# 同字符串的操做,用於增量迭代分批獲取元素,避免內存消耗太大

有序集合,在集合的基礎上,爲每元素排序;元素的排序須要根據另一個值來進行比較,因此,對於有序集合,每個元素有兩個值,即:值和分數,分數專門用來作排序。

zadd(name, *args, **kwargs)

1
2
3
4
5
# 在name對應的有序集合中添加元素
# 如:
      # zadd('zz', 'n1', 1, 'n2', 2)
      # 或
      # zadd('zz', n1=11, n2=22)

zcard(name)

1
# 獲取name對應的有序集合元素的數量

zcount(name, min, max)

1
# 獲取name對應的有序集合中分數 在 [min,max] 之間的個數

zincrby(name, value, amount)

1
# 自增name對應的有序集合的 name 對應的分數

r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 按照索引範圍獲取name對應的有序集合的元素
 
# 參數:
     # name,redis的name
     # start,有序集合索引發始位置(非分數)
     # end,有序集合索引結束位置(非分數)
     # desc,排序規則,默認按照分數從小到大排序
     # withscores,是否獲取元素的分數,默認只獲取元素的值
     # score_cast_func,對分數進行數據轉換的函數
 
# 更多:
     # 從大到小排序
     # zrevrange(name, start, end, withscores=False, score_cast_func=float)
 
     # 按照分數範圍獲取name對應的有序集合的元素
     # zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)
     # 從大到小排序
     # zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)

zrank(name, value)

1
2
3
4
# 獲取某個值在 name對應的有序集合中的排行(從 0 開始)
 
# 更多:
     # zrevrank(name, value),從大到小排序

zrangebylex(name, min, max, start=None, num=None)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 當有序集合的全部成員都具備相同的分值時,有序集合的元素會根據成員的 值 (lexicographical ordering)來進行排序,而這個命令則能夠返回給定的有序集合鍵 key 中, 元素的值介於 min 和 max 之間的成員
# 對集合中的每一個成員進行逐個字節的對比(byte-by-byte compare), 並按照從低到高的順序, 返回排序後的集合成員。 若是兩個字符串有一部份內容是相同的話, 那麼命令會認爲較長的字符串比較短的字符串要大
 
# 參數:
     # name,redis的name
     # min,左區間(值)。 + 表示正無限; - 表示負無限; ( 表示開區間; [ 則表示閉區間
     # min,右區間(值)
     # start,對結果進行分片處理,索引位置
     # num,對結果進行分片處理,索引後面的num個元素
 
# 如:
     # ZADD myzset 0 aa 0 ba 0 ca 0 da 0 ea 0 fa 0 ga
     # r.zrangebylex('myzset', "-", "[ca") 結果爲:['aa', 'ba', 'ca']
 
# 更多:
     # 從大到小排序
     # zrevrangebylex(name, max, min, start=None, num=None)

 

zrem(name, values)

1
2
3
# 刪除name對應的有序集合中值是values的成員
 
# 如:zrem('zz', ['s1', 's2'])

zremrangebyrank(name, min, max)

1
# 根據排行範圍刪除

zremrangebyscore(name, min, max)

1
# 根據分數範圍刪除

zremrangebylex(name, min, max)

1
# 根據值返回刪除

zscore(name, value)

1
# 獲取name對應有序集合中 value 對應的分數

zinterstore(dest, keys, aggregate=None)

1
2
# 獲取兩個有序集合的交集,若是遇到相同值不一樣分數,則按照aggregate進行操做
# aggregate的值爲:  SUM  MIN  MAX

zunionstore(dest, keys, aggregate=None)

1
2
# 獲取兩個有序集合的並集,若是遇到相同值不一樣分數,則按照aggregate進行操做
# aggregate的值爲:  SUM  MIN  MAX

zscan(name, cursor=0, match=None, count=None, score_cast_func=float)
zscan_iter(name, match=None, count=None,score_cast_func=float)

1
# 同字符串類似,相較於字符串新增score_cast_func,用來對分數進行操做

 其餘經常使用操做

delete(*names)

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

exists(name)

1
# 檢測redis的name是否存在

keys(pattern='*')

1
2
3
4
5
6
7
# 根據模型獲取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)

1
# 爲某個redis的某個name設置超時時間

rename(src, dst)

1
# 對redis的name重命名爲

move(name, db))

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

randomkey()

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

type(name)

1
# 獲取name對應值的類型

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

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

 

四、管道

redis-py默認在執行每次請求都會建立(鏈接池申請鏈接)和斷開(歸還鏈接池)一次鏈接操做,若是想要在一次請求中指定多個命令,則可使用pipline實現一次請求指定多個命令,而且默認狀況下一次pipline 是原子性操做。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
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)
 
r.set('name', 'alex')
r.set('role', 'sb')
 
pipe.execute()

 

 

五、發佈訂閱

 

發佈者:服務器

訂閱者:Dashboad和數據處理

Demo以下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import redis


class RedisHelper:

    def __init__(self):
        self.__conn = redis.Redis(host='10.211.55.4')
        self.chan_sub = 'fm104.5'
        self.chan_pub = 'fm104.5'

    def public(self, msg):
        self.__conn.publish(self.chan_pub, msg)
        return True

    def subscribe(self):
        pub = self.__conn.pubsub()
        pub.subscribe(self.chan_sub)
        pub.parse_response()
        return pub
RedisHelper

 

訂閱者:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
from monitor.RedisHelper import RedisHelper
 
obj = RedisHelper()
redis_sub = obj.subscribe()
 
while True:
    msg= redis_sub.parse_response()
    print msg

 發佈者:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
from monitor.RedisHelper import RedisHelper
 
obj = RedisHelper()
obj.public('hello')
相關文章
相關標籤/搜索