redis存储新闻列表_每日一面 - Redis程序设计中,上百万的新闻,如何实时展示最热点的top10条呢...
假设可以使用 MySQL,redis,本地缓存以及MQ。
用户量级千万,新闻数据百万,用户数比新闻数还多。用户的操作包括:关注某个新闻
获取某个新闻的关注数量
获取 top10 热点新闻
查询自己关注的新闻。
可以推测,获取 top10 热点新闻请求会远大于关注某个新闻的请求。这些请求都不能直接压入数据库,数据库受不了。
首先想到的是 Redis 中的 Zset,所有的新闻id作为key放入同一个zset中,用户关注某个新闻,使用 zincrby 给这个新闻分数 +1。读取 top 10的时候,用zrevrange.
并且,在实际业务上(例如微博热点话题,知乎热点话题,都是每过一段时间才更新的),top10 热点新闻并不是实时更新的,可以接受一点延迟,可以通过客户端实例的本地缓存,将读取到的 top 10 存在本地缓存一段时间,过了这段时间自动失效。
但是这样也会很快遇到性能瓶颈:
1.zset 在很大时可能不满足我们对于性能的要求: Redis 的 Zset 在数量够大的时候底层基于 skiplist:
skiplist 实现简单,插入、删除、查找的复杂度均为O(logN)。zincrby 实际上是一个查找+删除+插入(当然由于score只加了1,所以删除插入只修改相邻节点,这个有优化)
我们的场景是首先插入的新闻分数都是0,之后增长这个分数,在新闻很多,并且并不能确定某些新闻是热点的时候,zincrby 导致的节点变动很频繁。这个通过业务设计可以优化,例如新闻分级,不同级别的新闻初始分数不同
2.放入同一个 zset,对于单实例 redis 性能瓶颈时,扩展不友好。
用户千万量级,更新很频繁,如果都更新同一个 zset,很快会遇到性能瓶颈。读取还好说,可以通过本地缓存,因为展示最热点的top10的实时性要求并没有那么高。这时考虑 redis 集群,redis分片,但是如果放在同一个 zset,无法分摊压力。
那么我们可以换一种思路:redis 中,每个新闻id作为key,关注数作为value,存储简单的键值对。用户关注了某个新闻:
同步事务更新数据库中的用户关注新闻表,这个每个用户会均摊行锁压力 缓存新闻id key + 1(注意catch住缓存不可用的异常) 写入 MQ,之后返回 MQ 消费更新数据库这个新闻的关注数量,这样不会有性能瓶颈,同时针对新闻id做queue以及线程分区(就是同一个新闻总是对应特定的queue以及线程,尽量每一个行锁一个线程更新,避免数据库 lock wait timeout)
怎样获取 top 10:定时任务扫描数据库,按照新闻关注数量排序获取top10,直接放入缓存。用户请求都是读取这个缓存。虽然实时性差,但是能满足需求。
读取某个新闻的关注数量:这个就读缓存,缓存不可用,读取数据库。
获取某个用户关注的新闻列表:这个读取数据库,如果感觉也有性能瓶颈,对于每个用户id添加缓存保存关注的新闻列表即可。这个很简单
每日一刷,轻松提升技术,斩获各种offer:
redis存储新闻列表_每日一面 - Redis程序设计中,上百万的新闻,如何实时展示最热点的top10条呢...相关推荐
- 每日一面 - Redis程序设计中,上百万的新闻,如何实时展示最热点的top10条呢
假设可以使用 MySQL,redis,本地缓存以及MQ. 用户量级千万,新闻数据百万,用户数比新闻数还多.用户的操作包括: 关注某个新闻 获取某个新闻的关注数量 获取 top10 热点新闻 查询自己关 ...
- 2019新闻列表_每日新闻摘要:2019年3月12日以来的热门故事
2019新闻列表 Kaspars Grinvalds/Shutterstock Kaspars Grinvalds / Shutterstock Today, Microsoft showed off ...
- 解析聚合新闻数据,并显示到主界面上(简易新闻 二)
获取解析聚合新闻数据,并显示到主界面上(简易新闻 二) 关于之前的功能实现可以从制作简易新闻App导航篇中查看 先上一下最终效果图: 关于界面的搭建请看上一篇 使用Fragment+ViewPager ...
- vb6 获取zip列表_深入学习redis(压缩列表)
免责声明: 本人水平有限,难免有疏漏的地方.如果读者遇到文章中需要改进或者看不懂,甚至是觉得错误的地方,可以给我留言.我想做一个比较全面由浅入深去讲解redis原理和进阶的系列文章,内容偏源码较硬核, ...
- redis指定配置文件启动_深入学习 Redis 集群搭建方案及实现原理
" 在前面的文章中已经介绍了 本文将详细介绍集群,主要内容包括: 集群的作用 集群的搭建方法及设计方案 集群的基本原理 客户端访问集群的方法 实践须知(集群伸缩.故障转移.参数优化等) 集群 ...
- redis 启动无输出_深入剖析Redis系列: Redis入门简介与主从搭建
前言 Redis 是一种基于 键值对 的 NoSQL 数据库.与很多键值对数据库不同,Redis 提供了丰富的 值数据存储结构,包括 string(字符串).hash(哈希).list(列表).set ...
- redis lua 设置过期_详解 Redis 内存管理机制和实现
Redis是一个基于内存的键值数据库,其内存管理是非常重要的.本文内存管理的内容包括:过期键的懒性删除和过期删除以及内存溢出控制策略. 最大内存限制 Redis使用 maxmemory 参数限制最大可 ...
- kafka redis vs 发布订阅_对比平台--Redis Vs Kafka 之间的区别
Redis和Kafka之间的区别 在本文中,我们将探讨Redis与Kafka之间的最高差异和性能. Redis: Redis是一个内存中的键值数据存储,也是开源的.它可以非常快地用于缓存会话管理,高性 ...
- redis key命名规范_公司内部 Redis 使用规范
前言 在业务中,会经常使用 Redis 作为后端缓存.存储.如果结构规划不合理.命令使用不规范,会造成系统性能达到瓶颈.活动高峰系统可用性下降,也会增大运维难度.为了避免出现因 Redis 使用不当, ...
最新文章
- 个人网站架构设计(一)
- android 屏幕录像
- 阅读笔记1(面试题功能测试-自动化提升效率)
- CUBA平台–新的Java企业应用程序框架
- win7下用docker部署的基于openvino的yolov5算法(二)openvino的docker镜像下载和安装
- eclipse中怎么复制错误提示
- 自制XML解析器源码分析
- rect函数_Python基础进阶:从函数到高级魔法方法--Day 6
- string.format的使用与及转义
- matlab图像处理Lena大作业
- 人脸识别python face_recognize_python人脸识别库-face_recognition详解
- SpringBoot内置servlet容器分析
- HDU 5745 La Vie en rose 字符串匹配(暴力)
- 关于企业邮箱域名备案方法【企业邮箱申请】
- TeamViewer和向日葵远控软件的个人使用感觉
- 把电脑端的图片链接转换为API接口可以调用的链接
- 浏览器中访问网页、回退及前进模拟
- your browser doesn't support html5,video
- php类的定义与实例化方法
- java中获取当月1号零时零分的时间
热门文章
- [网络安全学习篇18]:ACL及实验(千峰网络安全视频笔记 18 day)
- ubuntu安装oracle
- Stateful和Stateless区别
- log4j升级为log4j2(不需要改动代码)
- JAVA EE架构师需要具备的知识
- 解决Chrome浏览器http自动转https的问题
- Qt/C++编写安防视频监控系统45-图文报表
- 力科示波器截屏功能 python代码实现
- 改变 PowerShell/CMD的背景图案及透明度
- 惠普微型计算机碟片,[hp]惠普笔记本放入碟片的口在哪?