成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

我們一起聊聊面試被吊打之Redis原理篇

存儲 存儲軟件 Redis
Redis不同版本之間采用的線程模型是不一樣的,在Redis4.0版本之前使用的是單線程模型,在4.0版本之后增加了多線程的支持。

[[385123]]

本文轉(zhuǎn)載自微信公眾號「JAVA日知錄」,作者單一色調(diào)。轉(zhuǎn)載本文請聯(lián)系JAVA日知錄公眾號。

小張興沖沖去面試,結(jié)果被面試官吊打!

小張:

面試官,你好。我是來參加面試的。

面試官:

你好,小張。我看了你的簡歷,熟練掌握Redis,那么我就隨便問你幾個Redis相關(guān)的問題吧。首先我的問題是,Redis是單線程還是多線程呢?

小張:

Redis不同版本之間采用的線程模型是不一樣的,在Redis4.0版本之前使用的是單線程模型,在4.0版本之后增加了多線程的支持。

在4.0之前雖然我們說Redis是單線程,也只是說它的網(wǎng)絡(luò)I/O線程以及Set 和 Get操作是由一個線程完成的。但是Redis的持久化、集群同步還是使用其他線程來完成。

4.0之后添加了多線程的支持,主要是體現(xiàn)在大數(shù)據(jù)的異步刪除功能上,例如 unlink key、flushdb async、flushall async 等

面試官:

回答的很好,那為什么Redis在4.0之前會選擇使用單線程?而且使用單線程還那么快?

小張:

選擇單線程個人覺得主要是使用簡單,不存在鎖競爭,可以在無鎖的情況下完成所有操作,不存在死鎖和線程切換帶來的性能和時間上的開銷,但同時單線程也不能完全發(fā)揮出多核CPU的性能。

至于為什么單線程那么快我覺得主要有以下幾個原因:

  1. Redis 的大部分操作都在內(nèi)存中完成,內(nèi)存中的執(zhí)行效率本身就很快,并且采用了高效的數(shù)據(jù)結(jié)構(gòu),比如哈希表和跳表。
  2. 使用單線程避免了多線程的競爭,省去了多線程切換帶來的時間和性能開銷,并且不會出現(xiàn)死鎖。
  3. 采用 I/O 多路復(fù)用機制處理大量客戶端的Socket請求,因為這是基于非阻塞的 I/O 模型,這就讓Redis可以高效地進行網(wǎng)絡(luò)通信,I/O的讀寫流程也不再阻塞。

面試官:

不錯,那Redis是如何實現(xiàn)數(shù)據(jù)不丟失的呢?

小張:

Redis數(shù)據(jù)是存儲在內(nèi)存中的,為了保證Redis數(shù)據(jù)不丟失,那就要把數(shù)據(jù)從內(nèi)存存儲到磁盤上,以便在服務(wù)器重啟后還能夠從磁盤中恢復(fù)原有數(shù)據(jù),這就是Redis的數(shù)據(jù)持久化。Redis數(shù)據(jù)持久化有三種方式。

AOF 日志(Append Only File,文件追加方式):記錄所有的操作命令,并以文本的形式追加到文件中。

RDB 快照(Redis DataBase):將某一個時刻的內(nèi)存數(shù)據(jù),以二進制的方式寫入磁盤。

混合持久化方式:Redis 4.0 新增了混合持久化的方式,集成了 RDB 和 AOF 的優(yōu)點。

面試官:

那你分別說說 AOF和 RDB的實現(xiàn)原理吧。

小張:

AOF采用的是寫后日志的方式,Redis先執(zhí)行命令把數(shù)據(jù)寫入內(nèi)存,然后再記錄日志到文件中。AOF日志記錄的是操作命令,不是實際的數(shù)據(jù),如果采用AOF方法做故障恢復(fù)時需要將全量日志都執(zhí)行一遍。

 

RDB采用的是內(nèi)存快照的方式,它記錄的是某一時刻的數(shù)據(jù),而不是操作,所以采用RDB方法做故障恢復(fù)時只需要直接把RDB文件讀入內(nèi)存即可,實現(xiàn)快速恢復(fù)。

面試官:

你剛提到了AOF采用的是 “寫后日志” 的方式,我們平時用的MySQL則采用的是 “寫前日志”,那Redis為什么要先執(zhí)行命令,再把數(shù)據(jù)寫入日志呢?

小張:額頭開始冒汗,問的是些啥問題呀。。。

額,這個主要是由于Redis在寫入日志之前,不對命令進行語法檢查,所以只記錄執(zhí)行成功的命令,避免出現(xiàn)記錄錯誤命令的情況,而且在命令執(zhí)行后再寫日志不會阻塞當前的寫操作。

面試官:

那 后寫日志又有什么風險呢?

小張:

我... 這個我不會。

面試官:

好吧,后寫日志主要有兩個風險可能會發(fā)生:

數(shù)據(jù)可能會丟失:如果 Redis 剛執(zhí)行完命令,此時發(fā)生故障宕機,會導致這條命令存在丟失的風險。

可能阻塞其他操作:AOF 日志其實也是在主線程中執(zhí)行,所以當 Redis 把日志文件寫入磁盤的時候,還是會阻塞后續(xù)的操作無法執(zhí)行。

我還有個問題是 RDB做快照時會阻塞線程嗎?

小張:

Redis 提供了兩個命令來生成 RDB 快照文件,分別是 save 和 bgsave。save 命令在主線程中執(zhí)行,會導致阻塞。而 bgsave 命令則會創(chuàng)建一個子進程,用于寫入 RDB 文件的操作,避免了對主線程的阻塞,這也是 Redis RDB 的默認配置。

面試官:

RDB 做快照的時候數(shù)據(jù)能修改嗎?

小張:

save是同步的會阻塞客戶端命令,bgsave的時候是可以修改的。

面試官:

那Redis是怎么解決在bgsave做快照的時候允許數(shù)據(jù)修改呢?

小張:(你咋還問。。。我™不會啊!)

額,這個我不太清楚...

 

面試官:

這里主要是利用 bgsave的子線程實現(xiàn)的,具體操作如下:

  • 如果主線程執(zhí)行讀操作,則主線程和 bgsave 子進程互相不影響;
  • 如果主線程執(zhí)行寫操作,則被修改的數(shù)據(jù)會復(fù)制一份副本,然后 bgsave子進程會把該副本數(shù)據(jù)寫入 RDB 文件,在這個過程中,主線程仍然可以直接修改原來的數(shù)據(jù)。

 

要注意,Redis 對 RDB 的執(zhí)行頻率非常重要,因為這會影響快照數(shù)據(jù)的完整性以及 Redis 的穩(wěn)定性,所以在 Redis 4.0 后,增加了 AOF 和 RDB 混合的數(shù)據(jù)持久化機制: 把數(shù)據(jù)以 RDB 的方式寫入文件,再將后續(xù)的操作命令以 AOF 的格式存入文件,既保證了 Redis 重啟速度,又降低數(shù)據(jù)丟失風險。

小張:

學到了學到了。

面試官:

那你再跟我說說Redis如何實現(xiàn)高可用吧?

小張:

Redis實現(xiàn)高可用主要有三種方式:主從復(fù)制、哨兵模式,以及 Redis 集群。

主從復(fù)制

將從前的一臺 Redis 服務(wù)器,同步數(shù)據(jù)到多臺從 Redis 服務(wù)器上,即一主多從的模式,這個跟MySQL主從復(fù)制的原理一樣。

 

哨兵模式

使用 Redis 主從服務(wù)的時候,會有一個問題,就是當 Redis 的主從服務(wù)器出現(xiàn)故障宕機時,需要手動進行恢復(fù),為了解決這個問題,Redis 增加了哨兵模式(因為哨兵模式做到了可以監(jiān)控主從服務(wù)器,并且提供自動容災(zāi)恢復(fù)的功能)。

 

Redis Cluster(集群)

Redis Cluster 是一種分布式去中心化的運行模式,是在 Redis 3.0 版本中推出的 Redis 集群方案,它將數(shù)據(jù)分布在不同的服務(wù)器上,以此來降低系統(tǒng)對單主節(jié)點的依賴,從而提高 Redis 服務(wù)的讀寫性能。

 

面試官:

使用哨兵模式在數(shù)據(jù)上有副本數(shù)據(jù)做保證,在可用性上又有哨兵監(jiān)控,一旦master宕機會選舉salve節(jié)點為master節(jié)點,這種已經(jīng)滿足了我們的生產(chǎn)環(huán)境需要,那為什么還需要使用集群模式呢?

小張:

額,哨兵模式歸根節(jié)點還是主從模式,在主從模式下我們可以通過增加salve節(jié)點來擴展讀并發(fā)能力,但是沒辦法擴展寫能力和存儲能力,存儲能力只能是master節(jié)點能夠承載的上限。所以為了擴展寫能力和存儲能力,我們就需要引入集群模式。

面試官:

集群中那么多Master節(jié)點,redis cluster在存儲的時候如何確定選擇哪個節(jié)點呢?

小張:

這應(yīng)該是使用了某種hash算法,但是我不太清楚。。。

 

面試官:

那好,今天的面試就到這里吧,你先回去等我們的面試通知。

小張:

好的,謝謝面試官,你能告訴我redis cluster怎么實現(xiàn)節(jié)點選擇的嗎?

面試官:

Redis Cluster采用的是類一致性哈希算法實現(xiàn)節(jié)點選擇的,至于什么是一致性哈希算法你自己回去看看。

Redis Cluster將自己分成了16384個Slot(槽位),哈希槽類似于數(shù)據(jù)分區(qū),每個鍵值對都會根據(jù)它的 key,被映射到一個哈希槽中,具體執(zhí)行過程分為兩大步。

根據(jù)鍵值對的 key,按照 CRC16 算法計算一個 16 bit 的值。

再用 16bit 值對 16384 取模,得到 0~16383 范圍內(nèi)的模數(shù),每個模數(shù)代表一個相應(yīng)編號的哈希槽。

每個Redis節(jié)點負責處理一部分槽位,加入你有三個master節(jié)點 ABC,每個節(jié)點負責的槽位如下:

節(jié)點 處理槽位
A 0-5000
B 5001 - 10000
C 10001 - 16383

 

這樣就實現(xiàn)了cluster節(jié)點的選擇。

 

責任編輯:武曉燕 來源: JAVA日知錄
相關(guān)推薦

2025-01-07 09:07:36

接口屬性路徑

2025-04-11 00:05:49

RPC底層分布式

2022-06-15 08:00:50

磁盤RedisRocketMQ

2024-02-20 21:34:16

循環(huán)GolangGo

2021-08-27 07:06:10

IOJava抽象

2023-08-10 08:28:46

網(wǎng)絡(luò)編程通信

2023-08-04 08:20:56

DockerfileDocker工具

2023-06-30 08:18:51

敏捷開發(fā)模式

2022-05-24 08:21:16

數(shù)據(jù)安全API

2023-09-10 21:42:31

2023-04-03 14:20:44

面試C++函數(shù)

2023-11-07 08:13:53

分布式網(wǎng)絡(luò)

2022-10-28 07:27:17

Netty異步Future

2022-11-12 12:33:38

CSS預(yù)處理器Sass

2022-02-14 07:03:31

網(wǎng)站安全MFA

2022-01-04 12:08:46

設(shè)計接口

2022-06-26 09:40:55

Django框架服務(wù)

2023-04-26 07:30:00

promptUI非結(jié)構(gòu)化

2022-04-06 08:23:57

指針函數(shù)代碼

2023-12-28 09:55:08

隊列數(shù)據(jù)結(jié)構(gòu)存儲
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 日韩色图视频 | 黄色网址在线免费播放 | 天天操网| 中文字幕蜜臀 | 在线播放中文字幕 | 久久四虎 | 免费观看毛片 | 91一区二区三区在线观看 | 日韩视频在线免费观看 | 免费天天干| 亚洲一区二区av | 91精品国产91久久综合桃花 | 久久99精品久久久久久国产越南 | 五月激情六月婷婷 | 精品一区电影 | 秋霞在线一区 | 欧美日韩黄色一级片 | 欧美日日 | 精品中文字幕一区二区三区 | 国产毛片视频 | 日韩午夜在线播放 | 久久精品手机视频 | 91精品国产综合久久久久久丝袜 | 365夜爽爽欧美性午夜免费视频 | 国产一区二区不卡 | 国产成人精品综合 | 在线亚洲一区二区 | av电影一区二区 | 国产欧美日韩一区二区三区在线 | 日韩成人影院 | 日韩av在线一区二区三区 | 伊人精品在线 | 日韩中文欧美 | 毛片av免费看 | 91视频网址 | 国产在线观看 | 999国产视频 | 美女视频黄色的 | 成年人国产在线观看 | 亚洲网站在线观看 | 黄色免费网站在线看 |