redis是Redis是一個開源的使用ANSI C語言編寫、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型激捏、Key-Value數(shù)據(jù)庫,并提供多種語言的API凄吏,那我們?yōu)槭裁匆褂胷edis呢远舅?
目錄
- Redis為什么速度這么快?
- 談?wù)凴edis有哪些應(yīng)用場景?
- 一對多的關(guān)系表,使用Redis設(shè)計會用到哪些數(shù)據(jù)結(jié)構(gòu)類型?
- Redis的ZSet集合應(yīng)用場景有哪些?
- 如何使用Redis完成訂單列表場景?
- Redis同時打開AOP與RDB持久化操作后,請描述Redis在恢復(fù)數(shù)據(jù)時加載的順序?
接下來我們來一一解決這些問題
一、redis為什么那么快痕钢?
從redis的存儲機(jī)制:
- 內(nèi)存數(shù)據(jù)庫图柏,基于key-value的nosql數(shù)據(jù)庫,內(nèi)存操作反應(yīng)迅速
- 高效的數(shù)據(jù)類型: 五種值類型對應(yīng)著七種數(shù)據(jù)結(jié)構(gòu)任连,更加細(xì)粒度的內(nèi)存選型使得內(nèi)存利用率更高蚤吹,因勢利導(dǎo),充分發(fā)揮內(nèi)存操作的效率
從redis的運行機(jī)制:
redis為什么選擇單線程随抠?官方解釋是因為cpu不是redis的性能瓶頸裁着,而內(nèi)存和網(wǎng)絡(luò)帶寬才是。所以順理成章就應(yīng)該設(shè)計成單線程的拱她,但是事實上我覺得原因很簡單二驰,因為單線程確實也快,那么單線程更簡單為什么不用呢秉沼?另外桶雀,這個快是沒法定義的,所以大可能以后還會在因為某些場景的原因引入多線程
貼士:使用ps -T -p PID可以查看進(jìn)程底下的線程氧猬,在4.0版本以后引入了多線程機(jī)制
- redis是單線程的數(shù)據(jù)庫背犯,數(shù)據(jù)庫訪問對應(yīng)io管理和io處理在一個線程中串行完成,避免了線程或者進(jìn)程切換的開銷盅抚,以及數(shù)據(jù)同步帶來的編程復(fù)雜性和效率損失漠魏;
- 單線程實現(xiàn)的機(jī)制是基于最高效的epoll(不同環(huán)境做編譯時適配)多路復(fù)用機(jī)制,該機(jī)制本身效率級高妄均;
- redis的底層模型不太一樣(主要是通信機(jī)制)
- 當(dāng)然redis在面對高并發(fā)場景下柱锹,也提供了分布式集群(基于主從復(fù)制),哨兵等高可用模型
注意:因為是單一線程丰包,所以同一時刻只有一個操作在進(jìn)行禁熏,所以,耗時的命令會導(dǎo)致并發(fā)的下降邑彪,不只是讀并發(fā)瞧毙,寫并發(fā)也會下降。而單一線程也只能用到一個CPU核心,所以可以在同一個多核的服務(wù)器中宙彪,可以啟動多個實例矩动,組成master-master或者master-slave的形式,耗時的讀命令可以完全在slave進(jìn)行释漆。
2. redis被用于哪些場景
補(bǔ)充:redis是一種nosql數(shù)據(jù)庫適合可擴(kuò)展性強(qiáng)的數(shù)據(jù)存儲悲没,對較大數(shù)據(jù)處理比較快,分布式方面的應(yīng)用也比較突出男图;但是對于結(jié)構(gòu)化查詢不太適合示姿,雖然支持事務(wù)操作,但是單線程執(zhí)行效率比較低逊笆。
3. 一對多的關(guān)系表栈戳,使用redis設(shè)計的時候會用到哪些數(shù)據(jù)結(jié)構(gòu)類型
注意:我們在進(jìn)行數(shù)據(jù)庫轉(zhuǎn)儲的時候,更多的是關(guān)注value值本身览露,也就對于關(guān)系型數(shù)據(jù)庫我們可能會優(yōu)先考慮將單個元組的數(shù)據(jù)作為value值(key可以自定義荧琼,也可以使用主鍵),這個時候使用hashmap的效率相對比較高差牛,但是如果僅僅存儲某一列的值命锄,我們又會優(yōu)先使用set,zset偏化,list等數(shù)據(jù)類型作為值脐恩。
下圖是一個使用hash作為值保存數(shù)據(jù)庫關(guān)系表的方式
redis的ZSet,list集合應(yīng)用場景有哪些
前者按照分值順序有序排列適合作為排行榜等侦讨,后者按照插入時間順序排列適合當(dāng)做有序隊列
注意:ZSet的底層數(shù)據(jù)結(jié)構(gòu)會根據(jù)數(shù)據(jù)量的大小進(jìn)行轉(zhuǎn)儲驶冒,數(shù)據(jù)量大的時候采用跳表