相關(guān)關(guān)鍵詞
關(guān)于我們
最新文章
- PHP中opcode緩存簡(jiǎn)單用法分析
- thinkPHP控制器變量在模板中的顯示方法示例
- PHP move_uploaded_file() 函數(shù)(將上傳的文件移動(dòng)到新位置)
- dirname(__FILE__)的含義和應(yīng)用說(shuō)明
- thinkPHP5框架實(shí)現(xiàn)分頁(yè)查詢功能的方法示例
- PHP中單雙號(hào)與變量
- PHP獲得當(dāng)日零點(diǎn)時(shí)間戳的方法分析
- Laravel ORM對(duì)Model::find方法進(jìn)行緩存示例詳解
- PHP讀寫(xiě)文件高并發(fā)處理操作實(shí)例詳解
- 【CLI】利用Curl下載文件實(shí)時(shí)進(jìn)度條顯示的實(shí)現(xiàn)
Redis構(gòu)建分布式鎖

1、前言
為什么要構(gòu)建鎖呢?因?yàn)闃?gòu)建合適的鎖可以在高并發(fā)下能夠保持?jǐn)?shù)據(jù)的一致性,即客戶端在執(zhí)行連貫的命令時(shí)上鎖的數(shù)據(jù)不會(huì)被別的客戶端的更改而發(fā)生錯(cuò)誤。同時(shí)還能夠保證命令執(zhí)行的成功率。
看到這里你不禁要問(wèn)redis中不是有事務(wù)操作么?事務(wù)操作不能夠?qū)崿F(xiàn)上面的功能么?
的確,redis中的事務(wù)可以watch可以監(jiān)控?cái)?shù)據(jù),從而能夠保證連貫執(zhí)行的時(shí)數(shù)據(jù)的一致性,但是我們必須清楚的認(rèn)識(shí)到,在多個(gè)客戶端同時(shí)處理相同的數(shù)據(jù)的時(shí)候,很容易導(dǎo)致事務(wù)的執(zhí)行失敗,甚至?xí)?dǎo)致數(shù)據(jù)的出錯(cuò)。
在關(guān)系型數(shù)據(jù)庫(kù)中,用戶首先向數(shù)據(jù)庫(kù)服務(wù)器發(fā)送BEGIN,然后執(zhí)行各個(gè)相互一致的寫(xiě)操作和讀操作,最后用戶可以選擇發(fā)送COMMIT來(lái)確認(rèn)之前的修改,或者發(fā)送ROLLBACK進(jìn)行回滾。
在redis中,通過(guò)特殊的命令MULTI為開(kāi)始,之后用戶傳入一連貫的命令,最后EXEC為結(jié)束(在這一過(guò)程中可以使用watch進(jìn)行監(jiān)控一些key)。進(jìn)一步分析,redis事務(wù)中的命令會(huì)先推入隊(duì)列,等到EXEC命令出現(xiàn)的時(shí)候才會(huì)將一條條命令執(zhí)行。假若watch監(jiān)控的key發(fā)生改變,這個(gè)事務(wù)將會(huì)失敗。這也就說(shuō)明Redis事務(wù)中不存在鎖,其他客戶端可以修改正在執(zhí)行事務(wù)中的有關(guān)數(shù)據(jù),這也就為什么在多個(gè)客戶端同時(shí)處理相同的數(shù)據(jù)時(shí)事務(wù)往往會(huì)發(fā)生錯(cuò)誤。
2、簡(jiǎn)單理解redis的單線程IO多路復(fù)用
Redis采用單線程IO多路復(fù)用模型來(lái)實(shí)現(xiàn)高內(nèi)存數(shù)據(jù)服務(wù)。何為單線程IO多路復(fù)用呢?從字面的意思可以知道redis采用的是單線程、使用的是多個(gè)IO。整個(gè)過(guò)程簡(jiǎn)單的來(lái)講就是,哪個(gè)命令的數(shù)據(jù)流先到達(dá)就先執(zhí)行。
請(qǐng)看下面的形象理解圖:圖中是一座窄橋,只能允許一輛車(chē)通過(guò),左邊是車(chē)輛進(jìn)入的通道,哪一輛車(chē)先到達(dá)就先進(jìn)入。即哪個(gè)IO流先到達(dá)就先處理哪個(gè)。
Linux下網(wǎng)絡(luò)IO使用socket套接字來(lái)通訊,普通IO模型只能監(jiān)聽(tīng)一個(gè)socket,而IO多路復(fù)用可同時(shí)監(jiān)控多個(gè)socket。IO多路復(fù)用避免阻塞在IO上,單線程保存多個(gè)socket的狀態(tài)后輪循處理。
3、并發(fā)測(cè)試
我們就模擬一個(gè)簡(jiǎn)單典型的并發(fā)測(cè)試,然后從這個(gè)測(cè)試中得出問(wèn)題,再進(jìn)一步研究。
并發(fā)測(cè)試思路:
1、在redis中設(shè)置一個(gè)字符串count,運(yùn)用程序?qū)⑵淙〕鰜?lái)加+1,再存儲(chǔ)回去,一直循環(huán)十萬(wàn)次
2、在兩個(gè)瀏覽器上同時(shí)執(zhí)行這個(gè)代碼
3、將count取出來(lái),查看結(jié)果
測(cè)試步驟:
1、建立test.php文件
<?php $redis=new Redis(); $redis->connect('192.168.95.11','6379'); for ($i=0; $i < 100000; $i++) { $count=$redis->get('count'); $count=$count+1; $redis->set('count',$count); } echo "this OK"; ?>