如何存储、获取随机 100 个页面的状态呢?

2018-03-23 12:12:22 +08:00
 xshwy

需求:获取排名前 100 个 url 的 HTTP 状态码存储,前台要显示排名前 100 个 url 非 200 状态码的页面有哪些。

目前想法:

  1. 获取排名前 100 的 url
  2. 轮询 100 个 url 状态码
  3. 删除之前的数据库数据
  4. 保存获取到的状态码

目前数据库设计:

遇到的难题:

  1. 在第 3 步删除之前数据的时候,需要一定的时间,前台用户查询的时候会显示没有数据,体验不好。
  2. 因为是获取排名前 100 的 url,所以每次查询的 url 可能不一样,无法在之前的数据上更新

请教: 有没有更优雅的存储方式? 后续可能会扩展到 1000 个、10000 个 url,遇到类似情况该如何解决呢?

先提前感谢各位大佬的回复了,感谢!

2954 次点击
所在节点    Python
24 条回复
twistoy
2018-03-23 12:25:41 +08:00
写进去的时候,加个时间戳,每次页面展示的时候,都请求最近的时间戳的。
pathbox
2018-03-23 12:35:51 +08:00
@twistoy 直接 id 排序是否可行
xshwy
2018-03-23 12:38:37 +08:00
#1 @twistoy 感谢提供解决方案,目前是可以解决这个问题,定期删除之前旧的记录就可以。

数据库这样设计:



#2 @pathbox id 排序是指什么样呢?求更详细


还会有更优雅的解决方案嘛?
wplct
2018-03-23 12:46:17 +08:00
为啥要删除啊。覆盖啊
xshwy
2018-03-23 12:49:14 +08:00
#4 @wplct 因为是获取排名前 100 的 url,所以每次查询的 url 可能不一样,无法在之前的数据上更新

比如我上次获取的前 100 个 url 是 a1 ~ a100,最后一次获取的是 a1~a50、b1~b50,前台只要显示最后一次获取的数据,如果要覆盖的话,还需要检查更新 a51~a100 的数据……
honeycomb
2018-03-23 12:56:02 +08:00
用 loading cache ?设定好阈值后,读写过程中会自动 evict 旧数据
stabc
2018-03-23 13:04:52 +08:00
直接把非 200 的都用数组放到 Redis 里。
SlipStupig
2018-03-23 13:27:00 +08:00
加上一个时间戳就可以解决
1.要是检测非 200 的
select url from your_table where status_code != 200 order by last_modified DESC limit 0, 100

2. 用你的程序获取状态码

3.直接 update 时间戳和状态码就完事了,根本不需要去删除老的数据
734506700qq
2018-03-23 13:39:24 +08:00
可以先将 100 条数据插入库中,然后设置初始状态,等待查询更新,添加更新时间戳字段,等待回写状态;若用户来查时,发现是初始状态,则直接逻辑中去查询一次这个 url,查询其状态,并将状态写入到数据库;
GoLand
2018-03-23 13:47:58 +08:00
主键自增 ID,直接存进去取的时候直接 select * from xxx order by id desc limit 100 不就行了?时间戳都不要。
porrat
2018-03-23 13:48:26 +08:00
redis
xshwy
2018-03-23 14:37:03 +08:00
#6 @honeycomb 感谢提供解决方案,我搜一下 python 相关的操作方式

#7 @stabc 感谢提供方案,因为只需要展示最后获取的 100 个 url 的 200 状态,如果方式 redis 的话也还是要清空之前的记录,清空期间担心用户访问的时候会显示数据为空。

#8 #9 #10 @SlipStupig @734506700qq @GoLand 感谢提供方案,需要获取最后一次获取到 100 个 url 的 200 状态,所以不能用 limit 0,100,因为可能最后查询到的 100 个 url 只有 20 个 url 是 200 状态,总数也不止 100 个,每次获取到的都是随机 100 个,所以 update 感觉也不太可行…


#11 @porrat 感谢提供思路,请问有更详细的解决方案嘛?
SlipStupig
2018-03-23 15:27:59 +08:00
@xshwy 用时间排序有什么不行的
honeycomb
2018-03-23 17:01:28 +08:00
@xshwy Java 里有 guava cache (以及很多同类工具)正好可以限制 cache 的大小的同时,又能监听 cache evict 事件(用来回调把抛弃的数据持久化到数据库),Python 肯定有类似的轮子。
honeycomb
2018-03-23 17:04:59 +08:00
@xshwy 随手搜了一下,有一个叫 beaker 的模块,应该能满足需要
chairuosen
2018-03-23 17:18:59 +08:00
关键信息没说:
是否要求某次排名更新后,所有 url 的 status 都查询一遍,前端才刷?
xshwy
2018-03-23 17:24:23 +08:00
#15 @honeycomb 感谢提供解决方案,我去搜搜相关模块的文档

#16 @chairuosen 每 5 分钟获取一次排前面 100 的 url,然后获取这 100 个 url 的状态,存储,前端由用户手动刷新即可
chairuosen
2018-03-23 17:32:30 +08:00
@xshwy 你还是没回答啊。排名出来了,状态查了 50 个,50 个没查呢,现在前端要数据,给什么?
kennylam777
2018-03-23 17:33:53 +08:00
redis 的 ZADD/ZRANK 似乎可以解決這種問題, 才 100 個 url 這種小型 dataset 應該是適合的
xshwy
2018-03-23 17:45:53 +08:00
#18 @chairuosen 所有 url 状态查完统一存储发出,设置的 5 分钟轮询就是想着 5 分钟应该足够 100 个 url 的状态查询了;没有查询完毕之前,继续返回上次的查询结果

#19 @kennylam777 好的 我查一下资料,非常感谢,不过后续可能会适配到 1000、10000 …

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/440731

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX