假设可以使用 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条呢...相关推荐

  1. 每日一面 - Redis程序设计中,上百万的新闻,如何实时展示最热点的top10条呢

    假设可以使用 MySQL,redis,本地缓存以及MQ. 用户量级千万,新闻数据百万,用户数比新闻数还多.用户的操作包括: 关注某个新闻 获取某个新闻的关注数量 获取 top10 热点新闻 查询自己关 ...

  2. 2019新闻列表_每日新闻摘要:2019年3月12日以来的热门故事

    2019新闻列表 Kaspars Grinvalds/Shutterstock Kaspars Grinvalds / Shutterstock Today, Microsoft showed off ...

  3. 解析聚合新闻数据,并显示到主界面上(简易新闻 二)

    获取解析聚合新闻数据,并显示到主界面上(简易新闻 二) 关于之前的功能实现可以从制作简易新闻App导航篇中查看 先上一下最终效果图: 关于界面的搭建请看上一篇 使用Fragment+ViewPager ...

  4. vb6 获取zip列表_深入学习redis(压缩列表)

    免责声明: 本人水平有限,难免有疏漏的地方.如果读者遇到文章中需要改进或者看不懂,甚至是觉得错误的地方,可以给我留言.我想做一个比较全面由浅入深去讲解redis原理和进阶的系列文章,内容偏源码较硬核, ...

  5. redis指定配置文件启动_深入学习 Redis 集群搭建方案及实现原理

    " 在前面的文章中已经介绍了 本文将详细介绍集群,主要内容包括: 集群的作用 集群的搭建方法及设计方案 集群的基本原理 客户端访问集群的方法 实践须知(集群伸缩.故障转移.参数优化等) 集群 ...

  6. redis 启动无输出_深入剖析Redis系列: Redis入门简介与主从搭建

    前言 Redis 是一种基于 键值对 的 NoSQL 数据库.与很多键值对数据库不同,Redis 提供了丰富的 值数据存储结构,包括 string(字符串).hash(哈希).list(列表).set ...

  7. redis lua 设置过期_详解 Redis 内存管理机制和实现

    Redis是一个基于内存的键值数据库,其内存管理是非常重要的.本文内存管理的内容包括:过期键的懒性删除和过期删除以及内存溢出控制策略. 最大内存限制 Redis使用 maxmemory 参数限制最大可 ...

  8. kafka redis vs 发布订阅_对比平台--Redis Vs Kafka 之间的区别

    Redis和Kafka之间的区别 在本文中,我们将探讨Redis与Kafka之间的最高差异和性能. Redis: Redis是一个内存中的键值数据存储,也是开源的.它可以非常快地用于缓存会话管理,高性 ...

  9. redis key命名规范_公司内部 Redis 使用规范

    前言 在业务中,会经常使用 Redis 作为后端缓存.存储.如果结构规划不合理.命令使用不规范,会造成系统性能达到瓶颈.活动高峰系统可用性下降,也会增大运维难度.为了避免出现因 Redis 使用不当, ...

最新文章

  1. 个人网站架构设计(一)
  2. android 屏幕录像
  3. 阅读笔记1(面试题功能测试-自动化提升效率)
  4. CUBA平台–新的Java企业应用程序框架
  5. win7下用docker部署的基于openvino的yolov5算法(二)openvino的docker镜像下载和安装
  6. eclipse中怎么复制错误提示
  7. 自制XML解析器源码分析
  8. rect函数_Python基础进阶:从函数到高级魔法方法--Day 6
  9. string.format的使用与及转义
  10. matlab图像处理Lena大作业
  11. 人脸识别python face_recognize_python人脸识别库-face_recognition详解
  12. SpringBoot内置servlet容器分析
  13. HDU 5745 La Vie en rose 字符串匹配(暴力)
  14. 关于企业邮箱域名备案方法【企业邮箱申请】
  15. TeamViewer和向日葵远控软件的个人使用感觉
  16. 把电脑端的图片链接转换为API接口可以调用的链接
  17. 浏览器中访问网页、回退及前进模拟
  18. your browser doesn't support html5,video
  19. php类的定义与实例化方法
  20. java中获取当月1号零时零分的时间

热门文章

  1. [网络安全学习篇18]:ACL及实验(千峰网络安全视频笔记 18 day)
  2. ubuntu安装oracle
  3. Stateful和Stateless区别
  4. log4j升级为log4j2(不需要改动代码)
  5. JAVA EE架构师需要具备的知识
  6. 解决Chrome浏览器http自动转https的问题
  7. Qt/C++编写安防视频监控系统45-图文报表
  8. 力科示波器截屏功能 python代码实现
  9. 改变 PowerShell/CMD的背景图案及透明度
  10. 惠普微型计算机碟片,[hp]惠普笔记本放入碟片的口在哪?