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);

    }
}


猜你喜欢

转载自blog.csdn.net/qinshi501/article/details/52786098