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

歡迎訪問 生活随笔!

生活随笔

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

数据库

大数据系列——Redis理论

發(fā)布時(shí)間:2024/1/18 数据库 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 大数据系列——Redis理论 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

概述

Remote Dictionary Server(Redis) 是一個(gè)由 Salvatore Sanfilippo寫的 key-value存儲(chǔ)系統(tǒng),是跨平臺(tái)的非關(guān)系型數(shù)據(jù)庫,也屬于一種nosql數(shù)據(jù)庫,通常被稱為數(shù)據(jù)結(jié)構(gòu)服務(wù)器。

Redis 是一個(gè)開源的使用 ANSI C 語言編寫、遵守 BSD 協(xié)議、支持網(wǎng)絡(luò)、可基于內(nèi)存、分布式、可選持久性的鍵值對(duì)(Key-Value)存儲(chǔ)數(shù)據(jù)庫,并提供多種語言的 API。

Redis 與其他 key - value 緩存產(chǎn)品有以下特點(diǎn)

Redis支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保存在磁盤中,重啟的時(shí)候可以再次加載進(jìn)行使用。

Redis不僅僅支持簡單的key-value類型的數(shù)據(jù),同時(shí)還提供list,set,zset,hash等數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ)。

Redis支持?jǐn)?shù)據(jù)的備份,即master-slave模式的數(shù)據(jù)備份。

性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。

原子性 – Redis的所有操作都是原子性的,同時(shí)Redis還支持對(duì)幾個(gè)操作全并后的原子性執(zhí)行。

豐富的特性 – Redis還支持 publish/subscribe, 通知, 設(shè)置key有效期等等特性。

下面從如下幾個(gè)方面介紹下其相關(guān)理論:

目錄

概述

架構(gòu)

核心知識(shí)點(diǎn):

部署方式:

優(yōu)缺點(diǎn)分析

常見應(yīng)用場景:

調(diào)優(yōu)經(jīng)驗(yàn):

API應(yīng)用:


架構(gòu)

核心知識(shí)點(diǎn):

1、數(shù)據(jù)類型

1)string(字符串)

string 是 redis 最基本的類型,你可以理解成與 Memcached 一模一樣的類型,一個(gè) key 對(duì)應(yīng)一個(gè) value。

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

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

2)list(雙向列表)

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

一個(gè)列表最多可以包含 232 - 1 個(gè)元素 (4294967295, 每個(gè)列表超過40億個(gè)元素)。

3)set(集合)

Redis 的 Set 是 String 類型的無序集合。集合成員是唯一的,這就意味著集合中不能出現(xiàn)重復(fù)的數(shù)據(jù)。

集合對(duì)象的編碼可以是 intset 或者 hashtable。

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

集合中最大的成員數(shù)為 232 - 1 (4294967295, 每個(gè)集合可存儲(chǔ)40多億個(gè)成員)。

4)hash(哈希)

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

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

Redis 中每個(gè) hash 可以存儲(chǔ) 232 - 1 鍵值對(duì)(40多億)。

5)zset(sorted set:有序集合)

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

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

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

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

集合中最大的成員數(shù)為 232 - 1 (4294967295, 每個(gè)集合可存儲(chǔ)40多億個(gè)成員)。

6)HyperLogLog

Redis 在 2.8.9 版本添加了 HyperLogLog 結(jié)構(gòu)。

Redis HyperLogLog 是用來做基數(shù)統(tǒng)計(jì)的算法,HyperLogLog 的優(yōu)點(diǎn)是,在輸入元素的數(shù)量或者體積非常非常大時(shí),計(jì)算基數(shù)所需的空間總是固定 的、并且是很小的。

在 Redis 里面,每個(gè) HyperLogLog 鍵只需要花費(fèi) 12 KB 內(nèi)存,就可以計(jì)算接近 2^64 個(gè)不同元素的基 數(shù)。這和計(jì)算基數(shù)時(shí),元素越多耗費(fèi)內(nèi)存就越多的集合形成鮮明對(duì)比。

但是,因?yàn)?HyperLogLog 只會(huì)根據(jù)輸入元素來計(jì)算基數(shù),而不會(huì)儲(chǔ)存輸入元素本身,所以 HyperLogLog 不能像集合那樣,返回輸入的各個(gè)元素

7)GEO

Redis GEO 主要用于存儲(chǔ)地理位置信息,并對(duì)存儲(chǔ)的信息進(jìn)行操作,該功能在 Redis 3.2 版本新增。

8)Stream

Redis Stream 是 Redis 5.0 版本新增加的數(shù)據(jù)結(jié)構(gòu)。

Redis Stream 主要用于消息隊(duì)列(MQ,Message Queue),Redis 本身是有一個(gè) Redis 發(fā)布訂閱 (pub/sub) 來實(shí)現(xiàn)消息隊(duì)列的功能,但它有個(gè)缺點(diǎn)就是消息無法持久化,

如果出現(xiàn)網(wǎng)絡(luò)斷開、Redis 宕機(jī)等,消息就會(huì)被丟棄。

簡單來說發(fā)布訂閱 (pub/sub) 可以分發(fā)消息,但無法記錄歷史消息。

而 Redis Stream 提供了消息的持久化和主備復(fù)制功能,可以讓任何客戶端訪問任何時(shí)刻的數(shù)據(jù),并且能記住每一個(gè)客戶端的訪問位置,還能保證消息不丟失。

9)、Bitmap

Bitmap在Redis中不是一種實(shí)際的數(shù)據(jù)類型,而是一種將String作為Bitmap使用的方法。可以理解為將String轉(zhuǎn)換為bit數(shù)組。使用Bitmap來存儲(chǔ)true/false類型的簡單數(shù)據(jù)極為節(jié)省空間。

2、持久化方式

redis將內(nèi)存中的數(shù)據(jù)異步寫入硬盤中有三種方式:RDB(默認(rèn))、AOF、混合(RDB + AOF增量)

1)RDB

通過bgsave命令觸發(fā),然后父進(jìn)程執(zhí)行fork操作創(chuàng)建子進(jìn)程,子進(jìn)程創(chuàng)建RDB文件,根據(jù)父進(jìn)程內(nèi)存生成臨時(shí)快照文件,

完成后對(duì)原有文件進(jìn)行原子替換(定時(shí)一次性將所有數(shù)據(jù)進(jìn)行快照生成一份副本存儲(chǔ)在硬盤中)。

優(yōu)點(diǎn):是一個(gè)緊湊壓縮的二進(jìn)制文件,Redis加載RDB恢復(fù)數(shù)據(jù)遠(yuǎn)遠(yuǎn)快于AOF的方式,異步執(zhí)行,非阻塞redis提供服務(wù)

缺點(diǎn):由于每次生成RDB開銷較大,非實(shí)時(shí)持久化,會(huì)阻塞redis提供服務(wù)

2)、AOF

開啟后,Redis每執(zhí)行一個(gè)修改數(shù)據(jù)的命令,都會(huì)把這個(gè)命令添加到AOF文件中。

優(yōu)點(diǎn):實(shí)時(shí)持久化。

缺點(diǎn):同步執(zhí)行,會(huì)阻塞redis提供服務(wù),? 當(dāng)AOF文件體積逐漸變大,需要定期執(zhí)行重寫操作來降低文件體積,加載慢。

3)、混合持久化:

AOF在重寫時(shí),會(huì)將 rdb 快照 和 增量的 AOF日志一起寫入新的aof文件,新的文件一開始不叫appendonly.aof,等到重寫完新的AOF文件才會(huì)進(jìn)行改名,原子的覆蓋原有的AOF文件,完成新舊兩個(gè)AOF文件的替換;

aof 根據(jù)配置規(guī)則(aof-use-rdb-preamble yes)在后臺(tái)自動(dòng)重寫,也可以人為執(zhí)行命令bgrewrite aof重寫AOF。 于是在 Redis 重啟的時(shí)候,可以先加載 rdb 的內(nèi)容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重啟效率因此大幅得到提升。

3、內(nèi)部執(zhí)行方式(這是Redis快速的原因所在)

1)、數(shù)據(jù)存于內(nèi)存

Redis的數(shù)據(jù)都在內(nèi)存中,所以其處理速度很快,所有需要處理的文件都放在文件描述符的集合里rset(fds)。

2)、用了多路復(fù)用I/O

Redis內(nèi)部采用了I/O多路復(fù)用技術(shù),該技術(shù)依賴于底層的操作系統(tǒng),一般有三種方式select、poll、epoll。前面兩種本質(zhì)上一致,一般操作系統(tǒng)都提供,epoll是Linux獨(dú)有的。

  • select
  • 1)、select模型每次都直接將rset(也就是fds)全部拷貝到內(nèi)核態(tài),因?yàn)閮?nèi)核態(tài)速度比用戶空間態(tài)快很多。

    2)、如果沒數(shù)據(jù)的話,select函數(shù)會(huì)阻塞,如果有數(shù)據(jù)的話會(huì)執(zhí)行兩步

    第一步:將有數(shù)據(jù)的那個(gè)fd置位(也就是標(biāo)記一下,代表這個(gè)fd有數(shù)據(jù))

    第二步:select函數(shù)不在阻塞,將繼續(xù)往下執(zhí)行。也就是整體遍歷fds,找到有數(shù)據(jù)的那個(gè)fd讀取數(shù)據(jù)做處理。他的fd不能重用,每一次都需要重新創(chuàng)建新的fds且將用戶空間態(tài)的fds拷貝到內(nèi)核態(tài)

    3)、缺點(diǎn)

    fds最大支持1024個(gè)(可以更改,但是意義不大)

    fd不可重用,每次內(nèi)核態(tài)都給置位了,導(dǎo)致為了標(biāo)記fd,必須創(chuàng)建一個(gè)新的rset從而導(dǎo)致fds在用戶態(tài)內(nèi)存態(tài)間多次拷貝(也就是fds)

    用戶控件態(tài)拷貝rset到內(nèi)核態(tài)也需要時(shí)間,雖然內(nèi)核態(tài)執(zhí)行比用戶態(tài)快,但是copy也需要開銷

    O(n)再次遍歷問題。因?yàn)閞set里的fd被置位后,select函數(shù)并不知道哪個(gè)被置位了,需要從頭遍歷到尾,逐個(gè)對(duì)比。

    Bpoll

    poll的結(jié)構(gòu)體是為了fd重復(fù)利用,不需要每次都拷貝到內(nèi)核態(tài)用的。

    1)、解決了select哪些問題

    采取的鏈表存儲(chǔ),而不是bitmap,解決了1024長度限制問題

    采取結(jié)構(gòu)體每次置位結(jié)構(gòu)體內(nèi)的revents字段,而不破壞fd本身,所以可重用,不需要每次都創(chuàng)建新的fd。

    2)、缺點(diǎn)

    用戶控件態(tài)拷貝rset到內(nèi)核態(tài)也需要時(shí)間,雖然內(nèi)核態(tài)執(zhí)行比用戶態(tài)快,但是copy也需要開銷

    O(n)再次遍歷問題。因?yàn)閞set里的fd被置位后,select函數(shù)并不知道哪個(gè)被置位了,需要從頭遍歷到尾,逐個(gè)對(duì)比。

    Cepoll

    epoll將fd放到了紅黑樹里,且不需要拷貝到內(nèi)核態(tài),因?yàn)樗扇×恕肮蚕韮?nèi)存”的概念。(其實(shí)還是復(fù)制,只是復(fù)制采取了其他技術(shù)可以使開銷極其的小)

    epoll的置位是重排,比如五個(gè)fd, 1 2 3 4 5,1 3 5這三個(gè)fd有數(shù)據(jù)了,那么他會(huì)重排序,排成如下1 3 5 2 4。(也有的說是單獨(dú)放到新的數(shù)組里)

    每一次置位nfds的值都+1。且會(huì)回調(diào)epoll_wait

    所以epoll_wait執(zhí)行完會(huì)返回有幾個(gè)fd有數(shù)據(jù),那么下面的for直接遍歷nfds次即可。解決了前面的兩種O(n)。變成了O1

    比如三個(gè)redis-cli,假設(shè)2個(gè)redis-cli寫入命令,

    select:那么select模型是輪詢這三個(gè)redis-cli的fd,看哪個(gè)fd有消息,有的話讀取處理消息。當(dāng)他下次再寫命令的時(shí)候還需要重新創(chuàng)建fd,然后復(fù)制到內(nèi)核態(tài)然后再遍歷全部。

    poll:那么poll模型是輪詢這三個(gè)redis-cli的fd,看哪個(gè)fd有消息,有的話讀取處理消息。下次再寫入的時(shí)候還是遍歷全局fd,看哪個(gè)fd有消息進(jìn)行處理。省去了每次都創(chuàng)建新的fd且復(fù)制的過程。

    epoll:epoll就不輪詢了,有消息進(jìn)來后你通知我,我去處理你的消息,那些沒消息的fd我不管。而且復(fù)制到內(nèi)核態(tài)的過程我采取牛逼的技術(shù)讓開銷達(dá)到最小的極致。

    多路復(fù)用I/O技術(shù)總結(jié)

    3)、單線程

    Redis是單線程提供應(yīng)用的。

    簡單來說,就是我們的redis-client在操作的時(shí)候,會(huì)產(chǎn)生具有不同事件類型的socket。在服務(wù)端,有一段I/0多路復(fù)用程序,將其置入隊(duì)列之中。然后,IO事件分派器,依次去隊(duì)列中取,

    轉(zhuǎn)發(fā)到不同的事件處理器中。如下圖:

    4、過期策略

    過期策略一般有三種方式:key過期清除策略、惰性策略、定期過期策略。

    key過期清除:依據(jù)寫入數(shù)據(jù)的過期時(shí)間來處理。

    惰性過期(類比懶加載,這是懶過期):只有當(dāng)訪問一個(gè)key時(shí),才會(huì)判斷該key是否已過期,過期則清除。該策略可以最大化地節(jié)省CPU資源,卻對(duì)內(nèi)存非常不友好。極端情況可能出現(xiàn)大量的過期key沒有再次被訪問,從而不會(huì)被清除,占用大量內(nèi)存。

    定期過期:每隔一定的時(shí)間,會(huì)掃描一定數(shù)量的數(shù)據(jù)庫的expires字典中一定數(shù)量的key,并清除其中已過期的key。該策略是前兩者的一個(gè)折中方案。通過調(diào)整定時(shí)掃描的時(shí)間間隔和每次掃描的限定耗時(shí),可以在不同情況下使得CPU和內(nèi)存資源達(dá)到最優(yōu)的平衡效果。

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

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

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

    定期刪除+惰性刪除工作流程:

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

    所以需要惰性刪除策略。也就是說在你獲取某個(gè)key的時(shí)候,redis會(huì)檢查一下,這個(gè)key如果設(shè)置了過期時(shí)間那么是否過期了?如果過期了此時(shí)就會(huì)刪除。

    采用定期刪除+惰性刪除不能確保完全的過期該過期的數(shù)據(jù):

    如果定期刪除沒刪除key,然后你也沒及時(shí)去請(qǐng)求key,也就是說惰性刪除也沒生效。這樣,redis的內(nèi)存會(huì)越來越高,所以還需要配合內(nèi)存淘汰機(jī)制。

    5、內(nèi)存淘汰機(jī)制

    在redis.conf中有一行配置,專門配置內(nèi)存淘汰機(jī)制。

    # maxmemory-policy allkeys-lru

    下面是一些備選機(jī)制:

    1)noeviction:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),新寫入操作會(huì)報(bào)錯(cuò)。應(yīng)該沒人用吧。

    2)allkeys-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在鍵空間中,移除最近最少使用的key。推薦使用。

    3)allkeys-random:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在鍵空間中,隨機(jī)移除某個(gè)key。應(yīng)該也沒人用吧,你不刪最少使用Key,去隨機(jī)刪。

    4)volatile-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間中,移除最近最少使用的key。這種情況一般是把redis既當(dāng)緩存,又做持久化存儲(chǔ)的時(shí)候才用。不推薦

    5)volatile-random:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間中,隨機(jī)移除某個(gè)key。依然不推薦

    6)volatile-ttl:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間中,有更早過期時(shí)間的key優(yōu)先移除。不推薦

    ps:如果沒有設(shè)置 expire 的key, 不滿足先決條件(prerequisites); 那么 volatile-lru, volatile-random 和 volatile-ttl 策略的行為, 和 noeviction(不刪除) 基本上一致。

    6、事務(wù)

    Redis 事務(wù)可以一次執(zhí)行多個(gè)命令, 并且?guī)в幸韵氯齻€(gè)重要的保證:

    批量操作在發(fā)送 EXEC 命令前被放入隊(duì)列緩存。

    收到 EXEC 命令后進(jìn)入事務(wù)執(zhí)行,事務(wù)中任意命令執(zhí)行失敗,其余的命令依然被執(zhí)行。

    在事務(wù)執(zhí)行過程,其他客戶端提交的命令請(qǐng)求不會(huì)插入到事務(wù)執(zhí)行命令序列中。

    一個(gè)事務(wù)從開始到執(zhí)行會(huì)經(jīng)歷以下三個(gè)階段:

    開始事務(wù)。

    命令入隊(duì)。

    執(zhí)行事務(wù)。

    PS:

    單個(gè) Redis 命令的執(zhí)行是原子性的,但 Redis 沒有在事務(wù)上增加任何維持原子性的機(jī)制,所以 Redis 事務(wù)的執(zhí)行并不是原子性的。

    事務(wù)可以理解為一個(gè)打包的批量執(zhí)行腳本,但批量指令并非原子化的操作,中間某條指令的失敗不會(huì)導(dǎo)致前面已做指令的回滾,也不會(huì)造成后續(xù)的指令不做。

    7、發(fā)布訂閱

    發(fā)布訂閱(pub/sub)是一種消息通信模式,主要是解除消息發(fā)布者和消息訂閱者之間通信的耦合。

    Redis作為一個(gè)pub/sub的服務(wù)器,在訂閱者和發(fā)布者之間起到了一個(gè)消息路由的功能。訂閱者可以通過subscribe和psubscribe命令向redis 服務(wù)器訂閱自己感興趣的消息類型,

    redis將信息類型稱為通道(channel)。當(dāng)發(fā)布者通過publish命令向redis server發(fā)送特定類型的信息時(shí),訂閱該信息類型的全部client都會(huì)收到此消息。

    8、集群中節(jié)點(diǎn)間內(nèi)部通信機(jī)制

    1)、基礎(chǔ)通信原理

    a、redis cluster節(jié)點(diǎn)間采取gossip協(xié)議進(jìn)行通信,沒有采用集中式的存儲(chǔ)在某個(gè)節(jié)點(diǎn)上

    b、10000端口

    ????? 每個(gè)節(jié)點(diǎn)都有一個(gè)專門用于節(jié)點(diǎn)間通信的端口,就是自己提供服務(wù)的端口號(hào)+10000,比如7001,那么用于節(jié)點(diǎn)間通信的就是17001端口

    ????? 每隔節(jié)點(diǎn)每隔一段時(shí)間都會(huì)往另外幾個(gè)節(jié)點(diǎn)發(fā)送ping消息,同時(shí)其他幾點(diǎn)接收到ping之后返回pong

    c、交換的信息

    ???? 故障信息、節(jié)點(diǎn)的增加和移除、hash slot信息,等等

    2)、gossip協(xié)議介紹

    ???? gossip 過程是由種子節(jié)點(diǎn)發(fā)起,當(dāng)一個(gè)種子節(jié)點(diǎn)有狀態(tài)需要更新到網(wǎng)絡(luò)中的其他節(jié)點(diǎn)時(shí),它會(huì)隨機(jī)的選擇周圍幾個(gè)節(jié)點(diǎn)散播消息,收到消息的節(jié)點(diǎn)也會(huì)重復(fù)該過程,

    ????? 直至最終網(wǎng)絡(luò)中所有的節(jié)點(diǎn)都收到了消息。這個(gè)過程可能需要一定的時(shí)間,由于不能保證某個(gè)時(shí)刻所有節(jié)點(diǎn)都收到消息,但是理論上最終所有節(jié)點(diǎn)都會(huì)收到消息,

    ????? 因此它是一個(gè)最終一致性協(xié)議。

    gossip協(xié)議包含多種消息,包括ping,pong,meet,fail,等等

    meet: 某個(gè)節(jié)點(diǎn)發(fā)送meet給新加入的節(jié)點(diǎn),讓新節(jié)點(diǎn)加入集群中,然后新節(jié)點(diǎn)就會(huì)開始與其他節(jié)點(diǎn)進(jìn)行通信

    redis-trib.rb add-node 其實(shí)內(nèi)部就是發(fā)送了一個(gè)gossip meet消息,給新加入的節(jié)點(diǎn),通知那個(gè)節(jié)點(diǎn)去加入我們的集群

    ping: 每個(gè)節(jié)點(diǎn)都會(huì)頻繁給其他節(jié)點(diǎn)發(fā)送ping,其中包含自己的狀態(tài)還有自己維護(hù)的集群元數(shù)據(jù),互相通過ping交換元數(shù)據(jù)

    ???????? 每個(gè)節(jié)點(diǎn)每秒都會(huì)頻繁發(fā)送ping給其他的集群,通過ping,頻繁的互相之間交換數(shù)據(jù),互相進(jìn)行元數(shù)據(jù)的更新

    pong: 返回ping和meet,包含自己的狀態(tài)和其他信息,也可以用于信息廣播和更新

    fail: 某個(gè)節(jié)點(diǎn)判斷另一個(gè)節(jié)點(diǎn)fail之后,就發(fā)送fail給其他節(jié)點(diǎn),通知其他節(jié)點(diǎn),指定的節(jié)點(diǎn)宕機(jī)了

    3)、ping消息深入

    ping很頻繁,而且要攜帶一些元數(shù)據(jù),所以可能會(huì)加重網(wǎng)絡(luò)負(fù)擔(dān)

    每個(gè)節(jié)點(diǎn)每秒會(huì)執(zhí)行10次ping,每次會(huì)選擇5個(gè)最久沒有通信的其他節(jié)點(diǎn)

    當(dāng)然如果發(fā)現(xiàn)某個(gè)節(jié)點(diǎn)通信延時(shí)達(dá)到了cluster_node_timeout / 2,那么立即發(fā)送ping,避免數(shù)據(jù)交換延時(shí)過長,落后的時(shí)間太長了

    9、數(shù)據(jù)備份與恢復(fù)

    Redis創(chuàng)建當(dāng)前數(shù)據(jù)庫的備份,有種方式:save、bgsave。

    save命令:同步執(zhí)行,會(huì)阻塞Redis服務(wù)

    bgsave命令:異步執(zhí)行,不會(huì)阻塞Redis服務(wù)

    這兩種方式都會(huì)在Redis安裝目錄中創(chuàng)建dump.rdb文件,如果需要恢復(fù)數(shù)據(jù),只需將備份文件 (dump.rdb) 移動(dòng)到 redis 安裝目錄并啟動(dòng)服務(wù)即可。

    10、管道技術(shù)和分區(qū)

    管道技術(shù):

    Redis 管道技術(shù)可以在服務(wù)端未響應(yīng)時(shí),客戶端可以繼續(xù)異步向服務(wù)端發(fā)送請(qǐng)求,并最終一次性讀取所有服務(wù)端的響應(yīng)。

    分區(qū):

    分區(qū)是分割數(shù)據(jù)到多個(gè)Redis實(shí)例的處理過程,因此每個(gè)實(shí)例只保存key的一個(gè)子集。

    有兩種分區(qū)類型:范圍分區(qū)、哈希分區(qū)。

    11、重要程序

    redis-server:Redis服務(wù)器程序

    redis-cli:Redis客戶端程序,它是一個(gè)命令行操作工具。也可以使用telnet根據(jù)其純文本協(xié)議操作。

    redis-benchmark:Redis性能測試工具,測試Redis在你的系統(tǒng)及配置下的讀寫性能。

    部署方式:

    1、單機(jī)模式

    ?? ??由一臺(tái)計(jì)算來提供Redis服務(wù), 容量和性能受限于機(jī)器的配置且不具備高可用。

    2、主從復(fù)制(本質(zhì)和單機(jī)一樣,只是多了查詢負(fù)載均衡)

    ????? 通過一臺(tái)主服務(wù)器Master和多臺(tái)備份服務(wù)器組成的集群提供服務(wù),支持自動(dòng)備份、負(fù)載均衡,主服務(wù)器掛掉,需要人工進(jìn)行切換(不支持高可用)。

    ???? ?Redis為了解決單點(diǎn)數(shù)據(jù)庫問題,會(huì)把數(shù)據(jù)復(fù)制多個(gè)副本部署到其他節(jié)點(diǎn)上,通過復(fù)制,對(duì)數(shù)據(jù)進(jìn)行冗余備份,從而保證數(shù)據(jù)高度可靠性。

    復(fù)制(Replication)的原理:

    ①從數(shù)據(jù)庫向主數(shù)據(jù)庫發(fā)送sync(數(shù)據(jù)同步)命令。

    ②主數(shù)據(jù)庫接收同步命令后,會(huì)保存快照,創(chuàng)建一個(gè)RDB文件。

    ③當(dāng)主數(shù)據(jù)庫執(zhí)行完保持快照后,會(huì)向從數(shù)據(jù)庫發(fā)送RDB文件,而從數(shù)據(jù)庫會(huì)接收并載入該文件。

    ④主數(shù)據(jù)庫將緩沖區(qū)的所有寫命令發(fā)給從服務(wù)器執(zhí)行。

    ⑤以上處理完之后,之后主數(shù)據(jù)庫每執(zhí)行一個(gè)寫命令,都會(huì)將被執(zhí)行的寫命令發(fā)送給從數(shù)據(jù)庫。

    注意:在Redis2.8之后,主從斷開重連后會(huì)根據(jù)斷開之前最新的命令偏移量進(jìn)行增量復(fù)制

    3、哨兵模式(主從復(fù)制+哨兵)(本質(zhì)和單機(jī)一樣,保證了高可用)

    ???? 通過一臺(tái)主服務(wù)器Master和多臺(tái)備份服務(wù)器組成的集群提供服務(wù),保證高可用。

    ????

    ???? 哨兵是Redis集群架構(gòu)中非常重要的一個(gè)組件,哨兵的出現(xiàn)主要是解決了主從復(fù)制出現(xiàn)故障時(shí)需要人為干預(yù)的問題。

    哨兵模式架構(gòu)圖

    ARedis哨兵主要功能

    1)集群監(jiān)控:負(fù)責(zé)監(jiān)控Redis master和slave進(jìn)程是否正常工作

    2)消息通知:如果某個(gè)Redis實(shí)例有故障,那么哨兵負(fù)責(zé)發(fā)送消息作為報(bào)警通知給管理員

    3)故障轉(zhuǎn)移:如果master node掛掉了,會(huì)自動(dòng)轉(zhuǎn)移到slave node上

    4)配置中心:如果故障轉(zhuǎn)移發(fā)生了,通知client客戶端新的master地址

    BRedis哨兵的高可用原理:

    當(dāng)主節(jié)點(diǎn)出現(xiàn)故障時(shí),由Redis Sentinel自動(dòng)完成故障發(fā)現(xiàn)和轉(zhuǎn)移,并通知應(yīng)用方,實(shí)現(xiàn)高可用性。

    哨兵機(jī)制建立了多個(gè)哨兵節(jié)點(diǎn)(進(jìn)程),共同監(jiān)控?cái)?shù)據(jù)節(jié)點(diǎn)的運(yùn)行狀況。

    同時(shí)哨兵節(jié)點(diǎn)之間也互相通信,交換對(duì)主從節(jié)點(diǎn)的監(jiān)控狀況。

    每隔1秒每個(gè)哨兵會(huì)向整個(gè)集群:Master主服務(wù)器+Slave從服務(wù)器+其他Sentinel(哨兵)進(jìn)程,發(fā)送一次ping命令做一次心跳檢測。

    哨兵用來判斷節(jié)點(diǎn)是否正常的重要依據(jù),涉及兩個(gè)新的概念:主觀下線和客觀下線。

    主觀下線:一個(gè)哨兵節(jié)點(diǎn)判定主節(jié)點(diǎn)down掉是主觀下線。

    客觀下線:只有半數(shù)哨兵節(jié)點(diǎn)都主觀判定主節(jié)點(diǎn)down掉,此時(shí)多個(gè)哨兵節(jié)點(diǎn)交換主觀判定結(jié)果,才會(huì)判定主節(jié)點(diǎn)客觀下線。

    基本上哪個(gè)哨兵節(jié)點(diǎn)最先判斷出這個(gè)主節(jié)點(diǎn)客觀下線,就會(huì)在各個(gè)哨兵節(jié)點(diǎn)中發(fā)起投票機(jī)制Raft算法(選舉算法),最終被投為領(lǐng)導(dǎo)者的哨兵節(jié)點(diǎn)完成主從自動(dòng)化切換的過程。

    C、哨兵選舉

    一般情況下當(dāng)哨兵發(fā)現(xiàn)主節(jié)點(diǎn)sdown之后 該哨兵節(jié)點(diǎn)會(huì)成為領(lǐng)導(dǎo)者負(fù)責(zé)處理主從節(jié)點(diǎn)的切換工作:

    哨兵A發(fā)現(xiàn)Redis主節(jié)點(diǎn)失聯(lián);

    哨兵A報(bào)出sdown,并通知其他哨兵,發(fā)送指令sentinel is-master-down-by-address-port給其余哨兵節(jié)點(diǎn);

    其余哨兵接收到哨兵A的指令后嘗試連接Redis主節(jié)點(diǎn),發(fā)現(xiàn)主節(jié)點(diǎn)確實(shí)失聯(lián);

    哨兵返回信息給哨兵A,當(dāng)超過半數(shù)的哨兵認(rèn)為主節(jié)點(diǎn)下線后,狀態(tài)會(huì)變成odown;

    最先發(fā)現(xiàn)主節(jié)點(diǎn)下線的哨兵A會(huì)成為哨兵領(lǐng)導(dǎo)者負(fù)責(zé)這次的主從節(jié)點(diǎn)的切換工作;

    哨兵的選舉機(jī)制是以各哨兵節(jié)點(diǎn)接收到發(fā)送sentinel is-master-down-by-address-port指令的哨兵id 投票,票數(shù)最高的哨兵id會(huì)成為本次故障轉(zhuǎn)移工作的哨兵Leader;

    D、哨兵故障轉(zhuǎn)移

    當(dāng)哨兵發(fā)現(xiàn)主節(jié)點(diǎn)下線之后經(jīng)過上面的哨兵選舉機(jī)制,選舉出本次故障轉(zhuǎn)移工作的哨兵節(jié)點(diǎn)完成本次主從節(jié)點(diǎn)切換的工作:

    哨兵Leader 根據(jù)一定規(guī)則從各個(gè)從節(jié)點(diǎn)中選擇出一個(gè)節(jié)點(diǎn)升級(jí)為主節(jié)點(diǎn);

    其余從節(jié)點(diǎn)修改對(duì)應(yīng)的主節(jié)點(diǎn)為新的主節(jié)點(diǎn);

    當(dāng)原主節(jié)點(diǎn)恢復(fù)啟動(dòng)的時(shí)候,變?yōu)樾碌闹鞴?jié)點(diǎn)的從節(jié)點(diǎn)

    哨兵Leader選擇新的主節(jié)點(diǎn)遵循下面幾個(gè)規(guī)則:

    健康度:從節(jié)點(diǎn)響應(yīng)時(shí)間快;

    完整性:從節(jié)點(diǎn)消費(fèi)主節(jié)點(diǎn)的offset偏移量盡可能的高;

    穩(wěn)定性:若仍有多個(gè)從節(jié)點(diǎn),則根據(jù)從節(jié)點(diǎn)的創(chuàng)建時(shí)間選擇最有資歷的節(jié)點(diǎn)升級(jí)為主節(jié)點(diǎn);

    在哨兵模式下主從節(jié)點(diǎn)總是會(huì)變更,因此在應(yīng)用中訪問哨兵模式下的Redis時(shí)可以使用對(duì)應(yīng)的哨兵接口連接:

    例如 java:JedisSentinelPoolPython:SentienlConnectionPool

    4、集群模式

    ?redis集群在3.0以后提供了分布式存儲(chǔ)方案,保證高可用,提高并發(fā)量。集群由多個(gè)節(jié)點(diǎn)(Node)組成,將數(shù)據(jù)按一定的規(guī)則分配到多臺(tái)機(jī)器,內(nèi)存/QPS不受限于單機(jī),實(shí)現(xiàn)高擴(kuò)展性。

    集群中的節(jié)點(diǎn)分為主節(jié)點(diǎn)和從節(jié)點(diǎn),只有主節(jié)點(diǎn)負(fù)責(zé)讀寫請(qǐng)求和集群信息的維護(hù),從節(jié)點(diǎn)只進(jìn)行主節(jié)點(diǎn)數(shù)據(jù)和狀態(tài)信息的復(fù)制。為了適應(yīng)選舉算法要求,一般要求集群的主節(jié)點(diǎn)和從節(jié)點(diǎn)數(shù)量都采用奇數(shù),最少需要3個(gè)節(jié)點(diǎn)。

    可以直接使用 redis-cli --cluster 來管理集群,包括創(chuàng)建集群、伸縮集群節(jié)點(diǎn)、槽遷移、完整性檢查、分區(qū)平衡等。

    集群模式架構(gòu)圖

    為了實(shí)現(xiàn)分布式集群,引入了槽的概念來處理數(shù)據(jù)分區(qū)。

    數(shù)據(jù)分區(qū)規(guī)則一般考量2個(gè)重要因素:1、是否均勻, 2、伸縮節(jié)點(diǎn)對(duì)數(shù)據(jù)分布的影響。

    一般有下面幾種方法來實(shí)現(xiàn)分區(qū)算法:

    1)、哈希取余

    根據(jù)key計(jì)算hash值,然后對(duì)節(jié)點(diǎn)數(shù)量取余。該方法初始化時(shí)能夠做到均勻分布,但后期伸縮時(shí)會(huì)引發(fā)大量數(shù)據(jù)遷移。

    2)、一致性哈希

    將hash值區(qū)間(0~2 32-1)抽象為一個(gè)順時(shí)針環(huán)形,節(jié)點(diǎn)均勻分布在環(huán)形上,根據(jù)key計(jì)算hash值,然后在環(huán)形上順時(shí)針查找節(jié)點(diǎn),找到第一個(gè)就將數(shù)據(jù)落到該節(jié)點(diǎn)。

    ??? 相比哈希取余來說,該方法減少數(shù)據(jù)遷移,因?yàn)槠鋵⒂绊懺L問控制到相鄰節(jié)點(diǎn),但會(huì)造成數(shù)據(jù)不均勻。

    3)、帶虛擬槽的一致性哈希

    Redis就是采用這種方式來處理數(shù)據(jù)分布的。一共設(shè)定16384個(gè)槽slot,采用hash算法將這些槽分配到各個(gè)節(jié)點(diǎn)上,hash_slot = crc16(key) mod 16384。

    ?? 該方法克服了上面兩種的缺點(diǎn),能夠很好的解決均勻分布、伸縮節(jié)點(diǎn)對(duì)數(shù)據(jù)分布影響很小。

      Redis集群內(nèi)節(jié)點(diǎn)通過ping/pong消息實(shí)現(xiàn)節(jié)點(diǎn)通信,消息不但可以傳播節(jié)點(diǎn)槽信息,還可以傳播其他狀態(tài)如:主從狀態(tài)、節(jié)點(diǎn)故障等。因此故障發(fā)現(xiàn)也是通過消息傳播機(jī)制實(shí)現(xiàn)的,主要環(huán)節(jié)包括:主觀下線(pfail)和客觀下線(fail)

    主客觀下線:集群中每個(gè)節(jié)點(diǎn)都會(huì)定期向其他節(jié)點(diǎn)發(fā)送ping消息,接收節(jié)點(diǎn)回復(fù)pong消息作為響應(yīng)。如果通信一直失敗,則發(fā)送節(jié)點(diǎn)會(huì)把接收節(jié)點(diǎn)標(biāo)記為主觀下線(pfail)狀態(tài)。

      

    客觀下線:超過半數(shù),對(duì)該主節(jié)點(diǎn)做客觀下線

    主節(jié)點(diǎn)選舉出某一主節(jié)點(diǎn)作為領(lǐng)導(dǎo)者,來進(jìn)行故障轉(zhuǎn)移

    ??? 其中虛擬槽的分配算法沒有采用最終一致性的hash算法原因如下:

    ????? 1)、發(fā)生縮容時(shí),需要知道被影響的那部分?jǐn)?shù)據(jù),要進(jìn)行手動(dòng)遷移

    ????? 2)、因?yàn)槠浔举|(zhì)是一個(gè)順時(shí)針環(huán),所有會(huì)發(fā)生熱點(diǎn)數(shù)據(jù)都集中在某一個(gè)Master上會(huì)出現(xiàn)性能瓶頸

    集群限制

    由于Redis集群中數(shù)據(jù)分布在不同的節(jié)點(diǎn)上,因此有些功能會(huì)受限:

    db庫:單機(jī)的Redis默認(rèn)有16個(gè)db數(shù)據(jù)庫,但在集群模式下只有一個(gè)db0;

    復(fù)制結(jié)構(gòu):上面的復(fù)制結(jié)構(gòu)有樹狀結(jié)構(gòu),但在集群模式下只允許單層復(fù)制結(jié)構(gòu);

    事務(wù)/lua腳本:僅允許操作的key在同一個(gè)節(jié)點(diǎn)上才可以在集群下使用事務(wù)或lua腳本;(使用Hash Tag可以解決)

    key的批量操作:如mget,mset操作,只有當(dāng)操作的key都在同一個(gè)節(jié)點(diǎn)上才可以執(zhí)行;(使用Hash Tag可以解決)

    keys/flushall只會(huì)在該節(jié)點(diǎn)之上進(jìn)行操作,不會(huì)對(duì)集群的其他節(jié)點(diǎn)進(jìn)行操作;?

    Hash Tag:

    上面介紹集群限制的時(shí)候,由于key被分布在不同的節(jié)點(diǎn)之上,因此無法跨節(jié)點(diǎn)做事務(wù)或lua腳本操作,但我們可以使用hash tag方式解決。

    hash tag:當(dāng)key包含{}的時(shí)候,不會(huì)對(duì)整個(gè)key做hash,只會(huì)對(duì){}包含的部分做hash然后分配槽slot;因此我們可以讓不同的key在同一個(gè)槽內(nèi),這樣就可以解決key的批量操作和事務(wù)及l(fā)ua腳本的限制了;

    但由于hash tag會(huì)將不同的key分配在相同的slot中,如果使用不當(dāng),會(huì)造成數(shù)據(jù)分布不均的情況,需要注意。

    優(yōu)缺點(diǎn)分析

    缺點(diǎn):

    1、容量及處理能力有限,受限于單臺(tái)機(jī)器的配置。

    ???? 為了應(yīng)對(duì)容量的問題,一般做如下處理:

    ???? a、采用分布式集群處理(分片集群),將數(shù)據(jù)通過路由代理分片到不同的服務(wù)器

    ???? b、采用集群方式,利用虛擬槽的概念來做。

    2redis和數(shù)據(jù)庫雙寫一致性問題

    ???? Redis只能做到最終一致性,不能保證強(qiáng)一致性。

    3、緩存穿透

    ????? 若緩存和數(shù)據(jù)庫中都沒有的數(shù)據(jù),大流量都會(huì)直接打到DB,導(dǎo)致DB掛掉,這種現(xiàn)象俗稱“緩存穿透”。

    ????? 為了應(yīng)對(duì)這種情況,一般做如下處理:

    ?????? a、會(huì)將該key寫入緩存值設(shè)置為null,為了減少對(duì)正常應(yīng)用的影響,把有效時(shí)間設(shè)置的短一點(diǎn),具體根據(jù)應(yīng)用場景來定。

    ?????? b、采用降級(jí)或限流控制流量入口

    4、緩存雪崩

    ???? 若緩存中的數(shù)據(jù)大批量已經(jīng)過期,大流量都會(huì)直接打到DB,導(dǎo)致DB掛掉,這種現(xiàn)象俗稱“緩存雪崩”。

    ???? 為了應(yīng)對(duì)這種情況,一般做如下處理:

    ???? a、緩存數(shù)據(jù)的過期時(shí)間設(shè)置隨機(jī),防止同一時(shí)間大量數(shù)據(jù)過期現(xiàn)象發(fā)生。

    ???? b、如果緩存數(shù)據(jù)庫是分布式部署,將熱點(diǎn)數(shù)據(jù)均勻分布在不同的緩存數(shù)據(jù)庫中,且設(shè)置不同的過期時(shí)間。

    ???? c、熱點(diǎn)數(shù)據(jù)考慮設(shè)置永遠(yuǎn)不過期。

    ???? d、采用降級(jí)或限流控制流量入口

    5、緩存擊穿

    ???? 若緩存中沒有但數(shù)據(jù)庫中有(指同一條數(shù)據(jù)),大流量并發(fā)取這條數(shù)據(jù)到DB,導(dǎo)致DB掛掉,這種現(xiàn)象俗稱“緩存擊穿”。

    ???? 為了應(yīng)對(duì)這種情況,一般做如下處理:

    ???? a、熱點(diǎn)數(shù)據(jù)考慮設(shè)置永遠(yuǎn)不過期。

    ???? b、采用布隆過濾器。

    ???? c、采用降級(jí)或限流控制流量入口。

    6、熱點(diǎn)Key并發(fā)競爭

    ???? 若同時(shí)有多個(gè)有個(gè)多個(gè)或不同系統(tǒng)請(qǐng)求并發(fā)設(shè)置一個(gè)key,會(huì)發(fā)生數(shù)據(jù)應(yīng)用不一致問題。例如像事務(wù)中的臟讀、幻讀等。

    ???? 為了應(yīng)對(duì)這種情況,一般做如下處理:

    ???? a、若不要求順序,可以采用加鎖或分布式鎖

    ???? b、若要求按順序,可以采用加鎖或分布式鎖,先放入隊(duì)列,然后異步處理隊(duì)列。

    ???? c、或者采用其他方式,做到串行處理set操作即可。? ???

    優(yōu)點(diǎn):

    1、數(shù)據(jù)處理速度快

    ???? 因?yàn)槠浠趦?nèi)存操作,每秒可以執(zhí)行大約 110000 個(gè)寫入操作,或者 81000 個(gè)讀操作,其速度遠(yuǎn)超數(shù)據(jù)庫。

    2、支持豐富的數(shù)據(jù)類型

    ???? Redis不僅僅支持簡單的key-value類型的數(shù)據(jù),同時(shí)還提供String,list,set,zset,hash等數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ)。

    3、支持?jǐn)?shù)據(jù)的持久化

    ????? 可以將內(nèi)存中的數(shù)據(jù)保存在磁盤中,重啟的時(shí)候可以再次加載進(jìn)行使用

    4、支持?jǐn)?shù)據(jù)的備份

    ???? 內(nèi)置支持master-slave模式的數(shù)據(jù)備份

    5、內(nèi)部操作原子性

    ???? Redis的所有操作都是原子性的(要不成功,要不失敗),同時(shí)Redis還支持對(duì)幾個(gè)操作全并后的原子性執(zhí)行,也就是事務(wù)。

    ???? 但要注意這里的事務(wù)只能保證批量塊的事務(wù),批量塊內(nèi)部的語句不具備事務(wù)性。

    6、豐富的特性

    ????? Redis 可以在如緩存、消息傳遞隊(duì)列中使用(Redis 支持“發(fā)布+訂閱”的消息模式),在應(yīng)用程序如 Web 應(yīng)用程序會(huì)話、網(wǎng)站頁面點(diǎn)擊數(shù)、設(shè)置key有效期等中使用。

    常見應(yīng)用場景:

    1、緩存

    ? 緩存現(xiàn)在幾乎是所有中大型網(wǎng)站都在用的必殺技,合理的利用緩存不僅能夠提升網(wǎng)站訪問速度,還能大大降低數(shù)據(jù)庫的壓力。Redis提供了鍵過期功能,也提供了靈活的鍵淘汰策略,

    所以,現(xiàn)在Redis用在緩存的場合非常多。例如:token、熱點(diǎn)數(shù)據(jù)。

    2、排行榜

      很多網(wǎng)站都有排行榜應(yīng)用的,如京東的月度銷量榜單、商品按時(shí)間的上新排行榜等。Redis提供的有序集合數(shù)據(jù)類構(gòu)能實(shí)現(xiàn)各種復(fù)雜的排行榜應(yīng)用。

    3、計(jì)數(shù)器

     ? 如電商網(wǎng)站商品的瀏覽量、視頻網(wǎng)站視頻的播放數(shù)等。為了保證數(shù)據(jù)實(shí)時(shí)效,每次瀏覽都得給+1,并發(fā)量高時(shí)如果每次都請(qǐng)求數(shù)據(jù)庫操作無疑是種挑戰(zhàn)和壓力。

    ? Redis提供的incr命令來實(shí)現(xiàn)計(jì)數(shù)器功能,內(nèi)存操作,性能非常好,非常適用于這些計(jì)數(shù)場景。

    4、分布式會(huì)話

      集群模式下,在應(yīng)用不多的情況下一般使用容器自帶的session復(fù)制功能就能滿足,當(dāng)應(yīng)用增多相對(duì)復(fù)雜的系統(tǒng)中,一般都會(huì)搭建以Redis等內(nèi)存數(shù)據(jù)庫為中心的session服務(wù),session不再由容器管理,而是由session服務(wù)及內(nèi)存數(shù)據(jù)庫管理。

    5、分布式鎖

     ? 在很多互聯(lián)網(wǎng)公司中都使用了分布式技術(shù),分布式技術(shù)帶來的技術(shù)挑戰(zhàn)是對(duì)同一個(gè)資源的并發(fā)訪問,如全局ID、減庫存、秒殺等場景,并發(fā)量不大的場景可以使用數(shù)據(jù)庫的悲觀鎖、樂觀鎖來實(shí)現(xiàn),但在并發(fā)量高的場合中,利用數(shù)據(jù)庫鎖來控制資源的并發(fā)訪問是不太理想的,大大影響了數(shù)據(jù)庫的性能。可以利用Redis的setnx功能來編寫分布式的鎖,如果設(shè)置返回1說明獲取鎖成功,否則獲取鎖失敗,實(shí)際應(yīng)用中要考慮的細(xì)節(jié)要更多。

    6 社交網(wǎng)絡(luò)

      點(diǎn)贊、踩、關(guān)注/被關(guān)注、共同好友等是社交網(wǎng)站的基本功能,社交網(wǎng)站的訪問量通常來說比較大,而且傳統(tǒng)的關(guān)系數(shù)據(jù)庫類型不適合存儲(chǔ)這種類型的數(shù)據(jù),Redis提供的哈希、集合等數(shù)據(jù)結(jié)構(gòu)能很方便的的實(shí)現(xiàn)這些功能。

    7、最新列表

     ? Redis列表結(jié)構(gòu),LPUSH可以在列表頭部插入一個(gè)內(nèi)容ID作為關(guān)鍵字,LTRIM可用來限制列表的數(shù)量,這樣列表永遠(yuǎn)為N個(gè)ID,無需查詢最新的列表,直接根據(jù)ID去到對(duì)應(yīng)的內(nèi)容頁即可。

    8、消息系統(tǒng)(不推薦使用)

    消息隊(duì)列是大型網(wǎng)站必用中間件,如ActiveMQ、RabbitMQ、Kafka等流行的消息隊(duì)列中間件,主要用于業(yè)務(wù)解耦、流量削峰及異步處理實(shí)時(shí)性低的業(yè)務(wù)。

    Redis提供了發(fā)布/訂閱及阻塞隊(duì)列功能,能實(shí)現(xiàn)一個(gè)簡單的消息隊(duì)列系統(tǒng)。

    調(diào)優(yōu)經(jīng)驗(yàn):

    PS:后續(xù)逐漸把實(shí)踐調(diào)優(yōu)過程補(bǔ)充上來

    API應(yīng)用:

    各個(gè)平臺(tái)一般都有相應(yīng)的操作組件,下面介紹下java和DoNet平臺(tái)下的訪問組件。

    java平臺(tái):

    1jedis

    <dependency>

    ??? <groupId>redis.clients</groupId>

    ??? <artifactId>jedis</artifactId>

    ??? <version>版本</version>

    </dependency>

    2Spring Boot整合Spring Cache應(yīng)用Redis

    <dependency>

    ??? <groupId>org.springframework.boot</groupId>

    ??? <artifactId>spring-boot-starter-data-redis</artifactId>

    ??? <version>版本</version>

    </dependency>

    3spring-data-redis

    <dependency>

    ??? <groupId>org.springframework.data</groupId>

    ??? <artifactId>spring-data-redis</artifactId>

    ??? <version>版本</version>

    </dependency>

    4Redisson(底層使用Netty

    <dependency>

    ???????? <groupId>org.redisson</groupId>

    ???????? <artifactId>redisson-spring-boot-starter</artifactId>

    ???????? <version>版本</version>

    </dependency>

    5Lettuce

    <dependency>

    ??? <groupId>io.lettuce</groupId>

    ??? <artifactId>lettuce-core</artifactId>

    ??? <version>5.1.8.RELEASE</version>

    </dependency>

    DoNet平臺(tái):

    1CSRedisCore 推薦使用這個(gè)

    Nuget: 下載CSRedisCore

    2StackExchange.Redis?

    Nuget: StackExchange.Redis

    3ServiceStack.Redis 微軟提供 收費(fèi)

    Nuget: ServiceStack.Redis

    總結(jié)

    以上是生活随笔為你收集整理的大数据系列——Redis理论的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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