程序员,想要彻底弄懂Redis,这15点你一定要明白~(纯干货)
?點(diǎn)擊上方?好好學(xué)java?,選擇?星標(biāo)?公眾號(hào)
重磅資訊、干貨,第一時(shí)間送達(dá) 今日推薦:Java實(shí)現(xiàn)QQ登錄和微博登錄個(gè)人原創(chuàng)+1博客:點(diǎn)擊前往,查看更多 作者:耿直的小碼農(nóng) 來(lái)源:https://segmentfault.com/a/1190000022105542Redis是一款開(kāi)源的、高性能的鍵-值存儲(chǔ)(key-value store)。它常被稱作是一款數(shù)據(jù)結(jié)構(gòu)服務(wù)器(data structure server)。
Redis的鍵值可以包括字符串(strings)類型,同時(shí)它還包括哈希(hashes)、列表(lists)、集合(sets)和 有序集合(sorted sets)等數(shù)據(jù)類型。對(duì)于這些數(shù)據(jù)類型,你可以執(zhí)行原子操作。例如:對(duì)字符串進(jìn)行附加操作(append);遞增哈希中的值;向列表中增加元素;計(jì)算集合的交集、并集與差集等。
為了獲得優(yōu)異的性能,Redis采用了內(nèi)存中(in-memory)數(shù)據(jù)集(dataset)的方式。同時(shí),Redis支持?jǐn)?shù)據(jù)的持久化,你可以每隔一段時(shí)間將數(shù)據(jù)集轉(zhuǎn)存到磁盤(pán)上(snapshot),或者在日志尾部追加每一條操作命令(append only file,aof)。
Redis同樣支持主從復(fù)制(master-slave replication),并且具有非??焖俚姆亲枞状瓮?#xff08; non-blocking first synchronization)、網(wǎng)絡(luò)斷開(kāi)自動(dòng)重連等功能。同時(shí)Redis還具有其它一些特性,其中包括簡(jiǎn)單的事物支持、發(fā)布訂閱 ( pub/sub)、管道(pipeline)和虛擬內(nèi)存(vm)等 。Redis具有豐富的客戶端,支持現(xiàn)階段流行的大多數(shù)編程語(yǔ)言。
本文目錄:
Redis安裝
Redis配置
Redis數(shù)據(jù)類型
Redis功能
持久化
主從復(fù)制
事務(wù)支持
發(fā)布訂閱
管道
虛擬內(nèi)存
Redis性能
Redis部署
Redis應(yīng)用場(chǎng)景
Redis總結(jié)
Redis安裝:
下載最新穩(wěn)定版 redis( http://redis.io/download )
tar zxvf redis-2.2.11 解壓縮
程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)cd src 進(jìn)入src目錄make 編譯Redismake test 可以測(cè)試一下(本步可省略)make install 安裝,默認(rèn)安裝目錄是 /usr/local/bin,生成如圖5個(gè)二進(jìn)制文件,可以將其拷到新建目錄下,例如: /usr/local/redis/bin
程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)cp 源碼/src/redis.conf /usr/local/redis/etc 配置文件復(fù)制cd /usr/local/redis./bin/redis-server ./etc/redis.conf 啟動(dòng)Redis服務(wù)此時(shí)redis已經(jīng)運(yùn)行,但要獲得好的性能,還需要對(duì)配置文件進(jìn)行合理的配置
Redis配置:
1. Redis默認(rèn)不是以守護(hù)進(jìn)程的方式運(yùn)行,可以通過(guò)該配置項(xiàng)修改,使用yes啟用守護(hù)進(jìn)程 daemonize no
2. 當(dāng)Redis以守護(hù)進(jìn)程方式運(yùn)行時(shí),Redis默認(rèn)會(huì)把pid寫(xiě)入/var/run/redis.pid文件,可以通過(guò)pidfile指定 pidfile /var/run/redis.pid
3. 指定Redis監(jiān)聽(tīng)端口,默認(rèn)端口為6379
4. 綁定的主機(jī)地址 bind 127.0.0.1
5.當(dāng) 客戶端閑置多長(zhǎng)時(shí)間后關(guān)閉連接,如果指定為0,表示關(guān)閉該功能 timeout 300
6. 指定日志記錄級(jí)別,Redis總共支持四個(gè)級(jí)別:debug、verbose、notice、warning,默認(rèn)為verbose loglevel verbose
7. 日志記錄方式,默認(rèn)為標(biāo)準(zhǔn)輸出,如果配置Redis為守護(hù)進(jìn)程方式運(yùn)行,而這里又配置為日志記錄方式為標(biāo)準(zhǔn)輸出,則日志將會(huì)發(fā)送給/dev/null logfile stdout
8. 設(shè)置數(shù)據(jù)庫(kù)的數(shù)量,默認(rèn)數(shù)據(jù)庫(kù)為0,可以使用SELECT命令在連接上指定數(shù)據(jù)庫(kù)id databases 16
9. 指定在多長(zhǎng)時(shí)間內(nèi),有多少次更新操作,就將數(shù)據(jù)同步到數(shù)據(jù)文件,可以多個(gè)條件配合 saveRedis默認(rèn)配置文件中提供了三個(gè)條件:save 900 1 save 300 10 save 60 10000 分別表示900秒(15分鐘)內(nèi)有1個(gè)更改,300秒(5分鐘)內(nèi)有10個(gè)更改以及60秒內(nèi)有10000個(gè)更改。
10. 指定存儲(chǔ)至本地?cái)?shù)據(jù)庫(kù)時(shí)是否壓縮數(shù)據(jù),默認(rèn)為yes,Redis采用LZF壓縮,如果為了節(jié)省CPU時(shí)間,可以關(guān)閉該選項(xiàng),但會(huì)導(dǎo)致數(shù)據(jù)庫(kù)文件變的巨大 rdbcompression yes
11. 指定本地?cái)?shù)據(jù)庫(kù)文件名,默認(rèn)值為dump.rdb dbfilename dump.rdb
12. 指定本地?cái)?shù)據(jù)庫(kù)存放目錄 dir ./
13. 設(shè)置當(dāng)本機(jī)為slav服務(wù)時(shí),設(shè)置master服務(wù)的IP地址及端口,在Redis啟動(dòng)時(shí),它會(huì)自動(dòng)從master進(jìn)行數(shù)據(jù)同步 slaveof
14. 當(dāng)master服務(wù)設(shè)置了密碼保護(hù)時(shí),slav服務(wù)連接master的密碼 masterauth
15. 設(shè)置Redis連接密碼,如果配置了連接密碼,客戶端在連接Redis時(shí)需要通過(guò)AUTH命令提供密碼,默認(rèn)關(guān)閉 requirepass foobared
16. 設(shè)置同一時(shí)間最大客戶端連接數(shù),默認(rèn)無(wú)限制,Redis可以同時(shí)打開(kāi)的客戶端連接數(shù)為Redis進(jìn)程可以打開(kāi)的最大文件描述符數(shù),如果設(shè)置 maxclients 0,表示不作限制。當(dāng)客戶端連接數(shù)到達(dá)限制時(shí),Redis會(huì)關(guān)閉新的連接并向客戶端返回max number of clients reached錯(cuò)誤信息 maxclients 128
17. 指定Redis最大內(nèi)存限制,Redis在啟動(dòng)時(shí)會(huì)把數(shù)據(jù)加載到內(nèi)存中,達(dá)到最大內(nèi)存后,Redis會(huì)先嘗試清除已到期或即將到期的Key,當(dāng)此方法處理 后,仍然到達(dá)最大內(nèi)存設(shè)置,將無(wú)法再進(jìn)行寫(xiě)入操作,但仍然可以進(jìn)行讀取操作。Redis新的vm機(jī)制,會(huì)把Key存放內(nèi)存,Value會(huì)存放在swap區(qū) maxmemory
18. 指定是否在每次更新操作后進(jìn)行日志記錄,Redis在默認(rèn)情況下是異步的把數(shù)據(jù)寫(xiě)入磁盤(pán),如果不開(kāi)啟,可能會(huì)在斷電時(shí)導(dǎo)致一段時(shí)間內(nèi)的數(shù)據(jù)丟失。因?yàn)?redis本身同步數(shù)據(jù)文件是按上面save條件來(lái)同步的,所以有的數(shù)據(jù)會(huì)在一段時(shí)間內(nèi)只存在于內(nèi)存中。默認(rèn)為no appendonly no
19. 指定更新日志文件名,默認(rèn)為appendonly.aof appendfilename appendonly.aof
20. 指定更新日志條件,共有3個(gè)可選值:no:表示等操作系統(tǒng)進(jìn)行數(shù)據(jù)緩存同步到磁盤(pán)(快) always:表示每次更新操作后手動(dòng)調(diào)用fsync()將數(shù)據(jù)寫(xiě)到磁盤(pán)(慢,安全) everysec:表示每秒同步一次(折衷,默認(rèn)值) appendfsync everysec
21. 指定是否啟用虛擬內(nèi)存機(jī)制,默認(rèn)值為no,簡(jiǎn)單的介紹一下,VM機(jī)制將數(shù)據(jù)分頁(yè)存放,由Redis將訪問(wèn)量較少的頁(yè)即冷數(shù)據(jù)swap到磁盤(pán)上,訪問(wèn)多的頁(yè)面由磁盤(pán)自動(dòng)換出到內(nèi)存中(在后面的文章我會(huì)仔細(xì)分析Redis的VM機(jī)制) vm-enabled no
22. 虛擬內(nèi)存文件路徑,默認(rèn)值為/tmp/redis.swap,不可多個(gè)Redis實(shí)例共享 vm-swap-file /tmp/redis.swap
23. 將所有大于vm-max-memory的數(shù)據(jù)存入虛擬內(nèi)存,無(wú)論vm-max-memory設(shè)置多小,所有索引數(shù)據(jù)都是內(nèi)存存儲(chǔ)的(Redis的索引數(shù)據(jù) 就是keys),也就是說(shuō),當(dāng)vm-max-memory設(shè)置為0的時(shí)候,其實(shí)是所有value都存在于磁盤(pán)。默認(rèn)值為0 vm-max-memory 0
24. Redis swap文件分成了很多的page,一個(gè)對(duì)象可以保存在多個(gè)page上面,但一個(gè)page上不能被多個(gè)對(duì)象共享,vm-page-size是要根據(jù)存儲(chǔ)的 數(shù)據(jù)大小來(lái)設(shè)定的,作者建議如果存儲(chǔ)很多小對(duì)象,page大小最好設(shè)置為32或者64bytes;如果存儲(chǔ)很大大對(duì)象,則可以使用更大的page,如果不 確定,就使用默認(rèn)值 vm-page-size 32
25. 設(shè)置swap文件中的page數(shù)量,由于頁(yè)表(一種表示頁(yè)面空閑或使用的bitmap)是在放在內(nèi)存中的,,在磁盤(pán)上每8個(gè)pages將消耗1byte的內(nèi)存。vm-pages 134217728
26. 設(shè)置訪問(wèn)swap文件的線程數(shù),最好不要超過(guò)機(jī)器的核數(shù),如果設(shè)置為0,那么所有對(duì)swap文件的操作都是串行的,可能會(huì)造成比較長(zhǎng)時(shí)間的延遲。默認(rèn)值為4 vm-max-threads 4
27. 設(shè)置在向客戶端應(yīng)答時(shí),是否把較小的包合并為一個(gè)包發(fā)送,默認(rèn)為開(kāi)啟 glueoutputbuf yes
28. 指定在超過(guò)一定的數(shù)量或者最大的元素超過(guò)某一臨界值時(shí),采用一種特殊的哈希算法 hash-max-zipmap-entries 64 hash-max-zipmap-value 512
29. 指定是否激活重置哈希,默認(rèn)為開(kāi)啟 activerehashing yes
30. 指定包含其它的配置文件,可以在同一主機(jī)上多個(gè)Redis實(shí)例之間使用同一份配置文件,而同時(shí)各個(gè)實(shí)例又擁有自己的特定配置文件 include /path/to/local.conf
Redis的數(shù)據(jù)類型:
Keys非二進(jìn)制安全的字符類型( not binary-safe strings )
ValuesStrings Lists Sets Sorted sets Hash
Key: redis本質(zhì)上一個(gè)key-value 數(shù)據(jù)庫(kù),所以我們首先來(lái)看看他的key.首先key也是字符串類型,由于key不是binary safe的字符串,所以像“my key”和“mykey\n”這樣包含空格和換行的key是不允許的。
我們?cè)谑褂玫臅r(shí)候可以自己定義一個(gè)Key的格式。例如 object-typefield Key不要太長(zhǎng)。占內(nèi)存,查詢慢。Key不要太短。u:1000:pwd 不如 user:1000:password 可讀性好
key的相關(guān)命令:
exitskey 測(cè)試指定key是否存在,返回1表示存在,0不存在
delkey1 key2 ....keyN 刪除給定key,返回刪除key的數(shù)目,0表示給定key都不存在
typekey 返回給定key的value類型。返回 none 表示不存在,key有string字符類型,list 鏈表類型 set 無(wú)序集合類型等...
keys pattern返回匹配指定模式的所有key(支持*,?,[abc ]的方式),下面給個(gè)例子
程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)randomkey返回從當(dāng)前數(shù)據(jù)庫(kù)中隨機(jī)選擇的一個(gè)key,如果當(dāng)前數(shù)據(jù)庫(kù)是空的,返回空串renameoldkey newkey 原子的重命名一個(gè)key,如果newkey存在,將會(huì)被覆蓋,返回1表示成功,0失敗。失敗可能是oldkey不存在或者和newkey相同renamenxoldkey newkey 同上,但是如果newkey存在返回失敗dbsize返回當(dāng)前數(shù)據(jù)庫(kù)的key數(shù)量expirekey seconds 為key指定過(guò)期時(shí)間,單位是秒。返回1成功,0表示key已經(jīng)設(shè)置過(guò)過(guò)期時(shí)間或者不存在ttlkey 返回設(shè)置了過(guò)期時(shí)間的key的剩余過(guò)期秒數(shù), -1表示key不存在或者沒(méi)有設(shè)置過(guò)過(guò)期時(shí)間selectdb-index 通過(guò)索引選擇數(shù)據(jù)庫(kù),默認(rèn)連接的數(shù)據(jù)庫(kù)所有是0,默認(rèn)數(shù)據(jù)庫(kù)數(shù)是16個(gè)。返回1表示成功,0失敗movekey db-index 將key從當(dāng)前數(shù)據(jù)庫(kù)移動(dòng)到指定數(shù)據(jù)庫(kù)。返回1成功。0 如果key不存在,或者已經(jīng)在指定數(shù)據(jù)庫(kù)中flushdb刪除當(dāng)前數(shù)據(jù)庫(kù)中所有key,此方法不會(huì)失敗。慎用flushall刪除所有數(shù)據(jù)庫(kù)中的所有key,此方法不會(huì)失敗。更加慎用
String類型:
string是redis最基本的類型,而且string類型是二進(jìn)制安全的。
redis的string可以包含任何數(shù)據(jù)。包括jpg圖片或者序列化的對(duì)象。最大上限是1G字節(jié)。如果只用string類型,redis就可以被看作加上持久化特性的memcached
String相關(guān)命令:
setkey value 設(shè)置key對(duì)應(yīng)的值為string類型的value,返回1表示成功,0失敗
setnxkey value 同上,如果key已經(jīng)存在,返回0 。nx 是not exist的意思getkey 獲取key對(duì)應(yīng)的string值,如果key不存在返回nilgetsetkey value 設(shè)置key的值,并返回key的舊值。如果key不存在返回nilmgetkey1 key2 ... keyN 一次獲取多個(gè)key的值,如果對(duì)應(yīng)key不存在,則對(duì)應(yīng)返回nil。下面是個(gè)實(shí)驗(yàn), nonexisting不存在,對(duì)應(yīng)返回nil
程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)msetkey1 value1 ... keyN valueN 一次設(shè)置多個(gè)key的值,成功返回1表示所有的值都設(shè)置了,失敗返回0表示沒(méi)有任何值被設(shè)置msetnxkey1 value1 ... keyN valueN 同上,但是不會(huì)覆蓋已經(jīng)存在的keyincrkey 對(duì)key的值做加加操作,并返回新的值。注意incr一個(gè)不是int的value會(huì)返回錯(cuò)誤,incr一個(gè)不存在的key,則設(shè)置key為1decrkey 同上,但是做的是減減操作,decr一個(gè)不存在key,則設(shè)置key為-1incrbykey integer 同incr,加指定值 ,key不存在時(shí)候會(huì)設(shè)置key,并認(rèn)為原來(lái)的value是 0decrbykey integer 同decr,減指定值。decrby完全是為了可讀性,我們完全可以通過(guò)incrby一個(gè)負(fù)值來(lái)實(shí)現(xiàn)同樣效果,反之一樣。
appendkey value 給指定key的字符串值追加value,返回新字符串值的長(zhǎng)度。下面給個(gè)例子
程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)substrkey start end 返回截取過(guò)的key的字符串值,注意并不修改key的值。下標(biāo)是從0開(kāi)始的。
List類型:
redis的list類型其實(shí)就是一個(gè)每個(gè)子元素都是string類型的雙向鏈表。我們可以通過(guò)push,pop操作從鏈表的頭部或者尾部添加刪除元素。這使得list既可以用作棧,也可以用作隊(duì)列。
list的pop操作還有阻塞版本的。當(dāng)我們[lr]pop一個(gè)list對(duì)象是,如果list是空,或者不存在,會(huì)立即返回nil。但是阻塞版本的b[lr]pop可以則可以阻塞,當(dāng)然可以加超時(shí)時(shí)間,超時(shí)后也會(huì)返回nil。為什么要阻塞版本的pop呢,主要是為了避免輪詢。舉個(gè)簡(jiǎn)單的例子如果我們用list來(lái)實(shí)現(xiàn)一個(gè)工作隊(duì)列。執(zhí)行任務(wù)的thread可以調(diào)用阻塞版本的pop去獲取任務(wù)這樣就可以避免輪詢?nèi)z查是否有任務(wù)存在。當(dāng)任務(wù)來(lái)時(shí)候工作線程可以立即返回,也可以避免輪詢帶來(lái)的延遲。
List的相關(guān)命令:
lpushkey string 在key對(duì)應(yīng)list的頭部添加字符串元素,返回1表示成功,0表示key存在且不是list類型rpushkey string 同上,在尾部添加llenkey 返回key對(duì)應(yīng)list的長(zhǎng)度,key不存在返回0,如果key對(duì)應(yīng)類型不是list返回錯(cuò)誤lrangekey start end 返回指定區(qū)間內(nèi)的元素,下標(biāo)從0開(kāi)始,負(fù)值表示從后面計(jì)算,-1表示倒數(shù)第一個(gè)元素 ,key不存在返回空列表ltrimkey start end 截取list,保留指定區(qū)間內(nèi)元素,成功返回1,key不存在返回錯(cuò)誤lsetkey index value 設(shè)置list中指定下標(biāo)的元素值,成功返回1,key或者下標(biāo)不存在返回錯(cuò)誤lremkey count value 從key對(duì)應(yīng)list中刪除count個(gè)和value相同的元素。count為0時(shí)候刪除全部lpopkey 從list的頭部刪除元素,并返回刪除元素。如果key對(duì)應(yīng)list不存在或者是空返回nil,如果key對(duì)應(yīng)值不是list返回錯(cuò)誤
rpop同上,但是從尾部刪除blpopkey1...keyN timeout 從左到右掃描返回對(duì)第一個(gè)非空l(shuí)ist進(jìn)行l(wèi)pop操作并返回,比如blpop list1 list2 list3 0 ,如果list不存在,list2,list3都是非空則對(duì)list2做lpop并返回從list2中刪除的元素。如果所有的list都是空或不存在,則會(huì)阻塞timeout秒,timeout為0表示一直阻塞。當(dāng)阻塞時(shí),如果有client對(duì)key1...keyN中的任意key進(jìn)行push操作,則第一在這個(gè)key上被阻塞的client會(huì)立即返回。如果超時(shí)發(fā)生,則返回nil。brpop同blpop,一個(gè)是從頭部刪除一個(gè)是從尾部刪除rpoplpushsrckey destkey 從srckey對(duì)應(yīng)list的尾部移除元素并添加到destkey對(duì)應(yīng)list的頭部,最后返回被移除的元素值,整個(gè)操作是原子的.如果srckey是空或者不存在返回nil
Set類型:
redis的set是string類型的無(wú)序集合。set元素最大可以包含(2的32次方-1)個(gè)元素。set的是通過(guò)hash table實(shí)現(xiàn)的,hash table會(huì)隨著添加或者刪除自動(dòng)的調(diào)整大小關(guān)于set集合類型除了基本的添加刪除操作,其他有用的操作還包含集合的取并集(union),交集(interp),差集(difference)。通過(guò)這些操作可以很容易的實(shí)現(xiàn)sns中的好友推薦和blog的tag功能。
Set的相關(guān)命令:
saddkey member 添加一個(gè)string元素到,key對(duì)應(yīng)的set集合中,成功返回1,如果元素以及在集合中返回0,key對(duì)應(yīng)的set不存在返回錯(cuò)誤sremkey member 從key對(duì)應(yīng)set中移除給定元素,成功返回1,如果member在集合中不存在或者key不存在返回0,如果key對(duì)應(yīng)的不是set類型的值返回錯(cuò)誤spopkey 刪除并返回key對(duì)應(yīng)set中隨機(jī)的一個(gè)元素,如果set是空或者key不存在返回nilsrandmemberkey 同spop,隨機(jī)取set中的一個(gè)元素,但是不刪除元素smovesrckey dstkey member 從srckey對(duì)應(yīng)set中移除member并添加到dstkey對(duì)應(yīng)set中,整個(gè)操作是原子的。成功返回1,如果member在srckey中不存在返回0,如果key不是set類型返回錯(cuò)誤scardkey 返回set的元素個(gè)數(shù),如果set是空或者key不存在返回0sismemberkey member 判斷member是否在set中,存在返回1,0表示不存在或者key不存在sinterkey1 key2...keyN 返回所有給定key的交集sinterstoredstkey key1...keyN 同sinter,但是會(huì)同時(shí)將交集存到dstkey下
sunionkey1 key2...keyN 返回所有給定key的并集sunionstoredstkey key1...keyN 同sunion,并同時(shí)保存并集到dstkey下sdiffkey1 key2...keyN 返回所有給定key的差集sdiffstoredstkey key1...keyN 同sdiff,并同時(shí)保存差集到dstkey下smemberskey 返回key對(duì)應(yīng)set的所有元素,結(jié)果是無(wú)序的
Sorted Set類型:
和set一樣sorted set也是string類型元素的集合,不同的是每個(gè)元素都會(huì)關(guān)聯(lián)一個(gè)double類型的score。sorted set的實(shí)現(xiàn)是skip list和hash table的混合體。當(dāng)元素被添加到集合中時(shí),一個(gè)元素到score的映射被添加到hash table中,另一個(gè)score到元素的映射被添加到skip list并按照score排序,所以就可以有序的獲取集合中的元素。
Sorted Set的相關(guān)命令:
zaddkey score member 添加元素到集合,元素在集合中存在則更新對(duì)應(yīng)score
zremkey member 刪除指定元素,1表示成功,如果元素不存在返回0zincrbykey incr member 增加對(duì)應(yīng)member的score值,然后移動(dòng)元素并保持skip list有序。返回更新后的score值zrankkey member 返回指定元素在集合中的排名(下標(biāo),非score),集合中元素是按score從小到大排序的zrevrankkey member 同上,但是集合中元素是按score從大到小排序zrangekey start end 類似lrange操作從集合中取指定區(qū)間的元素。返回的是有序結(jié)果zrevrangekey start end 同上,返回結(jié)果是按score逆序的zrangebyscorekey min max 返回集合中score在給定區(qū)間的元素zcountkey min max 返回集合中score在給定區(qū)間的數(shù)量zcardkey 返回集合中元素個(gè)數(shù)zscorekey element 返回給定元素對(duì)應(yīng)的scorezremrangebyrankkey min max 刪除集合中排名在給定區(qū)間的元素zremrangebyscorekey min max 刪除集合中score在給定區(qū)間的元素
Hash類型:
redis hash是一個(gè)string類型的field和value的映射表。hash特別適合用于存儲(chǔ)對(duì)象。相較于將對(duì)象的每個(gè)字段存成單個(gè)string類型。將一個(gè)對(duì)象存儲(chǔ)在hash類型中會(huì)占用更少的內(nèi)存,并且可以更方便的存取整個(gè)對(duì)象。
Hash的相關(guān)命令:
hsetkey field value 設(shè)置hash field為指定值,如果key不存在,則先創(chuàng)建
hgetkey field 獲取指定的hash fieldhmgetkey filed1....fieldN 獲取全部指定的hash filedhmsetkey filed1 value1 ... filedN valueN 同時(shí)設(shè)置hash的多個(gè)fieldhincrbykey field integer
Redis功能:
持久化:
redis是一個(gè)支持持久化的內(nèi)存數(shù)據(jù)庫(kù),也就是說(shuō)redis需要經(jīng)常將內(nèi)存中的數(shù)據(jù)同步到磁盤(pán)來(lái)保證持久化,這是相對(duì)memcache來(lái)說(shuō)的一個(gè)大的優(yōu)勢(shì)。redis支持兩種持久化方式,一種是 Snapshotting(快照)也是默認(rèn)方式,另一種是Append-only file(縮寫(xiě)aof)的方式。Snapshotting快照是默認(rèn)的持久化方式。這種方式將內(nèi)存中數(shù)據(jù)以快照的方式寫(xiě)入到二進(jìn)制文件中,默認(rèn)的文件名為dump.rdb??梢耘渲米詣?dòng)做快照持久 化的方式。我們可以配置redis在n秒內(nèi)如果超過(guò)m個(gè)key被修改就自動(dòng)做快照,下面是默認(rèn)的快照保存配置save 900 1 #900秒內(nèi)如果超過(guò)1個(gè)key被修改,則發(fā)起快照保存save 300 10 #300秒內(nèi)容如超過(guò)10個(gè)key被修改,則發(fā)起快照保存
Append-only file
aof 比快照方式有更好的持久化性,是由于在使用aof持久化方式時(shí),redis會(huì)將每一個(gè)收到的寫(xiě)命令都通過(guò)write函數(shù)追加到文件中(默認(rèn)是 appendonly.aof)。當(dāng)redis重啟時(shí)會(huì)通過(guò)重新執(zhí)行文件中保存的寫(xiě)命令來(lái)在內(nèi)存中重建整個(gè)數(shù)據(jù)庫(kù)的內(nèi)容。當(dāng)然由于os會(huì)在內(nèi)核中緩存 write做的修改,所以可能不是立即寫(xiě)到磁盤(pán)上。這樣aof方式的持久化也還是有可能會(huì)丟失部分修改。不過(guò)我們可以通過(guò)配置文件告訴redis我們想要 通過(guò)fsync函數(shù)強(qiáng)制os寫(xiě)入到磁盤(pán)的時(shí)機(jī)。
有三種方式如下(默認(rèn)是:每秒fsync一次)
appendonly yes //啟用aof持久化方式
appendfsync always //每次收到寫(xiě)命令就立即強(qiáng)制寫(xiě)入磁盤(pán),最慢的,但是保證完全的持久化,不推薦使用
appendfsync everysec //每秒鐘強(qiáng)制寫(xiě)入磁盤(pán)一次,在性能和持久化方面做了很好的折中,推薦
appendfsync no //完全依賴os,性能最好,持久化沒(méi)保證
主從復(fù)制:
主從復(fù)制允許多個(gè)slave server擁有和master server相同的數(shù)據(jù)庫(kù)副本。下面是關(guān)于redis主從復(fù)制的一些特點(diǎn)1.master可以有多個(gè)slave2.除了多個(gè)slave連到相同的master外,slave也可以連接其他slave形成圖狀結(jié)構(gòu)3.主從復(fù)制不會(huì)阻塞master。也就是說(shuō)當(dāng)一個(gè)或多個(gè)slave與master進(jìn)行初次同步數(shù)據(jù)時(shí),master可以繼續(xù)處理client發(fā)來(lái)的請(qǐng)求。相反slave在初次同步數(shù)據(jù)時(shí)則會(huì)阻塞,不能處理client的請(qǐng)求。4.主從復(fù)制可以用來(lái)提高系統(tǒng)的可伸縮性(我們可以用多個(gè)slave 專門(mén)用于client的讀請(qǐng)求,比如sort操作可以使用slave來(lái)處理),也可以用來(lái)做簡(jiǎn)單的數(shù)據(jù)冗余。5.可以在master禁用數(shù)據(jù)持久化,只需要注釋掉master 配置文件中的所有save配置,然后只在slave上配置數(shù)據(jù)持久化。
程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)事務(wù):
redis對(duì)事務(wù)的支持目前還比較簡(jiǎn)單。redis只能保證一個(gè)client發(fā)起的事務(wù)中的命令可以連續(xù)的執(zhí)行,而中間不會(huì)插入其他client的命令。Multi 事物開(kāi)始Exec 執(zhí)行事務(wù)Discard 放棄事物Watch 監(jiān)聽(tīng)keyUnwatch 放棄所有key的監(jiān)聽(tīng)watch 命令會(huì)監(jiān)視給定的key,當(dāng)exec時(shí)候如果監(jiān)視的key從調(diào)用watch后發(fā)生過(guò)變化,則整個(gè)事務(wù)會(huì)失敗。注意watch的key是對(duì)整個(gè)連接有效的,和事務(wù)一樣,如果連接斷開(kāi),監(jiān)視和事務(wù)都會(huì)被自動(dòng)清除。
事務(wù)演示:
程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)發(fā)布訂閱:
發(fā)布訂閱(pub/sub)是一種消息通信模式。訂閱者可以通過(guò)subscribe和psubscribe命令向redis server訂閱自己感興趣的消息類型,redis將消息類型稱為通道(channel)。當(dāng)發(fā)布者通過(guò)publish命令向redis server發(fā)送特定類型的消息時(shí)。訂閱該消息類型的全部client都會(huì)收到此消息。這里消息的傳遞是多對(duì)多的。一個(gè)client可以訂閱多個(gè) channel,也可以向多個(gè)channel發(fā)送消息。SubscribeUnsubscribePsubscribePunsubscribePublish
發(fā)布訂閱演示:
客戶端一:
程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)客戶端二:
程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)客戶端三:
程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)管道:
redis是一個(gè)cs模式的tcp server,使用和http類似的請(qǐng)求響應(yīng)協(xié)議。一個(gè)client可以通過(guò)一個(gè)socket連接發(fā)起多個(gè)請(qǐng)求命令。每個(gè)請(qǐng)求命令發(fā)出后client通常 會(huì)阻塞并等待redis服務(wù)處理,redis處理完后請(qǐng)求命令后會(huì)將結(jié)果通過(guò)響應(yīng)報(bào)文返回給client?;镜耐ㄐ胚^(guò)程如下Client: INCR
XServer: 1
Client: INCR
XServer: 2
Client: INCR
XServer: 3
Client: INCR
XServer: 4基本上四個(gè)命令需要8個(gè)tcp報(bào)文才能完成。由于通信會(huì)有網(wǎng)絡(luò)延遲,假如從client和server之間的包傳輸時(shí)間需要0.125秒。那么上面的四個(gè)命令8個(gè)報(bào)文至少會(huì)需要1秒才能完成。
利用pipeline的方式從client打包多條命令一起發(fā)出,不需要等待單條命令的響應(yīng)返回,而redis服務(wù)端會(huì)處理完多條命令后會(huì)將多條命令的處理結(jié)果打包到一起返回給客戶端。通信過(guò)程如下
Client: INCR
XClient: INCR
XClient: INCR
XClient: INCR
XServer: 1
Server: 2
Server: 3
Server: 4
虛擬內(nèi)存:
redis沒(méi)有使用os提供的虛擬內(nèi)存機(jī)制而是自己實(shí)現(xiàn)了自己的虛擬內(nèi)存機(jī)制 ,但是思路和目的都是相同的。就是暫時(shí)把不經(jīng)常訪問(wèn)的數(shù)據(jù)從內(nèi)存交換到磁盤(pán)中,從而騰出內(nèi)存空間用于其他需要訪問(wèn)的數(shù)據(jù)。尤其是對(duì)于redis這樣的內(nèi)存數(shù)據(jù)庫(kù),內(nèi)存總是不夠用的。除了可以將數(shù)據(jù)分割到多個(gè)redis server外。另外的能夠提高數(shù)據(jù)庫(kù)容量的辦法就是使用vm把那些不經(jīng)常訪問(wèn)的數(shù)據(jù)交換的磁盤(pán)上。如果我們的存儲(chǔ)的數(shù)據(jù)總是有少部分?jǐn)?shù)據(jù)被經(jīng)常訪問(wèn),大 部分?jǐn)?shù)據(jù)很少被訪問(wèn),對(duì)于網(wǎng)站來(lái)說(shuō)確實(shí)總是只有少量用戶經(jīng)?;钴S。當(dāng)少量數(shù)據(jù)被經(jīng)常訪問(wèn)時(shí),使用vm不但能提高單臺(tái)redis server數(shù)據(jù)庫(kù)的容量,而且也不會(huì)對(duì)性能造成太多影響。vm-enabled yes #開(kāi)啟vm功能vm-swap-file /tmp/redis.swap #交換的value保存的文件路徑/tmp/redis.swapvm-max-memory 1000000 #最大內(nèi)存上限,超過(guò)后開(kāi)始交換value到磁盤(pán)文件vm-page-size 32 #每個(gè)頁(yè)面的大小32個(gè)字節(jié)vm-pages 134217728 #最多使用在文件中使用多少頁(yè)面vm-max-threads 4 #用于執(zhí)行value對(duì)象換入換出的工作線程數(shù)量,0表示不使用工作線程
Redis性能:
程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)Redis部署:
程序員,想要徹底弄懂Redis,這15點(diǎn)你一定要明白~(純干貨)Redis應(yīng)用場(chǎng)景:
1.取最新N個(gè)數(shù)據(jù)的操作比如典型的取你網(wǎng)站的最新文章,通過(guò)下面方式,我們可以將最新的5000條評(píng)論的ID放在Redis的List集合中,并將超出集合部分從數(shù)據(jù)庫(kù)獲取使用LPUSH latest.comments命令,向list集合中插入數(shù)據(jù) 插入完成后再用LTRIM latest.comments 0 5000命令使其永遠(yuǎn)只保存最近5000個(gè)ID 然后我們?cè)诳蛻舳双@取某一頁(yè)評(píng)論時(shí)可以用下面的邏輯(偽代碼) FUNCTION get_latest_comments(start,num_items):id_list = redis.lrange("latest.comments",start,start+num_items-1)IF id_list.length < num_items id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...") END RETURN id_list END 如果你還有不同的篩選維度,比如某個(gè)分類的最新N條,那么你可以再建一個(gè)按此分類的List,只存ID的話,Redis是非常高效的。
2.排行榜應(yīng)用,取TOP N操作
這個(gè)需求與上面需求的不同之處在于,前面操作以時(shí)間為權(quán)重,這個(gè)是以某個(gè)條件為權(quán)重,比如按頂?shù)拇螖?shù)排序,這時(shí)候就需要我們的sorted set出馬了,將你要排序的值設(shè)置成sorted set的score,將具體的數(shù)據(jù)設(shè)置成相應(yīng)的value,每次只需要執(zhí)行一條ZADD命令即可。3.需要精準(zhǔn)設(shè)定過(guò)期時(shí)間的應(yīng)用比如你可以把上面說(shuō)到的sorted set的score值設(shè)置成過(guò)期時(shí)間的時(shí)間戳,那么就可以簡(jiǎn)單地通過(guò)過(guò)期時(shí)間排序,定時(shí)清除過(guò)期數(shù)據(jù)了,不僅是清除Redis中的過(guò)期數(shù)據(jù),你完全可以把Redis里這個(gè)過(guò)期時(shí)間當(dāng)成是對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的索引,用Redis來(lái)找出哪些數(shù)據(jù)需要過(guò)期刪除,然后再精準(zhǔn)地從數(shù)據(jù)庫(kù)中刪除相應(yīng)的記錄。4.計(jì)數(shù)器應(yīng)用Redis的命令都是原子性的,你可以輕松地利用INCR,DECR命令來(lái)構(gòu)建計(jì)數(shù)器系統(tǒng)。
5.Uniq操作,獲取某段時(shí)間所有數(shù)據(jù)排重值這個(gè)使用Redis的set數(shù)據(jù)結(jié)構(gòu)最合適了,只需要不斷地將數(shù)據(jù)往set中扔就行了,set意為集合,所以會(huì)自動(dòng)排重。6.實(shí)時(shí)系統(tǒng),反垃圾系統(tǒng)通過(guò)上面說(shuō)到的set功能,你可以知道一個(gè)終端用戶是否進(jìn)行了某個(gè)操作,可以找到其操作的集合并進(jìn)行分析統(tǒng)計(jì)對(duì)比等。沒(méi)有做不到,只有想不到。7.Pub/Sub構(gòu)建實(shí)時(shí)消息系統(tǒng)Redis的Pub/Sub系統(tǒng)可以構(gòu)建實(shí)時(shí)的消息系統(tǒng),比如很多用Pub/Sub構(gòu)建的實(shí)時(shí)聊天系統(tǒng)的例子。8.構(gòu)建隊(duì)列系統(tǒng)使用list可以構(gòu)建隊(duì)列系統(tǒng),使用sorted set甚至可以構(gòu)建有優(yōu)先級(jí)的隊(duì)列系統(tǒng)。9.緩存這個(gè)不必說(shuō)了,性能優(yōu)于Memcached(在某些方面,并不是全面優(yōu)于),數(shù)據(jù)結(jié)構(gòu)更多樣化。
Redis總結(jié):
Redis使用最佳方式是全部數(shù)據(jù)in-memory。Redis更多場(chǎng)景是作為Memcached的替代者來(lái)使用。當(dāng)需要除key/value之外的更多數(shù)據(jù)類型支持時(shí),使用Redis更合適。當(dāng)存儲(chǔ)的數(shù)據(jù)不能被剔除時(shí),使用Redis更合適。(持久化)
對(duì)數(shù)據(jù)高并發(fā)讀寫(xiě)對(duì)海量數(shù)據(jù)的高效率存儲(chǔ)和訪問(wèn) 對(duì)數(shù)據(jù)的高可擴(kuò)展性和高可用性(分布式)
有任何什么問(wèn)題或者不同想法,歡迎留言溝通
★特別聲明:本文素材來(lái)源于網(wǎng)絡(luò),僅作為分享學(xué)習(xí)之用,如有侵權(quán),請(qǐng)聯(lián)系刪除!
”總結(jié)
以上是生活随笔為你收集整理的程序员,想要彻底弄懂Redis,这15点你一定要明白~(纯干货)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 后端程序员必备:书写高质量SQL的30条
- 下一篇: 一文介绍 Mysql 索引模型 B+ 树