说到风控系统,笔者先抛出几个问题:
• 如何将更新数据在10s内推送给全国用户?
• 如何保证客户的数据是绝对安全的?
• 如何在10m内完成新数据中心的搭建?
• 如何做到全国任何用户访问都在10ms?
问题中提到了三个10,即10s,10m,10ms,本文以Red.Q云风控系统为例,来谈谈3个10的问题是如何解决的。
本文将按顺序讨论为什么风控系统需要实时性、安全性、便捷性和可靠性,这其中可靠性是最重要的,所有的技术细节比如跨数据中心通信,服务SLA,发布,运维监控,数据质检,分布式等会在文章后面的可靠性章节详细阐述。
实时性:10S
对风控来说,以前在说风险控制,现在都说风险预警,其实就是时间维度的控制,只有提前发现了风险才能有效控制风险。笔者这里举个简单的例子:
http 代理是一个可爱又可恨的东西,它可以帮助我们隐藏真实的身份,也可以帮助我们去做坏事不被发现。对于大部分的互联网企业来说,只要谈到用户访问来源是代理的时候都会有些紧张,因为http代理是目前成本低并且效果好的撕开企业各种风险控制系统和IP防火墙系统的一把利剑,学习成本低到只要会点互联网知识会使用搜索引擎就可以用,所以大部分互联网企业在如何防范代理ip访问上面都做了很多工作。但是当你好不容易把国内的代理IP都收集的差不多的时候,你会发现好多代理已经失效了,新的代理层出不穷,做这个维度的风控完全是跟时间赛跑。
那么如果Red.Q云风控系统有这样的一个功能:实时提供国内IP代理状态查询功能,你会不会觉得风控工作瞬间变得简单了很多呢。
在大流量面前,早发现可疑行为一分钟,对于企业都可能避免更多的损失,这只是实时性在风控领域的一个缩影,事实上有更多的数据需要很强的实时性和时效性。
例如我们的风控数据的更新量每天都很大,每天探索数以万计的数据,包括IP,手机号码,情报数据,我们一直在努力压缩数据从探索到质检到入库到推送各个数据节点的过程时长,一直希望给用户带来更好的实时性体验。就之前提到的代理ip数据而言,我们最快的从发现到推送的时间是10秒钟。
安全性
为什么我会提到安全性?我相信大部分互联网公司的核心都是其业务数据,公司的安全性就是这些数据的安全性。公司如果自己做风控系统那么无所谓,数据都是在公司内部流转,但是如果公司没有风控团队,技术也还不够成熟又想做风控就只能借助于第三方安全公司。
之前接触到一些云风控系统都是需要将客户的订单、登录等敏感的业务数据上传到云端进行分析产生决策,这些核心数据如何传输,如何存储都脱离了客户的控制。就算安全公司把自己如何如何安全说的天花乱坠可能也只是在安慰客户和自己,没有一家安全公司敢站出来说在这个黑客横行,0DAY乱跑的年代,我的客户数据是最安全的。
对于一个好的云风控系统来说就不存在或者很少存在这个问题。用户提供的数据非常的有限,我们不要求用户上传敏感数据,有限就代表可控,可控就代表安全,这就是岂安一直在倡导并始终坚持的安全性,除了自身数据的加密和防护,在同态加密的技术领域上我们也一直保持高度关注,笔者认为在不远的将来,同态加密的应用一定会是安全领域的一个颠覆。
便捷性:10m
首先,对于客户而言,风控系统需要的是接入简单,无需提供复杂数据格式,对照文档即可完成接入。
其次,对于公司自身而言,在现有的技术栈(docker,数据分发系统,发布系统,自动化安装,服务可伸缩)的基础上,我们新建或者重建(容灾)数据中心的成本异常的小,从发布到上线大概花费时间是10分钟,我们可以真正做到客户在哪里,数据节点就建到哪里,具体技术细节参见下文可靠性的发布章节。
可靠性:10ms
为什么可靠性很重要?有人会说你们又不是银行系统,也不是订单系统,只是一个工具而已,为什么要那么高的可靠性?笔者想说的是当一个公司在重视安全风控的情况下,将这个所谓的工具嵌入到注册登录流程以及交易流程中,成为关键一环时,可靠性的重要性就体现出来了。如果因为你的产品延迟过大或者拒绝服务影响客户的交易流程,导致客户受到财产损失时,也许老板已经把你fire了。
说到可靠性就不得不提SLA(service-level agreement),业界都在用得一个考量标准,如果做到SLA 四个九五个九,如何做到延迟20MS?假设我们的数据中心在上海,那么做到上海地区的20ms应该没有什么难度,那么北京的用户可以做到20ms么?深圳的用户可以做到么?
有人可能会问,使用CDN就可以了,当前CDN无论技术的成熟度和稳定性都做的非常的棒,笔者也承认CDN技术确实可以解决资源远端用户访问延迟的问题,不过只能解决静态资源调用,对于动态资源,只能通过优化骨干网线路来实现,但是局限性在于延迟的优化提升极限,它可以把你的网站访问延迟从2秒缩短到500ms,也有可能把你的查询接口从500ms缩短到50ms,但是当我们到了要把延迟从30ms降低到20ms的度时,CDN技术也许就无法胜任了。
举个例子,还是假设我们的数据中心在上海,深圳的用户要查询我们的数据,深圳到上海的直线距离是1200公里,通讯线路算1500公里,用户发出请求到数据返回给用户大概是3000公里,这里先不考虑数据包转发等损耗,仅仅是光速传输需要3000公里/300000公里=10ms,可以想象当我们的风控系统在追求极致的低延迟的时候,CDN技术已经被PASS了,我们需要的是多数据中心(多机房)!
Red.Q云风控系统目前有十个数据中心节点在部署中,主要分布在北上杭广深,同城访问可以覆盖70%的互联网公司,SaaS服务接口查询延迟在全国范围内基本控制在20MS以内,如果用户调用服务器跟我们处在同一机房,速度可以达到近10ms,最大程度提高接入速度和可靠性,这就是跨数据中心方案的好处。
下图则是用户在访问Red.Q业务时的抽象数据流向图:
1. 我们通过使用运营商提供的DNS定位功能将用户定位到离其最近的一个数据中心节点
2. 查询请求首先进入该节点LB并转发到后端服务器
3. Service处理本地数据并返回
4. Service加载远端机房数据并返回
这里提到的本地数据就是我们的核心业务数据,我们会在很低的可控延迟内做到所有数据中心的数据一致性同步。做到这一点就相当于把数据搬到了用户的家门口,用户99%的请求都是在请求“家门口的数据”,延迟问题得到解决,还有1%是第四点所说的远端机房数据请求,那么我们是如何做到数据传输和控制的呢?
我们采用微服务架构(MSA)对每个服务进行解耦,并且自己写了一套通讯框架【Babel】 用于service之间的通讯。下图描述了Babel的Workflow:
Babel有如下几个功能特性:
1. 多语言构建支持(目前支持Python和Java):最大程度发挥了不同技术栈程序员的优势。
2. 支持多种消息分发语义:shuffle(随机分发),sharding(数据切片),topic(消息copy)等
3. 数据传输方式支持Rpc请求,数据推送以及轮询等方式,满足了Bigsec目前的几乎所有数据传输要求。
4. 支持多种底层通讯协议(Rabbitmq,redis,0mq):满足分布式,单机,高速等需求。
5. 通过使用Rabbitmq的federation特性,在不同的机房搭建Rabbitmq节点来支持跨数据中心功能。
Red.Q云风控系统后端需要有很多的不同的服务组件支撑,每一个服务组件都搭建成多实例集群(这里的集群概念是指多个相同service进程)做负载和容灾(一个进程Down了不影响该服务),如图1的serviceA、B、C等,并用Babel框架连起来,再加上简单的配置就实现了跨数据中心特性。
下面一张图描述了我们的跨机房特性上线前后用户延迟粗略对比,效果比较明显。
优化之前
优化之后
关于Babel的技术细节可以参看我们推送的这篇文章:babel: yet another rpc, but far beyond rpc,本文仅作为通讯框架使用,Babel的跨数据中心通讯实现使上层业务基本不再关注跨数据中心的实现细节,但需要注意几点:
1. 跨数据中心的数据大小要控制
2. 使用跨数据中心特性要考虑延迟,准实时级别
3. 业务上层实现缓存机制,如上图ServiceA的Cache(黄色)
4. 做好熔断措施
当架构复杂了,随之而来的就是运维的难度,如何快速将代码部署到所有机房并上线?如何在第一时间知道哪个机房的哪个服务器的哪个service出了问题?这两个问题就引出了发布流程和监控系统。
发布流程
我相信很多大型的互联网公司已经可以在几千台甚至几万台服务器规模下把发布做得很棒,而且也完善的发布流程和自己的发布系统。不过这里笔者还是要说两句,这对于刚刚接触互联网或者初创公司来说,多多少少会有一些启发,还是画一张图来说明下我们公司的发布流程是什么样子的。
从左往右说:
• opservers是运维服务器集群,所有发布,运维,监控等服务都会放在这里,为了降低维护成本,仅存在于主数据中心
• Ansible (http://www.ansible.com) 是一款运维自动化工具,用于批量执行任务,功能强大又不失简单,对于任何运维工作,只需要定义两点:你要做什么(playbook) 、对谁去做(HostsInventory),将两者进行组合
• 橙色部分是Docker容器技术的使用,微服务概念哲学给我们带来使用docker的可能,完美的解决了应用的环境依赖问题,对于环境基线的更新也能像应用基线一样通过简单的commit、push、pull来实现,为了降低docker容器的运维成本,我们对docker的commit进行了层抽象:
• 系统层监控通过在服务器初始化的时候安装监控agent ,监控数据由agent发送
• 框架层监控集成到了Babel通讯框架中,Babel会将Service之间的msg通讯统计、产生错误、心跳数据定期上传到服务器,通过报表可以看到所有服务器上的每个service通讯和健康情况。
• 业务层监控:硬性规定要在业务代码的关键位置打点
简单描述下Red.Q云风控系统的发布步骤:
1. 代码开发完成提交GIT
2. 修改DockerFile Build新版本
3. 测试:拉取测试配置,推送新版本的Docker Commit ,测试通过
4. 生产: 拉取生产配置,推送新版本的Docker Commit
5. 生产:集群拉入拉出,服务重新启动。
6. 监控发布期间的Metric报警。
7. 上线成功
目前,我们通过编写Ansible Playbook 完成了以上发布流程的80%,大大节约了人力成本,提高发布质量。
这里提到一个问题:
由于机房服务器都存在于内网,所以为了解决跨数据中心运维服务的访问(不包括Babel业务通讯),也就是说让子数据中心能够访问运维服务器集群,本来子中心到主中心打通就可以,但是由于我们的jumpserver在主中心,所以如果要使用该跳板机管理子中心的服务器,就必须将主中心到子中心打通,所以我们采用的方法就是主机房建立vpn服务器,子机房拨号连接进来,同时在两端做路由和nat,并将各自机房的路由器添加互通路由就实现了机房互通。
当然这里面还会涉及到很多问题,比如版本控制,服务器初始化等,本文暂不涉及。
监控系统
• Influxdb是一个开源分布式时序、事件和指标数据库,写入速度快,非常适合用于监控
• Grafana跟influxdb搭配使用,将Metric web可视化,查看指标的重要工具。
• Metricalert 基于influxdb开发,设置报警规则进行报警。
• metricproxy 存在意义在于跨数据中心特性,为了保证proxyclient的稳定,每个数据中心的metric报警都会发到本地proxy并统一由proxy压缩发送到主中心服务器。
监控保障,依然采用分层体系:
• 系统层监控通过在服务器初始化的时候安装监控agent ,监控数据由agent发送
• 框架层监控集成到了Babel通讯框架中,Babel会将Service之间的msg通讯统计、产生错误、心跳数据定期上传到服务器,通过报表可以看到所有服务器上的每个service通讯和健康情况。
• 业务层监控:硬性规定要在业务代码的关键位置打点。
经统计,目前我们的监控布点大约有200+,可视监控报表大约80个,报警规则大约40条,从业务到系统,从通讯到进程,基本覆盖了98%的关键点。不过有句话说得好,出来混总归要还的,故障还是会发生,不过我们的Red.Q云风控系统在抵御故障能力上具备天然基因和优势,以下CaseList可以说明这一点:
1. service进程被杀:其他Service继续提供服务(继承Babel特性)
2. 服务器宕机:其他服务器继续提供服务(继承LB特性)
3. 机房光纤被铲:其他机房继续提供服务(继承DNS节点切换特性)
数据可靠性
那么最后一个影响可靠性的因素就是数据了,对于风控的数据,人工识别也好,机器判断也罢,由于数据的特殊性,无法做到100%的精确,不过在有限的领域我们可以做的还有很多,下图是一张关于数据质检以及发布的流程。
数据质检的定义在于数据质量的要求,Red.Q云风控系统后面有一个非常庞大的情报团队无时无刻的不在收集互联网上所有我们关心的数据,来源多,维度广,数量大,这类数据如何做到有效的关联和验证对于我们来说是一个持久的技术挑战。
对于提高数据质量来说,首先我们对所有的来源定义了可信指数,根据数据的类型、维度和来源定义了很多验证规则,所有的来源数据根据验证规则进行交叉验证,数据会被多次进行验证,数据每一次被验证可信指数都会增长。比如我们在鉴定某一个手机号码是否是非正常用户时,会通过硬件、语音识别等方式鉴别,对于IP,我们有分布式IP扫描系统和爬虫框架进行验证。
当质检仓库的某批数据达到了可信指数输出的设定值,该批次数据就会被打上版本Tag推送到生产仓库并对每一条数据生成Binlog,这里Tag的意义在于将每批次更新的数据区分开来,在生产数据出问题的时候能够做到迅速定位数据批次并回滚,最后通过Babel推送到全国各个节点。
上图中绿色部分是新数据中心搭建时候我们针对数据一致性所做的一些措施,我们首先会在数据主仓库中Dump一份数据并Copy到新数据中心,为了弥补在Dump-copy过程中更新数据的损失,我们会记录dump的时间点定位相关时间段日志数据Append到新库中,最后接入babel并上线。
这么多技术活归根结底一句话——在服务可靠性上面,我们是认真的。
数据
额外提一点就是数据这块,这一点对bigsec来说是业务发展的基石,目前bigsec拥有3.5亿风控数据体量,Babel消息总线每天传输处理3000W+的Msg,数十个数据来源不间断补充新数据,多种数据验证方式对数据质量进行把控,平均每周可以保持数据复合增长10%,虽然数据量越来越大,但谨小慎微依然是Bigsec技术人对数据的态度。
就拿一个很简单的一个归属地数据来说吧,为了能做到IP以及手机号码更高的准确度,我们并没有直接使用网上的开源库,而是花了好长时间爬取并整合了包括阿里,ip138,纯真等数据,在对数据的校验过程中,发现大量的归属地错误条目,只能通过人工去校正,最后开发出了bigsec版的归属地数据库,有人说这是重复造轮子,但是笔者认为只有对自己认真,别人才会对你认真。
总结
篇幅有限,很多东西只能一带而过,本文大概围绕了可靠性、实时性、安全性、便捷性、数据这几个关键词展开,用以说明这几点对于风控系统来说的重要性,尤其重申了容易被大家忽视的可靠性,但是在风控领域里面其实还有太多的东西要谈,有太多的东西要做。
笔者一直认为bigsec的技术发展之迅速是建立在巨人的肩膀上的,不是一个巨人,是无数巨人的肩膀,在这里向这些巨人致以最崇高的敬意,并抛砖引玉之。
笑天 岂安科技首席安全架构师
主导公司安全业务和 Red.Q 系统的研发工作。擅长 Python 编程,分布式系统的研发和运维。写代码里资深玩乐器的,艺术家里玩 Python 的。非著名斜杠青年。