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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

数据库

【Redis 开发与运维】总结篇

發(fā)布時(shí)間:2023/12/10 数据库 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Redis 开发与运维】总结篇 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • Redis 是什么?簡(jiǎn)述它的優(yōu)缺點(diǎn)?
  • Redis 為什么這么快?
  • Redis 相比 memcached 有哪些優(yōu)勢(shì)?
  • 說(shuō)說(shuō) Redis 的數(shù)據(jù)類型和使用場(chǎng)景
  • 如何通過(guò) Redis 實(shí)現(xiàn)分布式鎖
  • 如何使用 Redis 做異步隊(duì)列
  • 使用 Pipeline 的好處
  • Redis 過(guò)期鍵的刪除策略?
  • Redis 內(nèi)存淘汰機(jī)制?
  • Redis 持久化機(jī)制
  • 說(shuō)說(shuō)緩存設(shè)計(jì)中會(huì)出現(xiàn)的問(wèn)題和解決方案
  • 高并發(fā)場(chǎng)景下,如何解決數(shù)據(jù)庫(kù)與緩存雙寫(xiě)的時(shí)候數(shù)據(jù)不一致的情況?
  • Redis 中跳躍表 skiplist 實(shí)現(xiàn)原理
  • Redis 為什么用 skiplist 而不用紅黑樹(shù)?
  • 假如 Redis 里面有 1 億個(gè)key,其中有 10w 個(gè) key 是以某個(gè)固定的已知前綴開(kāi)頭的,如何將它們?nèi)空页鰜?lái)?
  • Redis6.0 為什么要引入多線程?
  • Redis 集群方案應(yīng)該怎么做?都有哪些方案?
  • 講一講位圖 Bitmap
  • 講一講 HyperLogLog
  • Redis 單線程如何處理那么多的并發(fā)客戶端連接?
  • 布隆過(guò)濾器的原理
  • 慢查詢場(chǎng)景有哪些?
  • 如何保證 redis/mysql 的一致性?


Redis 是什么?簡(jiǎn)述它的優(yōu)缺點(diǎn)?

  • Redis 本質(zhì)上是一個(gè) Key-Value 類型的內(nèi)存數(shù)據(jù)庫(kù),很像 memcached,整個(gè)數(shù)據(jù)庫(kù)統(tǒng)統(tǒng)加載在內(nèi)存當(dāng)中進(jìn)行操作,定期通過(guò)異步操作把數(shù)據(jù)庫(kù)數(shù)據(jù) flush 到硬盤(pán)上進(jìn)行保存。
  • 因?yàn)槭羌儍?nèi)存操作,Redis 的性能非常出色,每秒可以處理超過(guò) 10 萬(wàn)次讀寫(xiě)操作,是已知性能最快的 Key-Value DB。
  • Redis 的出色之處不僅僅是性能,Redis 最大的魅力是支持保存多種數(shù)據(jù)結(jié)構(gòu),此外單個(gè) value 的最大限制是 1GB,不像 memcached 只能保存 1MB 的數(shù)據(jù),因此 Redis 可以用來(lái)實(shí)現(xiàn)很多有用的功能。
  • Redis 的主要缺點(diǎn)是數(shù)據(jù)庫(kù)容量受到物理內(nèi)存的限制,不能用作海量數(shù)據(jù)的高性能讀寫(xiě),因此 Redis 適合的場(chǎng)景主要局限在較小數(shù)據(jù)量的高性能操作和運(yùn)算上。

Redis 為什么這么快?

  • 純內(nèi)存訪問(wèn),Redis 將所有數(shù)據(jù)都放在內(nèi)存中;
  • 采用的是基于非阻塞的 IO 多路復(fù)用機(jī)制,避免了網(wǎng)絡(luò) IO 上浪費(fèi)過(guò)多時(shí)間;
  • 單線程避免了線程切換和競(jìng)態(tài)產(chǎn)生的消耗。

Redis 相比 memcached 有哪些優(yōu)勢(shì)?

  • 數(shù)據(jù)類型:Redis 支持更豐富的數(shù)據(jù)類型(支持更復(fù)雜的應(yīng)用場(chǎng)景),Redis 不僅僅支持簡(jiǎn)單的 key/value 類型的數(shù)據(jù),同時(shí)還提供 list,set,zset,hash 等數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ)。memcache 只支持簡(jiǎn)單的數(shù)據(jù)類型 String。
  • 持久化:Redis 支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保持在磁盤(pán)中,重啟的時(shí)候可以再次加載進(jìn)行使用,而 Memecache 把數(shù)據(jù)全部存在內(nèi)存之中。
  • 集群模式:memcached 沒(méi)有原生的集群模式,需要依靠客戶端來(lái)實(shí)現(xiàn)往集群中分片寫(xiě)入數(shù)據(jù);而 Redis 原生支持集群模式。
  • 線程模型:Memcached 是多線程,非阻塞 IO 復(fù)用的網(wǎng)絡(luò)模型;Redis 使用單線程的多路 IO 復(fù)用模型。

說(shuō)說(shuō) Redis 的數(shù)據(jù)類型和使用場(chǎng)景

Redis 支持五種數(shù)據(jù)類型:string( 字符串),hash( 哈希),list( 列表),set( 集合)及 zset(sorted set:有序集合)。

  • string:redis 中字符串 value 最大可為 512M。可以用來(lái)做一些計(jì)數(shù)功能的緩存(也是實(shí)際工作中最常見(jiàn)的)。常規(guī)計(jì)數(shù):微博數(shù),粉絲數(shù)等。
  • hash:鍵值對(duì)集合,是一個(gè)字符串類型的 Key 和 Value 的映射表,也就是說(shuō)其存儲(chǔ)的 Value 是一個(gè)鍵值對(duì)(Key- Value),hash 特別適合用于存儲(chǔ)對(duì)象,后續(xù)操作的時(shí)候,可以直接僅僅修改這個(gè)對(duì)象中的某個(gè)字段的值。 比如我們可以 hash 數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)用戶信息,商品信息等等。
  • list:簡(jiǎn)單的字符串列表,按照插入順序排序,可以添加一個(gè)元素到列表的頭部(左邊)或者尾部(右邊),Redis list 的實(shí)現(xiàn)為一個(gè)雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過(guò)帶來(lái)了部分額外的內(nèi)存開(kāi)銷(xiāo)。可以實(shí)現(xiàn)一個(gè)簡(jiǎn)單消息隊(duì)列功能,做基于 redis 的分頁(yè)功能等。還可以通過(guò) lrange 命令做(微博、朋友圈)文章列表分頁(yè),就是從某個(gè)元素開(kāi)始讀取多少個(gè)元素,可以基于 list 實(shí)現(xiàn)高性能分頁(yè)。
  • set:是一個(gè)字符串類型的無(wú)序集合。可以用來(lái)進(jìn)行全局去重等,比如:在微博應(yīng)用中,可以將一個(gè)用戶所有的關(guān)注人存在一個(gè)集合中,將其所有粉絲存在一個(gè)集合,Redis 可以非常方便的實(shí)現(xiàn)如共同關(guān)注、共同粉絲、共同喜好等功能,這個(gè)過(guò)程也就是求交集的過(guò)程。
  • sorted set:是一個(gè)字符串類型的有序集合,給每一個(gè)元素一個(gè)固定的分?jǐn)?shù) score 來(lái)保持順序。可以用來(lái)做排行榜應(yīng)用或者進(jìn)行范圍查找等。

我們實(shí)際項(xiàng)目中比較常用的是 string、hash。 如果你是 Redis 的高級(jí)用戶,還需要加上下面幾種數(shù)據(jù)結(jié)構(gòu) HyperLogLog、Geo、Pub/Sub。

如果你說(shuō)還玩過(guò) Redis Module,像 BloomFilter,RedisSearch,Redis-ML,面試官得眼睛就開(kāi)始發(fā)亮了。

詳情請(qǐng)參考:《【Redis 開(kāi)發(fā)與運(yùn)維】API 的理解和使用》


如何通過(guò) Redis 實(shí)現(xiàn)分布式鎖

分布式鎖需要解決的問(wèn)題

  • 互斥性
  • 安全性
  • 死鎖
  • 容錯(cuò)

利用 SETNX key value:如果 key 不存在,則創(chuàng)建并賦值;設(shè)置成功,返回 1。設(shè)置失敗,返回 0。

問(wèn)題一:如何解決 SETNX 長(zhǎng)期有效的問(wèn)題

  • EXPIRE key seconds:設(shè)置 key 的生存時(shí)間,當(dāng) key 過(guò)期時(shí)(生存時(shí)間為0),會(huì)自動(dòng)被刪除
  • 缺點(diǎn):原子性得不到滿足,因?yàn)?SETNX 和 EXPIRE 命令是兩個(gè)操作不滿足原子性。

答:可以利用:SET key value [EX seconds] [PX milliseconds] [NX|XX]

  • Ex second:設(shè)置鍵的過(guò)期時(shí)間為 second 秒
  • PX milliseconds:設(shè)置鍵的過(guò)期時(shí)間為 millisecond 毫秒
  • NX:只在鍵不存在時(shí),才對(duì)鍵進(jìn)行設(shè)置操作
  • XX:只在鍵已經(jīng)存在時(shí),才對(duì)鍵進(jìn)行設(shè)置操作
  • SET 操作成功完成時(shí),返回 OK,否則返回 nil
  • 例如:set lock 12345 ex 10 nx,表示設(shè)置了一個(gè) key 為 lock 的鎖,鎖的過(guò)期時(shí)間為 10 秒

問(wèn)題二:怎么處理別人把我的鎖釋放(刪除)的問(wèn)題

  • 因?yàn)殒i的釋放無(wú)非就是刪除掉,那個(gè) key 嘛,刪了鎖就釋放了。

答:

  • 可以把鎖的值設(shè)為用戶 ID,刪除之前比對(duì)用戶 ID 和鎖的值是否相等,只有相等才能刪除。
  • 因?yàn)榕袛噫i相等和刪除鎖是兩個(gè)操作,不滿足原子性,于是可以利用 Lua 做到原子性。例如:
/*** 解鎖** @param id* @return*/ public boolean unlock(String id) {String script ="if redis.call('get',KEYS[1]) == ARGV[1] then" +" return redis.call('del',KEYS[1]) " +"else" +" return 0 " +"end";try {String result = jedis.eval(script, Collections.singletonList(LOCK_KEY), Collections.singletonList(id)).toString();return "1".equals(result) ? true : false;} finally {jedis.close();} }

大量的 key 同時(shí)過(guò)期的注意事項(xiàng)

  • 集中過(guò)期,由于清除大量的 key 很耗時(shí),會(huì)出現(xiàn)短暫的卡頓現(xiàn)象
  • 解決方案:在設(shè)置 key 的過(guò)期時(shí)間的時(shí)候,給每個(gè) key 加上隨機(jī)值

問(wèn)題三:鎖過(guò)期時(shí)間到了業(yè)務(wù)沒(méi)執(zhí)行完怎么辦?

  • 默認(rèn)情況下,加鎖的時(shí)間是 30 秒,如果加鎖的業(yè)務(wù)沒(méi)有執(zhí)行完,那么到 30-10 = 20 秒的時(shí)候,就會(huì)進(jìn)行一次續(xù)期,把鎖重置成 30 秒,那這個(gè)時(shí)候可能又有同學(xué)問(wèn)了,那業(yè)務(wù)的機(jī)器萬(wàn)一宕機(jī)了呢?宕機(jī)了定時(shí)任務(wù)跑不了,就續(xù)不了期,那自然30秒之后鎖就解開(kāi)了唄。

如何使用 Redis 做異步隊(duì)列

使用 Redis 的 List 作為隊(duì)列,RPUSH 生產(chǎn)消息,LPOP 消費(fèi)消息

  • 缺點(diǎn):沒(méi)有等待隊(duì)列里有值就直接消費(fèi)
  • 彌補(bǔ):可以通過(guò)在應(yīng)用層引入 Sleep 機(jī)制去調(diào)用 LPOP 重試

BLPOP key [key ...] timeout:阻塞直到隊(duì)列有消息或者超時(shí)

  • 缺點(diǎn):只能供一個(gè)消費(fèi)者消費(fèi)

pub/sub:主題訂閱者模式

  • 發(fā)送者(pub)發(fā)送消息,如:publish myTopic hello,表示向 myTopic 發(fā)布消息 hello
  • 訂閱者(sub)接收消息,如:subscribe myTopic,表示訂閱 myTopic 的消息
  • 訂閱者可以訂閱任意數(shù)量的頻道

    缺點(diǎn):消息的發(fā)布是無(wú)狀態(tài)的,無(wú)法保證可達(dá),消息還是即發(fā)即失的

使用 Pipeline 的好處

  • Redis 提供了批量操作命令(例如 mget、mset 等),有效地節(jié)約 RTT(Round Trip Time,往返時(shí)間)。但大部分命令是不支持批量操作的,例如要執(zhí)行 n 次 hset 命令,并沒(méi)有 mhset 命令存在,需要消耗 n 次 RTT。
  • Pipeline(流水線)機(jī)制能改善上面這類問(wèn)題,它能將一組 Redis 命令進(jìn)行組裝,通過(guò)一次 RTT 傳輸給 Redis,再將這組 Redis 命令的執(zhí)行結(jié)果按順序返回給客戶端。

詳情請(qǐng)參考:Redis 一些超好用的功能特性


Redis 過(guò)期鍵的刪除策略?

  • 定時(shí)刪除:超時(shí)時(shí)間到達(dá)時(shí),刪除
  • 惰性刪除:再次訪問(wèn)過(guò)期數(shù)據(jù)時(shí),刪除
  • 定期刪除:每隔一定周期,刪除
  • 對(duì)于定時(shí)刪除:由于數(shù)據(jù)庫(kù)可能同時(shí)接受成千上萬(wàn)個(gè)用戶的訪問(wèn),那么可能有大量的 key 需要?jiǎng)h除,如果我們?yōu)槊恳粋€(gè) key 的超時(shí)時(shí)間都設(shè)置一個(gè)定時(shí)器,每次超時(shí)就進(jìn)行刪除操作,那么會(huì)導(dǎo)致系統(tǒng)性能非常低。
  • 對(duì)于惰性刪除:如果一個(gè)過(guò)期 key 長(zhǎng)期沒(méi)有被訪問(wèn),那么該 key-value 對(duì)將會(huì)一直存儲(chǔ)在數(shù)據(jù)庫(kù)中,會(huì)一直占有內(nèi)存。而 redis 又是一個(gè)基于內(nèi)存的數(shù)據(jù)庫(kù),這樣很容易導(dǎo)致內(nèi)存被耗盡。
  • 對(duì)于定期刪除 :redis 難以確定執(zhí)行刪除操作的時(shí)長(zhǎng)和頻率
  • 因此 redis 采用惰性刪除和定期刪除相結(jié)合的方式,來(lái)刪除系統(tǒng)中的過(guò)期鍵

Redis 內(nèi)存淘汰機(jī)制?

  • Redis v4.0 前提供 6 種數(shù)據(jù)淘汰策略:
    • volatile-lru:利用 LRU 算法移除設(shè)置過(guò)期時(shí)間的 key(LRU:最近最少使用,Least Recently Used )
    • volatile-ttl:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集中挑選將要過(guò)期的數(shù)據(jù)淘汰
    • volatile-random:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集中任意選擇數(shù)據(jù)淘汰
    • allkeys-lru:當(dāng)內(nèi)存不足以容納新寫(xiě)入數(shù)據(jù)時(shí),在鍵空間中,移除最近最少使用的 key(這個(gè)是最常用的)
    • allkeys-random:當(dāng)內(nèi)存不足以容納新寫(xiě)入數(shù)據(jù)時(shí),從數(shù)據(jù)集中任意選擇數(shù)據(jù)淘汰
    • no-eviction:禁止驅(qū)逐數(shù)據(jù),也就是說(shuō)當(dāng)內(nèi)存不足以容納新寫(xiě)入數(shù)據(jù)時(shí),新寫(xiě)入操作會(huì)報(bào)錯(cuò)。
  • Redis v4.0 后增加以下 2 種:
    • volatile-lfu:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集中挑選最不經(jīng)常使用的數(shù)據(jù)淘汰(LFU,Least Frequently Used)算法,也就是最頻繁被訪問(wèn)的數(shù)據(jù)將來(lái)最有可能被訪問(wèn)到。
    • allkeys-lfu:當(dāng)內(nèi)存不足以容納新寫(xiě)入數(shù)據(jù)時(shí),在鍵空間中,移除最不經(jīng)常使用的 key。

Redis 持久化機(jī)制

詳情請(qǐng)參考:《【Redis 開(kāi)發(fā)與運(yùn)維】RDB 和 AOF 數(shù)據(jù)持久化》


說(shuō)說(shuō)緩存設(shè)計(jì)中會(huì)出現(xiàn)的問(wèn)題和解決方案

詳情請(qǐng)參考:《【Redis 開(kāi)發(fā)與運(yùn)維】緩存設(shè)計(jì)》


高并發(fā)場(chǎng)景下,如何解決數(shù)據(jù)庫(kù)與緩存雙寫(xiě)的時(shí)候數(shù)據(jù)不一致的情況?

Redis 中跳躍表 skiplist 實(shí)現(xiàn)原理

跳表(skiplist)是一個(gè)特殊的鏈表,相比一般的鏈表,有更高的查找效率,其效率可比擬于二叉查找樹(shù)。

跳表的性質(zhì):

  • 由很多層結(jié)構(gòu)組成
  • 每一層都是一個(gè)有序的鏈表
  • 最底層(Level 1)的鏈表包含所有元素
  • 如果一個(gè)元素出現(xiàn)在 Level i 的鏈表中,則它在 Level i 之下的鏈表也都會(huì)出現(xiàn)
  • 每個(gè)節(jié)點(diǎn)包含兩個(gè)指針,一個(gè)指向同一鏈表中的下一個(gè)元素,一個(gè)指向下面一層的元素。

隨機(jī)層數(shù)的設(shè)計(jì):

  • Redis 使用隨機(jī)層數(shù),解決插入、刪除時(shí),時(shí)間復(fù)雜度重新蛻化成 O(n) 的問(wèn)題
  • 它不要求上下相鄰兩層鏈表之間的節(jié)點(diǎn)個(gè)數(shù)有嚴(yán)格的對(duì)應(yīng)關(guān)系,而是為每個(gè)節(jié)點(diǎn)隨機(jī)出一個(gè)層數(shù)(level)。比如,一個(gè)節(jié)點(diǎn)隨機(jī)出的層數(shù)是 3,那么就把它鏈入到第 1 層到第 3 層這三層鏈表中。

隨機(jī)層數(shù)的計(jì)算方式:

  • 執(zhí)行插入操作時(shí)計(jì)算隨機(jī)數(shù)的過(guò)程,是一個(gè)很關(guān)鍵的過(guò)程,它對(duì) skiplist 的統(tǒng)計(jì)特性有著很重要的影響。這并不是一個(gè)普通的服從均勻分布的隨機(jī)數(shù),它的計(jì)算過(guò)程如下:
    • 首先,每個(gè)節(jié)點(diǎn)肯定都有第 1 層指針(每個(gè)節(jié)點(diǎn)都在第 1 層鏈表里)。
    • 如果一個(gè)節(jié)點(diǎn)有第 i 層(i >= 1)指針(即節(jié)點(diǎn)已經(jīng)在第 1 層到第 i 層鏈表中),那么它有第(i + 1)層指針的概率為 p。
    • 節(jié)點(diǎn)最大的層數(shù)不允許超過(guò)一個(gè)最大值,記為 MaxLevel。
  • 這個(gè)計(jì)算隨機(jī)層數(shù)的偽碼如下所示:
randomLevel()level := 1// random()返回一個(gè)[0...1)的隨機(jī)數(shù)while random() < p and level < MaxLevel dolevel := level + 1return level
  • randomLevel() 的偽碼中包含兩個(gè)參數(shù),一個(gè)是 p,一個(gè)是 MaxLevel。在 Redis 的 skiplist 實(shí)現(xiàn)中,這兩個(gè)參數(shù)的取值為:
p = 1/4 MaxLevel = 32
  • 所以,根據(jù)前面 randomLevel() 的偽碼,我們很容易看出,產(chǎn)生越高的節(jié)點(diǎn)層數(shù),概率越低。
  • 當(dāng) skiplist 中有 n 個(gè)節(jié)點(diǎn)的時(shí)候,它的總層數(shù)的概率均值是多少。這個(gè)問(wèn)題直觀上比較好理解。根據(jù)節(jié)點(diǎn)的層數(shù)隨機(jī)算法,容易得出:
    • 第 1 層鏈表固定有 n 個(gè)節(jié)點(diǎn);
    • 第 2 層鏈表平均有 n*p 個(gè)節(jié)點(diǎn);
    • 第 3 層鏈表平均有 n*p*p 個(gè)節(jié)點(diǎn);

Redis 為什么用 skiplist 而不用紅黑樹(shù)?

  • 插入、刪除、查找以及迭代輸出有序序列這幾個(gè)操作,紅黑樹(shù)也可以完成,時(shí)間復(fù)雜度跟跳表是一樣的。但是,按照區(qū)間來(lái)查找數(shù)據(jù)這個(gè)操作,紅黑樹(shù)的效率沒(méi)有跳表高,跳表可以做到 O(logn) 的時(shí)間復(fù)雜度;
  • 比起紅黑樹(shù)來(lái)說(shuō),跳表更容易代碼實(shí)現(xiàn);
  • 跳表更加靈活,它可以通過(guò)改變索引構(gòu)建策略有效平衡執(zhí)行效率和內(nèi)存消耗。

假如 Redis 里面有 1 億個(gè)key,其中有 10w 個(gè) key 是以某個(gè)固定的已知前綴開(kāi)頭的,如何將它們?nèi)空页鰜?lái)?

使用 keys 指令可以掃出指定模式的 key 列表。

追問(wèn):如果這個(gè) redis 正在給線上的業(yè)務(wù)提供服務(wù), 那使用 keys 指令會(huì)有什么問(wèn)題?

keys 指令會(huì)導(dǎo)致線程阻塞一段時(shí)間, 線上服務(wù)會(huì)停頓, 直到指令執(zhí)行完畢, 服務(wù)才能恢復(fù)。

可以使用 SCAN cusor [MATCH patten] [COUNT count],每次只返回少量元素

  • 基于游標(biāo)的迭代器,需要基于上一次的游標(biāo)延續(xù)之前的迭代過(guò)程
  • 以 0 作為游標(biāo)開(kāi)始一次新的迭代,直到命令返回游標(biāo) 0 完成一次遍歷,記得將上次返回的游標(biāo)作為下次 SCAN 的游標(biāo)
  • 不保證每次執(zhí)行都返回某個(gè)給定數(shù)量的元素,只能是大概率符合 count 參數(shù),支持模糊查詢
  • 可能會(huì)獲取到重復(fù) key 的問(wèn)題,需要在客戶端進(jìn)行去重,比如用 HashSet 接收
  • 如:scan 0 match k1* count 10,表示將鍵為 k1 開(kāi)頭的從 0 開(kāi)始的游標(biāo)數(shù) 10 個(gè)(10 個(gè)以內(nèi),不一定是 10 個(gè))返回

Redis6.0 為什么要引入多線程?

  • Redis6.0 的多線程是指,將網(wǎng)絡(luò)數(shù)據(jù)讀寫(xiě)和協(xié)議解析通過(guò)多線程的方式來(lái)處理,對(duì)于命令執(zhí)行來(lái)說(shuō),仍然使用單線程操作。也就是說(shuō),Redis6.0 的多線程是為了解決其網(wǎng)絡(luò) IO 的瓶頸。

Redis 集群方案應(yīng)該怎么做?都有哪些方案?

詳情請(qǐng)參考:《【Redis 開(kāi)發(fā)與運(yùn)維】Redis Cluster 集群》


講一講位圖 Bitmap

詳情請(qǐng)參考:【Redis 開(kāi)發(fā)與運(yùn)維】小功能大用處


講一講 HyperLogLog

HyperLogLog,它是 LogLog 算法的升級(jí)版,作用是能夠提供不精確的去重計(jì)數(shù)。存在以下的特點(diǎn):

  • 能夠使用極少的內(nèi)存來(lái)統(tǒng)計(jì)巨量的數(shù)據(jù),在 Redis 中實(shí)現(xiàn)的 HyperLogLog,只需要 12K 內(nèi)存就能統(tǒng)計(jì) 2^64 個(gè)數(shù)據(jù)
  • 計(jì)數(shù)存在一定的誤差,誤差率整體較低,標(biāo)準(zhǔn)誤差為 0.81%
  • 誤差可以被設(shè)置輔助計(jì)算因子進(jìn)行降低

為什么用 HyperLogLog,例如以下場(chǎng)景:

統(tǒng)計(jì) APP 或網(wǎng)頁(yè)的一個(gè)頁(yè)面,每天有多少用戶點(diǎn)擊進(jìn)入的次數(shù),同一個(gè)用戶的反復(fù)點(diǎn)擊進(jìn)入記為 1 次。

這種場(chǎng)景用 HashMap 這種數(shù)據(jù)結(jié)構(gòu)也可以,但是假設(shè) APP 中日活用戶達(dá)到百萬(wàn)或千萬(wàn)以上級(jí)別的話,采用 HashMap 的做法就會(huì)導(dǎo)致程序中占用大量的內(nèi)存。


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

因?yàn)?Redis 的線程模型:基于非阻塞的 IO 多路復(fù)用機(jī)制。多路指的是多個(gè) Socket 連接,復(fù)用指的是復(fù)用一個(gè)線程。

Redis 采用 IO 多路復(fù)用機(jī)制同時(shí)監(jiān)聽(tīng)多個(gè) Socket,多個(gè) Socket 會(huì)產(chǎn)生不同的事件,不同的事件對(duì)應(yīng)著不同的操作,當(dāng)這些 Socket 產(chǎn)生了事件,IO 多路復(fù)用程序會(huì)將這些事件放到一個(gè)隊(duì)列中,通過(guò)這個(gè)隊(duì)列,以有序、同步、每次一個(gè)事件的方式向文件時(shí)間分派器中傳送。當(dāng)事件處理器處理完一個(gè)事件后,IO 多路復(fù)用程序才會(huì)繼續(xù)向文件分派器傳送下一個(gè)事件。


布隆過(guò)濾器的原理

首先需要 k 個(gè) hash 函數(shù),每個(gè)函數(shù)可以把 key 散列成為 1 個(gè)整數(shù);

初始化時(shí),需要一個(gè)長(zhǎng)度為 n 比特的數(shù)組,每個(gè)比特位初始化為 0;

某個(gè) key 加入集合時(shí),用 k 個(gè) hash 函數(shù)計(jì)算出 k 個(gè)散列值,并把數(shù)組中對(duì)應(yīng)的比特位置為 1;

判斷某個(gè) key 是否在集合時(shí),用 k 個(gè) hash 函數(shù)計(jì)算出 k 個(gè)散列值,并查詢數(shù)組中對(duì)應(yīng)的比特位,如果所有的比特位都是 1,則命中,但不一定在集合中,如果存在比特位為 0,則未命中,一定不在集合中。

優(yōu)點(diǎn):不需要存儲(chǔ) key,節(jié)省空間

缺點(diǎn):

  • 算法判斷 key 在集合中時(shí),有一定的概率 key 其實(shí)不在集合中
  • 無(wú)法刪除

慢查詢場(chǎng)景有哪些?

  • 使用 O(n) 復(fù)雜度的命令,比如 keys *
  • 大對(duì)象的查詢也有可能造成慢查詢
  • 關(guān)于阻塞的原因,請(qǐng)參考:Redis 的噩夢(mèng):阻塞

如何保證 redis/mysql 的一致性?


巨人的肩膀:https://github.com/cosen1024/Java-Interview/blob/main/Redis/Redis.md

總結(jié)

以上是生活随笔為你收集整理的【Redis 开发与运维】总结篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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