大家好,我姓鄭,就是那個被魯智深三拳打死的那個屠夫的鄭~_~~_~
阿新 • • 發佈:2018-12-16
redis 實戰學習筆記1
redis:資料檔案儲存在dump.rdb中
第一章:
1、redis的持久化:資料存放問題
(1)時間點轉儲:指定時間段內指定數量的寫操作執行
(2)將之追加寫入設定為 從不同步,每秒同步,每寫入一個命令就同步一次
2、資料結構型別:
string、list、set、hash、zset
(1)string字串:鍵-值
命令:get set del
set 成功 返回OK,python返回Ture
get 成功 返回 鍵對應的值
del 成功 返回刪除值的數量,再次獲取該鍵的值時候返回nil, python返回None
set abc 123
get abc
del abc
get abc
(2)list列表: 連結串列
一個列表結構可以有序的儲存多個字串,
命令:lpush左、rpush右、lpop、rpop、lindex、lrange範圍所有元素
rpush list-key item
rpush list-key item2
rpush list-key item
lrange list-key 0 -1 取出該連結串列的所有元素 下表從0開始
lindex list-key 0
lpop list-key 彈出元素
(3 )set集合:無序unordered
命令:sadd、smembers、sismember、srem、 sinter、sunion、sdiff
sadd set-key item 新增元素成功返回1,存在返回0
smembers set-key 獲取集合所有元素 pyhton返回set
sismember set-key item 檢查元素是否存在於集合中0|1 python返回bool
srem set-key item2 移除元素,返回移除數量
(4)hash雜湊hset:儲存多個鍵值對之間的對映,值即可是字串又可以是數字值,鍵無序排列
它其實是一個字典或者map,只是每一個hash都有一個名字
鍵不重複
命令:hset、hget、hgetall、hdel
hset hashkey subkey1 value1
hset hashkey subkey2 value2
hset hashkey subkey2 value2
hgetall hashkey python 返回字典
hdel hashkey subkey2
hget hashkey subkey
hmset ( article,{
'title':title,link:link,poster:user,time:now,votes:1
}
)
hmset article title title1 link link1 poster zhengyi time now votes 1
hset:
article:110000{
title:title1
link:link1
poster:zhengyi
time:now
votes:1
}
hgetall article 返回字典
(5)zset有序集合:和雜湊一樣,儲存鍵值對。有序集合的鍵被稱為 成員,值則為分值,浮點數
集合有序、鍵不重複
命令:zadd、zrange、zrangebyscore、zrem、
zadd zsetkey 728 member1
zadd zsetkey 982 member2
zadd zsetkey 982 member0
zrange zsetkey 0 -1 withscores 省略withscores 則返回所有的成員
zrangebyscore zsetkey 0 800 withscires 返回分值在0~800之間的成員
zrem zsetkey member1 移除元素
zrange zsetkey 0 -1 返回所有的成員 不包括分值
zcard zsetkey 返回該集合成員個數
功能函式:
expire key seconds 讓某個鍵 多少秒後 自動刪除
第二章:使用redis構建web應用
web應用就是通過http協議對網頁遊覽器傳送的請求進行響應的服務
(1)伺服器對客戶端傳送的請求request進行解析
(2)請求被轉發給一個預定義的處理器handler
(3)處理器可能會從資料庫中取出資料
(4)處理器根據去除的資料對模板template進行渲染render
(5)處理器向客戶端返回渲染後的內容作為對請求的響應 response
這種請求被認為是無狀態的stateless
第三章:redis命令
1、字串string
字串可以儲存三種類型的值:位元組串,整數,浮點數
increment decrement
1)命令 用例描述
incr incr key-name 鍵儲存值+1
decr decr key-name -1
incrby incrby key-name amount 鍵儲存值+amount
decrby decrby key-name amount -amount
incrbyfloat incrbyfloat key-name amount +浮點數amount
append append key-name value 將value追加到鍵key-name當前儲存值的末尾 返回當前值字串的個數
getrange getrange key-name start end 獲取範圍內的所有字元組成的子串,包括start end在內
setrange setrange key-name offset value 從偏移量開始的子串設定給定值 setrange hello 0 H 0索引替換成H 也可以新增一個字串
getbit getbit key-name offset 將字串看作是二進位制位串,並返回位串中偏移量offset的二進位制位的值
setbit setbit key-name offset value 二進位制位的值設定為value
bitcount bitcount key-name [start end] 統計二進位制位串值為1的二進位制位的個數,可以選定範圍內的1的個數
bitop bitop operation dest-key key-name [key-name...]對一個或者多個二進位制位串執行包括
and、or、xor、not 在內任意一種按位運算操作,並將計算結果儲存在dest-key鍵裡面
python:
conn.set('key',0)
conn.get('key')
conn.incr('key')
conn.decr('key')
conn.incr('key',10)
conn.decr('key',10)
2、列表list
1)命令 用途描述
rpush rpush key-name value [value...] 將一個或多個值推入列表的右端
lpush lpush key-name value [value...] 將一個或多個值推入列表的左端
rpop rpop key-name 移除並返回最右端的元素
lpop lpop key-name 移除並返回最左端的元素
lindex lindex key-name offset 返回列表中偏移量為offset 的元素
lrange lrange key-name start end 返回偏移量[start,end]之間的所有元素包括兩端
lrange key-name 0 -1 返回列表所有元素
ltrim ltrim key-name start end 對列表進行修剪,只保留[start,end]之間的所有元素包括兩端
ltrim listkey 2 -1 保留第3個元素到最後
組合使用ltrim 和 lrange 可以構建出一次返回並彈出多個元素的操作
2)阻塞式的列表彈出命令及在列表之間移動元素的命令
blpop blpop key-name [key-name...] timeout 從第一個非空列表中彈出位於最左端的元素,
或者在timeout秒之內阻塞並等待可彈出的元素出現
brpop brpop key-name [key-name...] timeout
rpoplpush rpoplpush source-key dest-key 從source-key 列表中彈出位於最右端的元素,
然後將這個元素推入到dest-key列表的最左端,
並返回這個元素
brpoplpush brpoplpush source-key dest-key timeout 從source-key列表中彈出位於最右端的元素,
然後將這個元素推入到dest-key列表的最左端,並返回這個元素。
如果source-key為空,那麼在timeout秒之內阻塞並等待可彈出的元素出現
列表的一個主要優點在於可以包換多個字串值,可以將資料集中在同一個地方降低記憶體佔用
3、集合set
集合以無序的方式儲存不同的元素
1)命令 用途描述
sadd sadd key-name item [item...] 將一個或多個元素新增到集合裡面並返回數量
srem srem key-name item [item...] 從集合裡面移除一個或多個元素,並返回被移除的數量
sismember sismember key-name item 檢查元素是否存在於集合中
scard scard key-name 返回集合的元素數量
smembers smembers key-name 返回集合的所有元素
srandmember srandmember key-name [count] 從集合中隨機返回一個或多個元素,count為負數可能元素會重複出現
spop spop key-name 隨機移除集合中的一個元素,並返回
smove smove source-key dest-key item 如果集合source-key 包含元素item,那麼從source-key 裡面移除item
並將item新增到集合dest-key中,如果item被移除成功,那麼返回1,否則返回0
2)多個集合的命令
sdiff sdiff key-name [key-name....] 返回存在第一個集合而不存在其他集合的元素,差集運算
sdiffstore sdiffstore dest-key key-name [key-name...] 將存在第一個集合但不存在其他集合的元素,儲存到dest-key集合中
sinter sinter key-name [key-name...] 返回那麼同時存在於所有集合中的元素 交集
sinterstore sinterstore dest-key key-name [key-name...] 將所有集合的交集 儲存到dest-key集合中
sunion sunion key-name [key-name...] 返回至少存在於一個集合中的元素,並集
sunionstore sunionstore dest-key key-name [key-name] 並集的元素 儲存到dest-key集合中
4、雜湊hash
雜湊可以讓多個鍵值對儲存到一個鍵裡面
1)命令 用途描述
hset hset key-name key value
hget hget key-name key
hgetall hgetall key-name 返回該雜湊的所有鍵值對,python 返回字典
hmget hmget key-name key [key...] 從雜湊裡獲取一個或多個鍵的值
hmset hmset key-name key value [key value....] 為雜湊裡面的一個或多個鍵設定值
hdel hdel key-name key [key...] 刪除雜湊裡的一個或者多個鍵值對,返回成功找到並刪除的鍵值對數量
hlen hlen key-name 返回雜湊包含鍵值對的數量
hexists hexists key-name key 檢查給定的鍵是否存在雜湊中
hkeys hkeys key-name 獲取雜湊包含的所有鍵
hvals hvals key-name 獲取雜湊包含的所有值
hgetall hgetall key-name 獲取雜湊包含的所有鍵值對
hincrby hincrby key-name key increment 將鍵key的值+整數increment
hincrbyfloat hincrbyfloat key-name key increment 將鍵key的值+浮點數increment
5、有序集合zset
有序集合儲存著成員與分值之間的對映
1)命令 用途描述
zadd zadd key-name score member [score member ...] 將帶有給定分值的成員新增到有序結合裡面
zrem zrem key-name member [member...] 從有序結合裡面移除給定的成員,並返回移除成功的數量
zcard zcard key-name 返回有序集合包含的成員數量
zincrby zincrby key-name increment member 將member成員的分值加上increment
zcount zcount key-name min max 返回分值介於min和max之間的成員數量
zrank zrank key-name member 返回成員member在有序集合中的排名 從小到大排名0~max
zscore zscore key-name member 返回成員member的分值
zrange zrange key-name start stop [withscores] 返回有序結合中排名介於start和stop之間的成員
如果給定withscores,那麼連成員分值也一併返回
按照分值從小到大排列
zrevrank zrevrange key-name member 返回有序集合成員member排名 第0~第max 成員按照分值從大到小排列
zrevrange zrevrange key-name start stop [withscores] 返回有序結合給定排名範圍內的成員,成員按照分值從大到小排列
zrangebyscore zrangebyscore key min max [withscores] [limit offset count] 返回有序集合中分值介於min和max之間的所有成員 分值從小到大
zrevrangebyscore zrevrangebyscore key min max [withscores] [limit offset count] 返回有序集合中分值介於min和max之間的所有成員,並按照分值從大到小的順序來返回他們
zremrangebyrank zremrangebyrank key-name start stop 移除有序集合中排名介於start stop之間的所有成員
zremrangebyscore zremrangebyscore key-name min max 移除有序集合中分值介於min max之間的所有成員
zinterstore zinterstore dest-key key-count key [key...] [weights weight] 有序集合執行集合的交集運算 預設聚合函式為sum,相同的成員 分值相加,min取最小的分值,max取最大的分值
zunionstore zunionstore dest-key key-count key [key...] 有序集合並集操作 可以新增aggregate = min max sum 聚合函式
zinterstore,zunionstore可用來構建不同型別的搜尋系統
6、釋出與訂閱pub/sub
釋出與訂閱又稱pub/sub的特點是訂閱者負責訂閱頻道,傳送者負責向頻道傳送二進位制字串訊息
1)命令 用途描述
subscribe subscribe channel [channel...] 訂閱給定的一個或者多個頻道
unsubscribe unsubscribe [channel [channel...]] 退訂給定的一個或多個頻道,如果沒給頻道,則退訂所有頻道,取消訂閱
publish publish channel message 向給定頻道傳送訊息
psubscribe psubscribe pattern [pattern...] 訂閱與給定模式相匹配的所有頻道
punsubscribe punsubscribe [pattern [pattern....]] 退訂給定的模式,退訂所有模式
7、其他命令
7.1)排序
sort sort source-key [by pattern] [limit offset count] [get pattern [get pattern...]] [asc|desc] [alpha] [store dest-key]
根據給定的選項,對輸入的列表、集合、有序集合進行排序,然後返回或者儲存排序的結果
根據降序而不是預設的升序來排序元素
將元素看做是數字來進行排序,或者二進位制字串進行排序
使用被排序元素之外的其他值作為權重來進行排序,
rpush sortinput 23 15 110 7 列表
sort sortinput 預設升序 7 15 23 110
sort sortinput alpha 使用字典序 110 15 23 7
hset d-7 field 5
hset d-15 field 1
hset d-23 field 9
hset d-110 field 3
sort sortinput by 'd-*->field'
15 110 7 23
sort sortinput by 'd-*->field' get 'd-*->field'
1 3 5 9
sort命令不僅可以對列表進行排序,還可以對集合進行排序,返回一個列表形式的排序結果
7.2)redis事物
為了對相同或者不同型別的多個鍵執行操作,redis有5個命令可以讓使用者在不被打斷的情況下對多個鍵執行操作
watch、multi、exec、unwatch、discard
事務可以讓客戶端在不被其他客戶端打斷的情況下執行多個命令
被multi和exec包圍的命令會一個接一個執行
一個事務操作完畢後才會處理其他客戶端命令
redis會將素有命令放入到一個佇列裡面 等待exec命令執行
主要作用:移除競爭條件
7.3)鍵的過期時間
通過使用過期操作來自動刪除過期資料並降低redis記憶體佔用
1)命令 示例描述
persist persist key-name 移除鍵的過期時間
ttl ttl key-name 檢視給定鍵距離過期還有多少秒
expire expire key-name seconds 給定鍵在指定秒數後過期刪除
expireat expireat key-name timestamp 將給定鍵的過期時間設定給定的unix時間戳
pttl pttl key-name 檢視給定鍵距離過期還有多少毫秒
pexpire pexpire key-name milliseconds 給定的鍵多少毫毛後過期
pexpireat pexpireat key-name timestamp-milliseconds 將一個毫秒級經度的unix時間設定為過期時間
第四章:資料安全與效能保障
1、資料持久化-到硬盤裡
1)快照持久化
可以通過建立快照來獲得儲存在記憶體裡面的資料在某個時間點上的副本
利用快照進行建立相同的資料伺服器副本
快照被寫入dbfilename選項指定的檔案 dump.rdb裡面,並存儲在dir路徑上
2)建立快照的方法
[1]客戶端向redis傳送bgsave命令來建立快照--通過fork建立子程序負責寫入硬碟
[2]傳送save命令建立快照,並不響應其他命令,不常用
[3]設定save配置選項 save 60 10000 從最近一次快照之後算起 當60s內有10000次寫入 這個條件滿足時,自動觸發bgsave命令
可以設定多個save選項
[4]redis通過shutdown命令接收關閉伺服器請求時候或者受到term訊號時候 會執行save命令 執行完畢後關閉伺服器
[5]一個redis連線另一個redis併發送sync命令開始一次複製操作時候,主伺服器會執行bgsave命令
快照只使用與即使丟失一部分資料也不會造成問題的應用程式
[3] 大資料,儲存資料只有幾GB的時候 使用快照儲存資料是沒問題的很快
對於非常大的資料50GB等,每天可以在凌晨的時候備份快照一次通過save命令
2、AOF持久化(只追加檔案)
對於丟失資料不可接受,可以使用AOF持久化來儲存在記憶體中的資料儘快的儲存到硬盤裡面
AOF持久化 會將被執行的寫命令寫到AOF檔案的末尾,以此來記錄資料發生的變化
因此,redis只要從頭到尾重新執行一次AOF檔案包含的所有寫命令,就可以恢復AOF檔案所記錄的資料集
配置選項appendonly yes 開啟
appendfsync 選項同步頻率 always、everysec 、no建議everysec always會嚴重降低速度
最多也就丟失1s內的資料
缺陷:aof檔案的體積不斷增大,還原操作執行的時間就非常長(通過重新執行aof檔案的所有命令還原資料)
解決AOF檔案體積不斷增大的問題:傳送bgrewriteaof命令,移除aof檔案中冗餘命令來重寫aof檔案,使得aof檔案變得小的多
儘可能多的備份快照檔案和aof檔案
3、複製
1)複製可以讓其他伺服器擁有一個不斷更新的資料副本
一主多從伺服器,主:寫入 主更新從,從:讀取請求
客戶端可以向任意一個從伺服器傳送讀請求,將負載平均分配到各個從伺服器上
2)複製相關選項進行配置:
從伺服器連線主伺服器時,主伺服器會執行bgsave操作,
主伺服器需要 設定 dir 和 dbfilename
開啟從伺服器:slaveof <masterip> <masterport> 設定為masterip port 的從伺服器
slaveof no one 命令 可以讓伺服器終止複製操作,不再接收主伺服器的資料更新
slaveof host port命令 開始複製一個新的主伺服器
3)redis 複製的啟動過程
從伺服器連線主伺服器時的步驟
主伺服器操作 從伺服器操作
[1] 等待命令進入 連線主伺服器,傳送sync命令
[2] 執行bgsave,並使用緩衝區記錄 根據配置選項來來決定使用現有的資料
bgsave之後執行的所有寫命令 來處理客戶端的命令請求
[3] bgsave執行完,向從伺服器傳送快 丟棄所有舊資料,開始載入主伺服器傳送的快照
照檔案,並繼續記錄寫命令
[4] 快照發送完,開始向伺服器傳送 完成快照檔案的解釋操作,接受命令請求
儲存在緩衝區裡面的寫命令
[5] 緩衝區的寫命令傳送完, 執行主伺服器發來的所有緩衝區的寫命令,
從現在開始沒執行一個寫命令, 從現在開始,接收並執行主伺服器傳來的每個命令
就向從伺服器傳送相同的寫命令
建議:實際中主伺服器只使用50~60%的記憶體,留下30~45%記憶體用於執行bgsave命令和建立記錄寫命令的緩衝區
redis 不支援主主複製
4)主從鏈master/slave chaining
5)檢測硬碟寫入
檢查info命令輸出結果中aof_pending_bio_fsync的屬性是否為0,為0表示所有資料寫入到磁碟上面
info命令提供了redis伺服器當前狀態有關的資訊
通過使用 複製和AOF持久化,使用者可以增強redis 對系統崩潰的抵抗能力
4、處理系統故障
1)驗證快照檔案和aof檔案
命令:修復快照或者aof檔案 剔除出錯的命令
redis-check-aof
redis-check-dump
2)更換故障主伺服器
主A、從B、新C
首先:向B傳送save命令,建立新的快照檔案
接著:將快照檔案scp給機器C,並在C上啟動redis
最後:設定B為C的從伺服器 slaveof c port
5、redis事務,保證資料安全、防止資料出錯
多個客戶端同時處理相同的資料時、會出現競爭
使用 wathc、multi、exec命令對多種資料進行操作
6、非事務型 流水線
在不是用事務的情況下 ,可通過流水線來提升redis的效能
即使用conn.pipeline(false)使用流水線,不開啟事務操作
減少程式與redis之間的通訊往返次數 為一次
7、效能注意
測試機器各命令效能
redis-benchmark -c 1 -q
PING_INLINE: 19193.86 requests per second
PING_BULK: 19527.44 requests per second
SET: 18460.40 requests per second
GET: 18889.31 requests per second
INCR: 18719.58 requests per second
LPUSH: 18358.73 requests per second
RPUSH: 18372.22 requests per second
LPOP: 18412.81 requests per second
RPOP: 18453.59 requests per second
SADD: 18487.71 requests per second
SPOP: 18807.60 requests per second
LPUSH (needed to benchmark LRANGE): 18399.26 requests per second
LRANGE_100 (first 100 elements): 12286.52 requests per second
LRANGE_300 (first 300 elements): 8552.86 requests per second
LRANGE_500 (first 450 elements): 6349.61 requests per second
LRANGE_600 (first 600 elements): 5094.24 requests per second
MSET (10 keys): 17099.86 requests per second
不使用流水線的python客戶端的效能大概只有所示效能的50~60%
redis客戶端庫提供了內建連線池,python 只需穿件一個redis.Redis()物件
該物件按需穿件連線,重用已有連線並關閉超時連線,可以安全的應用於多程序多執行緒中