Maison > Questions et réponses > le corps du texte
比如说有一个微博的TID是1。 UID为1,2,3,4,5,6,7,8,9的用户都给这个微博点赞了。用redis缓存框架存储的话如何存储。微博可能有几十万个。如果用
key->set(value) 这种形式的话 key是微博ID的标示 value是 [1,2,3,4,5,6,7,8,9]这种形式,这样的话有多少个微博就有多少个K-V存储。我想知道这样会有什么弊端吗?或者有什么更好的方法吗?
怪我咯2017-04-22 09:01:23
Peut utiliser plusieurs stockages HashSet. Chaque Weibo n'est qu'une sous-clé dans le HashSet. Vous pouvez utiliser la commande HIncrBy pour augmenter le nombre de likes. Divisez le TID en blocs afin que les clés de chaque HashSet ne dépassent pas 100. La documentation officielle indique que HashSet utilise le stockage et l'analyse linéaires lorsque les éléments internes sont inférieurs à 100, ce qui est plus efficace et économise la mémoire par rapport à la structure arborescente à la même échelle de données.
Par exemple : Weibo avec TID 123456
existe dans le HashSet de z:1234
, et sa clé est 56. En supposant que le dernier Weibo soit également très actif, dans la plupart des cas, seuls quelques HashSets sont appelés, ce qui est très convivial pour le cache du processeur.
Si vous souhaitez gérer les utilisateurs qui l'aiment, vous pouvez personnaliser le format des données. Lorsque le nombre d'utilisateurs est petit, intégrez la liste complète des utilisateurs dans le champ de valeur de HashSet. Par exemple, lorsqu'il y a plus de 50 utilisateurs, séparez-les en un ensemble et enregistrez la clé Set dans le HashSet. Exemple :
bash
# 内嵌UID的情况 hget z:1234 56 > "1,2,3,4"... # 使用set的情况 hget z:1234 56 > "UIDlist:10" smembers UIDlist:10 > 1) "1" > 2) "2" > ...
Étant donné que la plupart des utilisateurs de Weibo ont moins de likes, HashSet peut enregistrer beaucoup de clés d'espace globales (les clés globales consomment plus de mémoire que les clés HashSet).
Réponse à propos de la @vente de sous-vêtements et de la connexion en ligne :
Si le tri rapide sur place est utilisé, l'efficacité du tri manuel de 50 utilisateurs est très élevée, car à cette échelle de données, la convivialité du cache apportée par le stockage compact des données est bien meilleure que l'amélioration apportée par Redis ZSet par rapport au tri manuel. Une fois les utilisateurs qui l'aiment promus, ils s'adapteront automatiquement à set ou zset pour garantir la complexité temporelle de l'algorithme. Si vous êtes toujours préoccupé par l'efficacité, vous pouvez réécrire la liste UID triée en une valeur dans le HashSet et l'utiliser directement s'il n'y a aucun changement de données à l'avenir.
L'utilisation de set ou de zset dépend toujours des besoins de l'affiche. La complexité de l'ajout d'un membre à set est O(1) et à zset est O(log N), mais set n'a pas de fonction de tri.
大家讲道理2017-04-22 09:01:23
Il n'est pas recommandé que LS utilise HASH pour stocker des données similaires car il n'y a aucun moyen de trier (si nécessaire. Je pense que cela doit être nécessaire)
.C'est ainsi que nous le gérons actuellement.
Vous pouvez utiliser les ensembles commandés par ZSET pour le stockage. Théoriquement, dans un ZSET, il n'y a pas de nombre inférieur à 100 000. En d'autres termes, le nombre de personnes qui aiment un Weibo est inférieur à 100 000 (c'est impossible).
Hmm, PS encore!!!php
$redis->ZADD("t:$tid:liked", time(), $uid); //$tid 为你的微博ID, $uid 为你的点赞人的UID //取出点赞的人(支持按照点赞时间来排序的哦:)).. 按照LSD的说的 HASH取出来的值没有任何顺序的. $uids = $redis->ZREVRANGE("t:$tid:liked", $offset, $max, TRUE); //倒序取值 $uids = $redis->ZRANGE("t:$tid:liked", $offset, $max, TRUE); //顺序取值 //$offset 和 $max 这样来算 $pagesize = 20; $offset = ($page > 1) ? ($page - 1) * $pagesize : 0; $max = ($page * $pagesize) - 1; //一次性取出所有的这样取. $total = $redis->ZCARD("t:$tid:liked"); $uids = $redis->ZREVANGE("t:$tid:liked", 0, $total - 1, TRUE); //拿到的$uids 是一个array 哦.. //判断一个用户是否点赞了这一来哦 $redis->ZSCORE("t:$tid:liked", $uid); //取消赞这样来 $redis->ZREM("t:$tid:liked", $uid); //批量取消某短时间内的点赞这样操作 $redis->ZREMRANGEBYSCORE("t:$tid:liked", $start_timestamp, $end_timestamp); //诸如此类的操作, 要比HASH强很多.
Si vous devez utiliser une base de données comme NOSQL pour stocker des données comme Weibo, vous pouvez les stocker comme ceci :).
PS encore, les commentaires Weibo sont stockés de la même manière. Il vous suffit de vous mettre d'accord sur le nom de $redis KEYS. Par exemple :php
$pipe = $redis->MULTI(Redis::PIPELINE); $pipe->SET("t:$tid", json_encode($data)) //json这种格式存储貌似有点废物. 如果能想到更好的格式的话,不要用JSON, 因为JSON太大了.. 比如MSGPACK这个个是就比JSON要好很多 ->ZADD("t:scores", time(), $tid); $pipe->EXEC(); //PIPE 这样的操作赞爆了. 如果你的REDIS支持事务的话, PIPE就不是一个原子性的操作了 //取出数据的话就很好取出了!! $tid = $reids->ZREVRANGE("t:scores", 0, 100); $pipe = $redis->MULTI(Redis::PIPELINE); foreach($tid as $key=> $value){ $pipe->GET("t:$value"); } $list = $pipe->EXEC(); //$list就是你的数据啦
.
c:<ID du commentaire> Comment l'associer aux données Weibo comme ceci :
Il est beaucoup plus pratique d'utiliser PIPELINE lors de la récupération de données.
Enfin, la KEY d'une base de données comme NOSQL doit être correctement configurée.
怪我咯2017-04-22 09:01:23
Est-il nécessaire de sauvegarder chaque uid, ou pensez-vous que c'est ce que fait Sina Weibo ? Dans la plupart des cas, tout le monde ne prête attention qu'à un nombre. Si tel est le cas, utilisez simplement un nombre pour stocker {tid->count}
Si vous devez enregistrer, il est recommandé d'utiliser {tid->set(uid)} pour enregistrer
Une optimisation est que vous pouvez définir un seuil. Par exemple, si plus de 100 personnes l'aiment, vous n'y ajouterez plus rien, mais ajouterez simplement un nombre (bien sûr, vous devez en enregistrer un autre {. tid-> ;count}). Parce qu'il y a plus de 10 000 likes sur Weibo, personne ne revient cliquer sur tous ceux qui l'aiment un par un. .