新聞中心
掌握高并發(fā)、高可用架構(gòu)
第三章 分布式
本章介紹分布式架構(gòu)的底層技術(shù)。主要說(shuō)明面試過(guò)程中可能被問(wèn)到的技術(shù)點(diǎn)。
專注于為中小企業(yè)提供成都網(wǎng)站制作、做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)東烏珠穆沁免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了1000+企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
第四節(jié) 緩存
緩存穿透
緩存學(xué)雪崩
redis
Memcached
Guava
1. 緩存使用中的幾個(gè)問(wèn)題
緩存穿透:查詢緩存和數(shù)據(jù)庫(kù)中一定不存在的數(shù)據(jù)時(shí),每次查詢都是直接到數(shù)據(jù)庫(kù)的,這種現(xiàn)象稱為緩存穿透
此時(shí),如果有大量的請(qǐng)求時(shí),會(huì)對(duì)數(shù)據(jù)庫(kù)造成直接沖擊,甚至?xí)?dǎo)致崩潰
- 緩存空數(shù)據(jù)
- 使用BloomFilter(布隆過(guò)濾器),即緩存數(shù)據(jù)庫(kù)中所有存在的Key
緩存雪崩:緩存服務(wù)器宕機(jī)了,那么所有查詢直接落在數(shù)據(jù)庫(kù),對(duì)數(shù)據(jù)庫(kù)造成巨大壓力
- 使用緩存集群,增大可用性
- 本地緩存
- 使用Hystrix(熔斷器),它通過(guò)熔斷、降級(jí)、限流三個(gè)手段來(lái)降低雪崩造成的損失
- 持久化機(jī)制
熱點(diǎn)數(shù)據(jù)集中失效:本身大批量數(shù)據(jù)同時(shí)失效對(duì)Redis服務(wù)器也會(huì)造成影響,可能會(huì)出現(xiàn)慢的情形;再者失效期間,所有的用戶請(qǐng)求都會(huì)落到數(shù)據(jù)庫(kù)上,也會(huì)對(duì)數(shù)據(jù)庫(kù)造成巨大的壓力
- 使用互斥鎖,當(dāng)發(fā)現(xiàn)緩存失效后,第一個(gè)請(qǐng)求加鎖,然后去查詢數(shù)據(jù)庫(kù),把數(shù)據(jù)存入緩存,這個(gè)操作只有一次,其他的請(qǐng)求都是阻塞的,查詢執(zhí)行完成后釋放鎖,此時(shí)已經(jīng)有了緩存數(shù)據(jù),也不會(huì)對(duì)數(shù)據(jù)庫(kù)造成壓力了
- 對(duì)熱點(diǎn)數(shù)據(jù)設(shè)置不同的失效時(shí)間,加上時(shí)間戳
2. Redis的數(shù)據(jù)結(jié)構(gòu)
string
Redis的最基本的數(shù)據(jù)結(jié)構(gòu),可以包含任意數(shù)據(jù)。一個(gè)key對(duì)應(yīng)一個(gè)string的value。string類型是二進(jìn)制安全的。每個(gè)string的value最大可以512M
支持的方法:set、get、mset、mget、setex、setnxlist
列表,一個(gè)簡(jiǎn)單的字符串列表,按照插入的順序排序,可以向頭部(左邊)或尾部(右邊)添加數(shù)據(jù),底層是鏈表
支持的方法:lpush、lpushx、lpop、lrange、lset、lindex、llen、rpush、rpopset
string的無(wú)序集合
支持的方法:sadd、scard、sdiff、sinter、sunion、sismember、smemberszset(sorted set)
sorted set有序集合,也是string的集合,但是有序的
支持的方法:zadd、zcardhash
hash是一個(gè)鍵值對(duì)集合,是一個(gè)string類型的key(這里叫做field)和value的映射表,key相當(dāng)于hash的名字,類似于Java中的Map
>
支持的方法:hset、hget、hdel、hexists、hkeys、hlen、hgetall3. Redis適合的場(chǎng)景
- 會(huì)話緩存(Session Cache)
- 全頁(yè)緩存(FPC)
- 隊(duì)列,利用list數(shù)據(jù)結(jié)構(gòu)
- 排行榜/計(jì)時(shí)器,利用zset
- 發(fā)布/訂閱系統(tǒng)
4. Redis處理并發(fā)競(jìng)爭(zhēng)問(wèn)題
Redis采用單進(jìn)程單線程模式,本身沒(méi)有鎖的概念,其對(duì)于多個(gè)客戶端訪問(wèn)不存在并發(fā)的問(wèn)題
通過(guò)jedis客戶端進(jìn)行并發(fā)訪問(wèn)時(shí)會(huì)出現(xiàn)連接超時(shí)、數(shù)據(jù)轉(zhuǎn)換錯(cuò)誤、阻塞等,通過(guò)以下方式解決:
- 客戶端與Redis通信時(shí),可以對(duì)連接進(jìn)行池化,每個(gè)對(duì)Redis的讀寫操作均采用synchronized
- 服務(wù)器端可以使用setnx
5. Redis設(shè)置過(guò)期時(shí)間
- 在set key的時(shí)候,可以指定expire time,也就是過(guò)期時(shí)間
- Jedis有單獨(dú)的expire方法
redis通過(guò)定期刪除和惰性刪除來(lái)刪除過(guò)期的key
- 定期刪除,Redis每隔100ms就隨機(jī)抽取一些設(shè)置了過(guò)期時(shí)間的key,檢查其是否過(guò)期,如果過(guò)期就刪除。因?yàn)閿?shù)據(jù)量巨大,遍歷全部key不現(xiàn)實(shí),太耗CPU,所以是隨機(jī)的
- 惰性刪除,發(fā)起查看key時(shí),會(huì)查看key是否過(guò)期,如果過(guò)期則刪除
只靠這兩種機(jī)制還是刪除不完全的,此時(shí)就需要內(nèi)存淘汰機(jī)制了
6. Redis內(nèi)存淘汰機(jī)制(如何保證熱點(diǎn))
- volatile-lru:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集合(server.db[i].expires)挑選最近最少使用的數(shù)據(jù)淘汰
- volatile-ttl:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集合中挑選將要過(guò)期的數(shù)據(jù)淘汰
- volatile-random:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集合中隨機(jī)挑選數(shù)據(jù)刪除
- allkeys-lru:在鍵空間中挑選最少使用的數(shù)據(jù)淘汰(這種策略最常用)
- allkeys-random:從數(shù)據(jù)集(server.db[i].dict)中隨機(jī)淘汰
- no-eviction:禁止淘汰數(shù)據(jù),當(dāng)寫入數(shù)據(jù)時(shí)報(bào)錯(cuò)處理
4.0新增
- volatile-lfu:從已設(shè)置過(guò)期時(shí)間的集合中挑選最不常用的數(shù)據(jù)淘汰
- allkeys-lfu:在鍵空間中挑選最不常用的數(shù)據(jù)淘汰
7. Redis的持久化策略
支持兩種持久化策略:一種是快照(snapshotting,RDB),另一種是只追加文件(append-only file,AOF)
- 快照持久化(RDB),通過(guò)創(chuàng)建快照來(lái)存儲(chǔ)在內(nèi)存里的數(shù)據(jù)在某個(gè)時(shí)間點(diǎn)的副本;創(chuàng)建快照之后,可以對(duì)快照進(jìn)行備份,可以將快照復(fù)制到其他服務(wù)器,還可以留在本地
是默認(rèn)的持久化方式。在redis.conf中有以下配置
save 900 1 #在900秒(15分鐘)之后,如果至少有1個(gè)key發(fā)生變化,就會(huì)觸發(fā)BFSAVE創(chuàng)建快照 save 300 10 #在300秒(5分鐘)之后,如果至少有10個(gè)key發(fā)生變化,就會(huì)觸發(fā)BFSAVE創(chuàng)建快照 save 60 10000 #在60秒(1分鐘)之后,如果至少有10000個(gè)key發(fā)生變化,就會(huì)觸發(fā)BFSAVE創(chuàng)建快照
- AOF(append-only file),AOF的實(shí)時(shí)性更好,默認(rèn)沒(méi)有開(kāi)啟,通過(guò)以下設(shè)置進(jìn)行開(kāi)啟
appendonly yes
開(kāi)啟AOF后,每執(zhí)行一條更改數(shù)據(jù)的命令,Redis就將該命令寫入硬盤中的AOF文件
在redis.conf中有三種不同的AOF配置
appendfsync always #每次更改數(shù)據(jù)都會(huì)寫入AOF文件,這會(huì)嚴(yán)重降低Redis的性能 appendfsync everysec #每秒同步一次,將多個(gè)命令同步到磁盤 appendfsync no #由操作系統(tǒng)決定何時(shí)同步
8. Redis事務(wù)
通過(guò)
MULTI
,EXEC
,WATCH
等命令來(lái)實(shí)現(xiàn)事務(wù)功能9. Redis的分布式鎖
通過(guò)setnx實(shí)現(xiàn)
10. Redis與Memcached的區(qū)別
- Redis支持豐富的數(shù)據(jù)結(jié)構(gòu),Memcached僅支持字符串
- Redis支持持久化,Memcached不支持
- Redis支持主從、哨兵、Cluster的集群模式,Memcached沒(méi)有
- Redis是單線程多路IO復(fù)用模型,Memcached是多線程非阻塞IO復(fù)用模型
11. Redis的集群
- 主從模式
主數(shù)據(jù)庫(kù)(master)和從數(shù)據(jù)庫(kù)(slave)
- 主數(shù)據(jù)庫(kù)進(jìn)行讀寫操作,當(dāng)數(shù)據(jù)發(fā)生變化時(shí)會(huì)自動(dòng)同步到從數(shù)據(jù)庫(kù)
- 從數(shù)據(jù)庫(kù)是只讀的
一個(gè)master對(duì)應(yīng)多個(gè)slave,一個(gè)slave只能有一個(gè)master
- 哨兵模式
哨兵的作用是監(jiān)控Redis系統(tǒng)的運(yùn)行情況
- 監(jiān)控主從是否正常運(yùn)行
- master出現(xiàn)故障時(shí),自動(dòng)將slave轉(zhuǎn)換為master
- 多哨兵之間也會(huì)互相監(jiān)控
多個(gè)哨兵監(jiān)控一個(gè)master
- 集群模式
只要將每個(gè)節(jié)點(diǎn)的cluster-enable配置打開(kāi)即可,每個(gè)集群最少三個(gè)節(jié)點(diǎn)
Memecached
選擇Memcached的理由:簡(jiǎn)單
本地緩存:Ehcache、Guava
Redis和Memcached的區(qū)別
- Redis支持的數(shù)據(jù)結(jié)構(gòu)更豐富
- Redis支持持久化,Memcached不支持
- Memcached沒(méi)有原生的集群模式,而Redis有主從、哨兵、集群
- Memcached是多線程、非阻塞IO復(fù)用的網(wǎng)絡(luò)模型,Redis是單線程多路IO復(fù)用的網(wǎng)絡(luò)模型
網(wǎng)頁(yè)標(biāo)題:掌握之分布式-4.緩存
標(biāo)題來(lái)源:http://fisionsoft.com.cn/article/pescos.html