高並發下的資料安全性
我們知道在多執行緒寫入同一個檔案的時候,會存現“執行緒安全”的問題(多個執行緒同時運行同一段程式碼,如果每次運行結果和單執行緒運行的結果是一樣的,結果和預期相同,就是執行緒安全的)。
如果是MySQL資料庫,可以使用它自帶的鎖定機制很好的解決問題,但是,在大規模並發的場景中,是不建議使用MySQL的。秒殺和搶購的場景中,還有另一個問題,就是“超發”,如果在這方面控制不慎,會產生發送過多的情況。
我們也曾經聽說過,某些電商搞搶購活動,買家成功拍下後,商家卻不承認訂單有效,拒絕發貨。這裡的問題,也許不一定是商家姦詐,而是系統技術層面有超發風險所導致的。
1、超發的原因
假設某個搶購場景中,我們一共只有100個商品,在最後一刻,我們已經消耗了99個商品,僅剩最後一個。這時候,系統發來多個並發請求,這批請求讀取到的商品餘裕都是99個,然後都通過了這一個餘量判斷,最終導致超發。 (同文章前面說的場景)
2、樂觀鎖
樂觀鎖,是相對於「悲觀鎖」採用更寬鬆的加鎖機制,大都是採用版本號(Version)更新。實作就是,這個資料所有請求都有資格去修改,但會得到一個該資料的版本號,只有版本號符合的才能更新成功,其他的回傳搶購失敗。
這樣的話,我們就不需要考慮佇列的問題,不過,它會增加CPU的運算開銷。但是,綜合來說,這是一個比較好的解決方案。
有許多軟體和服務都「樂觀鎖定」功能的支持,例如Redis中的watch就是其中之一。透過這個實現,我們保證了資料的安全。
優化方案:Redis中的watch
<?php $redis = new redis(); $result = $redis->connect('127.0.0.1', 6379); echo $mywatchkey = $redis->get("mywatchkey"); /* //插入抢购数据 if($mywatchkey>0) { $redis->watch("mywatchkey"); //启动一个新的事务。 $redis->multi(); $redis->set("mywatchkey",$mywatchkey-1); $result = $redis->exec(); if($result) { $redis->hSet("watchkeylist","user_".mt_rand(1,99999),time()); $watchkeylist = $redis->hGetAll("watchkeylist"); echo "抢购成功!<br/>"; $re = $mywatchkey - 1; echo "剩余数量:".$re."<br/>"; echo "用户列表:<pre class="brush:php;toolbar:false">"; print_r($watchkeylist); }else{ echo "手气不好,再抢购!";exit; } }else{ // $redis->hSet("watchkeylist","user_".mt_rand(1,99999),"12"); // $watchkeylist = $redis->hGetAll("watchkeylist"); echo "fail!<br/>"; echo ".no result<br/>"; echo "用户列表:<pre class="brush:php;toolbar:false">"; // var_dump($watchkeylist); }*/ $rob_total = 100; //抢购数量 if($mywatchkey<=$rob_total){ $redis->watch("mywatchkey"); $redis->multi(); //在当前连接上启动一个新的事务。 //插入抢购数据 $redis->set("mywatchkey",$mywatchkey+1); $rob_result = $redis->exec(); if($rob_result){ $redis->hSet("watchkeylist","user_".mt_rand(1, 9999),$mywatchkey); $mywatchlist = $redis->hGetAll("watchkeylist"); echo "抢购成功!<br/>"; echo "剩余数量:".($rob_total-$mywatchkey-1)."<br/>"; echo "用户列表:<pre class="brush:php;toolbar:false">"; var_dump($mywatchlist); }else{ $redis->hSet("watchkeylist","user_".mt_rand(1, 9999),'meiqiangdao'); echo "手气不好,再抢购!";exit; } } ?>
以上內容僅供參考!
推薦教學:PHP影片教學
#以上是php如何應對高並發的詳細內容。更多資訊請關注PHP中文網其他相關文章!