需求:获取排名前 100 个 url 的 HTTP 状态码存储,前台要显示排名前 100 个 url 非 200 状态码的页面有哪些。
目前想法:
目前数据库设计:
遇到的难题:
请教: 有没有更优雅的存储方式? 后续可能会扩展到 1000 个、10000 个 url,遇到类似情况该如何解决呢?
先提前感谢各位大佬的回复了,感谢!
1
twistoy 2018-03-23 12:25:41 +08:00
写进去的时候,加个时间戳,每次页面展示的时候,都请求最近的时间戳的。
|
3
xshwy OP |
4
wplct 2018-03-23 12:46:17 +08:00
为啥要删除啊。覆盖啊
|
5
xshwy OP #4 @wplct 因为是获取排名前 100 的 url,所以每次查询的 url 可能不一样,无法在之前的数据上更新
比如我上次获取的前 100 个 url 是 a1 ~ a100,最后一次获取的是 a1~a50、b1~b50,前台只要显示最后一次获取的数据,如果要覆盖的话,还需要检查更新 a51~a100 的数据…… |
6
honeycomb 2018-03-23 12:56:02 +08:00 via Android
用 loading cache ?设定好阈值后,读写过程中会自动 evict 旧数据
|
7
stabc 2018-03-23 13:04:52 +08:00
直接把非 200 的都用数组放到 Redis 里。
|
8
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 时间戳和状态码就完事了,根本不需要去删除老的数据 |
9
734506700qq 2018-03-23 13:39:24 +08:00
可以先将 100 条数据插入库中,然后设置初始状态,等待查询更新,添加更新时间戳字段,等待回写状态;若用户来查时,发现是初始状态,则直接逻辑中去查询一次这个 url,查询其状态,并将状态写入到数据库;
|
10
GoLand 2018-03-23 13:47:58 +08:00
主键自增 ID,直接存进去取的时候直接 select * from xxx order by id desc limit 100 不就行了?时间戳都不要。
|
11
porrat 2018-03-23 13:48:26 +08:00
redis
|
12
xshwy OP #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 感谢提供思路,请问有更详细的解决方案嘛? |
13
SlipStupig 2018-03-23 15:27:59 +08:00
@xshwy 用时间排序有什么不行的
|
14
honeycomb 2018-03-23 17:01:28 +08:00 via Android
@xshwy Java 里有 guava cache (以及很多同类工具)正好可以限制 cache 的大小的同时,又能监听 cache evict 事件(用来回调把抛弃的数据持久化到数据库),Python 肯定有类似的轮子。
|
16
chairuosen 2018-03-23 17:18:59 +08:00
关键信息没说:
是否要求某次排名更新后,所有 url 的 status 都查询一遍,前端才刷? |
17
xshwy OP #15 @honeycomb 感谢提供解决方案,我去搜搜相关模块的文档
#16 @chairuosen 每 5 分钟获取一次排前面 100 的 url,然后获取这 100 个 url 的状态,存储,前端由用户手动刷新即可 |
18
chairuosen 2018-03-23 17:32:30 +08:00
@xshwy 你还是没回答啊。排名出来了,状态查了 50 个,50 个没查呢,现在前端要数据,给什么?
|
19
kennylam777 2018-03-23 17:33:53 +08:00
redis 的 ZADD/ZRANK 似乎可以解決這種問題, 才 100 個 url 這種小型 dataset 應該是適合的
|
20
xshwy OP #18 @chairuosen 所有 url 状态查完统一存储发出,设置的 5 分钟轮询就是想着 5 分钟应该足够 100 个 url 的状态查询了;没有查询完毕之前,继续返回上次的查询结果
#19 @kennylam777 好的 我查一下资料,非常感谢,不过后续可能会适配到 1000、10000 … |
21
kennylam777 2018-03-23 17:52:29 +08:00
|
22
rrfeng 2018-03-23 17:53:36 +08:00 via Android
es kibana 啥代码也不要写
|
23
xshwy OP #22 @rrfeng 我搜索一下相关技术,感谢提供解决方案
#21 @kennylam777 哇 非常感谢,发现 ZADD/ZRANK 太好用了,可以实现我大部分的需求,可以自动更新已存在的数据,还可以直接排序好实用,也可以直接分页查询太好了! 不过有一点问题就是无法设置过期时间,查了一圈也没找到相关的解决方案,继续求教一下 第一次轮训查到三个状态码为非 200 的,按照排名顺序插入,排名也是必须的,所以 score 无法设置时间戳… > ZADD urls 1 xxx.com/001 > ZADD urls 3 xxx.com/002 > ZADD urls 25 xxx.com/003 前台可以展示出排名第几的 url 是非 200 状态,第二次轮训的时候只查到 1 个状态码为非 200 状态 > ZADD urls 23 xxx.com/001 问题来了,如何清空之前存储的 002、003 两个数据呢?或者如何设置自动清理超过 10 分钟没更新的数据呢? |
24
baojiwei 2018-03-29 02:50:54 +08:00
redis 的 zrank 就可以了
多使用缓存,这类问题不需要使用数据库 如果需要的话也是异步的,非高频操作 |