日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > > 架構(gòu)師社區(qū)
[導(dǎo)讀]提到Redis,大家一定會(huì)想到的幾個(gè)點(diǎn)是什么呢?高并發(fā)、KV存儲(chǔ)、內(nèi)存數(shù)據(jù)庫、豐富的數(shù)據(jù)結(jié)構(gòu)、單線程(版本6之前)等。那么,接下來,上面提到的這些,都會(huì)一一給大家解答,帶大家系統(tǒng)剖析一下Redis的架構(gòu)設(shè)計(jì)魅力!

-? ? ? 01、不一樣的Redis? ? -

提到Redis,大家一定會(huì)想到的幾個(gè)點(diǎn)是什么呢?

高并發(fā)、KV存儲(chǔ)、內(nèi)存數(shù)據(jù)庫、豐富的數(shù)據(jù)結(jié)構(gòu)、單線程(版本6之前)等。

那么,接下來,上面提到的這些,都會(huì)一一給大家解答,帶大家系統(tǒng)剖析一下Redis的架構(gòu)設(shè)計(jì)魅力!


深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)

-? ? ? 02、為什么會(huì)出現(xiàn)緩存?? ? -



一般情況下,數(shù)據(jù)都是在數(shù)據(jù)庫中,應(yīng)用系統(tǒng)直接操作數(shù)據(jù)庫。當(dāng)訪問量上萬,數(shù)據(jù)庫壓力增大,這個(gè)時(shí)候,怎么辦呢?


有小伙伴會(huì)說,分庫分表、讀寫分離。的確,這些確實(shí)是解決比較高的訪問量的解決辦法,但是,如果訪問量更大,10萬,100萬呢?怎么分似乎都不解決問題吧,所以我們需要用到其他辦法,來解決高并發(fā)帶來的數(shù)據(jù)庫壓力。


這個(gè)時(shí)候,緩存出現(xiàn)了,顧名思義,就是先把數(shù)據(jù)緩存在內(nèi)存中一份,當(dāng)訪問的時(shí)候,我們會(huì)先訪問內(nèi)存的數(shù)據(jù),如果內(nèi)存中的數(shù)據(jù)不存在,這個(gè)時(shí)候,我們再去讀取數(shù)據(jù)庫,之后把數(shù)據(jù)庫中的數(shù)據(jù)再備份一份到內(nèi)存中,這樣下次讀請求過來的時(shí)候,還是會(huì)直接先從內(nèi)存中訪問,訪問到內(nèi)存的數(shù)據(jù)了之后就直接返回了。這樣做就完美的降低了數(shù)據(jù)庫的壓力,可能十萬個(gè)請求進(jìn)來,全部都訪問了內(nèi)存中備份的數(shù)據(jù),而沒有去訪問數(shù)據(jù)庫,或者說只有少量的請求訪問到了數(shù)據(jù)庫,這樣真的是大大降低了數(shù)據(jù)庫的壓力,而且這樣做也提高了系統(tǒng)響應(yīng),大家想一下,內(nèi)存的讀寫速度是遠(yuǎn)遠(yuǎn)大于硬盤的讀寫速度的,一個(gè)請求進(jìn)來讀取的內(nèi)存可以比讀取硬盤快很多很多,用戶的體驗(yàn)也會(huì)很高。


深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)

-? ? ? 03、什么是緩存?? ? -



緩存原指CPU上的一種高速存儲(chǔ)器,它先于內(nèi)存與CPU交換數(shù)據(jù),速度很快。

現(xiàn)在泛指存儲(chǔ)在計(jì)算機(jī)上的原始數(shù)據(jù)的復(fù)制集,便于快速訪問。

在互聯(lián)網(wǎng)技術(shù)中,緩存是系統(tǒng)快速響應(yīng)的關(guān)鍵技術(shù)之一。


深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)

-? ? ? 04、緩存的三種讀寫模式? ? -



1、Cache Aside Pattern(常用)

Cache Aside Pattern(旁路緩存),是最經(jīng)典的緩存+數(shù)據(jù)庫讀寫模式。

讀的時(shí)候,先讀緩存,緩存沒有的話,就讀數(shù)據(jù)庫,然后取出數(shù)據(jù)后放入緩存,同時(shí)返回響應(yīng)。


深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)


更新的時(shí)候,先更新數(shù)據(jù)庫,然后再刪除緩存。


深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)


為什么是刪除緩存,而不是更新緩存呢?

1、緩存的值是一個(gè)結(jié)構(gòu),hash、list等更新數(shù)據(jù)需要遍歷;

2、懶加載,使用的時(shí)候才更新緩存,也可以采用異步的方式填充緩存。


高并發(fā)臟讀的三種情況:

1、先更新數(shù)據(jù)庫,在更新緩存;

深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)


update與commit之間,更新緩存,commit失敗,則DB與緩存數(shù)據(jù)不一致。


2、先刪除緩存,再更新數(shù)據(jù)庫

深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)


update與commit之間,有新的讀,緩存空,讀DB數(shù)據(jù)到緩存,數(shù)據(jù)是舊的數(shù)據(jù);

commit后DB為新的數(shù)據(jù);

則DB與緩存數(shù)據(jù)不一致。


3、先更新數(shù)據(jù)庫,再刪除緩存(推薦)


深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)


update與commit之間,有新的讀,緩存空,讀DB數(shù)據(jù)到緩存,數(shù)據(jù)是舊的數(shù)據(jù);

commit后DB為新的數(shù)據(jù);

則DB與緩存數(shù)據(jù)不一致;

采用延時(shí)雙刪策略。


2、Read/Write Through Pattern

應(yīng)用程序只操作緩存,緩存操作數(shù)據(jù)庫;

Read-Through(穿透讀模式/直讀模式):應(yīng)用程序讀緩存,緩存沒有,由緩存回源到數(shù)據(jù)庫,并寫入緩存;

Write-Through(穿透寫模式/直寫模式):應(yīng)用程序?qū)懢彺妫彺鎸憯?shù)據(jù)庫。該種模式需要提供數(shù)據(jù)庫的handler,開發(fā)較為復(fù)雜。


3、Write Behind Caching Pattern

應(yīng)用程序只更新緩存;

緩存通過異步的方式將數(shù)據(jù)批量或合并后更新到DB中,不能時(shí)時(shí)同步,甚至?xí)G數(shù)據(jù)。

深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)

-? ? ? 05、Redis又是什么?? ? -


Redis是一個(gè)高性能的開源的,C語言寫的NoSQL(非關(guān)系型數(shù)據(jù)庫)也叫做緩存數(shù)據(jù)庫,數(shù)據(jù)保存在內(nèi)存中。Redis是以key-value形式存儲(chǔ),和傳統(tǒng)的關(guān)系型數(shù)據(jù)庫不一樣。不一定遵循傳統(tǒng)數(shù)據(jù)庫的那些基本要求。比如,不遵循SQL標(biāo)準(zhǔn)、事務(wù)、表結(jié)構(gòu)等。Redis有非常豐富的數(shù)據(jù)類型,比如String,list,set,zset,hash等。


深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)

-? ? ? 06、Redis可以做什么?? ? -


1、減輕數(shù)據(jù)庫壓力,提高并發(fā)量,提高系統(tǒng)響應(yīng)時(shí)間


2、做Session分離

傳統(tǒng)的Session是由自己的tomcat進(jìn)行維護(hù)和管理的,在集群和分布式情況下,不同的tomcat要管理不同的session,只能在各個(gè)tomcat之間,通過網(wǎng)絡(luò)和IO進(jìn)行session復(fù)制,極大的影響了系統(tǒng)的性能。


Redis解決了這一個(gè)問題,將登陸成功后的session信息,存放在Redis中,這樣多個(gè)tomcat就可以共享Session信息。


深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)


3、做分布式鎖

一般Java中的鎖都是多線程鎖,是在一個(gè)進(jìn)程中的,多個(gè)進(jìn)程在并發(fā)的時(shí)候也會(huì)產(chǎn)生問題,也要控制時(shí)序性,這個(gè)時(shí)候Redis可以用來做分布式鎖,使用Redis的setnx命令來實(shí)現(xiàn)。


4、電商購物車:

1、以用戶id為key

2、商品id為field

3、商品數(shù)量為value

電商購物車操作:

1、添加商品:hset cart:1001 10088 1

2、增加數(shù)量:hincrby cart:1001 10088 1

3、商品總數(shù):hlen cart:1001

4、刪除商品:hdel cart:1001 10088

5、獲取購物車所有商品:hgetall cart:1001


深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)




5、zset集合操作實(shí)現(xiàn)排行榜

1、點(diǎn)擊新聞

ZINCRBY hotNews:20190819 1 守護(hù)香港

2、展示當(dāng)日排行前十

ZREVRANGE hotNews:20190819 0 9 WITHSCORES

3、七日搜索榜單計(jì)算

ZUNIONSTORE hotNews:20190813-20190819 7

hotNews:20190813 hotNews:20190814... hotNews:20190819

4、展示七日排行前十

ZREVRANGE hotNews:20190813-201908109 0 9 WITHSCORES


深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)



用Redis做緩存,有這么有多優(yōu)點(diǎn),那么,缺點(diǎn)是不是也會(huì)對應(yīng)的有很多呢?

1、額外的硬件支出

緩存是一種軟件系統(tǒng)中以空間換時(shí)間的技術(shù),需要額外的磁盤空間和內(nèi)存空間來存儲(chǔ)數(shù)據(jù)。


2、高并發(fā)緩存失效

在高并發(fā)的情況下,會(huì)出現(xiàn)緩存失效(緩存穿透,緩存雪崩,緩存擊穿等問題)造成瞬間數(shù)據(jù)庫訪問量增大,甚至崩潰,所以這些問題是一定要去解決。


3、緩存與數(shù)據(jù)庫數(shù)據(jù)同步

緩存與數(shù)據(jù)庫無法做到數(shù)據(jù)的實(shí)時(shí)同步。


4、緩存并發(fā)競爭

多個(gè)Redis客戶端同時(shí)對一個(gè)key進(jìn)行set值的時(shí)候由于執(zhí)行順序引起的并發(fā)的問題。


深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)

-? ? ? 07、Redis高性能設(shè)計(jì)? ? -

1、Redis是單線程的么?

Redis的單線程主要是指Redis的網(wǎng)絡(luò)IO和鍵值對讀寫是由一個(gè)線程來完成的,這也是Redis對外提供鍵值存儲(chǔ)服務(wù)的主要流程。但Redis的其他功能,比如持久化,異步刪除,集群數(shù)據(jù)同步等,都是由額外的線程執(zhí)行的。


2、Redis單線程為什么還能這么快?

這里我們在本地測試一下Redis支持的并發(fā)。

執(zhí)行這條命令:./redis-benchmark get
結(jié)果:
============ get ==========
100000 requests completed in 1.02 seconds
50 parallel clients
3 bytes payload
keep alive: 1
host configuration "save": 900 1 300 10 60 10000
host configuration "appendonly": no

multi-thread: no


0.00% <= 0.1 milliseconds
13.00% <= 0.2 milliseconds
55.85% <= 0.3 milliseconds
80.60% <= 0.4 milliseconds
92.57% <= 0.5 milliseconds
97.12% <= 0.6 milliseconds
99.06% <= 0.7 milliseconds
99.68% <= 0.8 milliseconds
99.86% <= 0.9 milliseconds
99.90% <= 1.0 milliseconds
99.90% <= 1.1 milliseconds

13.00% <= 0.2 milliseconds
55.85% <= 0.3 milliseconds
80.60% <= 0.4 milliseconds
92.57% <= 0.5 milliseconds
97.12% <= 0.6 milliseconds
99.06% <= 0.7 milliseconds
99.68% <= 0.8 milliseconds
99.86% <= 0.9 milliseconds
99.90% <= 1.0 milliseconds
99.90% <= 1.1 milliseconds
99.90% <= 1.2 milliseconds
99.91% <= 1.3 milliseconds
99.93% <= 1.4 milliseconds
99.95% <= 1.5 milliseconds
99.97% <= 1.6 milliseconds
99.98% <= 1.7 milliseconds
99.99% <= 1.8 milliseconds
99.99% <= 1.9 milliseconds
100.00% <= 2 milliseconds
100.00% <= 2 milliseconds
98328.42 requests per second

這里我們可以看到,每秒的話,差不多可以支持小10萬的并發(fā),這已經(jīng)是一個(gè)很恐怖的數(shù)據(jù)了。


因?yàn)樗乃袛?shù)據(jù)都在內(nèi)存中,所有的運(yùn)算都是內(nèi)存級別的運(yùn)算,而且單線程避免了多線程的切換性能消耗問題。正因?yàn)镽edis是單線程的,所以要小心使用Redis命令,對于那些耗時(shí)的指令(比如keys),一定要謹(jǐn)慎使用,一不小心就可能導(dǎo)致Redis卡頓。

Redis單線程如何處理那么多并發(fā)客戶端連接?


Redis的IO多路復(fù)用:Redis利用epoll來實(shí)現(xiàn)IO多路復(fù)用,將連接信息和事件放到隊(duì)列中,一次放到文件事件分派器,事件分派器將事件分發(fā)給事件處理器。


深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)

-? ? ? 08、Redis核心設(shè)計(jì)原理? ? -



Redis作為key-value存儲(chǔ)系統(tǒng),數(shù)據(jù)結(jié)構(gòu)如下:

深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)


一個(gè)Redis實(shí)例對應(yīng)多個(gè)DB,一個(gè)DB對應(yīng)多個(gè)key,key一般都是string的,后面的value叫做RedisObject,不是說value就是string,list,map這些,而是說這些所有的類型,都被Redis封裝成了一個(gè)叫RedisObjcet,具體是哪個(gè)類型呢?這里是用指針的方式來指向具體是哪個(gè)類型。

深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)


為什么要這么做,主要是為了提高Redis的性能。

PS:這里插一句,為什么使用指針的方式要比使用對象本身的方式性能更好呢?


這里有兩點(diǎn):

第一點(diǎn)是動(dòng)態(tài)分配;第二是指針一大特點(diǎn)在于你只需要在前面聲明一下指針指向的類型(而如果要使用實(shí)際的對象,你還需要定義一下)。這樣你就能降低你的編譯單元之間的耦合性從而減少編譯時(shí)間。


1、RedisDB結(jié)構(gòu)

Redis沒有表的概念,Redis實(shí)例所對應(yīng)的DB以編號區(qū)分,DB本身就是key的命名空間

比如:user:1000作為key的值,表示在user這個(gè)命名空間下id為1000的元素,類似于user表的id=1000的行。


2、SDS字符串

眾所周知,Redis是用C語言來實(shí)現(xiàn)的,在C語言中,String這個(gè)類型,其實(shí)就是一個(gè)char數(shù)組,比如char data[]="xxx\0",但是,客戶端往Redis發(fā)送set命令,是可以發(fā)任意的字符串的,是沒有校驗(yàn)的,所以假如我們發(fā)了一個(gè)字符串xx\0xx,那么\0后面的xx是不會(huì)讀的,只會(huì)讀前面的xx(C語言中用"\0"表示字符串結(jié)束,如果字符串本身就有"\0"字符,字符串就會(huì)被截?cái)啵?/span>


所以Redis自實(shí)現(xiàn)了一個(gè)string叫sds,sds中記錄了一個(gè)len和一個(gè)char buf[],len用來記錄buf的長度,比如char buf[] = "xx\0xx",那么len就是5,sds中還有一個(gè)比較重要的屬性就是free,表示還剩余多少。


free是通過改變len來計(jì)算,比如"xxx1234" 改成 "xxx123456",那么會(huì)按照(len+addlen)*2=18 來擴(kuò)容,這個(gè)時(shí)候len變成了9,free就是18-9也變成了9。


例如:

char buf[] = "xxx1234" 改成 "xxx123456" //這里的buf是柔性數(shù)組
free:12 變成free:10
len:8 變成len:10

Redis這樣設(shè)計(jì)SDS有什么好處:

1、二進(jìn)制安全的數(shù)據(jù)結(jié)構(gòu);

2、提供了內(nèi)存預(yù)分配機(jī)制,避免了頻繁的內(nèi)存分配;

3、兼容C語言的函數(shù)庫;

4、有單獨(dú)的統(tǒng)計(jì)變量len和free,可以方便的得到字符串長度,這樣就避免了讀取不完整的風(fēng)險(xiǎn);

5、內(nèi)容存放在柔性數(shù)組buf中,SDS對上層暴露的指針不是指向結(jié)構(gòu)體SDS的指針,而是直接指向柔性數(shù)組buf的指針。上層可像讀取C字符串一樣讀取SDS的內(nèi)容,兼容C語言處理字符串的各種函數(shù)。


這里解釋一下什么叫柔型數(shù)組?

柔型數(shù)組即數(shù)組大小待定的數(shù)組,C語言中結(jié)構(gòu)體的最后一個(gè)元素可以是大小未知的數(shù)組,也就是所謂的0長度,所以我們可以用結(jié)構(gòu)體來創(chuàng)建柔性數(shù)組。柔性數(shù)組主要用途是為了滿足需要變長度的結(jié)構(gòu)體,為了解決使用數(shù)組時(shí)內(nèi)存的冗余和數(shù)組的越界問題

這也是Redis3.2之前所實(shí)現(xiàn)的。


未完待續(xù),敬請期待下篇分析。

特別推薦一個(gè)分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒關(guān)注的小伙伴,可以長按關(guān)注一下:

深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)

深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)

深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)

長按訂閱更多精彩▼

深度剖析不一樣的Redis架構(gòu)設(shè)計(jì)

如有收獲,點(diǎn)個(gè)在看,誠摯感謝

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢抑制與過流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉