自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

12 個問題搞懂 Redis

存儲 Redis
隨著硬件性能的提升,Redis 的性能瓶頸有時會出現(xiàn)在網(wǎng)絡(luò) IO 的處理上,也就是說,單個主線程處理網(wǎng)絡(luò)請求的速度跟不上底層網(wǎng)絡(luò)硬件的速度,而讀寫的操作和網(wǎng)絡(luò) IO 是在一個主線程中,勢必會有所影響。

[[423393]]

都說學(xué)習(xí)需要帶著問題,帶著思考進(jìn)行學(xué)習(xí),下面就以問題的形式來學(xué)習(xí)下 Redis 。

1、什么是 Redis ?

  • Redis 是一個高性能的 key-value 數(shù)據(jù)庫;
  • 作者來自意大利西西里島的 Salvatore Sanfilippo ;
  • Redis 使用 ANSI C 語言編寫、并遵守 BSD 開源協(xié)議;
  • Redis 支持網(wǎng)絡(luò)、可基于內(nèi)存、分布式、也可以用來實(shí)現(xiàn)簡易的消息隊(duì)列;
  • 提供豐富的數(shù)據(jù)結(jié)構(gòu):字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets) 。

2、都說 Redis 是單線程模型,到底是什么意思?

  • 單線程并不是說在 Redis 中所有的操作都是由一個線程來完成;
  • 核心功能,比如:網(wǎng)絡(luò) IO 和數(shù)據(jù)的讀寫是由一個線程來進(jìn)行處理的;
  • 其他的一些輔助功能,比如:持久化、集群間的數(shù)據(jù)同步是由單獨(dú)的線程進(jìn)行處理;
  • 所以說 Redis 的單線程不是“真正”的單線程。

3、為什么在數(shù)據(jù)讀寫處理上不使用多線程?

  • 多線程雖然可以增加系統(tǒng)的吞吐率,但線程的切換會有開銷;
  • 多個線程對共享資源的并發(fā)處理問題,必然會用到各種鎖,有鎖就會存在等待鎖的釋放,反而吞吐率降低了;
  • 處理各種多線程帶來的問題,會使系統(tǒng)變得復(fù)雜,復(fù)雜的系統(tǒng)就容易出現(xiàn)問題。

4、為什么使用單線程,速度卻很快?

  • Redis 的操作是基于內(nèi)存的,相比較于磁盤,速度上有先天的優(yōu)勢;
  • Redis 有高效的數(shù)據(jù)結(jié)構(gòu),比如:哈希表、跳表;
  • 采用了多路復(fù)用機(jī)制,可以并發(fā)處理大量的請求,實(shí)現(xiàn)高吞吐率。

5、單線程處理的瓶頸是什么?

  • 如果有耗時長的操作,后面的請求都需要進(jìn)行等待;
  • 單個 value 的內(nèi)容過大,在添加、獲取、刪除時都會比較耗時;
  • 使用復(fù)雜的命令,比如:SORT/SUNION/ZUNIONSTORE;
  • 集合的數(shù)據(jù)非常大,而又進(jìn)行了全量查詢。
  • 并發(fā)量非常大時,雖然 IO 有多路復(fù)用機(jī)制,從內(nèi)核緩沖區(qū)中拷貝數(shù)據(jù)的操作仍然是同步操作,會帶來性能瓶頸。

6、Redis 6.0 調(diào)整為多線程的原因?

  • 上面提到過 6.0 之前的版本是網(wǎng)絡(luò) IO 和數(shù)據(jù)讀寫是在一個線程中完成的;
  • 隨著硬件性能的提升,Redis 的性能瓶頸有時會出現(xiàn)在網(wǎng)絡(luò) IO 的處理上,也就是說,單個主線程處理網(wǎng)絡(luò)請求的速度跟不上底層網(wǎng)絡(luò)硬件的速度,而讀寫的操作和網(wǎng)絡(luò) IO 是在一個主線程中,勢必會有所影響;
  • 所以在 Redis 6.0 中,網(wǎng)絡(luò) IO 是由多個 IO 線程并行處理,可以充分利用服務(wù)器的多核資源,提高網(wǎng)絡(luò)讀寫操作;
  • Redis 數(shù)據(jù)的讀寫處理仍然在單個主線程中完成。

7、在 Redis 中怎樣做持久化?

  • 在 Redis 實(shí)現(xiàn)持久化有兩種方式:AOF 日志 和 RDB 快照;
  • AOF 日志
    • 命令執(zhí)行成功后,才記錄日志;
    • 命令執(zhí)行后進(jìn)行日志記錄,不會堵塞當(dāng)前的寫操作。
    • 命令執(zhí)行完,日志記錄前宕機(jī),數(shù)據(jù)會丟失;
    • AOF 日志在主線程中執(zhí)行,有 IO 瓶頸時會對后面的操作有堵塞風(fēng)險;
    • 數(shù)據(jù)量比較大的時候,恢復(fù)很慢。
    • 配置項(xiàng)(appendfsync)

Always,同步寫回磁盤:每個寫命令執(zhí)行完,立即同步將日志寫回磁盤;

Everysec,每秒寫回磁盤:每個寫命令執(zhí)行完,只是先把日志寫到 AOF 文件的內(nèi)存緩沖區(qū),每隔一秒把緩沖區(qū)中的內(nèi)容寫入磁盤;

No,操作系統(tǒng)控制的寫回磁盤:每個寫命令執(zhí)行完,只是先把日志寫到 AOF 文件的內(nèi)存緩沖區(qū),由操作系統(tǒng)決定何時將緩沖區(qū)內(nèi)容寫回磁盤。

RDB 快照

  • 和 AOF 相比較,RDB 快照記錄的是某一個時刻的數(shù)據(jù),數(shù)據(jù)恢復(fù)是直接將 RDB 文件讀入內(nèi)存,速度很快;
  • 生成 RDB 文件的兩種方式:
    • save:在主線程中執(zhí)行,會導(dǎo)致阻塞;
    • bgsave:創(chuàng)建一個子進(jìn)程,專門用于寫入 RDB 文件,避免了主線程的阻塞,這也是 Redis RDB 文件生成的默認(rèn)配置。子進(jìn)程是由主線程 fork 生成的,可以共享主線程的所有內(nèi)存數(shù)據(jù)。
  • RDB 快照的間隔時間不宜設(shè)置過短,因?yàn)轭l繁進(jìn)行 Redis 的全量快照,會帶來性能問題:
    • 前一個快照還沒做完,后面一個開始了,會給磁盤帶來壓力;
    • bgsave 的子進(jìn)程雖然不會阻塞主線程,但創(chuàng)建的過程會阻塞,頻繁創(chuàng)建也會帶來性能問題。
  • 解決上面問題的一種辦法就是使用增量快照;
  • 在 Redis 4.0 中提出了一種混合 AOF 日志和 RDB 快照的方式:
    • RDB 快照的間隔時間可以設(shè)置比較大,就不會影響到主線程的操作;
    • 在快照的間隔期間可以使用 AOF 日志記錄所有的操作,當(dāng)下一次做全量 RDB 快照的時候,清空 AOF 日志;
    • 通過 aof-use-rdb-preamble yes 來進(jìn)行設(shè)置。

8、常說的緩存雪崩、擊穿、穿透是什么?

  • 雪崩、擊穿、穿透最終的結(jié)果都是請求壓力會轉(zhuǎn)移到數(shù)據(jù)庫,導(dǎo)致系統(tǒng)崩潰,但場景有所區(qū)別;
  • 雪崩
    • 大量的不同請求無法在 Redis 中命中,導(dǎo)致請求都流向了數(shù)據(jù)庫,數(shù)據(jù)庫的壓力劇增;
    • 發(fā)生雪崩的原因可能是,有大量的緩存 Key 在同一時間過期。
  • 擊穿
    • 并發(fā)很大的情況下,針對某個特定的請求,緩存中數(shù)據(jù)不存在,導(dǎo)致都請求到了數(shù)據(jù)庫,造成數(shù)據(jù)庫壓力過大;
    • 原因通常是某個 Key 過期了;
    • 和雪崩相比較,擊穿是針對的單個 Key。
  • 穿透
    • 緩存穿透是指請求的數(shù)據(jù)不在 Redis 緩存中,也不在數(shù)據(jù)庫中,導(dǎo)致訪問緩存時,找不到數(shù)據(jù),會去請求數(shù)據(jù)庫,而在數(shù)據(jù)庫中也找不到相應(yīng)的數(shù)據(jù);
    • 并發(fā)比較大的時候,數(shù)據(jù)庫會遭受巨大的壓力;
  • 發(fā)生穿透的原因可能有兩個:
    • 誤操作導(dǎo)致 Redis 和數(shù)據(jù)庫中的數(shù)據(jù)都被刪除了;
    • 惡意攻擊。

9、怎樣解決雪崩、擊穿、穿透帶來的問題?

  • 雪崩
    • 緩存的數(shù)據(jù)過期時間設(shè)置隨機(jī),防止同一時間大量數(shù)據(jù)過期現(xiàn)象發(fā)生;
    • 如果緩存數(shù)據(jù)庫是分布式部署,將熱數(shù)據(jù)均勻分布在不同緩存數(shù)據(jù)庫中;
    • 當(dāng)發(fā)生雪崩時,可以通過服務(wù)降級來應(yīng)對。
  • 擊穿
    • 設(shè)置熱數(shù)據(jù)永遠(yuǎn)不過期。
  • 穿透
    • 在接口層進(jìn)行校驗(yàn),將惡意請求直接過濾掉;
    • 使用布隆過濾器快速判斷數(shù)據(jù)是否存在;
    • 緩存空值或缺省值。

10、怎樣設(shè)計(jì)緩存的淘汰機(jī)制?

業(yè)務(wù)數(shù)據(jù)在不斷地增長,不可能將所有數(shù)據(jù)全部存儲在 Redis 緩存中,內(nèi)存的價格遠(yuǎn)遠(yuǎn)大于磁盤。所以需要做淘汰機(jī)制的設(shè)計(jì);

緩存的淘汰就是根據(jù)一定的策略,將不太重要的數(shù)據(jù)從緩存中進(jìn)行刪除;

Redis 一共有 8 種淘汰策略,在 Redis 4.0 之前有 6 種,4.0 之后又增加了 2 種,如下圖:

  • 緩存策略的解釋:
    • volatile-random:在設(shè)置了過期時間的數(shù)據(jù)中,進(jìn)行隨機(jī)刪除;
    • volatile-ttl:根據(jù)過期時間,越早過期的數(shù)據(jù)越先刪除;
    • volatile-lru:在設(shè)置了過期時間的數(shù)據(jù)中,根據(jù) LRU 算法進(jìn)行數(shù)據(jù)刪除;
    • volatile-lfu:在設(shè)置了過期時間的數(shù)據(jù)中,根據(jù) LFU 算法進(jìn)行數(shù)據(jù)刪除;
    • allkeys-lru:在所有數(shù)據(jù)中,根據(jù) LRU 算法進(jìn)行數(shù)據(jù)刪除;
    • allkeys-random:在所有數(shù)據(jù)中,進(jìn)行隨機(jī)刪除;
    • allkeys-lfu:在所有數(shù)據(jù)中,根據(jù) LFU 算法進(jìn)行數(shù)據(jù)刪除;
  • 默認(rèn)情況下,當(dāng) Redis 的使用空間超過 maxmemory 設(shè)置的大小時,并不會淘汰數(shù)據(jù),也就是執(zhí)行的 noeviction 策略,如果寫滿,再有寫請求時就會出錯;
  • 如果業(yè)務(wù)中有明顯的熱數(shù)據(jù)和冷數(shù)據(jù),優(yōu)先使用 allkeys-lru 策略,讓熱數(shù)據(jù)保留在緩存中;
  • 如果業(yè)務(wù)中沒有明顯冷熱數(shù)據(jù),可以使用 volatile-random 或 allkeys-random。

11、怎樣保證緩存和數(shù)據(jù)庫的數(shù)據(jù)一致?

  • 緩存和數(shù)據(jù)庫一致的意思是,當(dāng)緩存中有數(shù)據(jù)時,緩存和數(shù)據(jù)庫數(shù)據(jù)相同,當(dāng)沒有數(shù)據(jù)時,數(shù)據(jù)庫中是最新的;
  • 在做增刪改操作的時候,對緩存的更新有兩種方式:
    • 新增直接添加到數(shù)據(jù)庫,刪除和修改時先更新緩存,然后同步或異步進(jìn)行數(shù)據(jù)庫的更新;
    • 新增直接添加到數(shù)據(jù)庫,刪除和修改時先更新數(shù)據(jù)庫,再刪除對應(yīng)的緩存。
  • 上面的操作都涉及到兩個,操作 Redis 和操作數(shù)據(jù)庫,當(dāng)其中一個成功一個失敗時就會出現(xiàn)數(shù)據(jù)不一致的情況;
  • 解決不一致的問題:
    • 將操作通過消息隊(duì)列異步處理,設(shè)置重試機(jī)制,保證最終的一致性;
    • 使用分布式事務(wù),保證操作 Redis 和數(shù)據(jù)庫的兩個操作在一個事務(wù)中。

12、Redis 有什么使用規(guī)范?

 

  • Redis 單實(shí)例的內(nèi)存大小都不要設(shè)置太大,建議在 2~6GB ,設(shè)置太大,會導(dǎo)致 RDB 快照、從 AOF 日志恢復(fù)、主從集群進(jìn)行數(shù)據(jù)同步等都會耗時很長,阻塞正常請求的處理;
  • 對集合進(jìn)行全量數(shù)據(jù)獲取時,時間復(fù)雜度是 O(n),所以這個 n 不宜太大;
  • 單個 key 的值不要太大,即便是最新的 6.0 版本,在讀寫這部分仍然是單線程,大 value 的讀取會耗時,導(dǎo)致堵塞;
  • 根據(jù)具體的業(yè)務(wù)特點(diǎn)設(shè)計(jì)好淘汰策略;
  • 使用高效的序列化和壓縮方法對緩存數(shù)據(jù)進(jìn)行處理,來進(jìn)一步提升性能;
  • 生產(chǎn)環(huán)境中禁止使用 KEYS、FLUSHALL、FLUSHDB 等操作,數(shù)據(jù)量大的時候耗時長,會阻塞主線程;
  • 有時為了排查錯誤,會使用 MONITOR 命令進(jìn)行監(jiān)控,該命令也會對性能造成嚴(yán)重影響;
  • Redis 的知識遠(yuǎn)不止如此,本文總結(jié)了一些我認(rèn)為比較重要的一些點(diǎn),希望對您有所幫助!

 

責(zé)任編輯:武曉燕 來源: 不止dotNET
相關(guān)推薦

2020-03-26 10:33:36

工業(yè)互聯(lián)網(wǎng)概念

2020-03-26 10:25:26

工業(yè)互聯(lián)網(wǎng)IT工業(yè)物聯(lián)網(wǎng)

2020-03-27 15:49:17

工業(yè)物聯(lián)網(wǎng)技術(shù)5G

2022-03-24 08:51:48

Redis互聯(lián)網(wǎng)NoSQL

2013-07-03 09:30:53

軟件定義網(wǎng)絡(luò)SDN

2023-11-07 11:20:04

2019-07-15 09:09:29

RedisJava操作系統(tǒng)

2020-08-26 12:03:58

iPhone 12蘋果手機(jī)

2018-04-03 14:49:24

2022-11-11 08:19:03

redis分布式

2021-03-10 09:42:30

數(shù)字人民幣數(shù)字貨幣區(qū)塊鏈

2021-03-10 14:50:44

數(shù)字人民幣加密貨幣貨幣

2010-10-09 13:07:51

Javascript兼容

2020-01-14 10:17:13

深度學(xué)習(xí)人生第一份工作人工智能

2023-02-09 15:33:48

數(shù)據(jù)質(zhì)量數(shù)據(jù)集

2011-03-28 09:23:22

云計(jì)算提供商

2010-07-28 09:42:57

DB2性能

2023-02-02 14:28:33

數(shù)據(jù)質(zhì)量數(shù)據(jù)集

2018-07-11 09:10:34

閃存供應(yīng)商陣列

2025-02-19 08:00:00

移動端移動設(shè)備移動開發(fā)
點(diǎn)贊
收藏

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