PHP+Redis例【一】いいね+熱上編
33290 ワード
今回の冒頭は、この時間の積み重ねをまとめてみましょう.くだらないことはあまり言わないで、直接やります.
前言
いいねは実はおもしろい機能です.基本的なデザインの考え方は大体2つあります.1つはmysql(数百行のコードを書いてもまだ書き終わっていないので、毒があります)です.
データベースは直接格納され,もう1つは点賛の業務特徴を利用してredis(またはmemcache)に投げ込まれ,オフラインでmysqlなどにブラシが戻る.
私がここで話している機能はすべて私の前のプロジェクトに基づいて話しているので、一部の場所は気にしないことができます.私は主にこの機能の実現構想を記録しています.あなたが理解したら、基本的にどんな幽霊言語で書いても同じです.
Mysqlへの直接書き込み
Mysqlに直接書き込むのが一番簡単です.
3つの時計を作ればいいです. comment_infoは文章の主な内容を記録して、主にlike_がありますcount,hate_count,scoreの3つのフィールドは、今回の機能の主なフィールドです. comment_likeは文章がほめられた回数を記録し、何人がこのようなデータを褒めたことがあるかを直接表から調べることができる. user_like_Commentはユーザーがどの文章を褒めたかを記録し、文章リストを開くと、褒めたことがあるかどうかのデータがここに表示されます.
欠点データベース読み書き圧力大ヒット記事には多くのユーザーがいいねをしたり、短時間でたくさんいいねをされたりして、直接データベースを操作するのは長期的には理想的ではありません redisストレージはその後、一括してデータベースに消去されます.
redisの主な特徴は速いことです.結局、主なデータはメモリにありますか.
また、memcacheではなくredisを選択した主な理由は、hash、set、zsetなど、redisがより多くのデータ型をサポートしているからです.
以下、これらのタイプを具体的に使用します.
メリット高性能 データベースの読み書き圧力を緩和する実は私はもっと書く圧力を緩和することにあります.本当に読む圧力はmysqlの主従を通じてredisに参加することでホットスポットデータをキャッシュすることもできます.書く圧力は前の案にとって確かによくありません.
欠点開発は複雑でmysqlを直接書くよりも複雑で、考慮すべき点も多い. はデータの安全性を保証できないredisが掛けた時にデータを失うと同時に、redis中のデータをタイムリーに同期しないと、redisメモリが置換された時に淘汰される可能性がある.しかし、私たちに「いいね」をクリックしただけで、少しデータを失うのは問題ありません.
実は上の第2点の欠点は避けることができて、これはredisのいくつかの設計モードに関連して、分からないのは大丈夫で、私はできるだけ詳しく書いて、後で私はどのようにこの欠点を解決するかを提供します.
設計機能前の知識準備
1.使用するredisデータ型: zsetこのタイプは主にソートや数字の増減に用いられ、ここではlikeとhateの数字記録、熱の記録として用いられる. setこれは無秩序な集合で、主に今日更新する必要があるかどうかを記録するために使用され、今日ほめられた(点嫌いを含む)文章idを記録し、夜やこのデータの更新に便利です. hashこれはハッシュであり、主にデータおよびインデックスを格納するために使用されます.ここでは、ユーザーがどの文章に何を注文したかを記録し、次回の判断に便利です(ネット上の紹介を見てsetを使って記録してもいいですが、それはもっとスペースが省け、管理が便利で、あとはhashのスピードが速いと思います). listこれはキューの大物で、私たちのデータがmysqlに安全に戻ることができるかどうかはそれに頼っています.
2.熱についてどう判断するか:
文章がいいねを獲得すればするほど、文章の熱が高くなることはよく知られていますが、どう判断すればいいのでしょうか.賛数を直接記録すればいいのではないでしょうか.しかし、最新の文章についてはどうしますか.例えば、1年前に発表された文章があって、50個の賛を獲得して、最新の文章が49個の賛を獲得していますが、上記の1年前の文章の熱は最新よりも高くて、これは合理的ではありません.文章はすべて時効性で、誰もが最新の最も熱いものを見たいと思っています.
so!私たちは方法を変えてこの時効性を処理しなければなりません.ほとんどの言語にはタイムスタンプ生成の方法があります.タイムスタンプは時間が経つにつれて、数字が大きくなるにつれて、直接タイムスタンプを初期化して文章のscoreに割り当て、最新の文章は以前の文章より前になります.次にscoreに対するいいねの影響で、私たちは1日に20人のいいねを得るのが1日で最も暑くて、1日60*60*24=86400秒で、それから1人のいいねを得るのが86400/20=4320分だと仮定します.具体的な数字は自分のビジネスニーズを見て、私はただ例を挙げただけです.点hateはもちろん、対応する数字も減算されます.
わくわくする時!直接コードをつけました!詳細なコメントが入っています!
お知らせ:
1.上のコードは実装の方法の一つにすぎず、中のコードは細かく分けられておらず、ほとんどのパートナーが読むのに適しています.心を込めて見るといつも収穫がある.
2.サードパーティのインタフェースについては、外で1階以上包装するべきですが、サイド幅が限られているので、私はこのような詳細をしません.ヒントは、参考にすることができます.
3.残りのデータをデータに戻す方法は、次編以降に続きます.皆さん、心得を交流してください.
redisマニュアル中国語版転送ドア:http://www.cnblogs.com/zcy_soft/archive/2012/09/21/2697006.html#string_INCR;
転載先:https://www.cnblogs.com/sunshine-H/p/7922285.html
前言
いいねは実はおもしろい機能です.基本的なデザインの考え方は大体2つあります.1つはmysql(数百行のコードを書いてもまだ書き終わっていないので、毒があります)です.
データベースは直接格納され,もう1つは点賛の業務特徴を利用してredis(またはmemcache)に投げ込まれ,オフラインでmysqlなどにブラシが戻る.
私がここで話している機能はすべて私の前のプロジェクトに基づいて話しているので、一部の場所は気にしないことができます.私は主にこの機能の実現構想を記録しています.あなたが理解したら、基本的にどんな幽霊言語で書いても同じです.
Mysqlへの直接書き込み
Mysqlに直接書き込むのが一番簡単です.
3つの時計を作ればいいです.
欠点
redisの主な特徴は速いことです.結局、主なデータはメモリにありますか.
また、memcacheではなくredisを選択した主な理由は、hash、set、zsetなど、redisがより多くのデータ型をサポートしているからです.
以下、これらのタイプを具体的に使用します.
メリット
欠点
実は上の第2点の欠点は避けることができて、これはredisのいくつかの設計モードに関連して、分からないのは大丈夫で、私はできるだけ詳しく書いて、後で私はどのようにこの欠点を解決するかを提供します.
設計機能前の知識準備
1.使用するredisデータ型:
2.熱についてどう判断するか:
文章がいいねを獲得すればするほど、文章の熱が高くなることはよく知られていますが、どう判断すればいいのでしょうか.賛数を直接記録すればいいのではないでしょうか.しかし、最新の文章についてはどうしますか.例えば、1年前に発表された文章があって、50個の賛を獲得して、最新の文章が49個の賛を獲得していますが、上記の1年前の文章の熱は最新よりも高くて、これは合理的ではありません.文章はすべて時効性で、誰もが最新の最も熱いものを見たいと思っています.
so!私たちは方法を変えてこの時効性を処理しなければなりません.ほとんどの言語にはタイムスタンプ生成の方法があります.タイムスタンプは時間が経つにつれて、数字が大きくなるにつれて、直接タイムスタンプを初期化して文章のscoreに割り当て、最新の文章は以前の文章より前になります.次にscoreに対するいいねの影響で、私たちは1日に20人のいいねを得るのが1日で最も暑くて、1日60*60*24=86400秒で、それから1人のいいねを得るのが86400/20=4320分だと仮定します.具体的な数字は自分のビジネスニーズを見て、私はただ例を挙げただけです.点hateはもちろん、対応する数字も減算されます.
わくわくする時!直接コードをつけました!詳細なコメントが入っています!
1 php
2
3 class Good
4 {
5 public $redis = null;
6
7 //60*60*24/20=4320, , 。
8 public $score = 4320;
9
10 // , hate
11 public $num = 1;
12
13 //init redis
14 public $redis_host = "127.0.0.1";
15 public $redis_port = "6379";
16 public $redis_pass = "";
17
18 public function __construct()
19 {
20 $this->redis = new Redis();
21 $this->redis->connect($this->redis_host,$this->redis_port);
22 $this->redis->auth($this->redis_pass);
23 }
24
25 /**
26 * @param int $user_id id
27 * @param int $type 1. like,2. hate
28 * @param int $comment_id id
29 * @return string json;
30 */
31 public function click($user_id,$type,$comment_id)
32 {
33 // redis
34 // : redis
35 // redis zset-> zscore()
36 if($this->redis->zscore("comment:like",$comment_id))
37 {
38 //
39 //
40 if($type==1)
41 {
42 // , ?
43 //redis hash-> hget()
44 $rel = $this->redis->hget("comment:record",$user_id.":".$comment_id);
45 if(!$rel)
46 {
47 //
48 // 1
49 $this->redis->zincrby("comment:like",$this->num,$comment_id);
50 //
51 $this->redis->zincrby("comment:score",$this->score,$comment_id);
52 //
53 $this->redis->hset("comment:record",$user_id.":".$comment_id,$type);
54
55 $data = array(
56 "state" => 1,
57 "status" => 200,
58 "msg" => "like+1",
59 );
60 }
61 else if($rel==$type)
62 {
63 //
64 // 1
65 $this->redis->zincrby("comment:like",-($this->num),$comment_id);
66 //
67 $this->redis->zincrby("comment:score",-($this->score),$comment_id);
68 $data = array(
69 "state" => 2,
70 "status" => 200,
71 "msg" => "like-1",
72 );
73 }
74 else if($rel==2)
75 {
76 // hate
77 //hate 1
78 $this->redis->zincrby("comment:hate",-($this->num),$comment_id);
79 //
80 $this->redis->zincrby("comment:score",$this->score+$this->score,$comment_id);
81 // 1
82 $this->redis->zincrby("comment:like",$this->num,$comment_id);
83 //
84 $this->redis->hset("comment:record",$user_id.":".$comment_id,$type);
85
86 $data = array(
87 "state" => 3,
88 "status" => 200,
89 "msg" => "like+1",
90 );
91 }
92 }
93 else if($type==2)
94 {
95 // hate 。
96 $rel = $this->redis->hget("comment:record",$user_id.":".$comment_id);
97 if(!$rel)
98 {
99 //
100 // hate 1
101 $this->redis->zincrby("comment:hate",$this->num,$comment_id);
102 //
103 $this->redis->zincrby("comment:score",-($this->score),$comment_id);
104 //
105 $this->redis->hset("comment:record",$user_id.":".$comment_id,$type);
106
107 $data = array(
108 "state" => 4,
109 "status" => 200,
110 "msg" => "hate+1",
111 );
112 }
113 else if($rel==$type)
114 {
115 // hate
116 // hate 1
117 $this->redis->zincrby("comment:hate",-($this->num),$comment_id);
118 //
119 $this->redis->zincrby("comment:score",$this->score,$comment_id);
120
121 $data = array(
122 "state" => 5,
123 "status" => 200,
124 "msg" => "hate-1",
125 );
126 return $data;
127 }
128 else if($rel==2)
129 {
130 // like
131 //like 1
132 $this->redis->zincrby("comment:like",-($this->num),$comment_id);
133 //
134 $this->redis->zincrby("comment:score",-($this->score+$this->score),$comment_id);
135 // hate 1
136 $this->redis->zincrby("comment:hate",$this->num,$comment_id);
137
138 $data = array(
139 "state" => 6,
140 "status" => 200,
141 "msg" => "hate+1",
142 );
143 return $data;
144 }
145 }
146 }
147 else
148 {
149 //
150 if($type==1)
151 {
152 //
153 $this->redis->zincrby("comment:like",$this->num,$comment_id);
154 //
155 $this->redis->zincrby("comment:score",$this->score,$comment_id);
156 $data = array(
157 "state" => 7,
158 "status" => 200,
159 "msg" => "like+1",
160 );
161 }
162 else if($type==2)
163 {
164 // hate
165 $this->redis->zincrby("comment:hate",$this->num,$comment_id);
166 //
167 $this->redis->zincrby("comment:score",-($this->score),$comment_id);
168
169 $data = array(
170 "state" => 8,
171 "status" => 200,
172 "msg" => "hate+1",
173 );
174 }
175 //
176 $this->redis->hset("comment:record",$user_id.":".$comment_id,$type);
177 }
178
179 //
180 $this->ifUploadList($comment_id);
181
182 return $data;
183 }
184
185 public function ifUploadList($comment_id)
186 {
187 date_default_timezone_set("Asia/Shanghai");
188 $time = strtotime(date('Y-m-d H:i:s'));
189
190 if(!$this->redis->sismember("comment:uploadset",$comment_id))
191 {
192 // ,
193 $this->redis->sadd("comment:uploadset",$comment_id);
194 //
195 $data = array(
196 "id" => $comment_id,
197 "time" => $time,
198 );
199 $json = json_encode($data);
200 $this->redis->lpush("comment:uploadlist",$json);
201 }
202 }
203 }
204
205 //
206 $user_id = 100;
207 $type = 1;
208 $comment_id= 99;
209 $good = new Good();
210 $rel = $good->click($user_id,$type,$comment_id);
211 var_dump($rel);
お知らせ:
1.上のコードは実装の方法の一つにすぎず、中のコードは細かく分けられておらず、ほとんどのパートナーが読むのに適しています.心を込めて見るといつも収穫がある.
2.サードパーティのインタフェースについては、外で1階以上包装するべきですが、サイド幅が限られているので、私はこのような詳細をしません.ヒントは、参考にすることができます.
3.残りのデータをデータに戻す方法は、次編以降に続きます.皆さん、心得を交流してください.
redisマニュアル中国語版転送ドア:http://www.cnblogs.com/zcy_soft/archive/2012/09/21/2697006.html#string_INCR;
転載先:https://www.cnblogs.com/sunshine-H/p/7922285.html