偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

解決了Redis的這些問(wèn)題,你就是Redis高手

數(shù)據(jù)庫(kù) 其他數(shù)據(jù)庫(kù) Redis
Redis 本質(zhì)上是一個(gè) Key-Value 類型的內(nèi)存數(shù)據(jù)庫(kù), 整個(gè)數(shù)據(jù)庫(kù)加載在內(nèi)存當(dāng)中進(jìn)行操作, 定期通過(guò)異步操作把數(shù)據(jù)庫(kù)數(shù)據(jù) flush 到硬盤上進(jìn)行保存。

 解決了redis的這些問(wèn)題,你就是redis高手

什么是Redis?

Redis 本質(zhì)上是一個(gè) Key-Value 類型的內(nèi)存數(shù)據(jù)庫(kù), 整個(gè)數(shù)據(jù)庫(kù)加載在內(nèi)存當(dāng)中進(jìn)行操作, 定期通過(guò)異步操作把數(shù)據(jù)庫(kù)數(shù)據(jù) flush 到硬盤上進(jìn)行保存。

因?yàn)槭羌儍?nèi)存操作, Redis 的性能非常出色, 每秒可以處理超過(guò) 10 萬(wàn)次讀寫操作, 是已知性能

最快的 Key-Value DB。

Redis 的出色之處不僅僅是性能, Redis 最大的魅力是支持保存多種數(shù)據(jù)結(jié)構(gòu), 此外單個(gè)

value 的最大限制是 1GB, 不像 memcached 只能保存 1MB 的數(shù)據(jù), 因此 Redis 可以用

來(lái)實(shí)現(xiàn)很多有用的功能,比方說(shuō)用他的 List 來(lái)做 FIFO 雙向鏈表,實(shí)現(xiàn)一個(gè)輕量級(jí)的高性 能

消息隊(duì)列服務(wù), 用他的 Set 可以做高性能的 tag 系統(tǒng)等等。

另外 Redis 也可以對(duì)存入的Key-Value 設(shè)置 expire 時(shí)間, 因此也可以被當(dāng)作一 個(gè)功能加強(qiáng)版的 memcached 來(lái)用。

Redis 的主要缺點(diǎn)是數(shù)據(jù)庫(kù)容量受到物理內(nèi)存的限制, 不能用作海量數(shù)據(jù)的高性能讀寫, 因此 Redis 適合的場(chǎng)景主要局限在較小數(shù)據(jù)量的高性能操作和運(yùn)算上

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

(1) memcached 所有的值均是簡(jiǎn)單的字符串, Redis 作為其替代者, 支持更為豐富的數(shù)據(jù)類型

(2)Redis 的速度比 memcached 快很多

(3) Redis 可以持久化其數(shù)據(jù)

Redis 的全稱是什么?

Remote Dictionary Server。

支持哪幾種數(shù)據(jù)類型?

String、 List、 Set、 Sorted Set、 hashes

Redis 有哪幾種數(shù)據(jù)淘汰策略?

  1. noeviction:返回錯(cuò)誤當(dāng)內(nèi)存限制達(dá)到并且客戶端嘗試執(zhí)行會(huì)讓更多內(nèi)存被使用的命令(大部分的寫入指令, 但 DEL 和幾個(gè)例外)
  2. allkeys-lru: 嘗試回收最少使用的鍵(LRU), 使得新添加的數(shù)據(jù)有空間存放。
  3. volatile-lru: 嘗試回收最少使用的鍵(LRU), 但僅限于在過(guò)期集合的鍵,使得新添加的數(shù)據(jù)有空間存放。
  4. allkeys-random: 回收隨機(jī)的鍵使得新添加的數(shù)據(jù)有空間存放。
  5. volatile-random: 回收隨機(jī)的鍵使得新添加的數(shù)據(jù)有空間存放,但僅限于在過(guò)期集合的鍵。
  6. volatile-ttl: 回收在過(guò)期集合的鍵, 并且優(yōu)先回收存活時(shí)間(TTL) 較短的鍵,使得新添加的數(shù)據(jù)有空間存放

Redis為什么采用跳表而不是紅黑樹(shù)

在做范圍查找的時(shí)候,平衡樹(shù)比skiplist操作要復(fù)雜。在平衡樹(shù)上,我們找到指定范圍的小值之后,還需要以中序遍歷的順序繼續(xù)尋找其它不超過(guò)大值的節(jié)點(diǎn)。如果不對(duì)平衡樹(shù)進(jìn)行一定的改造,這里的中序遍歷并不容易實(shí)現(xiàn)。而在skiplist上進(jìn)行范圍查找就非常簡(jiǎn)單,只需要在找到小值之后,對(duì)第1層鏈表進(jìn)行若干步的遍歷就可以實(shí)現(xiàn)。

平衡樹(shù)的插入和刪除操作可能引發(fā)子樹(shù)的調(diào)整,邏輯復(fù)雜,而skiplist的插入和刪除只需要修改相鄰節(jié)點(diǎn)的指針,操作簡(jiǎn)單又快速。

從內(nèi)存占用上來(lái)說(shuō),skiplist比平衡樹(shù)更靈活一些。一般來(lái)說(shuō),平衡樹(shù)每個(gè)節(jié)點(diǎn)包含2個(gè)指針(分別指向左右子樹(shù)),而skiplist每個(gè)節(jié)點(diǎn)包含的指針數(shù)目平均為1/(1-p),具體取決于參數(shù)p的大小。如果像Redis里的實(shí)現(xiàn)一樣,取p=1/4,那么平均每個(gè)節(jié)點(diǎn)包含1.33個(gè)指針,比平衡樹(shù)更有優(yōu)勢(shì)。

查找單個(gè)key,skiplist和平衡樹(shù)的時(shí)間復(fù)雜度都為O(log n),大體相當(dāng);而哈希表在保持較低的哈希值沖突概率的前提下,查找時(shí)間復(fù)雜度接近O(1),性能更高一些。所以我們平常使用的各種Map或dictionary結(jié)構(gòu),大都是基于哈希表實(shí)現(xiàn)的。

從算法實(shí)現(xiàn)難度上來(lái)比較,skiplist比平衡樹(shù)要簡(jiǎn)單得多。

介紹一下HyperLogLog?

HyperLogLog 是一種概率數(shù)據(jù)結(jié)構(gòu),用來(lái)估算數(shù)據(jù)的基數(shù)。數(shù)據(jù)集可以是網(wǎng)站訪客的 IP 地址,E-mail 郵箱或者用戶 ID。

基數(shù)就是指一個(gè)集合中不同值的數(shù)目,比如 a, b, c, d 的基數(shù)就是 4,a, b, c, d, a 的基數(shù)還是 4。雖然 a 出現(xiàn)兩次,只會(huì)被計(jì)算一次。

使用 Redis 統(tǒng)計(jì)集合的基數(shù)一般有三種方法,分別是使用 Redis 的 HashMap,BitMap 和 HyperLogLog。前兩個(gè)數(shù)據(jù)結(jié)構(gòu)在集合的數(shù)量級(jí)增長(zhǎng)時(shí),所消耗的內(nèi)存會(huì)大大增加,但是 HyperLogLog 則不會(huì)。

Redis 的 HyperLogLog 通過(guò)犧牲準(zhǔn)確率來(lái)減少內(nèi)存空間的消耗,只需要12K內(nèi)存,在標(biāo)準(zhǔn)誤差0.81%的前提下,能夠統(tǒng)計(jì)2^64個(gè)數(shù)據(jù)。所以 HyperLogLog 是否適合在比如統(tǒng)計(jì)日活月活此類的對(duì)精度要不不高的場(chǎng)景。

這是一個(gè)很驚人的結(jié)果,以如此小的內(nèi)存來(lái)記錄如此大數(shù)量級(jí)的數(shù)據(jù)基數(shù)。

為什么 Redis 需要把所有數(shù)據(jù)放到內(nèi)存中?

Redis 為了達(dá)到最快的讀寫速度將數(shù)據(jù)都讀到內(nèi)存中, 并通過(guò)異步的方式將數(shù)據(jù)寫入磁盤。

所以 Redis 具有快速和數(shù)據(jù)持久化的特征。 如果不將數(shù)據(jù)放在內(nèi)存中, 磁盤 I/O 速度為嚴(yán)重

影響 Redis 的性能。 在內(nèi)存越來(lái)越便宜的今天, Redis 將會(huì)越來(lái)越受歡迎。

Redis支持的數(shù)據(jù)類型?

String字符串:

格式: set key value

string類型是二進(jìn)制安全的。意思是redis的string可以包含任何數(shù)據(jù)。比如jpg圖片或者序列化的對(duì)象 。

string類型是Redis最基本的數(shù)據(jù)類型,一個(gè)鍵最大能存儲(chǔ)512MB。

Hash(哈希)

格式: hmset name key1 value1 key2 value2

Redis hash 是一個(gè)鍵值(key=>value)對(duì)集合。

Redis hash是一個(gè)string類型的field和value的映射表,hash特別適合用于存儲(chǔ)對(duì)象。

List(列表)

Redis 列表是簡(jiǎn)單的字符串列表,按照插入順序排序。你可以添加一個(gè)元素到列表的頭部(左邊)或者尾部(右邊)

格式: lpush name value

在 key 對(duì)應(yīng) list 的頭部添加字符串元素

格式: rpush name value

在 key 對(duì)應(yīng) list 的尾部添加字符串元素

格式: lrem name index

key 對(duì)應(yīng) list 中刪除 count 個(gè)和 value 相同的元素

格式: llen name

返回 key 對(duì)應(yīng) list 的長(zhǎng)度

Set(集合)

格式: sadd name value

Redis的Set是string類型的無(wú)序集合。

集合是通過(guò)哈希表實(shí)現(xiàn)的,所以添加,刪除,查找的復(fù)雜度都是O(1)。

zset(sorted set:有序集合)

格式: zadd name score value

Redis zset 和 set 一樣也是string類型元素的集合,且不允許重復(fù)的成員。

不同的是每個(gè)元素都會(huì)關(guān)聯(lián)一個(gè)double類型的分?jǐn)?shù)。redis正是通過(guò)分?jǐn)?shù)來(lái)為集合中的成員進(jìn)行從小到大的排序。

zset的成員是唯一的,但分?jǐn)?shù)(score)卻可以重復(fù)。

sds相對(duì)c的改進(jìn)?

獲取長(zhǎng)度:c字符串并不記錄自身長(zhǎng)度,所以獲取長(zhǎng)度只能遍歷一遍字符串,redis直接讀取len即可。

緩沖區(qū)安全:c字符串容易造成緩沖區(qū)溢出,比如:程序員沒(méi)有分配足夠的空間就執(zhí)行拼接操作。而redis會(huì)先檢查sds的空間是否滿足所需要求,如果不滿足會(huì)自動(dòng)擴(kuò)充。

內(nèi)存分配:由于c不記錄字符串長(zhǎng)度,對(duì)于包含了n個(gè)字符的字符串,底層總是一個(gè)長(zhǎng)度n+1的數(shù)組,每一次長(zhǎng)度變化,總是要對(duì)這個(gè)數(shù)組進(jìn)行一次內(nèi)存重新分配的操作。因?yàn)閮?nèi)存分配涉及復(fù)雜算法并且可能需要執(zhí)行系統(tǒng)調(diào)用,所以它通常是比較耗時(shí)的操作。

Redis鏈表源碼?有什么特性?

雙端、無(wú)環(huán)、帶長(zhǎng)度記錄、

多態(tài):使用 void* 指針來(lái)保存節(jié)點(diǎn)值, 可以通過(guò) dup 、 free 、 match 為節(jié)點(diǎn)值設(shè)置類型特定函數(shù), 可以保存不同類型的值。

字典是如何實(shí)現(xiàn)的?

其實(shí)字典這種數(shù)據(jù)結(jié)構(gòu)也內(nèi)置在很多高級(jí)語(yǔ)言中,但是c語(yǔ)言沒(méi)有,所以redis自己實(shí)現(xiàn)了。

應(yīng)用也比較廣泛,比如redis的數(shù)據(jù)庫(kù)就是字典實(shí)現(xiàn)的。不僅如此,當(dāng)一個(gè)哈希鍵包含的鍵值對(duì)比較多,或者都是很長(zhǎng)的字符串,redis就會(huì)用字典作為哈希鍵的底層實(shí)現(xiàn)。

LRU?Redis里的具體實(shí)現(xiàn)?

LRU全稱是Least Recently Used,即最近最久未使用的意思。

LRU算法的設(shè)計(jì)原則是:如果一個(gè)數(shù)據(jù)在最近一段時(shí)間沒(méi)有被訪問(wèn)到,那么在將來(lái)它被訪問(wèn)的可能性也很小。也就是說(shuō),當(dāng)限定的空間已存滿數(shù)據(jù)時(shí),應(yīng)當(dāng)把最久沒(méi)有被訪問(wèn)到的數(shù)據(jù)淘汰。

redis原始的淘汰算法簡(jiǎn)單實(shí)現(xiàn):當(dāng)需要淘汰一個(gè)key時(shí),隨機(jī)選擇3個(gè)key,淘汰其中間隔時(shí)間最長(zhǎng)的key。**基本上,我們隨機(jī)選擇key,淘汰key效果很好。后來(lái)隨機(jī)3個(gè)key改成一個(gè)配置項(xiàng)"N隨機(jī)key"。但把默認(rèn)值提高改成5個(gè)后效果大大提高??紤]到它的效果,你根本不用修改他。

Redis的持久化?

  1. RDB持久化可以手動(dòng)執(zhí)行,也可以配置定期執(zhí)行,可以把某個(gè)時(shí)間的數(shù)據(jù)狀態(tài)保存到RDB文件中,反之,我們可以用RDB文件還原數(shù)據(jù)庫(kù)狀態(tài)。
  2. AOF持久化是通過(guò)保存服務(wù)器執(zhí)行的命令來(lái)記錄狀態(tài)的。還原的時(shí)候再執(zhí)行一遍即可。

如何選擇合適的持久化方式?

一般來(lái)說(shuō), 如果想達(dá)到足以媲美 PostgreSQL 的數(shù)據(jù)安全性, 你應(yīng)該同時(shí)使用兩種持久

化功能。 如果你非常關(guān)心你的數(shù)據(jù), 但仍然可以承受數(shù)分鐘以內(nèi)的數(shù)據(jù)丟失, 那么你可以

只使用 RDB 持久化。

有很多用戶都只使用 AOF 持久化, 但并不推薦這種方式: 因?yàn)槎〞r(shí)生成 RDB 快照

(snapshot) 非常便于進(jìn)行數(shù)據(jù)庫(kù)備份, 并且 RDB 恢復(fù)數(shù)據(jù)集的速度也要比 AOF 恢復(fù)

的速度要快, 除此之外, 使用 RDB 還可以避免之前提到的 AOF 程序的 bug。

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

1.twemproxy, 大概概念是, 它類似于一個(gè)代理方式, 使用方法和普通 Redis 無(wú)任何區(qū)別,

設(shè) 置 好它 下 屬 的多 個(gè) Redis 實(shí) 例 后, 使 用 時(shí)在 本 需 要 連接 Redis 的 地 方改 為 連接

twemproxy, 它會(huì)以一個(gè)代理的身份接收請(qǐng)求并使用一致性 hash 算法, 將請(qǐng)求轉(zhuǎn)接到具

體 Redis, 將結(jié)果再返回 twemproxy。 使用方式簡(jiǎn)便(相對(duì) Redis 只需修改連接端口), 對(duì)

舊項(xiàng)目擴(kuò)展的首選。 問(wèn)題: twemproxy 自身單端口實(shí)例的壓力, 使用一致性 hash 后, 對(duì)

Redis 節(jié)點(diǎn)數(shù)量改變時(shí)候的計(jì)算值的改變, 數(shù)據(jù)無(wú)法自動(dòng)移動(dòng)到新的節(jié)點(diǎn)。

2. codis, 目前用的最多的集群方案, 基本和 twemproxy 一致的效果, 但它支持在 節(jié)點(diǎn)

數(shù)量改變情況下, 舊節(jié)點(diǎn)數(shù)據(jù)可恢復(fù)到新 hash 節(jié)點(diǎn)。

3. Redis cluster3.0 自帶的集群, 特點(diǎn)在于他的分布式算法不是一致性 hash, 而是 hash

槽的概念, 以及自身支持節(jié)點(diǎn)設(shè)置從節(jié)點(diǎn)。 具體看官方文檔介紹。

4.在業(yè)務(wù)代碼層實(shí)現(xiàn), 起幾個(gè)毫無(wú)關(guān)聯(lián)的 Redis 實(shí)例, 在代碼層, 對(duì) key 進(jìn)行 hash 計(jì)算,

然后去對(duì)應(yīng)的 Redis 實(shí)例操作數(shù)據(jù)。 這種方式對(duì) hash 層代碼要求比較高, 考慮部分包括,

節(jié)點(diǎn)失效后的替代算法方案, 數(shù)據(jù)震蕩后的自動(dòng)腳本恢復(fù), 實(shí)例的監(jiān)控, 等等

MySQL 里有 2000w 數(shù)據(jù), Redis 中只存 20w 的數(shù)據(jù),

如何保證 Redis 中的數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù)?

Redis 內(nèi)存數(shù)據(jù)集大小上升到一定大小的時(shí)候, 就會(huì)施行數(shù)據(jù)淘汰策略

Redis 有哪些適合的場(chǎng)景?

(1)、 會(huì)話緩存(Session Cache)

最常用的一種使用 Redis 的情景是會(huì)話緩存(session cache)。 用 Redis 緩存會(huì)話比其他

存儲(chǔ)(如 Memcached) 的優(yōu)勢(shì)在于: Redis 提供持久化。 當(dāng)維護(hù)一個(gè)不是嚴(yán)格要求一致性

的緩存時(shí), 如果用戶的購(gòu)物車信息全部丟失, 大部分人都會(huì)不高興的, 現(xiàn)在, 他們還會(huì)這樣

嗎?

幸運(yùn)的是, 隨著 Redis 這些年的改進(jìn), 很容易找到怎么恰當(dāng)?shù)氖褂?Redis 來(lái)緩存會(huì)話的文

檔。 甚至廣為人知的商業(yè)平臺(tái) Magento 也提供 Redis 的插件。

(2)、 全頁(yè)緩存(FPC)

除基本的會(huì)話 token 之外, Redis 還提供很簡(jiǎn)便的 FPC 平臺(tái)。 回到一致性問(wèn)題, 即使重啟

了 Redis 實(shí)例, 因?yàn)橛写疟P的持久化, 用戶也不會(huì)看到頁(yè)面加載速度的下降, 這是一個(gè)極

大改進(jìn), 類似 PHP 本地 FPC。

再次以 Magento 為例, Magento 提供一個(gè)插件來(lái)使用 Redis 作為全頁(yè)緩存后端。

此外, 對(duì) WordPress 的用戶來(lái)說(shuō), Pantheon 有一個(gè)非常好的插件 wp-Redis, 這個(gè)插件

能幫助你以最快速度加載你曾瀏覽過(guò)的頁(yè)面。

(3)、 隊(duì)列

Reids 在內(nèi)存存儲(chǔ)引擎領(lǐng)域的一大優(yōu)點(diǎn)是提供 list 和 set 操作,這使得 Redis 能作為一個(gè)

很好的消息隊(duì)列平臺(tái)來(lái)使用。 Redis 作為隊(duì)列使用的操作, 就類似于本地程序語(yǔ)言(如

Python) 對(duì) list 的 push/pop 操作。

如果你快速的在 Google 中搜索“Redis queues”, 你馬上就能找到大量的開(kāi)源項(xiàng)目, 這些

項(xiàng)目的目的就是利用 Redis 創(chuàng)建非常好的后端工具, 以滿足各種隊(duì)列需求。 例如, Celery

有一個(gè)后臺(tái)就是使用 Redis 作為 broker, 你可以從這里去查看。

(4)、 排行榜/計(jì)數(shù)器

Redis在內(nèi)存中對(duì)數(shù)字進(jìn)行遞增或遞減的操作實(shí)現(xiàn)的非常好。集合(Set)和有序集合(Sorted

Set) 也使得我們?cè)趫?zhí)行這些操作的時(shí)候變的非常簡(jiǎn)單, Redis 只是正好提供了這兩種數(shù)據(jù)

結(jié)構(gòu)。 所以, 我們要從排序集合中獲取到排名最靠前的 10 個(gè)用戶–我們稱之為

“user_scores”, 我們只需要像下面一樣執(zhí)行即可:

當(dāng)然, 這是假定你是根據(jù)你用戶的分?jǐn)?shù)做遞增的排序。 如果你想返回用戶及用戶的分?jǐn)?shù), 你

需要這樣執(zhí)行:

ZRANGE user_scores 0 10 WITHSCORES

Agora Games 就是一個(gè)很好的例子, 用 Ruby 實(shí)現(xiàn)的, 它的排行榜就是使用 Redis 來(lái)存儲(chǔ)

數(shù)據(jù)的, 你可以在這里看到。

(5)、 發(fā)布/訂閱

最后 是 Redis 的發(fā)布/訂閱功能。 發(fā)布/訂閱的使用場(chǎng)景確實(shí)非

常多。 我已看見(jiàn)人們?cè)谏缃痪W(wǎng)絡(luò)連接中使用, 還可作為基于發(fā)布/訂閱的腳本觸發(fā)器, 甚至

用 Redis 的發(fā)布/訂閱功能來(lái)建立聊天系統(tǒng)。

說(shuō)說(shuō) Redis 哈希槽的概念?

Redis 集群沒(méi)有使用一致性 hash,而是引入了哈希槽的概念, Redis 集群有 16384 個(gè)哈希槽,

每個(gè) key 通過(guò) CRC16 校驗(yàn)后對(duì) 16384 取模來(lái)決定放置哪個(gè)槽, 集群的每個(gè)節(jié)點(diǎn)負(fù)責(zé)一部分

hash 槽

為什么Redis集群有16384個(gè)槽

(1)如果槽位為65536,發(fā)送心跳信息的消息頭達(dá)8k,發(fā)送的心跳包過(guò)于龐大。

如上所述,在消息頭中,最占空間的是myslots[CLUSTER_SLOTS/8]。 當(dāng)槽位為65536時(shí),這塊的大小是: 65536÷8÷1024=8kb 因?yàn)槊棵腌?,redis節(jié)點(diǎn)需要發(fā)送一定數(shù)量的ping消息作為心跳包,如果槽位為65536,這個(gè)ping消息的消息頭太大了,浪費(fèi)帶寬。

(2)redis的集群主節(jié)點(diǎn)數(shù)量基本不可能超過(guò)1000個(gè)。

如上所述,集群節(jié)點(diǎn)越多,心跳包的消息體內(nèi)攜帶的數(shù)據(jù)越多。如果節(jié)點(diǎn)過(guò)1000個(gè),也會(huì)導(dǎo)致網(wǎng)絡(luò)擁堵。因此redis作者,不建議redis cluster節(jié)點(diǎn)數(shù)量超過(guò)1000個(gè)。 那么,對(duì)于節(jié)點(diǎn)數(shù)在1000以內(nèi)的redis cluster集群,16384個(gè)槽位夠用了。沒(méi)有必要拓展到65536個(gè)。

(3)槽位越小,節(jié)點(diǎn)少的情況下,壓縮比高

Redis主節(jié)點(diǎn)的配置信息中,它所負(fù)責(zé)的哈希槽是通過(guò)一張bitmap的形式來(lái)保存的,在傳輸過(guò)程中,會(huì)對(duì)bitmap進(jìn)行壓縮,但是如果bitmap的填充率slots / N很高的話(N表示節(jié)點(diǎn)數(shù)),bitmap的壓縮率就很低。 如果節(jié)點(diǎn)數(shù)很少,而哈希槽數(shù)量很多的話,bitmap的壓縮率就很低。

Redis 集群會(huì)有寫操作丟失嗎? 為什么?

Redis 并不能保證數(shù)據(jù)的強(qiáng)一致性, 這意味這在實(shí)際中集群在特定的條件下可能會(huì)丟失寫操

作。

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

1.twemproxy,大概概念是,它類似于一個(gè)代理方式, 使用時(shí)在本需要連接 redis 的地方改為連接 twemproxy, 它會(huì)以一個(gè)代理的身份接收請(qǐng)求并使用一致性 hash 算法,將請(qǐng)求轉(zhuǎn)接到具體 redis,將結(jié)果再返回 twemproxy。

缺點(diǎn): twemproxy 自身單端口實(shí)例的壓力,使用一致性 hash 后,對(duì) redis 節(jié)點(diǎn)數(shù)量改變時(shí)候的計(jì)算值的改變,數(shù)據(jù)無(wú)法自動(dòng)移動(dòng)到新的節(jié)點(diǎn)。

2.codis,目前用的最多的集群方案,基本和 twemproxy 一致的效果,但它支持在 節(jié)點(diǎn)數(shù)量改變情況下,舊節(jié)點(diǎn)數(shù)據(jù)可恢復(fù)到新 hash 節(jié)點(diǎn)

3.redis cluster3.0 自帶的集群,特點(diǎn)在于他的分布式算法不是一致性 hash,而是 hash 槽的概念,以及自身支持節(jié)點(diǎn)設(shè)置從節(jié)點(diǎn)。具體看官方文檔介紹。

為什么要做 Redis 分區(qū)?

分區(qū)可以讓 Redis 管理更大的內(nèi)存, Redis 將可以使用所有機(jī)器的內(nèi)存。 如果沒(méi)有分區(qū), 你

最多只能使用一臺(tái)機(jī)器的內(nèi)存。 分區(qū)使 Redis 的計(jì)算能力通過(guò)簡(jiǎn)單地增加計(jì)算機(jī)得到成倍提

升,Redis 的網(wǎng)絡(luò)帶寬也會(huì)隨著計(jì)算機(jī)和網(wǎng)卡的增加而成倍增長(zhǎng)。

Redis 分區(qū)有什么缺點(diǎn)?

涉及多個(gè) key 的操作通常不會(huì)被支持。 例如你不能對(duì)兩個(gè)集合求交集, 因?yàn)樗麄兛赡鼙淮?/p>

儲(chǔ)到不同的 Redis 實(shí)例(實(shí)際上這種情況也有辦法, 但是不能直接使用交集指令)。

同時(shí)操作多個(gè) key,則不能使用 Redis 事務(wù).

分區(qū)使用的粒度是key,不能使用一個(gè)非常長(zhǎng)的排序key存儲(chǔ)一個(gè)數(shù)據(jù)集(The partitioning

granularity is the key, so it is not possible to shard a dataset with a single huge

key like a very big sorted set) .

當(dāng)使用分區(qū)的時(shí)候, 數(shù)據(jù)處理會(huì)非常復(fù)雜, 例如為了備份你必須從不同的 Redis 實(shí)例和主

機(jī)同時(shí)收集 RDB / AOF 文件。

分區(qū)時(shí)動(dòng)態(tài)擴(kuò)容或縮容可能非常復(fù)雜。 Redis 集群在運(yùn)行時(shí)增加或者刪除 Redis 節(jié)點(diǎn), 能

做到最大程度對(duì)用戶透明地?cái)?shù)據(jù)再平衡,但其他一些客戶端分區(qū)或者代理分區(qū)方法則不支持

這種特性。 然而, 有一種預(yù)分片的技術(shù)也可以較好的解決這個(gè)問(wèn)題。

Redis 與其他 key-value 存儲(chǔ)有什么不同?

Redis 有著更為復(fù)雜的數(shù)據(jù)結(jié)構(gòu)并且提供對(duì)他們的原子性操作,這是一個(gè)不同于其他數(shù)據(jù)庫(kù)

的進(jìn)化路徑。 Redis 的數(shù)據(jù)類型都是基于基本數(shù)據(jù)結(jié)構(gòu)的同時(shí)對(duì)程序員透明, 無(wú)需進(jìn)行額外

的抽象。

Redis 運(yùn)行在內(nèi)存中但是可以持久化到磁盤,所以在對(duì)不同數(shù)據(jù)集進(jìn)行高速讀寫時(shí)需要權(quán)衡

內(nèi)存, 應(yīng)為數(shù)據(jù)量不能大于硬件內(nèi)存。 在內(nèi)存數(shù)據(jù)庫(kù)方面的另一個(gè)優(yōu)點(diǎn)是, 相比在磁盤上

相同的復(fù)雜的數(shù)據(jù)結(jié)構(gòu), 在內(nèi)存中操作起來(lái)非常簡(jiǎn)單, 這樣 Redis 可以做很多內(nèi)部復(fù)雜性

很強(qiáng)的事情。 同時(shí), 在磁盤格式方面他們是緊湊的以追加的方式產(chǎn)生的, 因?yàn)樗麄儾⒉恍?/p>

要進(jìn)行隨機(jī)訪問(wèn)

Redis 的內(nèi)存用完了會(huì)發(fā)生什么?

如果達(dá)到設(shè)置的上限, Redis 的寫命令會(huì)返回錯(cuò)誤信息(但是讀命令還可以正常返回。) 或

者你可以將 Redis 當(dāng)緩存來(lái)使用配置淘汰機(jī)制,當(dāng) Redis 達(dá)到內(nèi)存上限時(shí)會(huì)沖刷掉舊的內(nèi)容。

Redis 是單線程的, 如何提高多核 CPU 的利用率?

可以在同一個(gè)服務(wù)器部署多個(gè) Redis 的實(shí)例, 并把他們當(dāng)作不同的服務(wù)器來(lái)使用, 在某些時(shí)

候, 無(wú)論如何一個(gè)服務(wù)器是不夠的,

所以, 如果你想使用多個(gè) CPU, 你可以考慮一下分片(shard)。

一個(gè) Redis 實(shí)例最多能存放多少的 keys? List、 Set、Sorted Set 他們最多能存放多少元素?

理論上 Redis 可以處理多達(dá) 232 的 keys, 并且在實(shí)際中進(jìn)行了測(cè)試, 每個(gè)實(shí)例至少存放了 2億 5 千萬(wàn)的 keys。 我們正在測(cè)試一些較大的值。

任何 list、 set、 和 sorted set 都可以放 232 個(gè)元素。

換句話說(shuō), Redis 的存儲(chǔ)極限是系統(tǒng)中的可用內(nèi)存值

修改配置不重啟 Redis 會(huì)實(shí)時(shí)生效嗎?

針對(duì)運(yùn)行實(shí)例, 有許多配置選項(xiàng)可以通過(guò) CONFIG SET 命令進(jìn)行修改, 而無(wú)需執(zhí)行任何

形式的重啟。 從 Redis 2.2 開(kāi)始, 可以從 AOF 切換到 RDB 的快照持久性或其他方式

而不需要重啟 Redis。 檢索 ‘CONFIG GET *’ 命令獲取更多信息。

但偶爾重新啟動(dòng)是必須的, 如為升級(jí) Redis 程序到新的版本, 或者當(dāng)你需要修改某些目前

CONFIG 命令還不支持的配置參數(shù)的時(shí)候

哨兵

Redis sentinel 是一個(gè)分布式系統(tǒng)中監(jiān)控 redis 主從服務(wù)器,并在主服務(wù)器下線時(shí)自動(dòng)進(jìn)行故障轉(zhuǎn)移。其中三個(gè)特性:

監(jiān)控(Monitoring): Sentinel 會(huì)不斷地檢查你的主服務(wù)器和從服務(wù)器是否運(yùn)作正常。

提醒(Notification): 被監(jiān)控的某個(gè) Redis 服務(wù)器出現(xiàn)問(wèn)題時(shí), Sentinel 可以通過(guò) API 向管理員或者其他應(yīng)用程序發(fā)送通知。

自動(dòng)故障遷移(Automatic failover): 當(dāng)一個(gè)主服務(wù)器不能正常工作時(shí), Sentinel 會(huì)開(kāi)始一次自動(dòng)故障遷移操作。

特點(diǎn):

1、保證高可用

2、監(jiān)控各個(gè)節(jié)點(diǎn)

3、自動(dòng)故障遷移

缺點(diǎn):主從模式,切換需要時(shí)間丟數(shù)據(jù)

沒(méi)有解決 master 寫的壓力

緩存穿透

一般的緩存系統(tǒng),都是按照key去緩存查詢,如果不存在對(duì)應(yīng)的value,就去后端系統(tǒng)查找(比如DB)。

一些惡意的請(qǐng)求會(huì)故意查詢不存在的key,請(qǐng)求量很大,就會(huì)對(duì)后端系統(tǒng)造成很大的壓力。這就叫做緩存穿透。

如何避免?

1:對(duì)查詢結(jié)果為空的情況也進(jìn)行緩存,這樣,再次訪問(wèn)時(shí),緩存層會(huì)直接返回空值。緩存時(shí)間設(shè)置短一點(diǎn),或者該key對(duì)應(yīng)的數(shù)據(jù)insert了之后清理緩存。

2:對(duì)一定不存在的key進(jìn)行過(guò)濾。具體請(qǐng)看布隆過(guò)濾器

緩存擊穿

是針對(duì)緩存中沒(méi)有但數(shù)據(jù)庫(kù)有的數(shù)據(jù)。

場(chǎng)景是,當(dāng)Key失效后,假如瞬間突然涌入大量的請(qǐng)求,來(lái)請(qǐng)求同一個(gè)Key,這些請(qǐng)求不會(huì)命中Redis,都會(huì)請(qǐng)求到DB,導(dǎo)致數(shù)據(jù)庫(kù)壓力過(guò)大,甚至扛不住,掛掉。

解決辦法

1、設(shè)置熱點(diǎn)Key,自動(dòng)檢測(cè)熱點(diǎn)Key,將熱點(diǎn)Key的過(guò)期時(shí)間加大或者設(shè)置為永不過(guò)期,或者設(shè)置為邏輯上永不過(guò)期

2、加互斥鎖。當(dāng)發(fā)現(xiàn)沒(méi)有命中Redis,去查數(shù)據(jù)庫(kù)的時(shí)候,在執(zhí)行更新緩存的操作上加鎖,當(dāng)一個(gè)線程訪問(wèn)時(shí),其它線程等待,這個(gè)線程訪問(wèn)過(guò)后,緩存中的數(shù)據(jù)會(huì)被重建,這樣其他線程就可以從緩存中取值。

緩存雪崩

是指大量Key同時(shí)失效,對(duì)這些Key的請(qǐng)求又會(huì)打到DB上,同樣會(huì)導(dǎo)致數(shù)據(jù)庫(kù)壓力過(guò)大甚至掛掉。

解決辦法

1)讓Key的失效時(shí)間分散開(kāi),可以在統(tǒng)一的失效時(shí)間上再加一個(gè)隨機(jī)值,或者使用更高級(jí)的算法分散失效時(shí)間。

2)構(gòu)建多個(gè)redis實(shí)例,個(gè)別節(jié)點(diǎn)掛了還有別的可以用。

3)多級(jí)緩存:比如增加本地緩存,減小redis壓力。

4)對(duì)存儲(chǔ)層增加限流措施,當(dāng)請(qǐng)求超出限制,提供降級(jí)服務(wù)(一般就是返回錯(cuò)誤即可)

單線程的redis為什么這么快

(一)純內(nèi)存操作

(二)單線程操作,避免了頻繁的上下文切換

(三)采用了非阻塞I/O多路復(fù)用機(jī)制

(其實(shí)就是歷史遺留問(wèn)題,非要吹的這么好。。。)

Redis采用的刪除策略

redis采用的是定期刪除+惰性刪除策略。

為什么不用定時(shí)刪除策略?

定時(shí)刪除,用一個(gè)定時(shí)器來(lái)負(fù)責(zé)監(jiān)視key,過(guò)期則自動(dòng)刪除。雖然內(nèi)存及時(shí)釋放,但是十分消耗CPU資源。在大并發(fā)請(qǐng)求下,CPU要將時(shí)間應(yīng)用在處理請(qǐng)求,而不是刪除key,因此沒(méi)有采用這一策略.

定期刪除+惰性刪除是如何工作的呢?

定期刪除,redis默認(rèn)每個(gè)100ms檢查,是否有過(guò)期的key,有過(guò)期key則刪除。需要說(shuō)明的是,redis不是每個(gè)100ms將所有的key檢查一次,而是隨機(jī)抽取進(jìn)行檢查(如果每隔100ms,全部key進(jìn)行檢查,redis豈不是卡死)。因此,如果只采用定期刪除策略,會(huì)導(dǎo)致很多key到時(shí)間沒(méi)有刪除。

于是,惰性刪除派上用場(chǎng)。也就是說(shuō)在你獲取某個(gè)key的時(shí)候,redis會(huì)檢查一下,這個(gè)key如果設(shè)置了過(guò)期時(shí)間那么是否過(guò)期了?如果過(guò)期了此時(shí)就會(huì)刪除。

為什么Redis的操作是原子性的,怎么保證原子性的?

對(duì)于Redis而言,命令的原子性指的是:一個(gè)操作的不可以再分,操作要么執(zhí)行,要么不執(zhí)行。

Redis的操作之所以是原子性的,是因?yàn)镽edis是單線程的。

Redis本身提供的所有API都是原子操作,Redis中的事務(wù)其實(shí)是要保證批量操作的原子性。

多個(gè)命令在并發(fā)中也是原子性的嗎?

不一定, 將get和set改成單命令操作,incr 。使用Redis的事務(wù),或者使用Redis+Lua==的方式實(shí)現(xiàn).

消息隊(duì)列

不要使用redis去做消息隊(duì)列,這不是redis的設(shè)計(jì)目標(biāo)。但實(shí)在太多人使用redis去做去消息隊(duì)列,redis的作者看不下去。

責(zé)任編輯:龐桂玉 來(lái)源: 今日頭條
相關(guān)推薦

2018-02-05 16:28:24

電腦硬件問(wèn)題

2023-11-27 18:09:46

Redis內(nèi)存數(shù)據(jù)庫(kù)

2018-10-19 11:55:36

數(shù)據(jù)庫(kù)Redis命令

2019-05-07 18:17:26

Redis服務(wù)器數(shù)據(jù)

2016-11-09 13:52:35

Hadoop分布式集群

2019-04-09 09:22:32

Redis內(nèi)存緩存

2020-11-02 13:25:45

Redis數(shù)據(jù)庫(kù)開(kāi)源

2021-11-30 05:45:16

固態(tài)硬盤總線接口

2018-07-25 14:27:43

Redis數(shù)據(jù)架構(gòu)存儲(chǔ)

2020-12-24 15:26:07

Redis數(shù)據(jù)庫(kù)

2023-05-06 07:36:06

Python文件讀取

2023-09-13 09:44:32

GLIBC系統(tǒng)

2022-02-19 22:02:21

Redisvalue元素

2018-02-02 14:11:04

數(shù)據(jù)庫(kù)Redis常用命令

2011-05-10 10:56:29

DBA面試

2021-06-04 10:11:07

鴻蒙安卓操作系統(tǒng)

2020-11-09 07:25:20

函數(shù) JavaScript數(shù)據(jù)

2023-10-23 08:12:34

并發(fā)問(wèn)題有鎖和無(wú)鎖

2023-07-14 08:50:37

2023-10-08 13:10:00

Redis數(shù)據(jù)庫(kù)
點(diǎn)贊
收藏

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