2021.06.14 - 记一次”分页“功能踩坑

项目背景

  • 需求:运营后台的分页功能(基于时间线的 审核 和 管理页面)
  • 项目场景:类似 朋友圈 的动态发布,会有大量朋友圈(图文/视频)发布,数量会达 几十W~百万级。
  • 技术框架:Django+Vue做前后端分离。

方案

方案1

  • 简介:第一次查询时,取出所有数据(符合查询条件的数据),然后进行分页 并放入本地缓存,得到一个缓存Key(Page Key),返回给前端。前端需要查询分页结果时,直接使用该Page Key和页码 从内存缓存中 取出。为保证 同一个后台账户可以在多个页面同时进行分页,Page Key根据时间戳生成,利用LRU机制,保证内存占用的上限。
  • 优点:思维直观,查看分页结果快。
  • 缺点:
    • 第一次查询大量数据,而且 生成缓存很大,特别是单词查询范围为 几十万条时,这次缓存可能达十几MB。
    • 因为进程间不能共享内存,导致 Django项目无法利用多进程进行并发,只能多线程。

Redis改进方案

  • 利用MemCache/Redis等第三方缓存服务,使 多个运行Django的进程可以使用 缓存。
  • 缺点:
    • Redis的String类型最大只能存500MB的字符串,换算为本项目 即为200W条朋友圈。
    • 体积很大的数据需要从Redis取出,io慢。
    • 为保证 同一个后台账户同时使用分页,Redis需要单独配置LRU,或 利用 过期时间,会导致无效缓存占用大量空间。(可通过访问时生成 特定的cookie或session,而不是 时间戳区分Page Key,覆盖上次分页缓存,节约空间)

粘性会话改进方案

  • 粘性访问:服务器会把某个用户的请求,每次交给集群中的同一个节点。
  • Gunicorn无该功能,uWSGI有。即可使用 多进程 + 内存缓存 分页结果。

方案2

  • 简介:直接根据页码,利用SQL的LIMITOFFSET语句取对应页码的数据,模拟分页效果。
  • 难点:
    • 此项目中不断会有大量新增的朋友圈,会把 第一页的数据 寄到第二页,因此发生混乱。可以朋友圈的自增id,每次分页时记录当前的最大id,前端回传改id时,即可避免新数据的干扰,保证分页的准确。
    • 在操作会改变数据属性时,操作后直接刷新当前页,避免分页结果混乱。
  • 优点:每次只取少量数据,接口响应快。
  • 缺点:每次请求直接到MySQL,无法满足高并发和大访问量的接口,但后台无此情况。

思考

  • 面向客户端的需要高并发的接口,直接瀑布式分页即可,每次请求带id,拿该id之后的一批即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值