成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

基于Redis的分布式鎖和Redlock算法

存儲(chǔ) 存儲(chǔ)軟件 分布式 算法 Redis
在單進(jìn)程的系統(tǒng)中,當(dāng)存在多個(gè)線程可以同時(shí)改變某個(gè)變量(可變共享變量)時(shí),就需要對(duì)變量或代碼塊做同步,使其在修改這種變量時(shí)能夠線性執(zhí)行消除并發(fā)修改變量。

[[403381]]

 本文轉(zhuǎn)載自微信公眾號(hào)「UP技術(shù)控」,作者conan5566。轉(zhuǎn)載本文請(qǐng)聯(lián)系UP技術(shù)控公眾號(hào)。

在單進(jìn)程的系統(tǒng)中,當(dāng)存在多個(gè)線程可以同時(shí)改變某個(gè)變量(可變共享變量)時(shí),就需要對(duì)變量或代碼塊做同步,使其在修改這種變量時(shí)能夠線性執(zhí)行消除并發(fā)修改變量。

而同步的本質(zhì)是通過(guò)鎖來(lái)實(shí)現(xiàn)的。為了實(shí)現(xiàn)多個(gè)線程在一個(gè)時(shí)刻同一個(gè)代碼塊只能有一個(gè)線程可執(zhí)行,那么需要在某個(gè)地方做個(gè)標(biāo)記,這個(gè)標(biāo)記必須每個(gè)線程都能看到,當(dāng)標(biāo)記不存在時(shí)可以設(shè)置該標(biāo)記,其余后續(xù)線程發(fā)現(xiàn)已經(jīng)有標(biāo)記了則等待擁有標(biāo)記的線程結(jié)束同步代碼塊取消標(biāo)記后再去嘗試設(shè)置標(biāo)記。這個(gè)標(biāo)記可以理解為鎖。

不同地方實(shí)現(xiàn)鎖的方式也不一樣,只要能滿足所有線程都能看得到標(biāo)記即可。如 Java 中 synchronize 是在對(duì)象頭設(shè)置標(biāo)記,Lock 接口的實(shí)現(xiàn)類基本上都只是某一個(gè) volitile 修飾的 int 型變量其保證每個(gè)線程都能擁有對(duì)該 int 的可見(jiàn)性和原子修改,linux 內(nèi)核中也是利用互斥量或信號(hào)量等內(nèi)存數(shù)據(jù)做標(biāo)記。

除了利用內(nèi)存數(shù)據(jù)做鎖其實(shí)任何互斥的都能做鎖(只考慮互斥情況),如流水表中流水號(hào)與時(shí)間結(jié)合做冪等校驗(yàn)可以看作是一個(gè)不會(huì)釋放的鎖,或者使用某個(gè)文件是否存在作為鎖等。只需要滿足在對(duì)標(biāo)記進(jìn)行修改能保證原子性和內(nèi)存可見(jiàn)性即可。

1 什么是分布式?

分布式的 CAP 理論告訴我們:

任何一個(gè)分布式系統(tǒng)都無(wú)法同時(shí)滿足一致性(Consistency)、可用性(Availability)和分區(qū)容錯(cuò)性(Partition tolerance),最多只能同時(shí)滿足兩項(xiàng)。

目前很多大型網(wǎng)站及應(yīng)用都是分布式部署的,分布式場(chǎng)景中的數(shù)據(jù)一致性問(wèn)題一直是一個(gè)比較重要的話題。基于 CAP理論,很多系統(tǒng)在設(shè)計(jì)之初就要對(duì)這三者做出取舍。在互聯(lián)網(wǎng)領(lǐng)域的絕大多數(shù)的場(chǎng)景中,都需要犧牲強(qiáng)一致性來(lái)?yè)Q取系統(tǒng)的高可用性,系統(tǒng)往往只需要保證最終一致性。

分布式場(chǎng)景

此處主要指集群模式下,多個(gè)相同服務(wù)同時(shí)開(kāi)啟.

在許多的場(chǎng)景中,我們?yōu)榱吮WC數(shù)據(jù)的最終一致性,需要很多的技術(shù)方案來(lái)支持,比如分布式事務(wù)、分布式鎖等。很多時(shí)候我們需要保證一個(gè)方法在同一時(shí)間內(nèi)只能被同一個(gè)線程執(zhí)行。在單機(jī)環(huán)境中,通過(guò) Java 提供的并發(fā) API 我們可以解決,但是在分布式環(huán)境下,就沒(méi)有那么簡(jiǎn)單啦。

  • 分布式與單機(jī)情況下最大的不同在于其不是多線程而是多進(jìn)程。
  • 多線程由于可以共享堆內(nèi)存,因此可以簡(jiǎn)單的采取內(nèi)存作為標(biāo)記存儲(chǔ)位置。而進(jìn)程之間甚至可能都不在同一臺(tái)物理機(jī)上,因此需要將標(biāo)記存儲(chǔ)在一個(gè)所有進(jìn)程都能看到的地方。

什么是分布式鎖?

  • 當(dāng)在分布式模型下,數(shù)據(jù)只有一份(或有限制),此時(shí)需要利用鎖的技術(shù)控制某一時(shí)刻修改數(shù)據(jù)的進(jìn)程數(shù)。
  • 與單機(jī)模式下的鎖不僅需要保證進(jìn)程可見(jiàn),還需要考慮進(jìn)程與鎖之間的網(wǎng)絡(luò)問(wèn)題。(我覺(jué)得分布式情況下之所以問(wèn)題變得復(fù)雜,主要就是需要考慮到網(wǎng)絡(luò)的延時(shí)和不可靠。。。一個(gè)大坑)
  • 分布式鎖還是可以將標(biāo)記存在內(nèi)存,只是該內(nèi)存不是某個(gè)進(jìn)程分配的內(nèi)存而是公共內(nèi)存如 Redis、Memcache。至于利用數(shù)據(jù)庫(kù)、文件等做鎖與單機(jī)的實(shí)現(xiàn)是一樣的,只要保證標(biāo)記能互斥就行。

2 我們需要怎樣的分布式鎖?

可以保證在分布式部署的應(yīng)用集群中,同一個(gè)方法在同一時(shí)間只能被一臺(tái)機(jī)器上的一個(gè)線程執(zhí)行。

  • 這把鎖要是一把可重入鎖(避免死鎖)
  • 這把鎖最好是一把阻塞鎖(根據(jù)業(yè)務(wù)需求考慮要不要這條)
  • 這把鎖最好是一把公平鎖(根據(jù)業(yè)務(wù)需求考慮要不要這條)

有高可用的獲取鎖和釋放鎖功能

獲取鎖和釋放鎖的性能要好

代碼實(shí)現(xiàn)

  1. public interface IDistributedLock 
  2.     { 
  3.         ILockResult Lock(string resourceKey); 
  4.         ILockResult Lock(string resourceKey, TimeSpan expiryTime); 
  5.         ILockResult Lock(string resourceKey, TimeSpan expiryTime, TimeSpan waitTime, TimeSpan retryTime); 
  6.         ILockResult Lock(string resourceKey, TimeSpan expiryTime, TimeSpan waitTime, TimeSpan retryTime, CancellationToken cancellationToken); 
  7.         Task<ILockResult> LockAsync(string resourceKey); 
  8.         Task<ILockResult> LockAsync(string resourceKey, TimeSpan expiryTime); 
  9.         Task<ILockResult> LockAsync(string resourceKey, TimeSpan expiryTime, TimeSpan waitTime, TimeSpan retryTime); 
  10.         Task<ILockResult> LockAsync(string resourceKey, TimeSpan expiryTime, TimeSpan waitTime, TimeSpan retryTime, CancellationToken cancellationToken); 
  11.     } 
  12.  
  13.     public interface ILockResult : IDisposable 
  14.     { 
  15.         string LockId { get; } 
  16.         bool IsAcquired { get; } 
  17.         int ExtendCount { get; } 
  18.     } 
  1. class EndPoint:RedLock.RedisLockEndPoint 
  2.     { 
  3.         private readonly string _connectionString; 
  4.         public EndPoint(string connectionString) 
  5.         { 
  6.             _connectionString = connectionString; 
  7.             //139.196.40.252,password=xstudio,defaultDatabase=9 
  8.             var connection = connectionString.Split(','); 
  9.             var dict = new Dictionary<string, string>(); 
  10.             foreach (var item in connection
  11.             { 
  12.                 var keypar = item.Split('='); 
  13.                 if (keypar.Length>1) 
  14.                 { 
  15.                     dict[keypar[0]] = keypar[1]; 
  16.                 } 
  17.             } 
  18.             this.EndPoint = new System.Net.DnsEndPoint(connection[0], 6379); 
  19.             if (dict.TryGetValue("password"out string password)) 
  20.             { 
  21.                 this.Password = password
  22.             } 
  23.             if (dict.TryGetValue("defaultDatabase"out string defaultDatabase) && int.TryParse(defaultDatabase,out int database)) 
  24.             { 
  25.                 RedisDatabase = database
  26.             } 
  27.         } 
  28.     } 
  1. [Export(typeof(IDistributedLock))] 
  2.     class InnerLock : IDistributedLock 
  3.     { 
  4.         private static Lazy<RedLock.RedisLockFactory> _factory; 
  5.  
  6.         static InnerLock() 
  7.         { 
  8.             _factory = new Lazy<RedisLockFactory>(() => new RedisLockFactory(new EndPoint(ConfigurationManager.AppSettings["Redis"])), System.Threading.LazyThreadSafetyMode.ExecutionAndPublication); 
  9.         } 
  10.         public ILockResult Lock(string resourceKey) 
  11.         { 
  12.             return new LockResult(_factory.Value.Create(resourceKey, TimeSpan.FromDays(1))); 
  13.         } 
  14.  
  15.         public ILockResult Lock(string resourceKey, TimeSpan expiryTime) 
  16.         { 
  17.             return new LockResult(_factory.Value.Create(resourceKey, expiryTime)); 
  18.         } 
  19.  
  20.         public ILockResult Lock(string resourceKey, TimeSpan expiryTime, TimeSpan waitTime, TimeSpan retryTime) 
  21.         { 
  22.             return new LockResult(_factory.Value.Create(resourceKey, expiryTime, waitTime, retryTime)); 
  23.         } 
  24.  
  25.         public ILockResult Lock(string resourceKey, TimeSpan expiryTime, TimeSpan waitTime, TimeSpan retryTime, CancellationToken cancellationToken) 
  26.         { 
  27.             return new LockResult(_factory.Value.Create(resourceKey, expiryTime, waitTime, retryTime, cancellationToken)); 
  28.         } 
  29.  
  30.         public async Task<ILockResult> LockAsync(string resourceKey) 
  31.         { 
  32.             var result = await _factory.Value.CreateAsync(resourceKey, TimeSpan.FromDays(1)); 
  33.             return new LockResult(result); 
  34.         } 
  35.  
  36.         public async Task<ILockResult> LockAsync(string resourceKey, TimeSpan expiryTime) 
  37.         { 
  38.             var result = await _factory.Value.CreateAsync(resourceKey, expiryTime); 
  39.             return new LockResult(result); 
  40.         } 
  41.  
  42.         public async Task<ILockResult> LockAsync(string resourceKey, TimeSpan expiryTime, TimeSpan waitTime, TimeSpan retryTime) 
  43.         { 
  44.             var result = await _factory.Value.CreateAsync(resourceKey, expiryTime, waitTime, retryTime); 
  45.             return new LockResult(result); 
  46.         } 
  47.  
  48.         public async Task<ILockResult> LockAsync(string resourceKey, TimeSpan expiryTime, TimeSpan waitTime, TimeSpan retryTime, CancellationToken cancellationToken) 
  49.         { 
  50.             var result = await _factory.Value.CreateAsync(resourceKey, expiryTime, waitTime, retryTime, cancellationToken); 
  51.             return new LockResult(result); 
  52.         } 
  53.     } 
  54.  
  55.     class LockResult : ILockResult 
  56.     { 
  57.         private IRedisLock _lock; 
  58.         public LockResult(IRedisLock redisLock) 
  59.         { 
  60.             _lock = redisLock; 
  61.         } 
  62.  
  63.         public string LockId => _lock.LockId; 
  64.  
  65.         public bool IsAcquired => _lock.IsAcquired; 
  66.  
  67.         public int ExtendCount => _lock.ExtendCount; 
  68.  
  69.         public void Dispose() 
  70.         { 
  71.             _lock.Dispose(); 
  72.         } 
  73.     } 

 

責(zé)任編輯:武曉燕 來(lái)源: UP技術(shù)控
相關(guān)推薦

2021-07-30 00:09:21

Redlock算法Redis

2019-06-19 15:40:06

分布式鎖RedisJava

2022-03-08 07:22:48

Redis腳本分布式鎖

2017-10-24 11:28:23

Zookeeper分布式鎖架構(gòu)

2017-04-13 10:51:09

Consul分布式

2021-09-17 07:51:24

RedissonRedis分布式

2022-06-16 08:01:24

redis分布式鎖

2022-01-06 10:58:07

Redis數(shù)據(jù)分布式鎖

2023-08-21 19:10:34

Redis分布式

2019-02-26 09:51:52

分布式鎖RedisZookeeper

2021-11-01 12:25:56

Redis分布式

2024-02-20 09:50:02

Redis分布式

2024-01-09 09:27:08

RedLock分布式鎖Redis

2022-10-27 10:44:14

分布式Zookeeper

2021-07-16 07:57:34

ZooKeeperCurator源碼

2022-03-08 15:24:23

BitMapRedis數(shù)據(jù)

2023-03-01 08:07:51

2020-11-16 12:55:41

Redis分布式鎖Zookeeper

2024-10-07 10:07:31

2022-09-19 08:17:09

Redis分布式
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 国产三级精品视频 | 国产激情精品视频 | www.欧美 | 久久逼逼 | 成人三级av | 波多野结衣在线观看一区二区三区 | 亚洲成人一级 | 国产精品小视频在线观看 | 国产精品久久网 | 一级久久久久久 | av一二三区 | 久久精品亚洲国产 | 日韩中文字幕视频在线观看 | 成人综合视频在线 | 国产精品三级 | 国产精品久久毛片av大全日韩 | 日本在线免费视频 | 久久精品无码一区二区三区 | 一级毛片免费完整视频 | 99热国产在线播放 | 91精品国产乱码久久蜜臀 | 日韩国产精品一区二区三区 | 国产成人精品一区二区三区网站观看 | www.国产日本 | 在线视频 欧美日韩 | 国产91久久精品一区二区 | 日日摸夜夜添夜夜添特色大片 | 国产精品成人一区二区三区 | 亚洲国产精品一区二区三区 | 成人小视频在线 | 天啪| 久久精品播放 | 欧美三级成人理伦 | 天天操天天操 | 国产精品日韩欧美一区二区三区 | 国产不卡一区在线观看 | 欧美日在线 | 韩日精品在线观看 | 欧美伊人久久久久久久久影院 | 午夜久久久久 | 国产一级片一区二区 |