個(gè)人網(wǎng)站建設(shè)收費(fèi)標(biāo)準(zhǔn)營(yíng)銷策略有哪幾種
一、get和set命令
Redis中最核心的兩個(gè)命令
get 根據(jù)key來(lái)取value
set 把key和value存儲(chǔ)進(jìn)去
redis是按照鍵值對(duì)的方式存儲(chǔ)數(shù)據(jù)的。必須要先進(jìn)入到redis客戶端。
語(yǔ)法 set key value? : key和value都是字符串。
對(duì)于上述這里的key value 不需要加上引號(hào),就是表示字符串,加上引號(hào)也無(wú)傷大雅。redis中的命令不區(qū)分大小寫。
使用get得到key對(duì)應(yīng)的value值。
get命令直接輸入key就能得到value。如果當(dāng)前key不存在,返回nil,和null/NULL就是一個(gè)意思。
redis使用簡(jiǎn)單,學(xué)習(xí)成本很低。
二、全局命令
Redis全局命令
Redis是支持很多種數(shù)據(jù)結(jié)構(gòu)的,整體上來(lái)說(shuō),Redis是鍵值對(duì)結(jié)構(gòu),key固定都是字符串,value實(shí)際上會(huì)有多種類型。比如字符串,哈希表,列表,集合,有序集合等等。每種數(shù)據(jù)結(jié)構(gòu)都會(huì)對(duì)應(yīng)著不同的命令,而全局命令就是能夠搭配任意一個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)使用的命令。
1)keys命令 用來(lái)查詢當(dāng)前服務(wù)器上匹配的key
通過(guò)一些特殊符號(hào)來(lái)描述key的模樣,匹配上述模樣的key就能被查詢出來(lái)。?
語(yǔ)法:keys pattern?
pattern 包含特殊符號(hào)的字符串,有的地方翻譯成樣式或者模式。重點(diǎn)去認(rèn)識(shí)這個(gè)英文術(shù)語(yǔ)。存在的意義,是去描述另外的字符串長(zhǎng)啥樣。
pattern具體咋寫,支持哪些通配符呢
?匹配任意一個(gè)字符
*匹配0個(gè)任意多個(gè)字符
[ae] 只能匹配到ae,別的不行,相當(dāng)于給出固定選項(xiàng)了
[^e] 排除e,只有e匹配不了,其他的都能匹配。
[a - e] 匹配a - e這個(gè)范圍內(nèi)的字符,包含兩側(cè)邊界。
設(shè)置這樣的key,通過(guò)上述的匹配方法進(jìn)行查詢
上述的匹配規(guī)則不需要去背。要查詢文檔。
keys命令的時(shí)間復(fù)雜度是O(N)。所以在生產(chǎn)環(huán)境上,一般都會(huì)禁止使用keys命令,尤其是大殺器keys * 。查詢r(jià)edis中所有的key!生產(chǎn)環(huán)境上的key可能會(huì)非常多!而redis是一個(gè)單線程的服務(wù)器,執(zhí)行keys * 的時(shí)間非常長(zhǎng),就是redis服務(wù)器被阻塞了。無(wú)法給其他客戶端提供服務(wù)。這樣的后果可能是災(zāi)難性的。redis經(jīng)常會(huì)用于做緩存,擋在mysql前面。替mysql負(fù)重前行。萬(wàn)一redis被一個(gè)keys * 阻塞住了,此時(shí)其他的查詢r(jià)edis操作就超時(shí)了。此時(shí)這些請(qǐng)求就會(huì)直接查數(shù)據(jù)庫(kù)。突然一大波請(qǐng)求到來(lái),mysql措手不及,會(huì)把它給搞掛了。這個(gè)操作非常危險(xiǎn),容易把工作給搞丟。那你就得讓你的媳婦吃土或者喝西北風(fēng)了,很可能你的媳婦就跟別人跑了。(開個(gè)小玩笑)。
穿插一個(gè)概念,叫做生產(chǎn)環(huán)境(線上環(huán)境):
未來(lái)的工作中會(huì)涉及到幾個(gè)環(huán)境:
1、辦公環(huán)境(入職之后,公司給你發(fā)個(gè)電腦)
筆記本電腦/臺(tái)式機(jī)。
2、開發(fā)環(huán)境:有的時(shí)候,開發(fā)環(huán)境和辦公環(huán)境是一個(gè),有的時(shí)候,開發(fā)環(huán)境是單獨(dú)的服務(wù)器,做前端/客戶端,一般來(lái)說(shuō)開發(fā)環(huán)境就是辦公環(huán)境了。后端來(lái)說(shuō),很可能是單獨(dú)的服務(wù)器,有的后端程序,會(huì)比較復(fù)雜。
1)一次時(shí)間特別久。
2)有的程序,啟動(dòng)要消耗很多的cpu和內(nèi)存資源。辦公電腦難以支撐。
3)有的程序比較依賴linux,在windows環(huán)境搭不起來(lái)。
3、測(cè)試環(huán)境(測(cè)試工程師用的)
4、線上環(huán)境/生產(chǎn)環(huán)境
(辦公環(huán)境,開發(fā)環(huán)境,測(cè)試環(huán)境,統(tǒng)稱為線下環(huán)境,外界用戶無(wú)法訪問(wèn)到的)。線上環(huán)境則是外界用戶能夠訪問(wèn)到的。一旦生產(chǎn)環(huán)境出問(wèn)題,一定會(huì)對(duì)于用戶的使用產(chǎn)生影響!直接的影響到公司營(yíng)收。
未來(lái)咱們?nèi)ゲ僮骶€上環(huán)境的任何一個(gè)設(shè)備/程序都要懷著12分的謹(jǐn)慎。
2)exists命令
exists判定key是否存在
語(yǔ)法:
返回值:key存在的個(gè)數(shù)。鍵值對(duì)存儲(chǔ)的體系中(類似于哈希表)key得是唯一的呀。
這里的個(gè)數(shù)對(duì)于多個(gè)key來(lái)說(shuō)是非常有用的 。他的查詢復(fù)雜度為O(1),redis組織這些key就是按照哈希表的方式來(lái)組織的。
redis支持很多數(shù)據(jù)結(jié)構(gòu) =》指的是一個(gè)value可以是一些復(fù)雜的數(shù)據(jù)結(jié)構(gòu),redis自身的這些鍵值對(duì),是通過(guò)哈希表的方式來(lái)組織的。redis具體的某個(gè)值,又可以是一些數(shù)據(jù)結(jié)構(gòu)。
分開查詢和一起查詢會(huì)有什么區(qū)別嗎。
我們要知道,redis是一個(gè)客戶端,服務(wù)器結(jié)構(gòu)的程序??蛻舳撕头?wù)器之間通過(guò)網(wǎng)絡(luò)來(lái)進(jìn)行通信!我們所敲的命令都會(huì)構(gòu)建一個(gè)請(qǐng)求發(fā)送給服務(wù)器,服務(wù)器返回回復(fù)報(bào)文。要進(jìn)行網(wǎng)絡(luò)通信,它是相對(duì)于內(nèi)存來(lái)說(shuō),效率比較低,成本比較高。
進(jìn)行網(wǎng)絡(luò)通信的時(shí)候,發(fā)送方發(fā)送一個(gè)數(shù)據(jù),這個(gè)數(shù)據(jù)就要從應(yīng)用層,到物理層,層層封裝。勢(shì)必會(huì)導(dǎo)致傳輸速度慢。所以我們要盡量少發(fā)請(qǐng)求。能用一個(gè)命令不用兩個(gè)命令。
3)del(delete)刪除指定的key
語(yǔ)法,返回值:刪除掉的key的個(gè)數(shù)。
redis主要的應(yīng)用場(chǎng)景,就是作為緩存,此時(shí)redis里存的只是一個(gè)熱點(diǎn)數(shù)據(jù),全量數(shù)據(jù)是在mysql數(shù)據(jù)庫(kù)中。此時(shí)如果把redis中的key刪除了幾個(gè),一般來(lái)說(shuō),問(wèn)題不大。但是如果把所有的數(shù)據(jù)或者一大半數(shù)據(jù)一下都干沒(méi)了,這種影響會(huì)很大。相比之下,如果是mysql這樣的數(shù)據(jù),哪怕誤刪了一個(gè)數(shù)據(jù),都可能影響很大的。如果把redis作為數(shù)據(jù)庫(kù),此時(shí)誤刪數(shù)據(jù)的影響就大了。如果把redis作為消息隊(duì)列,這種情況誤刪數(shù)據(jù)就得按情況來(lái)具體分析了。所以我們不能亂刪數(shù)據(jù)。自己挖坑自己跳,得不償失。
4)expire命令
作用是給指定的key設(shè)置過(guò)期時(shí)間,key存活時(shí)間超出這個(gè)指定的值,就會(huì)被自動(dòng)刪除。設(shè)置的時(shí)間單位是秒?;趓edis實(shí)現(xiàn)分布式鎖,為了避免出現(xiàn)不能正確解鎖的情況,通常都會(huì)在加鎖的時(shí)候設(shè)置一下過(guò)期時(shí)間(所謂的使用redis作為分布式鎖,就是給redis里寫一個(gè)特殊的key value)。
語(yǔ)法:
pexpire key mseconds 毫秒級(jí)
返回值:1成功,0失敗
此處的設(shè)定的過(guò)期時(shí)間,必須是針對(duì)已經(jīng)存在的key設(shè)置,設(shè)置成功返回1,設(shè)置失敗返回0。時(shí)間復(fù)雜度也是O(1)。
過(guò)期后get不到value。
5)ttl命令
ttl time to live 存活時(shí)間。網(wǎng)絡(luò)原理IP協(xié)議報(bào)頭中,有一個(gè)字段TTL。IP中的TTL不是用時(shí)間衡量過(guò)期的,而是用次數(shù)。
ttl是一個(gè)時(shí)間。查看當(dāng)前key的過(guò)期時(shí)間還剩多少
pttl查詢毫秒級(jí)的key的過(guò)期時(shí)間。
時(shí)間復(fù)雜度也是O(1)。
redis的key的過(guò)期策略 【經(jīng)典面試題】
redis的key的過(guò)期策略是怎么實(shí)現(xiàn)的?
一個(gè)redis中可能同時(shí)存在很多很多key,這些key中可能有很大一部分都有過(guò)期時(shí)間,此時(shí),redis服務(wù)器咋知道哪些key已經(jīng)過(guò)期要被刪除,哪些key還沒(méi)過(guò)期?
如果直接遍歷所有的key,顯然是行不通的,效率非常低。
redis整體的策略是:
1、定期刪除:此處也需要結(jié)合定期刪除的操作,每次抽出一部分驗(yàn)證過(guò)期時(shí)間,保證這個(gè)抽取檢查的過(guò)程足夠快。對(duì)于定期刪除的時(shí)間,有明確的要求:因?yàn)閞edis是單線程的程序。主要的任務(wù)(處理每個(gè)命令的任務(wù),剛才掃描過(guò)期的key)如果掃描過(guò)期key消耗的時(shí)間太多了,就可能導(dǎo)致正常處理請(qǐng)求命令就被阻塞了,產(chǎn)生了類似key *這樣的效果。
2、惰性刪除:假設(shè)這個(gè)key已經(jīng)到過(guò)期時(shí)間了,但是暫時(shí)還沒(méi)刪它,key還存在,緊接著,后面有一次訪問(wèn),正好用到了這個(gè)key,于是這次訪問(wèn)就會(huì)讓redis服務(wù)器觸發(fā)刪除key的操作,同時(shí)在返回一個(gè)nil。
雖然有了上述兩種策略結(jié)合,整體的效果一般,仍然可能會(huì)有很多過(guò)期的key被殘留了,沒(méi)有及時(shí)刪除掉,redis為了對(duì)上述進(jìn)行補(bǔ)充,還提供了一系列的內(nèi)存淘汰機(jī)制。
1)redis中并沒(méi)有采取定時(shí)器的方式來(lái)實(shí)現(xiàn)過(guò)期key刪除
2)如果有多個(gè)key過(guò)期,也可以通過(guò)一個(gè)定時(shí)器來(lái)高效/節(jié)省cpu的前提下來(lái)處理多個(gè)key。
為啥redis沒(méi)有采取這種定時(shí)器的方式呢?
很難考證為啥,個(gè)人的猜測(cè):基于定時(shí)器實(shí)現(xiàn),勢(shì)必就要引入多線程了。redis早期版本就是奠定了單線程的基調(diào),引入多線程打破了作者的初衷。
定時(shí)器的實(shí)現(xiàn)原理:
定時(shí)器:在某個(gè)時(shí)間到達(dá)之后,執(zhí)行指定的任務(wù)
1、基于優(yōu)先級(jí)隊(duì)列/堆
正常的隊(duì)列是先進(jìn)先出。而優(yōu)先級(jí)隊(duì)列則是按照指定的優(yōu)先級(jí),先出。啥叫優(yōu)先級(jí)高?自定義的。在redis過(guò)期key的場(chǎng)景中,就可以通過(guò)“過(guò)期時(shí)間越早,就是優(yōu)先級(jí)越高”?,F(xiàn)在假定有很多key設(shè)置了過(guò)期時(shí)間,就可以把這些key加入到優(yōu)先級(jí)隊(duì)列中,指定優(yōu)先級(jí)規(guī)則是過(guò)期時(shí)間早的先出隊(duì)列。隊(duì)首元素就是最早要過(guò)期的key!此時(shí)定時(shí)器中只要分配分配一個(gè)線程,讓這個(gè)線程取檢查隊(duì)首元素,看是否過(guò)期即可!如果隊(duì)首元素沒(méi)有過(guò)期,后續(xù)元素一定沒(méi)過(guò)期。此時(shí)掃描線程不需要遍歷所有key只盯住這一個(gè)隊(duì)首元素即可!另外在掃描線程檢查隊(duì)首元素過(guò)期時(shí)間的時(shí)候,也不能檢查太頻繁。此時(shí)做法就是可以根據(jù)當(dāng)前時(shí)刻和隊(duì)首元素的過(guò)期時(shí)間設(shè)置一個(gè)等待。當(dāng)時(shí)間差不多到了,系統(tǒng)再喚醒這個(gè)線程。此時(shí)掃描線程,不需要高頻掃描隊(duì)首元素,把CPU的開銷也節(jié)省下來(lái)了。
萬(wàn)一在線程休眠的時(shí)候,來(lái)了一個(gè)新的任務(wù)是11:30要執(zhí)行??梢栽谛氯蝿?wù)添加的時(shí)候,喚醒一下剛才的線程,重新檢查一下隊(duì)首元素,再根據(jù)時(shí)間差距重新調(diào)整阻塞時(shí)間即可。
2、基于時(shí)間輪實(shí)現(xiàn)的定時(shí)器
把時(shí)間劃分成很多小段(劃分的粒度,看實(shí)際需求)。
每一個(gè)小段上都掛著一個(gè)鏈表,每個(gè)鏈表都代表一個(gè)要執(zhí)行的任務(wù),(相當(dāng)于一個(gè)函數(shù)指針,以及對(duì)應(yīng)的參數(shù)。有點(diǎn)像jiava中也可以通過(guò)對(duì)象來(lái)實(shí)現(xiàn)類似的效果)。?
假設(shè)需要添加一個(gè)key,這個(gè)key在300ms之后過(guò)期。添加到第三個(gè)格子,每個(gè)格子是100毫秒所以是第三個(gè)格子,此時(shí)這個(gè)指針,就會(huì)每隔固定的間隔每次走到一個(gè)格子,就會(huì)把這個(gè)格子上鏈表的任務(wù)嘗試執(zhí)行一下。對(duì)于時(shí)間輪來(lái)說(shuō),每個(gè)各自是多長(zhǎng)時(shí)間,一共多少個(gè)格子都是需要根據(jù)實(shí)際的場(chǎng)景,靈活調(diào)配的。
此處大家注意,Redis并沒(méi)有采取上述的方案。但是要了解這兩種方案,都是屬于高效的定時(shí)器的實(shí)現(xiàn)方式,很多場(chǎng)景可能都會(huì)用得到。
6)type命令
返回key對(duì)應(yīng)的value的類型。此處redis所有的key都是string,key對(duì)應(yīng)的value可能會(huì)存在多種類型。
stream是redis作為消息隊(duì)列的時(shí)候,使用這個(gè)類型的value。
在redis中上述類型操作方式差別很大,使用的命令,都是完全不同的。時(shí)間復(fù)雜度也是O(1)
小結(jié)
當(dāng)前已經(jīng)學(xué)習(xí)了redis中幾個(gè)基本的全局命令
set:設(shè)置一個(gè)kv值
get:通過(guò)key得到value
keys:用來(lái)查看匹配規(guī)則的key。
exists:用來(lái)判定指定key是否存在。
del:刪除指定的key
expire:給key設(shè)置過(guò)期時(shí)間
ttl:查詢key的過(guò)期時(shí)間
type:查詢key對(duì)應(yīng)的value的類型。
接下來(lái)就是圍繞每個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)介紹相關(guān)命令了。
當(dāng)前版本的redis支持10個(gè)數(shù)據(jù)類型。