使用Redis构建文章投票网站
涉及到的key:
1. article_time, 记录文章的发布时间,zset结构
2. article_score, 记录文章的得分, zset结构
得分 = 发布时间 + 投票用户数 X 432
3. voted_article_id, 记录文章的投票用户集合,文章的发布者默认为文章的投票用户,set结构
4. article_article_id, 用来描述文章,hash结构
5. group_groupname, 群组groupname下的文章集合,set结构
6. score_groupname, 群组groupname下的文章得分集合,zset结构
- # python3
- # -*- coding: utf-8 -*-
- import redis
- import time
- ONE_WEEK_IN_SECONDS = 7 * 86400
- # 如果一篇文章获得200个赞,那么这篇文章就是有趣的
- VOTE_SCORE = 86400 / 200
- ARTICLES_PER_PAGE = 25
- def redis_init(redis):
- # article_time记录文章发布时间
- redis.zadd('article_time', article_100408=1496762197, article_100635=1496769721, article_100716=1496760089)
- # article_score记录文章得分
- redis.zadd('article_score', article_100408=1496766517, article_100635=1496770153, article_100716=1496765705)
- # voted_article_id记录编号为article_id的文章的点赞用户集合
- redis.sadd('voted_100408', 'user_234487', 'user_253378', 'user_364680',
- 'user_132097', 'user_350917')
- # 用hash描述每篇文章
- article_desc = {'title':'kunlun', 'link':'www.kunlun.com', 'poster':'user_234487',
- 'time':1441728000, 'votes':523}
- redis.hmset('article_100408', article_desc)
- article_desc = {'title': 'zhuxian', 'link': 'www.zhuxian.com', 'poster': 'user_234488',
- 'time': 1081440000, 'votes': 677}
- redis.hmset('article_100635', article_desc)
- article_desc = {'title': 'soushenji', 'link': 'www.soushenji.com', 'poster': 'user_234489',
- 'time': 1187280000, 'votes': 421}
- redis.hmset('article_100635', article_desc)
- # 记录文章总数
- redis.set('article_index', 200000)
- # 用户给文章投票
- def article_vote(conn, user, article):
- cutoff = time.time() - ONE_WEEK_IN_SECONDS
- if conn.zscore('article_time', article) < cutoff:
- return
- article_id = article.partition('_')[-1]
- if conn.sadd('voted_' + article_id, user):
- conn.zincrby('article_score', article, VOTE_SCORE)
- conn.hincrby(article, 'votes', 1)
- # 发布新文章
- def post_article(conn, user, title, link):
- article_id = str(conn.incr('article_index'))
- voted = 'voted_' + article_id
- # poster默认为文章的投票用户
- conn.sadd(voted, user)
- # 设置key过期时间
- conn.expire(voted, ONE_WEEK_IN_SECONDS)
- now = time.time()
- article = 'article_' + article_id
- conn.hmset(article, {
- 'title': title,
- 'link': link,
- 'poster': user,
- 'time': now,
- 'votes': 1,
- })
- conn.zadd('article_score', article, now + VOTE_SCORE)
- conn.zadd('article_time', article, now)
- return article_id
- # 取出评分最高的文章
- # 取最新发布的文章,order='article_time'
- # page, 按页取
- def get_articles(conn, page, order='article_score'):
- start = (page-1) * ARTICLES_PER_PAGE
- end = start + ARTICLES_PER_PAGE - 1
- ids = conn.zrevrange(order, start, end)
- articles = []
- for id in ids:
- article_data = conn.hgetall(id)
- article_data['id'] = id
- articles.append(article_data)
- return articles
- # 添加文章到群组,或者从群组里删除文章
- def add_remove_groups(conn, article_id, to_add=[], to_remove=[]):
- article = 'article_' + article_id
- for group in to_add:
- conn.sadd('group_' + group, article)
- for group in to_remove:
- conn.srem('group_' + group, article)
- # 获取群组中的文章
- def get_group_articles(conn, group, page, order='article_score'):
- key = order + group
- if not conn.exists(key):
- conn.zinterstore(key,
- ['group_' + group, order],
- aggregate='max'
- )
- # 缓存60s
- conn.expire(key, 60)
- return get_articles(conn, page, key)
- r = redis.Redis(host='redis_serverip', port=6379, password='redis_passwd', db=0)
- # redis_init(r)
- # article_vote(r,'use_115423', 'article_100408')
- #
- # new_article_id = post_article(r, 'user_5424', 'yingxiongzhi', 'www.yingxiongzhi.com')
- # print('new_article_id:', new_article_id)
- #
- # add_remove_groups(r, 'article_100408')
- #
- # get_group_articles(r, 'programming', 1)
PS:
redis-py模块中有两个类:Redis和StrictRedis,两者部分API稍有不同,本文使用Redis这个类。
反对票的实现:
- def article_against(conn, user, article):
- cutoff = time.time() - ONE_WEEK_IN_SECONDS
- if conn.zscore('article_time', article) < cutoff:
- return
- article_id = article.partition('_')[-1]
- if conn.sadd('against_' + article_id, user):
- conn.incrby('article_score', article, -VOTE_SCORE)
- conn.hincrby(article, 'votes', -1)
移除投票的竞争条件:
- def article_against(conn, user, article):
- cutoff = time.time() - ONE_WEEK_IN_SECONDS
- if conn.zscore('article_time', article) < cutoff:
- return
- article_id = article.partition('_')[-1]
- if conn.sadd('against_' + article_id, user):
- pipeline = conn.pipeline()
- conn.incrby('article_score', article, -VOTE_SCORE)
- conn.hincrby(article, 'votes', -1)
- pipeline.execute()
参考资料:
《Redis实战》
https://pypi.python.org/pypi/redis
https://redis-py.readthedocs.io/en/latest/
使用Redis构建文章投票网站的更多相关文章
- redis 实例2 构建文章投票网站后端
redis 实例2 构建文章投票网站后端 1.限制条件 一.如果网站获得200张支持票,那么这篇文章被设置成有趣的文章 二.如果网站发布的文章中有一定数量被认定为有趣的文章,那么这些文章需要被设置 ...
- 使用redis构建文章投票系统
首先,我得说明这篇博客基本上就是<<redis in action>>第一章内容的读书笔记. 需求 首先,说明一下,我们的需求 用户可以发表文章,发表时,自己就默认的给自己的文 ...
- Redis构建文章聚合信息分类网站
本系列教程内容提要 Java工程师之Redis实战系列教程教程是一个学习教程,是关于Java工程师的Redis知识的实战系列教程,本系列教程均以解决特定问题为目标,使用Redis快速解决在实际生产中的 ...
- Redis实现文章投票功能
Redis的具体操作这里就不说了,说一下需求和设计思路. 需求:自己实现一个文章投票的功能1.能够按照时间分页倒叙查看文章信息2.能够给文章投票,一个用户给一篇文章只能投票一次3.需要记录分值.每次投 ...
- 使用Redis构建电商网站
涉及到的key: 1. login,hash结构,存储用户token与用户ID之间的映射. 2. recent_tokens,存储最近登陆用户token,zset结构 member: token,sc ...
- Redis in Action 文章投票
原书用 Python 与 Redis 进行交互,我用 PHP 来实现. 环境:LNMP(CentOS 6.6 + Nginx 1.8.0 + MySQL 5.6.23 + PHP 5.6.9)+ Re ...
- Redis 实战 —— 02. Redis 简单实践 - 文章投票
需求 功能: P15 发布文章 获取文章 文章分组 投支持票 数值及限制条件 P15 如果一篇文章获得了至少 200 张支持票,那么这篇文章就是一篇有趣的文章 如果这个网站每天有 50 篇有趣的文章, ...
- .Net Redis实战——实现文章投票并排序
本系列文章为学习Redis实战一书记录的随笔. 软件和环境版本:Redis:5.0.7 .Net 5.0 文中不会对Redis基础概念做过多介绍. Redis数据类型和命令可在菜鸟教程学习:http ...
- Skeljs – 用于构建响应式网站的前端开发框架
skelJS 是一个轻量级的前端框架,用于构建响应式站点和应用程序.让设计人员和开发人员可能够使用四个强大的组件:CSS 网格系统,响应式处理程序,CSS 的快捷方式和插件系统. 您可能感兴趣的相关文 ...
随机推荐
- boost multi_index简单了解
#include <string> #include <iostream> #include <boost/multi_index_container.hpp> # ...
- 逻辑对象中时间类型 保存时 隐藏bug
开发功能中的一些逻辑对象中的一些时间 属性,在保存数据库时有一个隐藏的bug,假如 我vo属性定义的就是date 类型,那我定时保存数据库时可能就会出错,eq:假如这个属性隔天要重置一些东西,表中这个 ...
- golang trace 分析 简例
今天,通过一个例子,一方面熟悉trace在自定义范围内的分析,另一方面golang 在协程调度策略上的浅析. Show Code // trace_example.go package main im ...
- CentOS7.5 使用Docker部署Jumpserver
1.环境准备 # 查看系统版本 $ cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) # 查看内核版本 $ uname -a L ...
- 【Server】Windows系统安装Tomcat服务器
安装Tomcat服务器 Tomcat服务器地址:https://tomcat.apache.org/download-80.cgi 当前版本点选8以上版本,最新的可能不稳定,所以选8或者9版本 直接解 ...
- Extjs更新grid
基于Extjs4.2 原理是创建一个新的store,来覆盖原有的store. //创建数据 var newdatas = { name: "ly", age: 17, adress ...
- python实现服务器监控报警消息用微信发送(附代码)
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:NicePython PS:如有需要Python学习资料的小伙伴可以加 ...
- mybatis配置的逻辑删除不好使了
在使用mybatisplus中,可使用逻辑删除.案例中,使用mybatisplus逆向生成model,使用delete_status为识别逻辑删除字段. springboot 中配置启动逻辑删除 my ...
- [HTML] <base>链接默认打开方式标签元素
HTML 超链接(锚文本)默认打开方式与默认链接URL地址标签元素 一.语法与结构 <base target="_blank" href="http://www.l ...
- ansible playbook loop 翻译
ansible源文档地址 有时候你想多次重复一个任务. 在计算机编程中,这叫做循环. 常见的 Ansible 循环包括使用文件模块更改几个文件和 / 或目录的所有权,使用用户模块创建多个用户,并重复一 ...