中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

大型的網(wǎng)站開發(fā)crm系統(tǒng)網(wǎng)站

大型的網(wǎng)站開發(fā),crm系統(tǒng)網(wǎng)站,wordpress 免費ssl證書,中文網(wǎng)站域名注冊道生一,一生二,二生三,三生萬物 我旁邊的一位老哥跟我說,你知道分布式是是用來干什么的嘛?一句話給我干懵了,我能隱含知道,大概是用來做分壓處理的,并增加系統(tǒng)穩(wěn)定性的。但是具體如…

道生一,一生二,二生三,三生萬物

我旁邊的一位老哥跟我說,你知道分布式是是用來干什么的嘛?一句話給我干懵了,我能隱含知道,大概是用來做分壓處理的,并增加系統(tǒng)穩(wěn)定性的。但是具體如何,我卻道不出個1,2,3?,F(xiàn)在就將這些做一個詳細的總結(jié)。至少以后碰到面試官可以說上個123。

那么就正式進入正題:

文章目錄

  • 道生一,一生二,二生三,三生萬物
  • 分布式概念
  • 分布式鎖
  • 分布式鎖實現(xiàn)的方案
  • 數(shù)據(jù)庫實現(xiàn)(Mysql)
    • 方式1:樂觀鎖
    • 方式2:讀寫鎖的實現(xiàn)
      • 第一步:鏈接數(shù)據(jù)庫
      • 第二部:建立數(shù)據(jù)庫表
      • 第三步:讀方法(讀操作)
        • 讀加鎖操作
        • 讀解鎖操作
      • 第四步:寫方法(寫操作)
        • 寫加鎖
        • 寫解鎖
  • redis實現(xiàn)

分布式概念

分布式是一種,將一個大問題拆分成多個小問題,并分別由多個節(jié)點協(xié)同完成的計算機解決方案。

既然是解決問題,那么是解決什么呢?

分布式的目的:是為了解決單個機器無法滿足性能要求的問題

至于為什么單個機器無法滿足,其實回頭細想,現(xiàn)代的計算數(shù)據(jù)都是突出一個字,,這個大字就意味著處理數(shù)據(jù)的運算速度也得大,但是因為現(xiàn)代材料局限,一個主機的運算的能力有限,然而數(shù)據(jù)是成指數(shù)倍的增長,為了解決這個問題就是增加主機的數(shù)量,但是這就出現(xiàn)了另一個問題:->:如何將這些主機有機結(jié)合起來?分布式就是解決這個問題的。其實很多公司其實都不需要分布式,但是,時代進步的。不管現(xiàn)在是不是要用,但是未來的事情誰又說的清?

這個是網(wǎng)圖,但是我認為這個是可以將現(xiàn)在大部分的分布式知識做一個較為全面的總結(jié)的
請?zhí)砑訄D片描述

分布式這種框架的誕生,伴隨著許多的問題,包括硬件,也包括軟件,比如:

  1. 數(shù)據(jù)一致性
  2. 數(shù)據(jù)亂序
  3. 數(shù)據(jù)丟失
  4. 分庫分表的擴容

問題可以說是非常多。

但是大部分是可以用技術手段去避免很多的問題。而分布式加鎖就是一個較為有效的手段。不過就是犧牲了一部分的時效性,但是對于人類來說,這點時間的損耗,就是一個眨眼的功夫。希望日后會出現(xiàn)更多手段,去解決這方面的問題。

接下來就是對于分布式鎖介紹

分布式鎖

分布式鎖的應用場景,這些既是應用場景也是問題所在:

  1. 處理緩存擊穿
  2. 處理緩存雪崩
  3. 重試處理
  4. 冪等性
  5. 數(shù)據(jù)不一致的問題

基本上很多分布式應用上的問題基本可以用分布式鎖處理

那么什么算是一個合格的分布式鎖呢?眾多巨人的文章中無不透露以下這幾點:

  1. 互斥性:這個是鎖的基本功能,即:同一時刻只允許一個客戶端持有鎖
  2. 避免死鎖:獲取到鎖的客戶端出現(xiàn)問題了,沒有辦法解鎖,所以要避免死鎖。讓系統(tǒng)繼續(xù)運行下去(有些也叫安全性)
  3. 容錯:既然是服務器,那么提供鎖的系統(tǒng)也是有可能崩潰的,所以要保證這一點。

這些屬性,將會貫穿這篇文章。

分布式鎖實現(xiàn)的方案

這些我會舉出大體的實現(xiàn)思路,并不會全部去實現(xiàn)。

🌝每種實現(xiàn)類型中都有不同實現(xiàn)方式 ,比如mysql有悲觀鎖和樂觀鎖,讀寫鎖這些方式的實現(xiàn)方式

常見的實現(xiàn)方案有:

  1. 數(shù)據(jù)庫實現(xiàn)(我這里用的是mysql)
  2. redis實現(xiàn)
  3. zookeeper實現(xiàn)
  4. Redlock 算法實現(xiàn)

這里都會說到,但是對于實現(xiàn)來說,我目前就是只說MySQL的實現(xiàn),redis的實現(xiàn)

語言對于程序員來說只是說某種工具而言,真正重要的是邏輯(算法)數(shù)據(jù)結(jié)構,這個才是一個程序員安生立命的本錢。

所以這篇文章我會用go語言實現(xiàn),其他語言的版本這里就不多說了。但是我會將常見的語言包說出,方便友友們能夠快速查到相關的資料。

數(shù)據(jù)庫實現(xiàn)(Mysql)

這里我用MySQL去實現(xiàn):

技術:golanggorm數(shù)據(jù)結(jié)構

方式1:樂觀鎖

實現(xiàn)方式:通過對數(shù)據(jù)表添加一個字段 Version實現(xiàn)(數(shù)據(jù)版本(Version)記錄機制實現(xiàn))

主要邏輯:為數(shù)據(jù)庫表增加一個數(shù)字類型的 version 字段來實現(xiàn)。當讀取數(shù)據(jù)時,將version字段的值一同讀出,數(shù)據(jù)每更新一次,對此version值加

如果對于跟新操作,需要先判斷當前version與數(shù)據(jù)庫中的version版本號是否對應,對應的上就允許跟新,諾是不相同,就會導致沖突,此時就更新失敗。

是不是很簡單?是的確實很簡單。畫個圖解釋一下

在這里插入圖片描述
在這里插入圖片描述

那么悲觀鎖如何實現(xiàn)我相信大家肯定也就明白了。但是這里我就淺淺提一點:

sql語句后添加for update

邏輯實現(xiàn):

  1. 通過添加線程做輪詢等待,然后搶鎖
  2. 添加過期時間
  3. 更新版本號

接下來重點是讀寫鎖的實現(xiàn)

方式2:讀寫鎖的實現(xiàn)

而這兩種鎖的實現(xiàn),需要滿足一下幾個特點:

  1. 執(zhí)行操作的環(huán)境是分布式的(當然單機不是不能用)
  2. 讀操作,不做限制,里面資源是共享的??梢灾С侄鄠€線程或者協(xié)程對資源的讀取的操作。
  3. 寫操作,是互斥的,也就是說明一個時刻只允許一個協(xié)程或者進程對資源進行訪問。
  4. 讀操作,寫操作兩者是互斥的。不能同時存在

ps:相當于對于讀寫這兩個操作來說,都有自己的申請鎖和解鎖的方法,讀模式共享,寫模式互斥

讀寫鎖的有點在于:

  1. 分布式讀寫鎖是比分布式鎖粒度更小的鎖
  2. 對于業(yè)務場景更加靈活

所以綜上的出:讀寫鎖的狀態(tài)有:讀加鎖狀態(tài)、寫加鎖狀態(tài)、無鎖狀態(tài)

當前鎖狀態(tài)讀鎖請求寫鎖請求
無鎖狀態(tài)可以可以
讀鎖狀態(tài)可以不可以
寫鎖狀態(tài)不可以不可以

第一步:鏈接數(shù)據(jù)庫

每個程序員的鏈接手法各不相同,所以這里就不獻丑了。只要連上數(shù)據(jù)庫就好。然后將客戶端暴露出來。

第二部:建立數(shù)據(jù)庫表

要包含一下這幾個字段。

var (statusUnLock    = "Unlock"statusReadLock  = "ReadLock"statusWirteLock = "WirteLock"
)type RWLock struct {
//表示某條數(shù)據(jù)加鎖的狀態(tài),只能是讀鎖、寫鎖、無鎖狀態(tài)中的一種,默認狀態(tài)為無鎖狀態(tài)LockStatus    string `gorm:"default:'Unlock'"` //ReadLockCount 字段則記錄當前并發(fā)訪問的 goroutine(可以理解成線程) 數(shù)量ReadLockCount uint32 `gorm:"default:0"`       LockReason    string //記錄當前加鎖的原因
}// Stock 存儲鎖
type Stock struct {gorm.ModelRWLockCount int64
}func (Stock) TableName() string {return "stock"
}

這三個是狀態(tài)值,分別代表:無鎖,讀鎖,寫鎖

statusUnLock = “Unlock”
statusReadLock = “ReadLock”
statusWirteLock = “WirteLock”

gorm.Model中包含了:一下字段:

//主鍵idID        uint `gorm:"primarykey"`//創(chuàng)建時間CreatedAt time.Time//更新時間UpdatedAt time.Time//刪除時間,軟刪除DeletedAt DeletedAt `gorm:"index"`

這里我們通過的方式是,建立一個鎖表來管理整個鎖。相應的字段的功能我這里就不做贅述,在代碼中已經(jīng)有了。


第三步:讀方法(讀操作)

讀加鎖操作
// ReadLock 讀鎖
func (s Stock) ReadLock(ctx context.Context, db *gormX.DataBD, lockReason string) error {fields := map[string]interface{}{"lock_status":     statusReadLock,"read_lock_count": gorm.Expr("read_lock_count + ?", 1),"lock_reason":     lockReason,}//將所屬的id鎖的寫狀態(tài)改為讀狀態(tài)result := db.DB(ctx).Model(&Stock{}).Where("id=? AND lock_status=?", s.ID, statusWirteLock).Updates(fields)if result.Error != nil {return result.Error}if result.RowsAffected == 0 {return errors.New("重入鎖失敗,受影響的行數(shù)為 0")}return nil
}

我將對這里的代碼做一個解釋:

context.Context:上下文,用來管理請求
db *gormX.DataBD: 用來處理mysql連接的
lockReason:對每個鎖進行備注

這里的讀鎖就是做一個統(tǒng)計,統(tǒng)計有多少個線程,是讀鎖狀態(tài)

result := db.DB(ctx).Model(&Stock{}).Where("id=? AND lock_status=?", s.ID, statusWirteLock).Updates(fields):
這個整個sql的翻譯,{參數(shù)}

update stock 
setlock_status={statusReadLock},read_lock_count =read_lock_count +1 ,//這個不是參數(shù)lock_reason={lockReason} where id={s.ID} and statusWirteLoc={statusWirteLock}

這里為什么是update呢?因為在這里gorm中,update沒有的數(shù)據(jù)的話,會變成insert插入數(shù)據(jù)。其他語言在做的時候一定要注意。

讀解鎖操作
// UnReadLock 讀解鎖
func (s Stock) UnReadLock(ctx context.Context, db *gormX.DataBD, UnLockReason string) error {fields := map[string]interface{}{"read_lock_count": gorm.Expr("if(read_lock_count>0),read_lock_count-1,0"),"lock_status":     gorm.Expr("if(lock_status < 1),?,?", statusUnLock, statusReadLock),"lock_reason":     UnLockReason,}result := db.DB(ctx).Model(&Stock{}).Where("id=? and lock_status=?", s.ID, statusReadLock).UpdateColumns(fields)if result.Error != nil {return result.Error}if result.RowsAffected == 0 {return errors.New("解讀鎖失敗,受影響的行數(shù)為 0")}return nil
}

這里將讀操作做完的業(yè)務進行釋放后,在表中做統(tǒng)計減少的操作。
我將對這里的代碼做一個解釋:
result := db.DB(ctx).Model(&Stock{}).Where("id=? and lock_status=?", s.ID, statusReadLock).UpdateColumns(fields)

update stock 
setlock_status=(if(read_lock_count>0),read_lock_count-1,0),read_lock_count =(if(lock_status < 1),{statusUnLock},{statusReadLock}),lock_reason={lockReason} where id={s.ID} and statusWirteLoc={statusReadLock}

第四步:寫方法(寫操作)

寫加鎖
// WriteLock 寫鎖
func (s Stock) WriteLock(ctx context.Context, db *gormX.DataBD, lockReason string) error {fields := map[string]interface{}{"read_lock_count": 0,"lock_status":     statusWirteLock,"lock_reason":     lockReason,}result := db.DB(ctx).Model(&Stock{}).Where("id=? and lock_status=?", s.ID, statusUnLock).Updates(fields)if result.Error != nil {return result.Error}if result.RowsAffected == 0 {return errors.New("寫入鎖失敗,受影響的行數(shù)為 0")}return nil
}

這里不對線程進行統(tǒng)計,因為這是互斥的。并將鎖寫入狀態(tài)
我將對這里的代碼做一個解釋:
result := db.DB(ctx).Model(&Stock{}).Where("id=? and lock_status=?", s.ID, statusUnLock).Updates(fields)

update stock 
setlock_status={statusWirteLock},read_lock_count =0 ,//這個不是參數(shù)lock_reason={lockReason} where id={s.ID} and statusWirteLoc={statusWirteLock}

這里為什么是update呢?因為在這里gorm中,update沒有的數(shù)據(jù)的話,會變成insert插入數(shù)據(jù)。其他語言在做的時候一定要注意。

寫解鎖
// UnWriteLock 寫解鎖
func (s Stock) UnWriteLock(ctx context.Context, db gormX.DataBD, UnLockReason string) error {fields := map[string]interface{}{"read_lock_count": 0,"lock_status":     statusUnLock,"lock_reason":     UnLockReason,}result := db.DB(ctx).Model(&Stock{}).Where("id=? and lock_status=?", s.ID, statusWirteLock).Updates(fields)if result.Error != nil {return result.Error}if result.RowsAffected == 0 {return errors.New("解寫鎖失敗,受影響的行數(shù)為 0")}return nil
}

這里不對線程進行統(tǒng)計,因為這是互斥的。并修改其狀態(tài)
我將對這里的代碼做一個解釋:
result := db.DB(ctx).Model(&Stock{}).Where("id=? and lock_status=?", s.ID, statusWirteLock).Updates(fields)

update stock 
setlock_status={statusUnLock},read_lock_count =0 ,//這個不是參數(shù)lock_reason={lockReason} where id={s.ID} and statusWirteLoc={statusWirteLock}

redis實現(xiàn)

今天太晚了,先不寫,明天補上:連接

續(xù):今天補上了:請看這篇文章

http://www.risenshineclean.com/news/28794.html

相關文章:

  • 免費網(wǎng)站制作效果百度一下你就知道123
  • 邯鄲做移動網(wǎng)站費用seo專業(yè)論壇
  • 網(wǎng)站網(wǎng)速慢刷百度關鍵詞排名
  • 瑞安做網(wǎng)站建設湖南網(wǎng)站建設seo
  • 桐鄉(xiāng)做網(wǎng)站正規(guī)seo大概多少錢
  • 網(wǎng)站不兼容怎么辦鄭州seo博客
  • 網(wǎng)站內(nèi)容全屏截屏怎么做網(wǎng)站做seo教程
  • 自己站網(wǎng)站如何進行搜索引擎優(yōu)化
  • 查法人信息的網(wǎng)站培訓計劃和培訓內(nèi)容
  • 建網(wǎng)站要花錢嗎seo如何建立優(yōu)化網(wǎng)站
  • 上海網(wǎng)站建設定制公司谷歌推廣代理公司
  • 用wordpress怎么做網(wǎng)站免費s站推廣網(wǎng)站
  • 濰坊網(wǎng)站建設客服代寫文章質(zhì)量高的平臺
  • 電子商務網(wǎng)站開發(fā)是什么官方正版清理優(yōu)化工具
  • cnzz網(wǎng)站建設廣州seo好找工作嗎
  • 廣州家居網(wǎng)站設計nba最新交易匯總
  • 大學生想做網(wǎng)站西安seo優(yōu)化推廣
  • 青島網(wǎng)站建設小公司seo綜合查詢工具
  • 網(wǎng)站是否必須做可信網(wǎng)站認證seo自動優(yōu)化軟件下載
  • 訂房網(wǎng)站開發(fā)長春網(wǎng)站建設推廣
  • 網(wǎng)站開發(fā)驗收單8大營銷工具指的是哪些
  • 怎么做提卡密網(wǎng)站域名解析網(wǎng)站
  • 專注做一家男人最愛的網(wǎng)站廣州seo運營
  • 全網(wǎng)搜索石家莊seo全網(wǎng)營銷
  • 東莞網(wǎng)絡展示平臺東莞seo外包
  • 網(wǎng)站建設與維護是做什么seo公司上海牛巨微
  • wordpress的app怎么用而的跟地seo排名點擊軟件
  • 設計高端網(wǎng)站怎么宣傳自己的產(chǎn)品
  • 成都網(wǎng)站排名優(yōu)化今日新聞頭條新聞今天
  • 常寧網(wǎng)頁設計西安百度關鍵詞優(yōu)化排名