不知道現(xiàn)在做web功能測(cè)試,需要了解這么多東西,Redis一直都是我比較頭疼的一塊,作為一名出色的功能測(cè)試工程師,真的不是隨便點(diǎn)點(diǎn)就可以,需要從多方面去了解一個(gè)項(xiàng)目,一個(gè)系統(tǒng)的原理,配置,才可以更好,更完善的做好測(cè)試,今天給大家分享一篇關(guān)于Redis的作用和使用場(chǎng)景的文章。
1、Redis
一、為什么使用
解決應(yīng)用服務(wù)器的cpu和內(nèi)存壓力
減少io的讀操作,減輕io的壓力
關(guān)系型數(shù)據(jù)庫(kù)的擴(kuò)展性不強(qiáng),難以改變表結(jié)構(gòu)
二、優(yōu)點(diǎn):
nosql數(shù)據(jù)庫(kù)沒(méi)有關(guān)聯(lián)關(guān)系,數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)單,拓展表比較容易
nosql讀取速度快,對(duì)較大數(shù)據(jù)處理快
三、適用場(chǎng)景:
數(shù)據(jù)高并發(fā)的讀寫(xiě)
海量數(shù)據(jù)的讀寫(xiě)
對(duì)擴(kuò)展性要求高的數(shù)據(jù)
四、不適場(chǎng)景:
需要事務(wù)支持(非關(guān)系型數(shù)據(jù)庫(kù))
基于sql結(jié)構(gòu)化查詢儲(chǔ)存,關(guān)系復(fù)雜
五、Redis結(jié)構(gòu):
Redis是一個(gè)開(kāi)源的key—value型數(shù)據(jù)庫(kù),支持string、list、set、zset和hash類型數(shù)據(jù)。對(duì)這些數(shù)據(jù)的操作都是原子性的,redus為了保證效率會(huì)定期持久化數(shù)據(jù)。
六、使用場(chǎng)景:
配合關(guān)系型數(shù)據(jù)庫(kù)做高速緩存
緩存高頻次訪問(wèn)的數(shù)據(jù),降低數(shù)據(jù)庫(kù)io
分布式架構(gòu),做session共享
可以持久化特定數(shù)據(jù)。
利用zset類型可以存儲(chǔ)排行榜
利用list的自然時(shí)間排序存儲(chǔ)最新n個(gè)數(shù)據(jù)
七、Linux下redis:
redis目錄:usr/local/bin
linux下redis常用命令:
redis-benchmark:性能測(cè)試工具
redis-server:?jiǎn)?dòng)redis服務(wù)器
redis-cli:?jiǎn)?dòng)redis客戶端,操作入口
八、Redis基礎(chǔ)知識(shí)
端口:6379
默認(rèn)16個(gè)數(shù)據(jù)庫(kù),下標(biāo)從0開(kāi)始
單線程:redis是單線程+io多路復(fù)用:檢查文件描述的就緒狀態(tài)
Memchached:多線程+鎖
redis數(shù)據(jù)類型:String set list hash zset
2、redis 實(shí)際應(yīng)用中的緩存作用
有人說(shuō)互聯(lián)網(wǎng)用戶是用腳投票的,這句話其實(shí)也從側(cè)面說(shuō)明了,用戶體驗(yàn)是多么的重要;這就要求在軟件架構(gòu)設(shè)計(jì)時(shí),不但要注重可靠性、安全性、可擴(kuò)展性以及可維護(hù)性等等的一些指標(biāo),更要注重用戶的體驗(yàn),用戶體驗(yàn)分很多方面,但是有一點(diǎn)非常重要就是對(duì)用戶操作的響應(yīng)一定要快;怎樣提高用戶訪問(wèn)的響應(yīng)速度,這就是擺在架構(gòu)設(shè)計(jì)中必須要解決的問(wèn)題;說(shuō)道提高服務(wù)的響應(yīng)速度就不得不說(shuō)緩存了;
從系統(tǒng)的層面說(shuō),CPU的速度遠(yuǎn)遠(yuǎn)高于磁盤(pán)IO的速度;所以要想提高響應(yīng)速度,必須減少磁盤(pán)IO的操作,但是有很多信息又是存在數(shù)據(jù)庫(kù)當(dāng)中的,每次查詢數(shù)據(jù)庫(kù)就是一次IO操作;比如查詢用戶信息的例子,通常如下圖:

請(qǐng)求響應(yīng)時(shí)間等于網(wǎng)絡(luò)響應(yīng)時(shí)間和服務(wù)器響應(yīng)時(shí)間;網(wǎng)絡(luò)我們控制不了,服務(wù)器響應(yīng)時(shí)間包括CPU計(jì)算時(shí)間和磁盤(pán)IO時(shí)間,其中CPU計(jì)算時(shí)間這個(gè)有硬件資源決定的,我們盡量減少算法的復(fù)雜度來(lái)減少它,磁盤(pán)IO時(shí)間,這個(gè)時(shí)間是非常慢的,應(yīng)該盡量減少;
當(dāng)客戶端調(diào)用getUser接口的查詢用戶信息的時(shí)候,執(zhí)行順序1、2、3、4;由于用戶信息存放在DB中,所以2、3就有一次磁盤(pán)IO;這個(gè)看似非常簡(jiǎn)單業(yè)務(wù)邏輯,但是當(dāng)你做架構(gòu)設(shè)計(jì)的時(shí)候往往要考慮最壞的場(chǎng)景,或者當(dāng)成千上萬(wàn)的用戶頻繁的調(diào)用這個(gè)接口應(yīng)該怎么處理?如果按照上圖這樣的架構(gòu)處理,這個(gè)看似簡(jiǎn)單業(yè)務(wù)的接口會(huì)使整個(gè)系統(tǒng)變慢,這樣用戶的請(qǐng)求就會(huì)長(zhǎng)時(shí)間得不到響應(yīng);這樣的問(wèn)題怎么解決那,這時(shí)候就該緩存登場(chǎng)了;
談到緩存有幾種形式,其中最簡(jiǎn)單的是在每個(gè)進(jìn)程中開(kāi)辟一塊內(nèi)存,存放緩存的信息,每次先從內(nèi)存查… … ?但是在一個(gè)分布式或者集群的環(huán)境中,getUser的接口可能會(huì)部署多套,每個(gè)進(jìn)程的的內(nèi)存是不能共享、相互獨(dú)立的,這就悲劇了;還有一種使用一個(gè)第三方的緩存也叫公共緩存(比如redis、memcache等);不論部署多少個(gè)包含getUser接口的服務(wù),都去訪問(wèn)同一套緩存,那結(jié)果就不一樣了,看一下下面這幅圖:

當(dāng)用客戶端調(diào)用getUser接口查詢用戶信息的時(shí)候,getUser接口直接去redis中查詢,如果redis中有該用戶信息,直接返回,避免查詢DB,從而避免了磁盤(pán)IO操作;如果redis中沒(méi)有該用戶信息,則從DB查詢,并且把該用戶信息存放到redis中;這樣在服務(wù)接口(getUser)和DB中間,增加了一個(gè)緩存層;看似邏輯增加了,其實(shí)當(dāng)面對(duì)高并發(fā)的時(shí)候,比如上邊提到的頻繁查詢用戶信息的情況,只有第一次查詢有磁盤(pán)IO操作,以后只要redis中存在就沒(méi)必要再查詢數(shù)據(jù)庫(kù)了;由于沒(méi)有了磁盤(pán)IO操作,并且redis所有數(shù)據(jù)都在內(nèi)存操作,所以速度回大大提升;
我們上面用到的緩存是redis,其實(shí)常用的還有memcache等,它們都提供了集群模式,并且都是直接內(nèi)存操作,所以速度特別快,也是目前業(yè)內(nèi)使用的比較熱門(mén)的技術(shù);redis相對(duì)于memcache提供了更豐富的數(shù)據(jù)類型,根據(jù)不同的業(yè)務(wù)場(chǎng)景可以選在不同的數(shù)據(jù)類型;redis本身也提供了主從模式、集群模式;也有第三方的比如codis提供了redis集群解決方案;這次咱們主要聊緩存在架構(gòu)設(shè)計(jì)中的作用,等有機(jī)會(huì)詳細(xì)介紹redis的使用;
總之一句話,要想提高系統(tǒng)的性能,盡量減少I(mǎi)O的操作,特別是磁盤(pán)IO的操作;使用緩存可以有效的避免這種情況;所以在架構(gòu)設(shè)計(jì)過(guò)程中,社交到查詢數(shù)據(jù)庫(kù)的時(shí)候,應(yīng)該考慮一下是不是考慮使用緩存技術(shù)來(lái)提高系統(tǒng)的性能,并且降低數(shù)據(jù)庫(kù)的負(fù)載。
3、Redis的7個(gè)應(yīng)用場(chǎng)景
一:緩存——熱數(shù)據(jù)
熱點(diǎn)數(shù)據(jù)(經(jīng)常會(huì)被查詢,但是不經(jīng)常被修改或者刪除的數(shù)據(jù)),首選是使用redis緩存,畢竟強(qiáng)大到冒泡的QPS和極強(qiáng)的穩(wěn)定性不是所有類似工具都有的,而且相比于memcached還提供了豐富的數(shù)據(jù)類型可以使用,另外,內(nèi)存中的數(shù)據(jù)也提供了AOF和RDB等持久化機(jī)制可以選擇,要冷、熱的還是忽冷忽熱的都可選。
結(jié)合具體應(yīng)用需要注意一下:很多人用spring的AOP來(lái)構(gòu)建redis緩存的自動(dòng)生產(chǎn)和清除,過(guò)程可能如下:
Select 數(shù)據(jù)庫(kù)前查詢r(jià)edis,有的話使用redis數(shù)據(jù),放棄select 數(shù)據(jù)庫(kù),沒(méi)有的話,select 數(shù)據(jù)庫(kù),然后將數(shù)據(jù)插入redis
update或者delete數(shù)據(jù)庫(kù)錢(qián),查詢r(jià)edis是否存在該數(shù)據(jù),存在的話先刪除redis中數(shù)據(jù),然后再u(mài)pdate或者delete數(shù)據(jù)庫(kù)中的數(shù)據(jù)
上面這種操作,如果并發(fā)量很小的情況下基本沒(méi)問(wèn)題,但是高并發(fā)的情況請(qǐng)注意下面場(chǎng)景:
為了update先刪掉了redis中的該數(shù)據(jù),這時(shí)候另一個(gè)線程執(zhí)行查詢,發(fā)現(xiàn)redis中沒(méi)有,瞬間執(zhí)行了查詢SQL,并且插入到redis中一條數(shù)據(jù),回到剛才那個(gè)update語(yǔ)句,這個(gè)悲催的線程壓根不知道剛才那個(gè)該死的select線程犯了一個(gè)彌天大錯(cuò)!于是這個(gè)redis中的錯(cuò)誤數(shù)據(jù)就永遠(yuǎn)的存在了下去,直到下一個(gè)update或者delete。
二:計(jì)數(shù)器
諸如統(tǒng)計(jì)點(diǎn)擊數(shù)等應(yīng)用。由于單線程,可以避免并發(fā)問(wèn)題,保證不會(huì)出錯(cuò),而且100%毫秒級(jí)性能!爽。
命令:INCRBY
當(dāng)然爽完了,別忘記持久化,畢竟是redis只是存了內(nèi)存!
三:隊(duì)列
相當(dāng)于消息系統(tǒng),ActiveMQ,RocketMQ等工具類似,但是個(gè)人覺(jué)得簡(jiǎn)單用一下還行,如果對(duì)于數(shù)據(jù)一致性要求高的話還是用RocketMQ等專業(yè)系統(tǒng)。
由于redis把數(shù)據(jù)添加到隊(duì)列是返回添加元素在隊(duì)列的第幾位,所以可以做判斷用戶是第幾個(gè)訪問(wèn)這種業(yè)務(wù)
隊(duì)列不僅可以把并發(fā)請(qǐng)求變成串行,并且還可以做隊(duì)列或者棧使用
四:位操作(大數(shù)據(jù)處理)
用于數(shù)據(jù)量上億的場(chǎng)景下,例如幾億用戶系統(tǒng)的簽到,去重登錄次數(shù)統(tǒng)計(jì),某用戶是否在線狀態(tài)等等。
想想一下騰訊10億用戶,要幾個(gè)毫秒內(nèi)查詢到某個(gè)用戶是否在線,你能怎么做?千萬(wàn)別說(shuō)給每個(gè)用戶建立一個(gè)key,然后挨個(gè)記(你可以算一下需要的內(nèi)存會(huì)很恐怖,而且這種類似的需求很多,騰訊光這個(gè)得多花多少錢(qián)。。)好吧。這里要用到位操作——使用setbit、getbit、bitcount命令。
原理是:
redis內(nèi)構(gòu)建一個(gè)足夠長(zhǎng)的數(shù)組,每個(gè)數(shù)組元素只能是0和1兩個(gè)值,然后這個(gè)數(shù)組的下標(biāo)index用來(lái)表示我們上面例子里面的用戶id(必須是數(shù)字哈),那么很顯然,這個(gè)幾億長(zhǎng)的大數(shù)組就能通過(guò)下標(biāo)和元素值(0和1)來(lái)構(gòu)建一個(gè)記憶系統(tǒng),上面我說(shuō)的幾個(gè)場(chǎng)景也就能夠?qū)崿F(xiàn)。用到的命令是:setbit、getbit、bitcount
五:分布式鎖與單線程機(jī)制
驗(yàn)證前端的重復(fù)請(qǐng)求(可以自由擴(kuò)展類似情況),可以通過(guò)redis進(jìn)行過(guò)濾:每次請(qǐng)求將request Ip、參數(shù)、接口等hash作為key存儲(chǔ)redis(冪等性請(qǐng)求),設(shè)置多長(zhǎng)時(shí)間有效期,然后下次請(qǐng)求過(guò)來(lái)的時(shí)候先在redis中檢索有沒(méi)有這個(gè)key,進(jìn)而驗(yàn)證是不是一定時(shí)間內(nèi)過(guò)來(lái)的重復(fù)提交
秒殺系統(tǒng),基于redis是單線程特征,防止出現(xiàn)數(shù)據(jù)庫(kù)“爆破”
全局增量ID生成,類似“秒殺”
六:最新列表
例如新聞列表頁(yè)面最新的新聞列表,如果總數(shù)量很大的情況下,盡量不要使用select a from A limit 10這種low貨,嘗試redis的 LPUSH命令構(gòu)建List,一個(gè)個(gè)順序都塞進(jìn)去就可以啦。不過(guò)萬(wàn)一內(nèi)存清掉了咋辦?也簡(jiǎn)單,查詢不到存儲(chǔ)key的話,用mysql查詢并且初始化一個(gè)List到redis中就好了。
七:排行榜
誰(shuí)得分高誰(shuí)排名往上。命令:ZADD(有續(xù)集,sorted set)
最近在研究股票,發(fā)現(xiàn)量化交易是個(gè)非常好的辦法,通過(guò)臆想出來(lái)規(guī)律,用程序?qū)v史數(shù)據(jù)進(jìn)行驗(yàn)證,來(lái)判斷這個(gè)臆想出來(lái)的規(guī)律是否有效,這玩意真牛!
注:本文由網(wǎng)絡(luò)多方文章總結(jié)而出,如有雷同純屬巧合