日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

牛客面试系列之Redis

發(fā)布時(shí)間:2023/12/15 数据库 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客面试系列之Redis 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • Redis數(shù)據(jù)類型
    • Redis基本數(shù)據(jù)類型的使用和使用場(chǎng)景
    • String
    • hash
    • list
    • set
    • zset
    • 標(biāo)題為什么使用Redis?
    • 標(biāo)題為什么Redis的性能高?
    • 標(biāo)題Redis為什么使用單線程?
    • Redis過期策略
    • Redis淘汰策略
    • Redis緩存穿透
    • Redis緩存擊穿
    • Redis緩存雪崩
    • Redis分布式鎖
    • 單Redis實(shí)例實(shí)現(xiàn)分布式鎖
    • 多Redis實(shí)例實(shí)現(xiàn)分布式鎖

?作者簡(jiǎn)介:我是18shou,一名即將秋招的java實(shí)習(xí)生

🔥系列專欄:牛客面經(jīng)專欄

📃推薦一款八股、面經(jīng)、模擬面試、刷題神器👉 超級(jí)無敵之牛客

耗時(shí)數(shù)小時(shí)從牛客整理的面經(jīng)以及筆記

Redis數(shù)據(jù)類型

數(shù)據(jù)類型 :最大存儲(chǔ)數(shù)據(jù)量
key:512M
string:512M
hash:2^32-1
list:2^32-1
set:2^32-1
sorted setbitmap:512M
hyperloglog:12K

Redis基本數(shù)據(jù)類型的使用和使用場(chǎng)景

String

String:set(添加鍵值對(duì)),get(獲取鍵值對(duì)),decr(自減1),incr(自增1),mget(同時(shí)獲取一個(gè)或多個(gè)value)
適合用于高頻訪問的信息,比如書一個(gè)大V的粉絲數(shù)量,微博數(shù)量等等,可以用Redis的String來存放。如博客訪問次數(shù)、網(wǎng)站訪問量。

hash

hash: hget,hset,hgetall 可以應(yīng)用在電商網(wǎng)站購物車的設(shè)計(jì),用戶就是一個(gè)key,商品是一個(gè)field,數(shù)量為value。

list

list:
lpush(從左邊插入一個(gè)或多個(gè)值),rpush(從右邊插入一個(gè)或多個(gè)值),rpop(從右邊吐出一個(gè)值),lrange(key,start,stop)(按照索引下標(biāo)獲得元素從左到右)
可以運(yùn)用在微信朋友圈點(diǎn)贊,比如說要求按照點(diǎn)贊的順序來顯示好友信息,如果取消點(diǎn)贊,就移除點(diǎn)贊列表。微博中我的關(guān)注列表

set

set: sadd(添加一個(gè)或多個(gè)值), spop (隨機(jī)從集合中吐出一個(gè)值),
smembers(取出對(duì)應(yīng)鍵所有值),sunion(sunion:sunion key1 key2 取key1和key2的并集)
假如一個(gè)公司里面有很多的員工,在內(nèi)部的OA系統(tǒng)中就具有700多個(gè)角色,3000多個(gè)業(yè)務(wù)操作,20000多種數(shù)據(jù),那么如何快速進(jìn)行業(yè)務(wù)操作的相關(guān)校驗(yàn)?zāi)?
Redis的set是string類型的無序集合,和list不同的是,set中不會(huì)出現(xiàn)重復(fù)的成員,集合最大的好處就是可以進(jìn)行交集或差集的操作。
?使用場(chǎng)景:共同好友、二度好友,記錄訪問網(wǎng)站的獨(dú)立IP等 ?常用命令:sadd、spop、smembers、sunion等。

zset

zset (有序集合)
Redis中的zset和set一樣,都是string類型的集合,也不允許有重復(fù)的成員,但不同的是zset的每個(gè)元素都會(huì)有一個(gè)double類型的分?jǐn)?shù)(score)與之關(guān)聯(lián),而Redis也是通過這個(gè)分?jǐn)?shù)來為這個(gè)集合排序的。

應(yīng)用場(chǎng)景:在線游戲的積分排行榜、熱點(diǎn)新聞排行榜等 常用命令:zadd、zrange、zrem、zcard等。

標(biāo)題為什么使用Redis?

因?yàn)槭腔趦?nèi)存,可持久化的Key-Value數(shù)據(jù)庫,具有速度快,可持久化,豐富數(shù)據(jù)類型,支持?jǐn)?shù)據(jù)備份的功能。

標(biāo)題為什么Redis的性能高?

(1)Redis的數(shù)據(jù)是完全存放在內(nèi)存中的,類似hashmap優(yōu)勢(shì)是查找和操作的時(shí)間復(fù)雜度都是O(1)
(2)Redis采用了單線程,避免了不必要的上下文切換和競(jìng)爭(zhēng)條件以及多線程導(dǎo)致的相關(guān)鎖的問題。
(3)采用多路I/O復(fù)用模型,非阻塞IO,空閑時(shí)把當(dāng)前線程阻塞,當(dāng)有IO流事件時(shí),就從阻塞狀態(tài)喚醒,然后程序會(huì)輪詢一邊所有的流,并一次順序處理事件的流,避免了大量的無用操作。

標(biāo)題Redis為什么使用單線程?

(1)使用Redis時(shí)幾乎不存在CPU瓶頸,主要受限于網(wǎng)絡(luò)和內(nèi)存,比如說Linux下Redis可以pipelining每秒處理100萬個(gè)請(qǐng)求。
(2)使用單線程可維護(hù)性高,多線程雖然優(yōu)秀但是帶來的程序執(zhí)行順序不確定,并發(fā)讀寫一系列問題,增加系統(tǒng)復(fù)雜度,同時(shí)線程切換,造成的性能消耗。
(3)Redis采用的時(shí)I/O復(fù)用模型,處理性能高,沒必要用多線程,并且單線程Redis內(nèi)部實(shí)現(xiàn)復(fù)雜度低。

Redis過期策略

Redis會(huì)把設(shè)置了過期時(shí)間的key放入一個(gè)獨(dú)立的字典里,在key過期時(shí)并不會(huì)立刻刪除它。Redis會(huì)通過如下兩種策略,來刪除過期的key:

  • 惰性刪除 客戶端訪問某個(gè)key時(shí),Redis會(huì)檢查該key是否過期,若過期則刪除。
  • 定期掃描 Redis默認(rèn)每秒執(zhí)行10次過期掃描(配置hz選項(xiàng)),掃描策略如下:
    1.從過期字典中隨機(jī)選擇20個(gè)key;
    2.刪除這20個(gè)key中已過期的key;
    3.如果過期的key的比例超過25%,則重復(fù)步驟1;
  • Redis淘汰策略

    當(dāng)Redis占用內(nèi)存超出最大限制(maxmemory)時(shí),
    可采用如下策略(maxmemory-policy),讓Redis淘汰一些數(shù)據(jù),以騰出空間繼續(xù)提供讀寫服務(wù):

    .noeviction:對(duì)可能導(dǎo)致增大內(nèi)存的命令返回錯(cuò)誤(大多數(shù)寫命令,DEL除外); · volatile-ttl:在設(shè)置了過期時(shí)間的key中,選擇剩余壽命(TTI)最短的key,將其淘汰; .volatile-lru:(在設(shè)置了過期時(shí)間的key中,選擇最少使用的key (LRU),將其淘汰; . volatile-random:在設(shè)置了過期時(shí)間的key中,隨機(jī)選擇一些key,將其淘汰; . allkeys-lru:在所有的key中,選擇最少使用的key (LRU),將其淘汰; .allkeys-random:在所有的key中,隨機(jī)選擇一些key,將其淘汰;

    Redis緩存穿透

    場(chǎng)景 查詢根本不存在的數(shù)據(jù),使得請(qǐng)求直達(dá)存儲(chǔ)層,導(dǎo)致其負(fù)載過大,甚至宕機(jī)。 ·解決方案 1.緩存空對(duì)象
    存儲(chǔ)層未命中后,仍然將空值存入緩存層。再次訪問該數(shù)據(jù)時(shí),緩存層會(huì)直接返回空值。2.布隆過濾器
    將所有存在的key提前存入布隆過濾器,在訪問緩存層之前,先通過過濾器攔截,若請(qǐng)求的是不存在的key,則直接返回空值。

    Redis緩存擊穿

    場(chǎng)景 一份熱點(diǎn)數(shù)據(jù),它的訪問量非常大。在其緩存失效瞬間,大量請(qǐng)求直達(dá)存儲(chǔ)層,導(dǎo)致服務(wù)崩潰。·解決方案 1.加互斥鎖
    對(duì)數(shù)據(jù)的訪問加互斥鎖,當(dāng)一個(gè)線程訪問該數(shù)據(jù)時(shí),其他線程只能等待。
    這個(gè)線程訪問過后,緩存中的數(shù)據(jù)將被重建,屆時(shí)其他線程就可以直接從緩存取值。2.永不過期
    不設(shè)置過期時(shí)間,所以不會(huì)出現(xiàn)上述問題,這是“物理”上的不過期。為每個(gè)value設(shè)置邏輯過期時(shí)間,當(dāng)發(fā)現(xiàn)該值邏輯
    過期時(shí),使用單獨(dú)的線程重建緩存。

    Redis緩存雪崩

    場(chǎng)景 由于某些原因,緩存層不能提供服務(wù),導(dǎo)致所有的請(qǐng)求直達(dá)存儲(chǔ)層,造成存儲(chǔ)層宕機(jī)。·解決方案
    1.避免同時(shí)過期 設(shè)置過期時(shí)間時(shí),附加一個(gè)隨機(jī)數(shù),避免大量的key同時(shí)過期。2.構(gòu)建高可用的Redis緩存 部署多個(gè)Redis實(shí)例,個(gè)別節(jié)點(diǎn)宕機(jī),依然可以保持服務(wù)的整體可用。3.構(gòu)建多級(jí)緩存
    增加本地緩存,在存儲(chǔ)層前面多加一級(jí)屏障,降低請(qǐng)求直達(dá)存儲(chǔ)層的幾率。4.啟用限流和降級(jí)措施
    對(duì)存儲(chǔ)層增加限流措施,當(dāng)請(qǐng)求超出限制時(shí),對(duì)其提供降級(jí)服務(wù)。

    Redis分布式鎖

    場(chǎng)景
    修改時(shí),經(jīng)常需要先將數(shù)據(jù)讀取到內(nèi)存,在內(nèi)存中修改后再存回去。在分布式應(yīng)用中,可能多個(gè)進(jìn)程同時(shí)執(zhí)行上述操作,而讀取和修改非原子操作,所以會(huì)產(chǎn)生沖突。增加分布式鎖,可以解決此類問題基本原理
    同步鎖:在多個(gè)線程都能訪問到的地方,做一個(gè)標(biāo)記,標(biāo)識(shí)該數(shù)據(jù)的訪問權(quán)限。分布式鎖:在多個(gè)進(jìn)程都能訪問到的地方,做一個(gè)標(biāo)記,標(biāo)識(shí)該數(shù)據(jù)的訪問權(quán)限。實(shí)現(xiàn)方式
    1.基于數(shù)據(jù)庫實(shí)現(xiàn)分布式鎖;2.基于Redis實(shí)現(xiàn)分布式鎖;3.基于zookeeper實(shí)現(xiàn)分布式鎖;

    Redis實(shí)現(xiàn)分布式鎖的原則

    1.安全屬性:獨(dú)享。在任一時(shí)刻,只有一個(gè)客戶端持有鎖。
    2.活性A:無死鎖。即便持有鎖的客戶端崩潰或者網(wǎng)絡(luò)被分裂,鎖仍然可以被獲取。3.活性B:容錯(cuò)。只要大部分Redis節(jié)點(diǎn)都活著,客戶端就可以獲取和釋放鎖。

    單Redis實(shí)例實(shí)現(xiàn)分布式鎖

    1.獲取鎖使用命令: SET resource_name my_random_value NX PX 3000o
    NX:僅在key不存在時(shí)才執(zhí)行成功。
    PX:設(shè)置鎖的自動(dòng)過期時(shí)間。
    2.通過Lua腳本釋放鎖: 可以避免刪除別的客戶端獲取成功的鎖:
    if redis.call ( "get",KEYS[1])==ARGV [1] then return redis.call ( "del",KEYS [1]) else return 0 end
    A加鎖->A阻塞->因超時(shí)釋放鎖 ->B加鎖->A恢復(fù)->釋放鎖

    多Redis實(shí)例實(shí)現(xiàn)分布式鎖

    Redlock算法,該算法有現(xiàn)成的實(shí)現(xiàn),其Java版本的厙為Redisson。
    1.獲取當(dāng)前Unix時(shí)間,以毫秒為單位。
    2.依次嘗試從N個(gè)實(shí)例,使用相同的key和隨機(jī)值獲取鎖,并設(shè)置響應(yīng)超時(shí)時(shí)間。如果服務(wù)器沒有在
    規(guī)定時(shí)間內(nèi)響應(yīng),客戶端應(yīng)該盡快嘗試另外一個(gè)Redis實(shí)例。
    3.客戶端使用當(dāng)前時(shí)間減去開始獲取鎖的時(shí)間,得到獲取鎖使用的時(shí)間。當(dāng)且僅當(dāng)大多數(shù)的Redis節(jié)
    點(diǎn)都取到鎖,并且使用的時(shí)間小于鎖失效時(shí)間時(shí),鎖才算取得成功。
    4.如果取到了鎖,key的真正有效時(shí)間等于有效時(shí)間減去獲取鎖使用的時(shí)間。5.如果獲取鎖失敗,客戶端應(yīng)該在所有的Redis實(shí)例上進(jìn)行解鎖。

    📃推薦超級(jí)無敵之牛客

    總結(jié)

    以上是生活随笔為你收集整理的牛客面试系列之Redis的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。