《Redis實(shí)戰(zhàn)》讀書筆記
Redis的重要性不必多說(shuō),所以我將從0開(kāi)始學(xué)習(xí)Redis宁否,并記錄下來(lái)窒升。我將把《Redis實(shí)戰(zhàn)》這本書作為我的入門書籍,沒(méi)有多少原因慕匠,找書的時(shí)候發(fā)現(xiàn)這個(gè)比較適合我饱须,既介紹了基礎(chǔ)的語(yǔ)法等知識(shí),也用一些實(shí)戰(zhàn)項(xiàng)目來(lái)應(yīng)用Redis台谊,下面開(kāi)始學(xué)習(xí)之旅吧~~~
Ubunut下Redis安裝
書上介紹了Linux, OS X, Windows三種系統(tǒng)下的Redis安裝步驟蓉媳,我自己的電腦為Ubuntu 16.04,所以只記錄Linux相關(guān)步驟锅铅。
簡(jiǎn)單方法
apt-get install redis-server
不推薦這個(gè)方法酪呻,因?yàn)楦鶕?jù)Ubuntu版本的不同,這種安裝方法會(huì)安裝舊版本的Redis盐须。
源碼編譯安裝
- 安裝構(gòu)建工具
sudo apt-get update
sudo apt-get install make gcc python-dev
-
下載Redis源碼
- 從Redis官網(wǎng)下載最新stable版本的Redis源碼
- 解壓源碼玩荠,編譯,安裝并啟動(dòng)Redis
~:$ tar -xzf redis-4.0.7.tar.gz 解壓源碼 ~:$ cd redis-4.0.7/ ~/redis-4.0.7:$ make 編譯Redis cd src && make all ... 編譯信息 ... 注意觀察編譯信息,不應(yīng)看到錯(cuò)誤 make[1]: leaving directory '~/redis-4.0.7/src ~/redis-4.0.7:$ sudo make install 安裝Redis cd src && make install ... 安裝信息不應(yīng)有錯(cuò) make[1]: leaving directory '~/redis-4.0.7/src ~/redis-4.0.7:$ redis-server redis.conf 啟動(dòng)Redis
3.下載安裝Python語(yǔ)言的Redis客戶端庫(kù)
pip3 install redis hiredis
hiredis包是一個(gè)C庫(kù)阶冈,提高Python的Redis客戶端速度屉凯。
在Ipython中測(cè)試是否可以連接(省略)
問(wèn)題
我的步驟跟書上不是完全一樣,以上操作是根據(jù)我自己的實(shí)際操作寫出眼溶。我在Ipython中連接redis失敗,因?yàn)閞edis沒(méi)有啟動(dòng)晓勇。原來(lái)用redis-server
啟動(dòng)不能夠保持Redis在后臺(tái)一直運(yùn)行堂飞,在終端被關(guān)閉時(shí)就關(guān)閉,有兩種解決辦法绑咱。
運(yùn)行命令時(shí)添加'&',
redis-server &
修改redis.conf文件绰筛,將默認(rèn)的daemonize no改為yes
第一部分 入門
第一部分包括前兩章,前兩章簡(jiǎn)單的介紹了一下Redis,以及兩個(gè)入手的小例子描融。
Redis是一個(gè)速度非陈霖快的非關(guān)系數(shù)據(jù)庫(kù),是一個(gè)內(nèi)存數(shù)據(jù)庫(kù)窿克。因此Redis不需要事先定義表結(jié)構(gòu)等操作骏庸,Redis提供了5種不同類型的數(shù)據(jù)結(jié)構(gòu)來(lái)幫助我們更高效的解決問(wèn)題。這五種數(shù)據(jù)結(jié)構(gòu)分別是:
- STRING 字符串
- LIST 列表
- SET 集合
- HASH 散列
- ZSET 有序集合
前兩章包括了兩個(gè)例子年叮,一個(gè)是在博客網(wǎng)站上對(duì)文章進(jìn)行評(píng)分和展示具被,一個(gè)是用Redis構(gòu)建Web應(yīng)用,因?yàn)檫€沒(méi)有講解Redis命令只损,且對(duì)Redis的數(shù)據(jù)結(jié)構(gòu)還不夠熟悉一姿,看示例代碼時(shí)有些命令看得有些費(fèi)力,但是命令的理解不是前兩章的重點(diǎn)跃惫,代碼的整體思路也是能看看明白的叮叹,重點(diǎn)在于觀念的改變,理解Redis可以用在什么場(chǎng)合爆存,以及如何使用Redis蛉顽。書本配套示例代碼
在關(guān)系數(shù)據(jù)庫(kù)中,我們遇到問(wèn)題經(jīng)常需要扭曲問(wèn)題來(lái)適應(yīng)數(shù)據(jù)庫(kù)终蒂,但是Redis的數(shù)據(jù)結(jié)構(gòu)可以自然而然的應(yīng)用于我們的問(wèn)題蜂林。
命令
第二部分深入介紹了Redis的命令,每個(gè)不同的數(shù)據(jù)結(jié)構(gòu)有不同的命令拇泣,整體的掌握這些數(shù)據(jù)結(jié)構(gòu)以及命令才能恰當(dāng)?shù)貙edis應(yīng)用到具體的問(wèn)題噪叙,達(dá)到更好的優(yōu)化效果。
字符串 String
字符串是一個(gè)由字節(jié)組成的序列霉翔,可以存儲(chǔ)字符串睁蕾,整數(shù)或者浮點(diǎn)數(shù),與編程語(yǔ)言中的字符串相去不大。
處理數(shù)值
- set key value 將鍵key的值設(shè)為value
- get key 獲取存在鍵key里的值
- del key 刪除key這個(gè)鍵值對(duì)
- incr key key存儲(chǔ)的值加1(若key不存在子眶,默認(rèn)初值為0)
- decr key key存儲(chǔ)的值減1(同上)
- incrby key amount key存儲(chǔ)的值加整數(shù)amount(同上)
- decrby key amount key存儲(chǔ)的值減整數(shù)amount(同上)
- incrbyfloat key amount 浮點(diǎn)數(shù)amount
處理子串
- append key value 將value追加到key值尾端
- getrane key start end 獲取偏移量start到end(包括兩端)的所有字符組成的子串
- setrange key start value 將從start偏移量開(kāi)始的子串設(shè)置為value
列表 LIST
列表可以有序的存儲(chǔ)多個(gè)字符串瀑凝。
- rpush key value [value ...] 將一個(gè)或多個(gè)value推入列表右端
- lpush key value [value ...]
- rpop key 移除并返回列表最右端的值
- lpop key
- lindex key 返回列表中偏移量為offset的元素
- lrange key start end 返回列表從start到end的所有元素(包括兩端)
- ltrim key start end 保留列表從start到end的所有元素(包括兩端)
集合
集合以無(wú)序的方式存儲(chǔ)多個(gè)各不相同的元素。
- sadd key item [item ...] 將一個(gè)或多個(gè)元素添加到集合key臭杰,返回被添加元素不在原始集合的元素?cái)?shù)量
- srem key item [item ...] 從集合里移除一個(gè)或多個(gè)元素粤咪,返回被移除的元素?cái)?shù)量
- sismember key item 檢查item是否在集合Key中
- scard key 返回集合包含元素?cái)?shù)量
- smembers 返回集合的所有元素
- srandmember key [count] 從集合里隨機(jī)返回一個(gè)或多個(gè)元素。當(dāng)count為正渴杆,元素不會(huì)重復(fù)寥枝,為負(fù)時(shí)可能重復(fù)
- spop key 從集合key隨機(jī)移除一個(gè)元素并返回
- smove source-key dest-key item 如果集合source-key包含item,移除item并添加到dest-key集合;成功移除返回1,否則0
- sdiff key [key ...] 返回那些存在第一個(gè)集合磁奖,但不在其他集合的元素(差集)
- sdiffstore dest-key key [key ...] 將上一條命令的元素存儲(chǔ)在dest-key集合中
- sinter key [key ...] 返回同時(shí)存在于所有集合的元素(交集)
- sinterstore dest-key key [key ...] 將上一條命令的元素存儲(chǔ)在dest-key集合中
- sunion key [key ...] 返回至少在一個(gè)集合中出現(xiàn)過(guò)的元素(并集)
- sunionstore dest-key key [key ...] 將上一條命令的元素存儲(chǔ)在dest-key集合中
散列 HASH
將多個(gè)鍵值對(duì)存儲(chǔ)在一個(gè)鍵值里囊拜。
- hmget key-name key [key ...] 從散列里獲取一個(gè)或多個(gè)值
- hmset key-name key [key ...] 為散列設(shè)置一個(gè)或多個(gè)值
- hdel key-name key [key ...] 刪除,并返回成功刪除數(shù)量
- hlen key-name 返回散列包含的鍵值對(duì)數(shù)量
- hexists key-name key 檢查key鍵是否在散列中
- hkeys key-name 獲取散列的所有鍵
- hvals key-name 獲取散列的所有值
- hgetall key-name 獲取散列的所有鍵值對(duì)
- hincrby key-name key increment 將鍵Key存儲(chǔ)的值加上整數(shù)increment
- hincrbyfloat key-name key increment 浮點(diǎn)數(shù)
有序集合 ZSET
與散列存儲(chǔ)著鍵和值之間的映射類似比搭,有序集合存儲(chǔ)著成員與分值之間的映射冠跷。
- zadd key-name score member [score member ...] 將帶有給定分值score的成員member添加到有序集合
- zrem key-name member [member ...] 從有序集合刪除給定成員,返回被移除成員數(shù)量
- zcard key-name 返回有序集合成員數(shù)量
- zincrby key-name increment member 將member的分值加上increment(python客戶端參數(shù)位置有變化)
- zcount key-name min max 返回分值介于min和max之前的成員數(shù)量
- zrank key-name member 返回成員member在有序集合中的排名(從0開(kāi)始)
- zscore key-name member 返回成員member的分值
- zrange key-name start stop [withscores] 返回排名介于start和stop之間的成員(包括兩端)身诺,如果加上withscores蜜托,則成員的分值一并返回
- zrevrank key-name member 返回member的排名,成員按照分值從大到小排列
- zrevrange key-name start stop [withscores] 返回start到stop范圍內(nèi)的成員霉赡,按值從大到小排列
- zrangebyscore key min max [withscores] 返回分值介于min,max間的所有成員
- zrevrangebyscore key min max [withscores] 返回分值介于min,max間的所有成員,按值從大到小
- zremrangebyrank key-name start stop 移除排名介于start,stop的成員
- zremrangebyscore key-name min max 移除分值介于min,max的成員
- zinterstore dest-key key-count key [key...] [weights weight [weight]] [aggregate sum|min|max] 對(duì)給定有序集合執(zhí)行類似于集合的交集運(yùn)算
- zunionstore dest-key key-count key [key...] [weights weight [weight]] [aggregate sum|min|max] 執(zhí)行并集運(yùn)算
關(guān)于5種數(shù)據(jù)結(jié)構(gòu)的常用命令盗冷,上面已經(jīng)列出來(lái)很多,但是其實(shí)還有很多同廉。我個(gè)人覺(jué)得記住所有的是有難度的(記性差)仪糖,這些命令的命名規(guī)則還是有許多相似之處,可以方便記憶迫肖,但是更好的辦法是記住一些常用的锅劝,然后了解Redis的命令可以實(shí)現(xiàn)什么樣的操作,當(dāng)需要這樣的操作時(shí)再去查命令蟆湖。
其他命令
- sort source-key 相當(dāng)于關(guān)系數(shù)據(jù)庫(kù)的order by(有很多可選參數(shù))
- persist key-name 移除鍵的過(guò)期時(shí)間
- ttl key-name 查看距離過(guò)期時(shí)間還有多少秒
- expire key-name seconds 讓給定鍵在指定秒數(shù)之后過(guò)期
- expireat key-name timestamp 將給定鍵的過(guò)期時(shí)間設(shè)置為給定的UNIX時(shí)間戳
- 事務(wù)命令
- 發(fā)布訂閱命令
更多命令參考 官網(wǎng)
數(shù)據(jù)安全與性能保障
與關(guān)系數(shù)據(jù)庫(kù)類似故爵,Redis也需考慮數(shù)據(jù)的安全,需要備份數(shù)據(jù)隅津,保障出現(xiàn)故障后能夠全部或最大化的恢復(fù)損失诬垂。但與關(guān)系數(shù)據(jù)庫(kù)不同的是,Redis是內(nèi)存數(shù)據(jù)庫(kù)伦仍,數(shù)據(jù)是存儲(chǔ)在內(nèi)存里的结窘,在程序崩潰、重啟等情況下內(nèi)存數(shù)據(jù)就會(huì)丟失充蓝,還需要考慮數(shù)據(jù)持久化隧枫,即將內(nèi)存的數(shù)據(jù)寫入磁盤喉磁。Redis提供了兩種數(shù)據(jù)持久化的方法,一種為快照持久化官脓,另一種為只追加文件(append-only file AOF)协怒。可以單獨(dú)使用卑笨,或者同時(shí)使用孕暇,甚至都不使用。
持久化后的數(shù)據(jù)就是安全的了嗎赤兴?不是的芭商,現(xiàn)在面臨的就是和關(guān)系數(shù)據(jù)庫(kù)類似的備份數(shù)據(jù)問(wèn)題了。需要將數(shù)據(jù)復(fù)制到多臺(tái)服務(wù)器來(lái)保證數(shù)據(jù)安全搀缠,這就是主從服務(wù)器的一部分。
Redis復(fù)制啟動(dòng)過(guò)程
步驟 | 主服務(wù)器操作 | 從服務(wù)器操作 |
---|---|---|
1 | (等待命令進(jìn)入) | 連接(重連接)主服務(wù)器近迁,發(fā)送SYNC命令 |
2 | 開(kāi)始執(zhí)行BGSAVE艺普,并使用緩沖區(qū)記錄BGSAVE之后執(zhí)行的所有寫命令 | 根據(jù)配置決定是否使用現(xiàn)有數(shù)據(jù)來(lái)處理客戶端請(qǐng)求,還是向客戶端返回錯(cuò)誤 |
3 | BGSAVE執(zhí)行完畢鉴竭,向從服務(wù)器發(fā)送快照文件歧譬,在發(fā)送期間繼續(xù)使用緩沖區(qū)記錄被執(zhí)行的寫命令 | 丟棄舊數(shù)據(jù),載入主服務(wù)器的快照文件 |
4 | 快照發(fā)送完畢搏存,向從服務(wù)器發(fā)送存儲(chǔ)在緩沖區(qū)里的寫命令 | 完成對(duì)快照文件的解釋操作瑰步,像往常一樣開(kāi)始接受命令請(qǐng)求 |
5 | 緩沖區(qū)存儲(chǔ)的寫命令發(fā)送完畢;現(xiàn)在開(kāi)始,每執(zhí)行一個(gè)寫命令璧眠,向從服務(wù)器發(fā)送相同的寫命令 | 執(zhí)行主服務(wù)器發(fā)來(lái)的所有存儲(chǔ)在緩沖區(qū)里面的寫命令缩焦,并開(kāi)始接受并執(zhí)行主服務(wù)器發(fā)來(lái)的每個(gè)寫命令 |
性能優(yōu)化
大家都知道在程序運(yùn)行過(guò)程中,IO訪問(wèn)速度是遠(yuǎn)遠(yuǎn)不如CPU計(jì)算速度的责静,在Redis中也有類似的問(wèn)題存在袁滥。Redis客戶端發(fā)送命令到Redis服務(wù)器、Redis服務(wù)器響應(yīng)發(fā)送到客戶端的過(guò)程是相對(duì)較慢的灾螃,因此要減少客戶端與服務(wù)器的通信次數(shù)题翻,通過(guò)使用pipeline技術(shù)將多個(gè)命令放在一次通信過(guò)程中會(huì)大大提高Redis的效率。
最后
寫到這其實(shí)只占了書本篇幅的2/5,但是后面的篇幅大多數(shù)都是結(jié)合著具體例子腰鬼,介紹了一些Redis常用場(chǎng)景嵌赠,通過(guò)分析例子需求實(shí)現(xiàn)的一個(gè)個(gè)小功能,是一些Python代碼片段熄赡,包含著Redis命令和邏輯處理姜挺,記錄下來(lái)的意義不大,因?yàn)閷?shí)際需求總在發(fā)生變化彼硫,總是不同的初家。
Redis的相關(guān)知識(shí)肯定遠(yuǎn)遠(yuǎn)不止這些,這些只是最最基礎(chǔ)的,我以后可能會(huì)繼續(xù)分享Redis的相關(guān)文章溜在,學(xué)習(xí)過(guò)程等等陌知。一起加油!R蠢摺仆葡!