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