redis緩存數據庫
redis
介紹
redis是業界主流的key-value nosql 數據庫之一。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步。
Redis優點
-
異常快速 : Redis是非常快的,每秒可以執行大約110000設置操作,81000個/每秒的讀取操作。
-
支持豐富的數據類型 : Redis支持最大多數開發人員已經知道如列表,集合,可排序集合,哈希等數據類型。
這使得在應用中很容易解決的各種問題,因為我們知道哪些問題處理使用哪種數據類型更好解決。 -
操作都是原子的 : 所有 Redis 的操作都是原子,從而確保當兩個客戶同時訪問 Redis 服務器得到的是更新後的值(最新值)。
- MultiUtility工具:Redis是一個多功能實用工具,可以在很多如:緩存,消息傳遞隊列中使用(Redis原生支持發布/訂閱),在應用程序中,如:Web應用程序會話,網站頁面點擊數等任何短暫的數據
redis安裝
centos下安裝:
wget http://download.redis.io/releases/redis-4.0.9.tar.gz tar xvf redis-4.0.9.tar.gz cd redis-4.0.9/ make && make install
啟動:/mnt/redis-4.0.9/src/redis-server /mnt/redis-4.0.9/redis.conf &
或修改配置文件redis.conf的選項daemonize為yes開啟守護進程,這redis個版默認是no:/mnt/redis-4.0.9/src/redis-server /mnt/redis-4.0.9/redis.conf
Redis API使用
Redis支持五種數據類型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
redis-py 的API的使用可以分類為:
- 連接方式
- 連接池
- 操作
- String 操作
- Hash 操作
- List 操作
- Set 操作
- Sort Set 操作
- 管道
- 發布訂閱
redis連接方式
1、操作模式
redis-py提供兩個類Redis和StrictRedis用於實現Redis的命令,StrictRedis用於實現大部分官方的命令,並使用官方的語法和命令,Redis是StrictRedis的子類,用於向後兼容舊版本的redis-py。
python遠程操作redis:
import redis r = redis.Redis(host=‘192.168.10.128‘,port=6379) r.set(‘name‘,‘xiaogang‘) print(r.get(‘name‘))
2、連接池
redis-py使用connection pool來管理對一個redis server的所有連接,避免每次建立、釋放連接的開銷。默認,每個Redis實例都會維護一個自己的連接池。可以直接建立一個連接池,然後作為參數Redis,這樣就可以實現多個Redis實例共享一個連接池。
Redis操作字符串(String)
Redis 字符串數據類型的相關命令用於管理 redis 字符串值。
查看語法格式命令:help
127.0.0.1:6379> help set SET key value [EX seconds] [PX milliseconds] [NX|XX] summary: Set the string value of a key since: 1.0.0 group: string
set(key, value, ex=None, px=None, nx=False, xx=False)
在Redis中設置值,默認,不存在則創建,存在則修改 參數: ex,過期時間(秒) px,過期時間(毫秒) nx,如果設置為True,則只有key不存在時,當前set操作才執行 xx,如果設置為True,則只有key存在時,崗前set操作才執行
get key
獲取值
setnx key value
設置值,只有name不存在時,執行設置操作(添加)
setex key value time
# 設置值 # 參數: # time,過期時間(數字秒 或 timedelta對象)
psetex key time_ms value
# 設置值 # 參數: # time_ms,過期時間(數字毫秒 或 timedelta對象)
mset *args, **kwargs
批量設置值 如: 127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 k4 v4 OK
mget *args **kwargs
#批量獲取值 127.0.0.1:6379> mget k1 k2 k3 k4 1) "v1" 2) "v2" 3) "v3" 4) "v4"
getset key value
#設置新值並返回原來的值 127.0.0.1:6379> getset k1 v111111 "v1"
getrange key start end
# 獲取子序列(根據字節獲取,非字符) # 參數: # start,起始位置(字節) # end,結束位置(字節) #字母和數字占一個字節,一個漢字三個字節 # 如: 127.0.0.1:6379> getrange k1 0 6 "v111111"
setrange key offset value
# 修改字符串內容,從指定字符串索引開始向後替換(新值太長時,則向後添加) # 參數: # offset,字符串的索引,字節(一個漢字三個字節) # value,要設置的值 127.0.0.1:6379> set k1 "hello world!" OK 127.0.0.1:6379> setrange k1 6 "redis" (integer) 12 127.0.0.1:6379> get k1 "hello redis!"
setbit key offset value
# 對name對應值的二進制表示的位進行操作 # 參數: # name,redis的name # offset,位的索引(將值變換成二進制後再進行索引) # value,值只能是 1 或 0 # 註:如果在Redis中有一個對應: n1 = "foo", 通過ord(),bin()得出字符串foo的二進制表示為:01100110 01101111 01101111 所以,如果執行 setbit(‘n1‘, 7, 1),則就會將第7位設置為1, 那麽最終二進制則變成 01100111 01101111 01101111,即:"goo" 127.0.0.1:6379> set k1 foo OK 127.0.0.1:6379> 127.0.0.1:6379> setbit k1 7 1 (integer) 0 127.0.0.1:6379> get k1 "goo"
strlen key
#返回name對應值的字節長度(一個漢字3個字節) 127.0.0.1:6379> get k1 "goo" 127.0.0.1:6379> strlen k1 (integer) 3
getbit key offset
# 獲取name對應的值的二進制表示中的某位的值 (0或1)
bitcount key start end
# 獲取name對應的值的二進制表示中 1 的個數 # 參數: # key,Redis的name # start,位起始位置 # end,位結束位置
incr key
#key的數字值自增1,當key不存在時,值為1 127.0.0.1:6379> set k1 10 OK 127.0.0.1:6379> incr k1 (integer) 11 127.0.0.1:6379> get k1 "11"
127.0.0.1:6379> incr kk
(integer) 1
127.0.0.1:6379> get kk
"1"
incrby key incement
將 key 中儲存的數字加上指定的增量值。 如果 key 不存在,那麽 key 的值會先被初始化為 0 ,然後再執行 INCRBY 命令。 如果值包含錯誤的類型,或字符串類型的值不能表示為數字,那麽返回一個錯誤。 本操作的值限制在 64 位(bit)有符號數字表示之內。 127.0.0.1:6379> set k1 10 OK 127.0.0.1:6379> incrby k1 29 (integer) 39 127.0.0.1:6379> get k1 "39" 127.0.0.1:6379> incrby kt 29 (integer) 29
incrbyfloat key incement
#將key存儲的值加上指定浮點數增量值 127.0.0.1:6379> incrbyfloat k1 29.5 "68.5"
decr key
# 自減 name對應的值,當name不存在時,則創建name=amount,否則,則自減。 # 參數: # name,Redis的name # amount,自減數(整數) 127.0.0.1:6379> set k1 10 OK 127.0.0.1:6379> decr k1 (integer) 9
append key
# 在redis name對應的值後面追加內容 # 參數: key, redis的name value, 要追加的字符串 127.0.0.1:6379> append k1 "hello" (integer) 6 127.0.0.1:6379> get k1 "9hello"
Redis 哈希(Hash)
hash表現形式上有些像pyhton中的dict,可以存儲一組關聯性較強的數據 , redis中Hash在內存中的存儲格式如下圖:
HSET key field value HMGET
和
key field [field ...]
Hset 命令用於為哈希表中的字段賦值 。 如果哈希表不存在,一個新的哈希表被創建並進行 HSET 操作。 如果字段已經存在於哈希表中,舊值將被覆蓋。 Hmget 命令用於返回哈希表中,一個或多個給定字段的值。 如果指定的字段不存在於哈希表,那麽返回一個 nil 值。 127.0.0.1:6379> hset info name lisi (integer) 1 127.0.0.1:6379> hset info age 24 (integer) 1 127.0.0.1:6379> hset info sex male (integer) 1 127.0.0.1:6379> hmget info name age sex 1) "lisi" 2) "24" 3) "male"
hexists key field
HDEL key field [field ...]
Hexists 命令用於查看哈希表的指定字段是否存在,如果哈希表含有給定字段,返回 1 。 如果哈希表不含有給定字段,或 key 不存在,返回 0 。 Redis Hdel 命令用於刪除哈希表 key 中的一個或多個指定字段,不存在的字段將被忽略。 127.0.0.1:6379> hexists info name (integer) 1 127.0.0.1:6379> hdel info name (integer) 1 127.0.0.1:6379> hget info name (nil)
hkeys key
hgetall key
hkeys key 獲取所有哈希表的key值 hgetall key 返回哈希表中,所有的字段和值。在返回值裏,緊跟每個字段名(field name)之後是字段的值(value),所以返回值的長度是哈希表大小的兩倍。 127.0.0.1:6379> hkeys info 1) "age" 2) "sex" 127.0.0.1:6379> hgetall info 1) "age" 2) "24" 3) "sex" 4) "male"
hincrby key field increment
HINCRBYFLOAT key field increment
Hincrby 命令用於為哈希表中的字段值加上指定增量值。 增量也可以為負數,相當於對指定字段進行減法操作。 如果哈希表的 key 不存在,一個新的哈希表被創建並執行 HINCRBY 命令。 如果指定的字段不存在,那麽在執行命令前,字段的值被初始化為 0 。 對一個儲存字符串值的字段執行 HINCRBY 命令將造成一個錯誤。 本操作的值被限制在 64 位(bit)有符號數字表示之內。
HINCRBYFLOAT命令用於為哈希表中的字段值加上指定浮點數增量值。 如果指定的字段不存在,那麽在執行命令前,字段的值被初始化為 0 。 127.0.0.1:6379> hincrby info age 1 (integer) 25 127.0.0.1:6379> hincrbyfloat info age 2.5 "27.5"
hlen key
hvalue key
hlen key 獲取key鍵值對個數 hvalue key 獲取哈希表中所有值 127.0.0.1:6379> hlen info (integer) 3 127.0.0.1:6379> hvals info 1) "27.5" 2) "male" 3) "1" 127.0.0.1:
HMSET key field value [field value ...] 同時將多個 field-value (域-值)對設置到哈希表 key 中。
HSCAN key cursor [MATCH pattern] [COUNT count] 叠代哈希表中的鍵值對。
hmset 命令用於同時將多個 field-value (字段-值)對設置到哈希表中。 此命令會覆蓋哈希表中已存在的字段。 如果哈希表不存在,會創建一個空哈希表,並執行 HMSET 操作 hscan 叠代哈希表中的鍵值對。 127.0.0.1:6379> hmset class python alex linux laonanhai OK 127.0.0.1:6379> hscan class 3 1) "0" 2) 1) "python" 2) "alex" 3) "linux" 4) "laonanhai"
redis列表(list)
List操作,redis中的List在在內存中按照一個name對應一個List來存儲。如圖:
Lpush命令將一個或多個值插入到列表頭部。 如果 key 不存在,一個空列表會被創建並執行 LPUSH 操作。 當 key 存在但不是列表類型時,返回一個錯誤。
LPUSH key value [value ...] 將一個或多個值插入到列表頭部。
LRANGE key start stop 獲取列表指定範圍內的元素。
127.0.0.1:6379> lpush names shaowei xiaogang lisi zhangsan (integer) 9 127.0.0.1:6379> lrange names 0 -1 1) "zhangsan" 2) "lisi" 3) "xiaogang" 4) "shaowei"
BLPOP key [key ...] timeout 移出並獲取列表的第一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。
BRPOP key [key ...] 移出並獲取列表的最後一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。
127.0.0.1:6379> lrange number 0 -1 1) "five" 2) "four" 3) "three" 4) "two" 5) "one" 127.0.0.1:6379> blpop number 1 1) "number" 2) "five" 127.0.0.1:6379> brpop number 1 1) "number" 2) "one" 127.0.0.1:6379> lrange number 0 -1 1) "four" 2) "three" 3) "two"
LINDEX key index 通過索引獲取列表中的元素。
LLEN key 獲取列表長度。
127.0.0.1:6379> lindex number 0 "four" 127.0.0.1:6379> lindex number 1 "three" 127.0.0.1:6379> llen number (integer) 3
LINSERT key BEFORE|AFTER pivot value 在列表的元素前或者後插入元素。
LPUSHX key value 將一個值插入到已存在的列表頭部。
127.0.0.1:6379> linsert names before lisi alex (integer) 5 127.0.0.1:6379> lrange names 0 -1 1) "alex" 2) "lisi" 3) "xiaogang" 4) "shaowei" 5) "zhangsan" 127.0.0.1:6379> lpushx names xiaoming (integer) 6 127.0.0.1:6379> lrange names 0 -1 1) "xiaoming" 2) "alex" 3) "lisi" 4) "xiaogang" 5) "shaowei" 6) "zhangsan"
LREM key count value 移除列表元素。
LSET key index value 通過索引設置列表元素的值。
127.0.0.1:6379> lrem names 0 shaowei (integer) 1 127.0.0.1:6379> lrange names 0 -1 1) "xiaoming" 2) "alex" 3) "lisi" 4) "xiaogang" 5) "zhangsan" 127.0.0.1:6379> lset names 0 xiaohong OK 127.0.0.1:6379> lrange names 0 -1 1) "xiaohong" 2) "xiaohong" 3) "lisi" 4) "xiaogang" 5) "zhangsan"
LTRIM key start stop 對一個列表進行修剪(trim),就是說,讓列表只保留指定區間內的元素,不在指定區間之內的元素都將被刪除。
Ltrim 對一個列表進行修剪(trim),就是說,讓列表只保留指定區間內的元素,不在指定區間之內的元素都將被刪除。
下標 0 表示列表的第一個元素,以 1 表示列表的第二個元素,以此類推。 你也可以使用負數下標,以 -1 表示列表的最後一個元素, -2 表示列表的倒數第二個元素,以此類推。
RPOP key 移除並獲取列表最後一個元素。
127.0.0.1:6379> lpush numbers one two three four five (integer) 5 127.0.0.1:6379> ltrim numbers 1 -2 OK 127.0.0.1:6379> lrange numbers 0 -1 1) "four" 2) "three" 3) "two"
127.0.0.1:6379> rpop numbers
"two"
127.0.0.1:6379> lrange numbers 0 -1
1) "four"
2) "three"
RPOPLPUSH source destination 移除列表的最後一個元素,並將該元素添加到另一個列表並返回。
RPUSHX key value 為已存在的列表添加值。
127.0.0.1:6379> lrange names 0 -1 1) "xiaohong" 2) "xiaohong" 3) "lisi" 4) "xiaogang" 127.0.0.1:6379> lrange numbers 0 -1 1) "four" 2) "three" 127.0.0.1:6379> rpoplpush names numbers "xiaogang" 127.0.0.1:6379> lrange numbers 0 -1 1) "xiaogang" 2) "four" 3) "three" 127.0.0.1:6379> rpushx numbers one (integer) 4 127.0.0.1:6379> lrange numbers 0 -1 1) "xiaogang" 2) "four" 3) "three" 4) "one"
redis 集合(set)
Redis 的 Set 是 String 類型的無序集合。集合成員是唯一的,這就意味著集合中不能出現重復的數據。
Redis 中集合是通過哈希表實現的,所以添加,刪除,查找的復雜度都是 O(1)。
集合中最大的成員數為 232 - 1 (4294967295, 每個集合可存儲40多億個成員)。
SADD key member [member ...] 向集合添加一個或多個值元素。
scard key 獲取集合元素數。
127.0.0.1:6379> sadd name1 xiaoming lisi zhangsan (integer) 3 127.0.0.1:6379> scard name1 (integer) 3
SDIFF key [key ...] 返回給定所有集合的差集。
SDIFFSTORE destination key [key ...] 返回給定所有集合的差集並存儲在 destination 中。
127.0.0.1:6379> sdiff name1 name2 1) "xiaoming" 2) "zhangsan" 127.0.0.1:6379> sdiffstore name3 name1 name2 (integer) 2
SINTER key [key ...] 返回給定所有集合的交集。
SINTERSTORE destination key [key ...] 返回給定所有集合的交集並存儲在 destination 中。
127.0.0.1:6379> sadd num1 one two three four (integer) 4 127.0.0.1:6379> sadd num2 one 2 two 32 (integer) 4 127.0.0.1:6379> sinter num1 num2 1) "one" 2) "two"
127.0.0.1:6379> sinterstore num3 num2 num1
(integer) 2
SISMEMBER key member 判斷 member 元素是否是集合 key 的成員
SMEMBERS key 返回集合中的所有成員
127.0.0.1:6379> sismember num1 ‘one‘ (integer) 1 127.0.0.1:6379> smembers num1 1) "one" 2) "four" 3) "three" 4) "two"
SMOVE source destination member 將 member 元素從 source 集合移動到 destination 集合
SPOP key 移除並返回集合中的一個隨機元素
127.0.0.1:6379> smembers num2 1) "2" 2) "one" 3) "32" 4) "two" 127.0.0.1:6379> smove num1 num2 ‘four‘ (integer) 1 127.0.0.1:6379> smembers num2 1) "2" 2) "one" 3) "32" 4) "two" 5) "four"
127.0.0.1:6379> smembers num2
1) "2"
2) "one"
3) "32"
4) "two"
5) "four"
127.0.0.1:6379> spop num2
"32"
SREM key member [member ...] 移除集合中一個或多個元素
SRANDMEMBER key [count] 返回集合中一個或多個隨機數
127.0.0.1:6379> srem num2 32 noe (integer) 0
127.0.0.1:6379> srandmember num2 2
1) "one"
2) "2"
SUNION key [key ...] 返回所有給定集合的並集
SUNIONSTORE destination key1 [key2] 所有給定集合的並集存儲在 destination 集合中
127.0.0.1:6379> smembers num1 1) "one" 2) "three" 3) "two" 127.0.0.1:6379> smembers num2 1) "one" 2) "four" 127.0.0.1:6379> sunion num1 num2 1) "one" 2) "four" 3) "three" 4) "two"
127.0.0.1:6379> sunionstore num4 num2 num1
(integer) 4
127.0.0.1:6379> smembers num4
1) "one"
2) "four"
3) "three"
4) "two"
Redis 有序集合(sorted set)
Redis 有序集合和集合一樣也是string類型元素的集合,且不允許重復的成員。
不同的是每個元素都會關聯一個double類型的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。
有序集合的成員是唯一的,但分數(score)卻可以重復。
ZADD key score1 member1 [score2 member2] 向有序集合添加一個或多個元素,或者更新已存在成員的分數
ZRANGE key start stop [WITHSCORES] 通過索引區間返回有序集合成指定區間內的成員
127.0.0.1:6379> zadd z1 8 jack 9 lisi 3 jerry 2 bitch (integer) 4 127.0.0.1:6379> zrange z1 0 -1 withscores 1) "bitch" 2) "2" 3) "jerry" 4) "3" 5) "jack" 6) "8" 7) "lisi" 8) "9"
ZCARD key 獲取有序集合的成員數
ZCOUNT key min max 計算在有序集合中指定區間分數的成員數
127.0.0.1:6379> zcard z1 (integer) 4 127.0.0.1:6379> zcount z1 2 8 (integer) 3
ZINCRBY key increment member 有序集合中對指定成員的分數加上增量 increment,可以通過傳遞一個負數值 increment ,讓分數減去相應的值,比如 ZINCRBY key -5 member ,就是讓 member 的 score 值減去 5 。
當 key 不存在,或分數不是 key 的成員時, ZINCRBY key increment member 等同於 ZADD key increment member 。當 key 不是有序集類型時,返回一個錯誤。分數值可以是整數值或雙精度浮點數。
ZINTERSTORE destination numkeys key [key ...] 計算給定的一個或多個有序集的交集並將結果集存儲在新的有序集合 key 中
127.0.0.1:6379> zincrby z1 19 bitch "21" 127.0.0.1:6379> zadd z2 89 ‘tom‘ 77 ‘li lianjei‘ 3 ‘jerry‘ (integer) 3 127.0.0.1:6379> zinterstore z3 2 z1 z2 (integer) 1 127.0.0.1:6379> zrange z3 0 -1 withscores 1) "jerry" 2) "6"
ZLEXCOUNT key min max 在有序集合中計算指定字典區間內成員數量
ZRANGEBYLEX key min max [LIMIT offset count] 通過字典區間返回有序集合的成員
127.0.0.1:6379> zlexcount z2 [jerry [tom (integer) 3 127.0.0.1:6379> zrange z2 0 -1 withscores 1) "jerry" 2) "3" 3) "li lianjei" 4) "77" 5) "tom" 6) "89" 127.0.0.1:6379> zrangebylex z2 [jerry [tom 1) "jerry" 2) "li lianjei" 3) "tom"
ZRANK key member 返回有序集合中指定成員的索引
ZREM key member [member ...] 移除有序集合中的一個或多個成員
127.0.0.1:6379> zrange z2 0 -1 withscores 1) "jerry" 2) "3" 3) "li lianjei" 4) "77" 5) "tom" 6) "89" 127.0.0.1:6379> zrank z2 ‘li lianjei‘ (integer) 1 127.0.0.1:6379> zrank z2 ‘jerry‘ (integer) 0 127.0.0.1:6379> zrank z2 ‘tom‘ (integer) 2 127.0.0.1:6379> zrem z2 ‘jerry‘ (integer) 1
ZSCORE key member 返回有序集中,成員的分數值
127.0.0.1:6379> zscore z2 tom "89"
redis另外命令操作
DEL key [key ...] 刪除一個key
EXISTS key [key ...] 檢redis的key是否存在
EXPIRE key seconds 為某個redis的key設置存在時間
RENAME key newkey 為key重命名
randomkey 隨機獲取一個key
type key 獲取key的對應值類型
發布訂閱
發布者:服務器
訂閱者:Dashboad和數據處理
Demo如下:
import redis class RedisHelper: def __init__(self): self.__conn = redis.Redis(host=‘192.168.10.142‘) 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
訂閱者
from redishelper import RedisHelper obj = RedisHelper() redis_sub = obj.subscribe() while True: msg = redis_sub.parse_response() print(msg)
發布者
from monitor.RedisHelper import RedisHelper obj = RedisHelper() obj.public(‘hello‘)
redis緩存數據庫