momosecurity / aswan

陌陌风控系统静态规则引擎,零基础简易便捷的配置多种复杂规则,实时高效管控用户异常行为。
GNU Lesser General Public License v2.1
2.99k stars 828 forks source link

数据上报redis 详细说明? #2

Closed npc7 closed 5 years ago

npc7 commented 5 years ago

数据上报,数据存储在redis的 sorted set 存储说明 可否说一下

Flynnon commented 5 years ago

这个解释起来有点麻烦,因此这里只简单介绍下思路,具体逻辑直接看代码吧。

大致思路

存储

key

在其中存储尽可能多的东西,包括 上报的数据源(source_name),存储格式是什么(这里使用了对应Source的class_name),策略配置时的字段有哪些(此处会排序),这些上报上来的值分别是什么,这样后续的很多操作都能直接对应某一个具体zset_key上,无需额外操作

score

直接使用上报的时间戳

member

存储策略需要特别记录的值,若没有则使用当前精确(ms级)时间戳,减少value重复导致的member覆盖几率

查询

在查询时,只需要按照配置项及查询的参数即可拼接出可能的key

示例

假设存在如下生效的策略

相同ip,uid,在最近24小时内,限1次(初始样例数据源)

某条上报数据为

{"source_name":"init_source_key", "ip": "1.1.1.1", "uid": "123456", "timestamp": 1561302884, "phone": "", "user_id": "111"}

则会产生一个如下 zset

# zset_key = "init_source_key_FreqSource_ip_uid:1.1.1.1_123456"
zset_key = "_".join([source_name, source_cls_name] + sorted(["ip", "uid"]))
# score str(data['timestamp'])
member = "1561302884"
# member str(int(time.time() * 1000))
score = "1561302884123"

某次查询时的req_body正好为

{"rule_id": "1", "ip": "1.1.1.1", "uid": "123456", "phone": "", "user_id": "222"}

则根据rule_id为"1"可以定位到正在生效的策略,然后按照相同的规则使用查询时的参数即可拼接出可能使用的zset_key("init_source_key_FreqSource_ip_uid:1.1.1.1_123456"),然后对取出的数据进行计算即可判断是否命中此条策略

代码位置

限用户数型

相关代码详见 aswan/risk_models/source.py 下的 UserSource.

时段频控型

相关代码详见 aswan/risk_models/source.py 下的 FreqSource.