1. 程式人生 > >redis下高併發投票設計

redis下高併發投票設計

最近閒來無事,研究了下redis,看過書籍之後,為了理解的更透徹,就實踐寫一個例子。

先說寫投票吧,具體的流程是使用者可以發起投票,發起成功後,其他使用者可以投票,首頁顯示話題標題,票數和時間等資訊。

我使用的redis設計了五個表一個是文章表,儲存話題的相關資訊,一個評分表,一個話題被投票評分就增加,一個是時間表,用來後期按時間對話題進行排序,一個是投票表,用的是單ip限制,一個ip一天只能投一次票,最後一個次數表,一個ip一天最多釋出5個話題。

好了資料庫設計完我們就開始做吧,我用的是php寫的,主要功能:

(1)使用者可以釋出投票,單ip一天最多釋出5個話題;

(2)使用者投票,單ip一天只能投一次;

(3)釋出人不能對自己的文章投票;

(4)可以按照話題評分和釋出時間進行排序;

下面附上主要程式碼和截圖(投票介面樣式太差就不展示了大笑):




資料庫設計



核心程式碼:


//獲取投票文章
public function vote_list(Request $request){
    $order='score:';
    $start=0;
    $end=10;
    $result = array();
    $data = $this->get_zadd($order,$start,$end);
    foreach 
($data as $value){ array_push($result,$this->get_hash($value)); } if(!empty($result)){ //return view('votes.vote_list',["test" => 'df']); return view('votes.vote_list',['result' => $result]); } } //釋出文章投票 public function add_articles(Request $request){
if ($request->isMethod('post')) { $user = $request->user; $title = $request->title; if(empty($user)||empty($title)){ $resData = ReturnApi::addResult($id=6); return response()->json($resData); } $ip = ($_SERVER["HTTP_X_FORWARDED_FOR"]=='')?$_SERVER["REMOTE_ADDR"]:$_SERVER["HTTP_X_FORWARDED_FOR"]; //每個ip釋出最多5個 $k = 'counts:'; if($this->get_zadd_any($k,$ip)){ if($this->get_zadd_any($k,$ip)==5){ $resData = ReturnApi::addResult($id=7); return response()->json($resData); } $this->update_zadd_any($k,1,$ip); }else{ $this->zadd_add($k,1,$ip); $this->set_time($k,env('ARTICLE_END')); } $article_id = $this->get_incr_id(); //把釋出文章使用者ip寫到已投票名單並設定時間為一天 $voted = 'voted:' . $article_id; $this->sadd_add($voted,$ip); $this->set_time($voted,env('ARTICLE_END')); $now = time(); $article = 'article:' . $article_id; //儲存文章資訊 $value = array( 'article_id' => $article, 'title:' => $title, 'poster:' => $user, 'time:' => $now, 'votes:' => 1, ); $resData = ReturnApi::addResult(); foreach ($value as $k=>$v){ if($this->hash_add($article,$k,$v)){ continue; } return response()->json($resData); } //將文章儲存在根據時間和評分排序的有序集合 $this->zadd_add('score:',env('VOTE_SCORE'),$article); $this->zadd_add('time:',$now,$article); $resData = ReturnApi::addResult($id=2); return response()->json($resData); } } //投票 public function votes(Request $request){ #投票時間超過一天就不能投 $cutooff = time() - env('ARTICLE_END'); if ($request->isMethod('post')) { $ip = ($_SERVER["HTTP_X_FORWARDED_FOR"]=='')?$_SERVER["REMOTE_ADDR"]:$_SERVER["HTTP_X_FORWARDED_FOR"]; $article = $request->article; $resData = ReturnApi::addResult($id=5); if($this->get_zadd_any('time:', $article) < $cutooff){ return response()->json($resData); } $article_id = substr($article,-1); # 使用者第一次投票就增加投票數 $resData = ReturnApi::addResult($id=4); if ($this->sadd_add('voted:' . $article_id, $ip)){ # 評分增加 $this->update_zadd_any('score:', env('VOTE_SCORE'),$article); # 文章表投票增加 $this->hash_update($article, 'votes:', 1); $resData = ReturnApi::addResult($id=3); return response()->json($resData); } return response()->json($resData); } }