1、redis簡介python
Redis是一個key-value存儲系統。和Memcached相似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操做,並且這些操做都是原子性的。在此基礎上,redis支持各類不一樣方式的排序。與memcached同樣,爲了保證效率,數據都是緩存在內存中。區別的是redis會週期性的把更新的數據寫入磁盤或者把修改操做寫入追加的記錄文件,而且在此基礎上實現了master-slave(主從)同步。 Redis的出現,很大程度補償了memcached這類key/value存儲的不足,在部分場合能夠對關係數據庫起到很好的補充做用。它提供了Python,Ruby,Erlang,PHP客戶端,使用很方便,而且Redis還支持主從同步。數據能夠從主服務器向任意數量的從服務器上同步,從服務器能夠是關聯其餘從服務器的主服務器。這使得Redis可執行單層樹複製。從盤能夠有意無心的對數據進行寫操做。因爲徹底實現了發佈/訂閱機制,使得從數據庫在任何地方同步樹時,可訂閱一個頻道並接收主服務器完整的消息發佈記錄。git
2、redis使用github
一、redis安裝redis
3.0版本數據庫
#cd /usr/local/src #wget http://download.redis.io/releases/redis-3.0.1.tar.gz #tar xzf redis-3.0.1.tar.gz #cd redis-3.0.1 #make #src/redis-server & 檢查redis是否正常啓動 Ps –ef |grep redis Netstat –lnp |grep 6379
2.8版本緩存
yum install -y epel-release yum install -y gcc jemalloc-devel wget cd /usr/local/src wget https://codeload.github.com/antirez/redis/tar.gz/2.8.21 -O redis-2.8.21.tar.gz tar xf redis-2.8.21.tar.gz cd redis-2.8.21 make make PREFIX=/usr/local/redis install mkdir /usr/local/redis/etc wget http://www.apelearn.com/study_v2/.redis_conf -O /usr/local/redis/etc/redis.conf 2>/dev/null # 下載配置文件 wget http://www.apelearn.com/study_v2/.redis_init -O /etc/init.d/redis 2>/dev/null # 下載啓動腳本 useradd -s /sbin/nologin redis mkdir /usr/local/redis/var chmod 777 /usr/local/redis/var chmod 755 /etc/init.d/redis chkconfig --add redis chkconfig redis on /etc/init.d/redis start
安裝redis的客戶端服務器
Pip install redisapp
配置主從dom
只須要在從的配置文件上加 slavof 主(ip) 6379(端口)socket
客戶端鏈接
/usr/local/redis/bin/redis-cli
[root@localhost ~]# /usr/local/redis/bin/redis-cli // 鏈接Redis 127.0.0.1:6379> keys * // keys 用於查看全部key,也能夠模糊匹配,如 keys my* 127.0.0.1:6379> exists name // exists 用於判斷是否有某個key,有返回1,沒有返回0 127.0.0.1:6379> del name // del 用於刪除指定的key,成功返回1,失敗返回0 127.0.0.1:6379> expire name 100 // expire 用於設置指定的key多長時間後過時,單位爲秒 127.0.0.1:6379> persist name // persist 用於取消指定key的過時時間 127.0.0.1:6379> ttl name // ttl 用於查看指定的key還有多長時間過時,返回-2表示沒有該key,返回-1表示沒有設置過時時間,其餘表示還有多長時間過時 127.0.0.1:6379> select 0 // select 用於選擇哪一個庫 127.0.0.1:6379> move name 2 // move 用於把指定的key移到哪一個庫下 127.0.0.1:6379> randomkey // randomkey 用於隨機返回一個key 127.0.0.1:6379> rename k1 k2 // rename 用於重命名key 127.0.0.1:6379> type name // type 用於查看指定key的類型 127.0.0.1:6379> dbsize // dbsize 用於返回當前數據庫中key的數目 127.0.0.1:6379> info // info 用於返回redis數據庫的狀態信息 127.0.0.1:6379> flushdb // flushdb 用於清空當前數據庫中的全部key 127.0.0.1:6379> flushall // flushall 用於清空全部數據庫中的全部key
安裝redis模塊
cd /usr/local/src wget --no-check-certificate https://pypi.python.org/packages/source/r/redis/redis-2.8.0.tar.gz tar xf redis-2.8.0.tar.gz mv redis-2.8.0 python-redis-2.8.0 cd python-redis-2.8.0/ python setup.py install
Python 鏈接並操做 redis
import redis r = redis.Redis(host="192.168.214.22", port=6379) r.set("jim", "I love you!") print(r.get("jim")) print(r.keys()) # print(dir(r)) 結果: I love you! ['jim', 'ajing']
鏈接池
Redis對象使用connection pool來管理對一個redis server的全部鏈接,避免每次創建、釋放鏈接的開銷。默認,每一個Redis實例都會維護一個本身的鏈接池。能夠直接創建一個鏈接池,而後做爲參數Redis,這樣就能夠實現多個Redis實例共享一個鏈接池。
import redis pool = redis.ConnectionPool(host="192.168.214.22") # redis.ConnectionPool() 用於建立一個鏈接池 r = redis.Redis(connection_pool=pool) # 經過 redis.Redis() 鏈接到鏈接池 r.set("name", "jim") # 執行 redis 操做 print(r.get("name"))
管道pipline
Redis是一個cs模式的tcp server,使用和http相似的請求響應協議。一個client能夠經過一個socket鏈接發起多個請求命令。每一個請求命令發出後client一般會阻塞並等待redis服務處理,redis處理完後請求命令後會將結果經過響應報文返回給client。基本的通訊過程以下
import redis pool = redis.ConnectionPool(host='10.0.0.3',port='6379',db=0) r = redis.Redis(connection_pool=pool) pipline = r.pipeline(transaction=True) pipline.set('hobby','girl') pipline.set('hobby','girl') pipline.set('hobby','girl') pipline.set('hobby','girl') pipline.set('hobby','girl') pipline.execute() # 利用redis對象的pipline建立pipline對象 # 利用pipeline對象執行set命令 # 利用pipline對象的execute函數批量執行
理解:pipline對象就是一個容器,咱們把要執行的語句放入其中,調用其excute函數去批量執行。
注意:在get請求的時候,執行pipe.exceute(),會批量返回,可是是有序的,咱們能夠定義多個變量去接受
import redis pool = redis.ConnectionPool(host='10.0.0.3',port='6379',db=0) r = redis.Redis(connection_pool=pool) pipline = r.pipeline(transaction=True) pipline.get('name') pipline.get('age') pipline.get('job') pipline.get('hobby') name,age,job,hobby = pipline.execute() # 定義4個變量接受 print(name,age,job,hobby)
一、set 設置值,不存在建立,存在則更新。
import redis pool = redis.ConnectionPool(host='10.0.0.3',port='6379',db=0) r = redis.Redis(connection_pool=pool) r.set(name, value, ex=None, px=None, nx=False, xx=False) # name 表示key的名稱 # value 表示對應的值 # ex 過時時間(秒) # px 過時時間(毫秒) # nx 若是設置爲True,則只有name不存在時,當前set操做才執行,同setnx(name, value) # xx 若是設置爲True,則只有name存在時,當前set操做才執行
PS:針對過時時間還能夠用另外兩個函數進行單獨調整
setex(name, value, time) #設置過時時間(秒) psetex(name, time_ms, value) #設置過時時間(豪秒)
二、mset 批量設置值,是set的升級款
r.mset(name='bigk', age='18') r.mset({"name":'bigk', "age":'18'}) # mset接受 *args和 **kwargs。 # 因此只能傳遞dict 或者 命名關鍵詞參數,不然會報RedisError異常
三、get/mget 獲取/批量獲取key值
r.get(name) r.mget(name1,name2) # get函數只有一個參數:key名稱 # mget能夠列舉多個key名稱,或者傳遞一個list li = ['name','age'] print(r.mget(li))
四、getset 設置新值,打印原值
r.getset(name,value) print(r.getset('name','dachenzi')) # 打印name的值,並設置其的值爲dachenzi
五、getrange 字符串的截取(相似字符串的切片)
r.getrange(name,start,end) # key 起始位置 結束位置 r.set('name','dachenzi') print(r.getrange('name',2,5)) # 則會打印 chen
六、setrange(name, offset, value) 字符串的分片替換
# r.setrange(name,offset,value) # key,偏移位置(起始位置), 要替換的字符串 #修改字符串內容,從指定字符串索引開始向後替換,若是新值太長時,則向後添加 r.set('name','dachenzi') r.setrange('name',5,'a') print(r.get('name')) # 打印dacheazi
七、strlen 統計字符串的字節長度
# r.strlen(name) r.set('name','dachenzi') print(r.strlen('name')) # 打印8 # 注意:一個漢字佔用3個字節
八、incr/decr 自增/自減對應的值(整型)
# r.incr(name,amount) amount默認值爲1 # 自增mount對應的值,當mount不存在時,則建立mount=amount,不然,則自增,amount爲自增數(整數,也能夠理解爲步長) print(r.incr("mount",amount=2)) #輸出:2 print(r.incr("mount")) #輸出:3 print(r.incr("mount",amount=3)) #輸出:6 print(r.incr("mount",amount=6)) #輸出:12 print(r.get("mount")) #輸出:12 # r.decr(name,amount) amount默認值爲1 # 自減name對應的值,當name不存在時,則建立name=amount,不然,則自減,amount爲自增數(整數)
九、append 在對應的key後面進行追加
# r.append(name,value) 在 name的對應的值後面追加value # name存在會追加,不存在會建立 r.set('name','daxin') r.append('name',' hello world') print(r.get('name)) # 打印: 'daxin hello world'
一、lpush(name,values) 向list中添加元素,FIFO模式(先進先出)
# 在name對應的list中添加元素,每一個新的元素都添加到列表的最左邊 r.lpush("daxin_list",2) r.lpush("daxin_list",3,4,5) print(r.lrange('daxin_list',0,-1)) 保存在列表中的順序爲5,4,3,2
二、rpush(name,values) 向list中添加元素,棧模式(先進後出)
# 在name對應的list中添加元素,每一個新的元素都添加到列表的最右邊 r.rpush("daxin_list2",2) r.rpush("daxin_list2",3,4,5) print(r.lrange('daxin_list2',0,-1)) # 2,3,4,5
三、lpushx(name,value) 在name對應的list中添加元素,只有name已經存在時,值添加到列表的最左邊
四、rpushx(name,value) 在name對應的list中添加元素,只有name已經存在時,值添加到列表的最右邊
五、llen(name) 獲取name對應的list元素的個數
print(r.llen("daxin_list"))
六、linsert(name, where, refvalue, value)) 插入元素
# 在name對應的列表的某一個值前或後插入一個新值 r.linsert("daxin_list","BEFORE","2","SS")#在列表內找到第一個元素2,在它前面插入SS # 參數: # name: redis的name # where: BEFORE(前)或AFTER(後) # refvalue: 列表內的值 # value: 要插入的數據
七、lset(name, index, value) 對list中的某一個索引位置從新賦值
r.lset("daxin_list",0,"bbb")
八、lrem(name, value, count) 刪除name對應的list中的指定值
r.lrem(name,value,count) # 參數: # name: redis的name # value: 要刪除的值 # count > 0 : 從表頭開始向表尾搜索,移除與 VALUE 相等的元素,數量爲 COUNT 。 # count < 0 : 從表尾開始向表頭搜索,移除與 VALUE 相等的元素,數量爲 COUNT 的絕對值。 # count = 0 : 移除表中全部與 VALUE 相等的值。
九、lpop(name) 移除列表的左側第一個元素,返回值則是第一個元素
print(r.lpop("daxin_list"))
十、lindex(name, index) 根據索引獲取列表內元素
print(r.lindex("daxin_list",1))
十一、lrange(name, start, end) 分片獲取元素
print(r.lrange("daxin_list",0,-1)) # 0 表示 其實位置,-1表示末尾 # 因此 0,-1 就表示列表的全部
十二、ltrim(name, start, end) 移除列表內沒有在該索引以內的值
r.lrange('daxin_list') # 2,3,4,5 r.ltrim("daxin_list",0,2) # 會刪除 5
1三、rpoplpush(src, dst) 從src取出最右邊的元素,同時將其添加至dst的最左邊
r.lpush('dachenzi_list',1,2,3,4,5) r.lpush('dachenzi_list2',5,4,3,2,1) r.rpoplpush('dachenzi_list','dachenzi_list2') # dachenzi_list: 2,3,4,5 # dachenzi_list2: 1,1,2,3,4,5
1四、brpoplpush(src, dst, timeout=0)
#同rpoplpush,多了個timeout, timeout:取數據的列表沒元素後的阻塞時間,0爲一直阻塞 r.brpoplpush("dachenzi_list","dachezi_list2",timeout=0)
1五、blpop(keys, timeout)
#將多個列表排列,按照從左到右去移除各個列表內的元素 r.lpush("dachenzi_list",3,4,5) r.lpush("dachenzi_list2",3,4,5) while True: print(r.blpop(["dachenzi_list","dachenzi_list2"],timeout=0)) print(r.lrange("dachenzi_list",0,-1),r.lrange("dachenzi_list2",0,-1)) # 先挨個刪除dachenzi_list,而後再挨個刪除dachenzi_list2。 # r.blpop(keys,timout) # 參數: # keys: redis的name的集合 # timeout: 超時時間,獲取完全部列表的元素以後,阻塞等待列表內有數據的時間(秒), 0 表示永遠阻塞'''
1六、brpop(keys, timeout) 同blpop,將多個列表排列,按照從右像左去移除各個列表內的元素
Set集合就是不容許重複的列表,在redis中,集合分爲無序和有序,set表示無序集合,sortes set表示有序集合
一、sadd(name,values) 給name對應的集合中添加元素
r.sadd('daxin_set1',1,2,3,4,5) r.sadd('daxin_set1',1,2,3,4,5,6,7) print(r.smembers('daxin_set1'))
二、smembers(name) 獲取name對應的集合的全部成員
三、scard(name) 獲取name對應的集合中的元素個數
r.sadd('daxin_set',1,2,3,4,5) r.sadd('daxin_set',1,2,3,4,5,6,7) print(r.scard('daxin_set')) # 打印7個
四、sdiff(keys, *args) 在第一個name對應的集合中且不在其餘name對應的集合的元素集合(第一個set和其餘set的差集)
r.sadd('daxin_set',1,2,3) r.sadd('daxin_set2',2) r.sadd('daxin_set3',3) print(r.sdiff('daxin_set','daxin_set2','daxin_set3')) # 打印1
五、sdiffstore(dest, keys, *args) 至關於把sdiff獲取的值加入到dest對應的集合中
r.sadd('daxin_set',1,2,3) r.sadd('daxin_set2',2) r.sadd('daxin_set3',3) r.sdiffstore('daxin_set4','daxin_set','daxin_set2','daxin_set3') print(r.smembers('daxin_set4')) # 打印1
六、sinter(keys, *args) 獲取同時存在指定集合中的元素
r.sadd('daxin_set',1,2,3) r.sadd('daxin_set2',2,1) r.sadd('daxin_set3',3,1) print(r.sinter('daxin_set','daxin_set2','daxin_set3')) # 打印1
七、sinterstore(dest, keys, *args) 獲取多個name對應集合的並集,再講其加入到dest對應的集合中
八、sismember(name, value) 檢查value是不是name對應的集合內的元素
r.sadd('daxin_set','a','b','c') print(r.sismember('daxin_set','c')) # true print(r.sismember('daxin_set','d')) # false
九、smove(src, dst, value) 將某個元素從一個集合中移動到另一個集合
r.sadd('daxin_set','a','b','c') r.sadd('daxin_set2',1,2) r.smove('daxin_set','daxin_set2','c') print(r.smembers('daxin_set2')) # 打印1,2,c
十、spop(name) 從集合的右側移除一個元素,並將其返回
十一、srandmember(name, numbers) 從name對應的集合中隨機獲取numbers個元素
r.sadd('daxin_set','a','b','c','d','e','f','g') print(r.srandmember('daxin_set',2)) # 隨機取兩個,每次都不一樣
十二、srem(name, values) 刪除name對應的集合中的某些值
r.sadd('daxin_set','a','b','c','d','e','f','g') print(r.srem('daxin_set','a','b','z')) # 返回實際刪除的members個數,這裏返回2 print(r.smembers('daxin_set'))
1三、sunion(keys, *args) 獲取多個name對應的集合的並集
r.sadd('daxin_set','a','b') r.sadd('daxin_set1','c','d') r.sadd('daxin_set2','e','f','g') print(r.sunion('daxin_set','daxin_set2','daxin_set1')) # 打印 {b'c', b'a', b'f', b'e', b'g', b'd', b'b'}
1四、sunionstore(dest,keys, *args) 獲取多個name對應的集合的並集,並將結果保存到dest對應的集合中
set之有序集合
在集合的基礎上,爲每元素排序,元素的排序須要根據另一個值來進行比較,因此,對於有序集合,每個元素有兩個值,即:值和分數(能夠理解爲index,索引),分數專門用來作排序。
一、zadd(name, *args, **kwargs) 在name對應的有序集合中添加元素 # r.zadd(name,value,score...) r.zadd('daxin_set','name',1,'age',2,'job',3) print(r.zrange('daxin_set',0,-1)) # 打印 [b'name', b'age', b'job'] 2、zcard(name) 獲取有序集合內元素的數量 3、zcount(name, min, max) 獲取有序集合中分數在[min,max]之間的個數 r.zadd('daxin_set','name',1,'age',6,'job',3) print(r.zcount('daxin_set',1,2)) # 打印1 print(r.zcount('daxin_set',1,3)) # 打印2 4、zincrby(name, value, amount) 自增有序集合內value對應的分數 r.zadd('daxin_set','name',1,'age',6,'job',3) print(r.zrange('daxin_set',0,-1)) # 順序是 [b'name', b'job', b'age'] r.zincrby('daxin_set','name',amount=7) # 改變了name的score,影響排序 print(r.zrange('daxin_set',0,-1)) # 順序是 [b'job', b'age', b'name'] 五、zrange( name, start, end, desc=False, withscores=False, score_cast_func=float) 按照索引範圍獲取name對應的有序集合的元素 r.zrange("name",start,end,desc=False,withscores=True,score_cast_func=int) # 參數: # name redis的name # start 有序集合索引發始位置 # end 有序集合索引結束位置 # desc 排序規則,默認按照分數從小到大排序 # withscores 是否獲取元素的分數,默認只獲取元素的值 # score_cast_func 對分數進行數據轉換的函數 r.zadd('daxin_set','name',1,'age',6,'job',3) print(r.zrange('daxin_set',0,1,withscores=True)) zrevrange(name, start, end, withscores=False, score_cast_func=float) #同zrange,集合是從大到小排序的 zrank(name, value)、zrevrank(name, value) #獲取value值在name對應的有序集合中的排行位置(從0開始) print(r.zrank("zset_name", "a2")) print(r.zrevrank("zset_name", "a2"))#從大到小排序 zscore(name, value) #獲取name對應有序集合中 value 對應的分數 print(r.zscore("zset_name","a1")) zrem(name, values) #刪除name對應的有序集合中值是values的成員 r.zrem("zset_name","a1","a2") zremrangebyrank(name, min, max) #根據排行範圍刪除 zremrangebyscore(name, min, max) #根據分數範圍刪除 zinterstore(dest, keys, aggregate=None) 複製代碼 複製代碼 r.zadd("zset_name", "a1", 6, "a2", 2,"a3",5) r.zadd('zset_name1', a1=7,b1=10, b2=5) # 獲取兩個有序集合的交集並放入dest集合,若是遇到相同值不一樣分數,則按照aggregate進行操做 # aggregate的值爲: SUM MIN MAX r.zinterstore("zset_name2",("zset_name1","zset_name"),aggregate="MAX") print(r.zscan("zset_name2")) 複製代碼 複製代碼 zunionstore(dest, keys, aggregate=None) #獲取兩個有序集合的並集並放入dest集合,其餘同zinterstore,
其餘經常使用操做
delete(*names) #根據name刪除redis中的任意數據類型 exists(name) #檢測redis的name是否存在 keys(pattern='*') #根據* ?等通配符匹配獲取redis的name expire(name ,time) # 爲某個name設置超時時間 rename(src, dst) # 重命名 move(name, db)) # 將redis的某個值移動到指定的db下 randomkey() #隨機獲取一個redis的name(不刪除) type(name) # 獲取name對應值的類型