一谁榜、什么是分布式鎖
在單體架構(gòu)中幅聘,系統(tǒng)只有一個,系統(tǒng)所用的內(nèi)存和進程也只有一個惰爬,多個線程可以共享同一份數(shù)據(jù)喊暖。這樣只要使用java提供的鎖機制就可以解決并發(fā)訪問帶來的問題惫企,但是分布式系統(tǒng)中撕瞧,系統(tǒng)是多個,并且所使用的內(nèi)存也是不同的狞尔,每個系統(tǒng)也都有獨立的進程丛版,這樣Java提供的鎖就沒辦法解決分布式系統(tǒng)中的并發(fā)訪問問題。因此就需要引入分布式鎖來解決分布式系統(tǒng)中共享資源訪問的問題偏序。
1.2 分布式鎖的特性
1.要保證同一時刻內(nèi)页畦,只有一個服務(wù)獲取到這個鎖
2.這把鎖要能重入,在某些業(yè)務(wù)下會出現(xiàn)同一把鎖的重入
3.具備鎖續(xù)命研儒,保證高并發(fā)下不會因鎖的時效問題引起數(shù)據(jù)錯誤
4.具有非阻塞式獲取鎖豫缨,在獲取鎖失敗后立刻返回
1.3 基于Redisson實現(xiàn)的分布式鎖
Redisson中分布式鎖的架構(gòu):關(guān)于Redisson分布式鎖的使用:
private Integer setInfo(Long key){
// 獲取分布式鎖
RLock lock = redisson.getLock("Ext_Info:" + key);
// 加鎖
lock.lock();
try{
// 業(yè)務(wù)處理
Product product = productDao.get(key);
return 1;
}catch (Exception e){
e.printStackTrace();
}finally {
// 解鎖
lock.unlock();
}
return -1;
}
1.4 分布式鎖失效問題
當主從或集群機構(gòu)的主節(jié)點掛掉后,該節(jié)點存儲的分布式鎖信息可能會丟失端朵。而當從節(jié)點選舉成新節(jié)點后好芭,其它線程又可以對新的主節(jié)點進行添加分布式鎖信息,這就會引起并發(fā)安全問題冲呢。
為了解決這個問題舍败,就引入了redlock。
redlock的邏輯就是向多個節(jié)點寫入加鎖的信息敬拓,如果寫入成功邻薯,加代表加鎖成功。但是如果寫入的節(jié)點丟失了鎖的信息乘凸,仍然是會出現(xiàn)分布式鎖失效問題厕诡。
還有一點就是性能問題,我們使用redis就是為了它的高性能营勤,但是使用redlock后每次加鎖都要寫入多個節(jié)點灵嫌,這就會降低redis性能信柿,這樣還不如使用zookeeper。
二醒第、Redisson實現(xiàn)分布式鎖源碼剖析
加鎖的核心邏輯:三渔嚷、分布式鎖的優(yōu)化
對于讀多寫少的業(yè)務(wù),可以使用readwirte鎖:
public Product update(Product product) {
Product productResult = null;
// 獲取分布式鎖
RReadWriteLock readWriteLock = redisson.getReadWriteLock(LOCK_PRODUCT_UPDATE_PREFIX + product.getId());
// 寫鎖
RLock writeLock = readWriteLock.writeLock();
// 加鎖
writeLock.lock();
try {
productResult = productDao.update(product);
// 設(shè)置過期時間
redisUtil.set(productResult.getId(), JSON.toJSONString(productResult),
genProductCacheTimeout(), TimeUnit.SECONDS);
} finally {
// 釋放鎖
writeLock.unlock();
}
return productResult;
}
redisson實現(xiàn)的讀寫鎖稠曼,大體上和上面的分布式鎖邏輯相同形病,只是加了一個mode,用于區(qū)分是讀還是寫霞幅。對于讀讀而言漠吻,就等于是鎖的重入,不會阻塞司恳;對于讀寫途乃、寫寫操作,就會阻塞保證并發(fā)的安全扔傅。
四耍共、緩存問題
1、什么是緩存擊穿猎塞?
當同一時刻有大量的緩存失效试读,就會導(dǎo)致大量的請求打到數(shù)據(jù)庫,會造成數(shù)據(jù)庫壓力過大甚至宕機荠耽。
解決辦法:在給緩存數(shù)據(jù)設(shè)置過期時間時钩骇,增加一個隨機的擾動因子,避免讓大量的緩存數(shù)據(jù)都同一時刻失效铝量。
2倘屹、什么是緩存穿透?
緩存層和數(shù)據(jù)庫都沒有數(shù)據(jù)慢叨,每次請求都會落到數(shù)據(jù)庫纽匙,如果是高并發(fā)場景下,就會引起數(shù)據(jù)的壓力劇增插爹,甚至宕機哄辣。
解決辦法:
1、對于不存在的數(shù)據(jù)赠尾,可以在緩存層面設(shè)置對應(yīng)key的空值
2力穗、布隆過濾器,向布隆過濾器中添加key時气嫁,會先使用多個hash函數(shù)進行運算当窗,然后定位到布隆過濾器的數(shù)組中某個下標。當某個key查詢布隆過濾器數(shù)據(jù)時寸宵,會同樣使用多個hash函數(shù)進行運算崖面,然后得到數(shù)組中的下標位置元咙。
3、什么是緩存雪崩巫员?
緩存層的作用就是分擔數(shù)據(jù)庫層面的壓力庶香,如果緩存層宕機,大量的請求就直接打到數(shù)據(jù)庫简识,高并發(fā)下數(shù)據(jù)庫有可能宕機赶掖。
解決辦法:
1、確保緩存層的高可用七扰,比如搭建集群奢赂、主從架構(gòu)
2、在后端應(yīng)用上設(shè)置限流或服務(wù)降級