本篇內(nèi)容主要講解“有哪些Rust緩存”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“有哪些Rust緩存”吧!
十年的隰縣網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。網(wǎng)絡(luò)營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整隰縣建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)建站從事“隰縣網(wǎng)站設(shè)計”,“隰縣網(wǎng)站推廣”以來,每個客戶項目都認(rèn)真落實執(zhí)行。
那什么是緩存穿透,它就是指當(dāng)用戶在查詢一條數(shù)據(jù)的時候,而此時數(shù)據(jù)庫和緩存卻沒有關(guān)于這條數(shù)據(jù)的任何記錄,而這條數(shù)據(jù)在緩存中沒找到就會向數(shù)據(jù)庫請求獲取數(shù)據(jù)。它拿不到數(shù)據(jù)時,是會一直查詢數(shù)據(jù)庫,這樣會對數(shù)據(jù)庫的訪問造成很大的壓力。
如:用戶查詢一個 id = -1 的商品信息,一般數(shù)據(jù)庫 id 值都是從 1 開始自增,很明顯這條信息是不在數(shù)據(jù)庫中,當(dāng)沒有信息返回時,會一直向數(shù)據(jù)庫查詢,給當(dāng)前數(shù)據(jù)庫的造成很大的訪問壓力。
這時候我們要想一想,該如何解決這個問題呢?o(╥﹏╥)o
一般我們可以想到從緩存開始出發(fā),想如果我們給緩存設(shè)置一個如果當(dāng)前數(shù)據(jù)庫不存在的信息,把它緩存成一個空對象,返回給用戶。
^_^沒錯,這是一個解決方案,也就是我們常說的緩存空對象(代碼維護簡單,但是效果不是很好)。
redis 也為我們提供了一種解決方案,那就是布隆過濾器(代碼維護比較復(fù)雜,效果挺好的)。
搜索Java專欄公眾號,回復(fù)“手冊”,送你一份Java面試題寶典.pdf
那接下來,先解釋下這兩種方案:
那什么是緩存空對象呀!別急,緩存空對象它就是指一個請求發(fā)送過來,如果此時緩存中和數(shù)據(jù)庫都不存在這個請求所要查詢的相關(guān)信息,那么數(shù)據(jù)庫就會返回一個空對象,并將這個空對象和請求關(guān)聯(lián)起來存到緩存中,當(dāng)下次還是這個請求過來的時候,這時緩存就會命中,就直接從緩存中返回這個空對象,這樣可以減少訪問數(shù)據(jù)庫的壓力,提高當(dāng)前數(shù)據(jù)庫的訪問性能。我們接下來可以看下面這個流程呀~
這時候,我們就會問了呀 ~,如果大量不存在的請求過來,那么這時候緩存豈不是會緩存許多空對象了嗎~~~
沒錯哦!這也是使用緩存空對象會導(dǎo)致的一個問題:如果時間一長這樣會導(dǎo)致緩存中存在大量空對象,這樣不僅會占用許多的內(nèi)存空間,還會浪費許多資源呀!。那這有沒有什么可以解決的方法呢?我們來想一想:我們可以將這些對象在一段時間之后清理下不久可以了嗎 ~
嗯嗯,沒錯!在想想 Redis 里是不是給我們提供了有關(guān)過期時間的命令呀(^▽^),這樣我們可以在設(shè)置空對象的時間,順便設(shè)置一個過期時間,就可以解決個問題了呀!
setex key seconds valule:設(shè)置鍵值對的同時指定過期時間(s)
在Java 中直接調(diào)用 API 操作即可:
redisCache.put(Integer.toString(id), null, 60) //過期時間為 60s
那布隆過濾器是不是不是一個過濾器,過濾東西的呀!哎呀,你太聰明了,沒錯它就是用來過濾東西的,它是一種基于概率的數(shù)據(jù)結(jié)構(gòu),主要使用愛判斷當(dāng)前某個元素是否在該集合中,運行速度快。我們也可以簡單理解為是一個不怎么精確的 set 結(jié)構(gòu)(set 具有去重的效果)。但是有個小問題是:當(dāng)你使用它的 contains 方法去判斷某個對象是否存在時,它可能會誤判。也就是說布隆過濾器不是特別不精確,但是只要參數(shù)設(shè)置的合理,它的精確度可以控制的相對足夠精確,只會有小小的誤判概率(這是可以接受的呀 ~)。當(dāng)布隆過濾器說某個值存在時,這個值可能不存在;當(dāng)它說不存在時,那就肯定不存在。
這里有個典型的例子呀,來自錢大:
打個比方,當(dāng)它說不認(rèn)識你時,肯定就不認(rèn)識;當(dāng)它說見過你時,可能根本就沒見過面,不過因為你的臉跟它認(rèn)識的人中某臉比較相似 (某些熟臉的系數(shù)組合),所以誤判以前見過你。在上面的使用場景中,布隆過濾器能準(zhǔn)確過濾掉那些已經(jīng)看過的內(nèi)容,那些沒有看過的新內(nèi)容,它也會過濾掉極小一部分 (誤判),但是絕大多數(shù)新內(nèi)容它都能準(zhǔn)確識別。這樣就可以完全保證推薦給用戶的內(nèi)容都是無重復(fù)的。
說了這么久,那布隆過濾器到底有什么特點呢:
特點嗎,多多來讓一個個跟你吹吹(吹到你懷疑人生(≧?≦)?)
一個非常大的二進制位數(shù)組(數(shù)組中只存在 0 和 1)
擁有若干個哈希函數(shù)(Hash Function)
在空間效率和查詢效率都非常高
布隆過濾器不會提供刪除方法,在代碼維護上比較困難。
每個布隆過濾器對應(yīng)到 Redis 的數(shù)據(jù)結(jié)構(gòu)里面就是一個大型的位數(shù)組和幾個不一樣的無偏 hash 函數(shù)。所謂無偏就是能夠把元素的 hash 值算得比較均勻。
向布隆過濾器中添加 key 時,會使用多個 hash 函數(shù)對 key 進行 hash 算得一個整數(shù)索引值然后對位數(shù)組長度進行取模運算得到一個位置,每個 hash 函數(shù)都會算得一個不同的位置。再把位數(shù)組的這幾個位置都置為 1 就完成了 add 操作。( 每一個 key 都通過若干的hash函數(shù)映射到一個巨大位數(shù)組上,映射成功后,會在把位數(shù)組上對應(yīng)的位置改為1。)
那為什么布隆過濾器會存在誤判率呢?
誤判嗎?人生哪有不摔跤,只要鋤頭揮得好,照樣能挖到。(咳咳咳,說偏了...)
其實它會誤判是如下這個情況:
當(dāng) key1 和 key2 映射到位數(shù)組上的位置為 1 時,假設(shè)這時候來了個 key3,要查詢是不是在里面,恰好 key3 對應(yīng)位置也映射到了這之間,那么布隆過濾器會認(rèn)為它是存在的,這時候就會產(chǎn)生誤判(因為明明 key3 是不在的)。
O(∩_∩)O哈哈~,這時候你會問了:如何提高布隆過濾器的準(zhǔn)確率呢?
要提高布隆過濾器的準(zhǔn)確率,就要說到影響它的三個重要因素:
哈希函數(shù)的好壞
存儲空間大小
哈希函數(shù)個數(shù)
hash函數(shù)的設(shè)計也是一個十分重要的問題,對于好的hash函數(shù)能大大降低布隆過濾器的誤判率。
(這就好比優(yōu)秀的配件之所以能夠運行這么順暢就在于其內(nèi)部設(shè)計的得當(dāng)。)
同時,對于一個布隆過濾器來說,如果其位數(shù)組越大的話,那么每個key通過hash函數(shù)映射的位置會變得稀疏許多,不會那么緊湊,有利于提高布隆過濾器的準(zhǔn)確率。同時,對于一個布隆過濾器來說,如果key通過許多hash函數(shù)映射,那么在位數(shù)組上就會有許多位置有標(biāo)志,這樣當(dāng)用戶查詢的時候,在通過布隆過濾器來找的時候,誤判率也會相應(yīng)降低。
對于其內(nèi)部原理,有興趣的同學(xué)可以看看關(guān)于布隆過濾的數(shù)學(xué)知識,里面有關(guān)于它的設(shè)計算法和數(shù)學(xué)知識。(其實也挺簡單~)
緩存擊穿是指有某個key經(jīng)常被查詢,經(jīng)常被用戶特殊關(guān)懷,用戶非常 love 它 (^▽^),也就類比“熟客” 或者 一個key經(jīng)常不被訪問。但是這時候,如果這個key在緩存的過期時間失效的時候或者這是個冷門key時,這時候突然有大量有關(guān)這個key的訪問請求,這樣會導(dǎo)致大并發(fā)請求直接穿透緩存,請求數(shù)據(jù)庫,瞬間對數(shù)據(jù)庫的訪問壓力增大。
歸納起來:造成緩存擊穿的原因有兩個。
(1)一個“冷門”key,突然被大量用戶請求訪問。
(2)一個“熱門”key,在緩存中時間恰好過期,這時有大量用戶來進行訪問。
對于緩存擊穿的問題:我們常用的解決方案是加鎖。對于key過期的時候,當(dāng)key要查詢數(shù)據(jù)庫的時候加上一把鎖,這時只能讓第一個請求進行查詢數(shù)據(jù)庫,然后把從數(shù)據(jù)庫中查詢到的值存儲到緩存中,對于剩下的相同的key,可以直接從緩存中獲取即可。
如果我們是在單機環(huán)境下:直接使用常用的鎖即可(如:Lock、Synchronized等),在分布式環(huán)境下我們可以使用分布式鎖,如:基于數(shù)據(jù)庫、基于Redis或者zookeeper 的分布式鎖。
緩存雪崩是指在某一個時間段內(nèi),緩存集中過期失效,如果這個時間段內(nèi)有大量請求,而查詢數(shù)據(jù)量巨大,所有的請求都會達到存儲層,存儲層的調(diào)用量會暴增,引起數(shù)據(jù)庫壓力過大甚至宕機。
搜索Java專欄公眾號,回復(fù)“手冊”,送你一份Java面試題寶典.pdf
原因:
Redis突然宕機
大部分?jǐn)?shù)據(jù)失效
舉個例子理解下吧:
比如我們基本上都經(jīng)歷過購物狂歡節(jié),假設(shè)商家舉辦 23:00-24:00 商品打骨折促銷活動。程序小哥哥在設(shè)計的時候,在 23:00 把商家打骨折的商品放到緩存中,并通過redis的expire設(shè)置了過期時間為1小時。這個時間段許多用戶訪問這些商品信息、購買等等。但是剛好到了24:00點的時候,恰好還有許多用戶在訪問這些商品,這時候?qū)@些商品的訪問都會落到數(shù)據(jù)庫上,導(dǎo)致數(shù)據(jù)庫要抗住巨大的壓力,稍有不慎會導(dǎo)致,數(shù)據(jù)庫直接宕機(over)。
當(dāng)商品沒有失效的時候是這樣的:
當(dāng)緩存GG(失效)的時候卻是這樣的:
對于緩存雪崩有以下解決方案:
(1)redis高可用
redis有可能掛掉,多增加幾臺redis實例,(一主多從或者多主多從),這樣一臺掛掉之后其他的還可以繼續(xù)工作,其實就是搭建的集群。
(2)限流降級
在緩存失效后,通過加鎖或者隊列來控制讀數(shù)據(jù)庫寫緩存的線程數(shù)量,對某個key只允許一個線程查詢數(shù)據(jù)和寫緩存,其他線程等待。
(3)數(shù)據(jù)預(yù)熱
數(shù)據(jù)加熱的含義就是在正式部署之前,我先把可能的數(shù)據(jù)先預(yù)先訪問一遍,這樣部分可能大量訪問的數(shù)據(jù)就會加載到緩存中。在即將發(fā)生大并發(fā)訪問前手動觸發(fā)加載緩存不同的key。
(4)不同的過期時間
設(shè)置不同的過期時間,讓緩存失效的時間點盡量均勻。
到此,相信大家對“有哪些Rust緩存”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
網(wǎng)頁標(biāo)題:有哪些Rust緩存
文章網(wǎng)址:http://jinyejixie.com/article30/psgdso.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站、App開發(fā)、網(wǎng)站設(shè)計、網(wǎng)站改版、做網(wǎng)站、網(wǎng)站維護
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)