反架构

软件架构可以说是软件开发的“政治正确”,不谈“高大上”的架构,不但得不到客户的信任,也无法在团队中获得话语权,今天就来“反”一下。 架构设计本身就是个抽象过程,不但包含实践的方法和过程,还有抽象的理论和总结。而这个过程表象很容易掩盖本质,有时还可能是陷阱或骗局。 我一直是个实用主义者,也就是相信架构设计是以需求为出发点,遵循最小投入最大产出的原则进行。所以我主要“反”的是两种: 理想主义的架构 商业包装的架构 而很多坑都是在这两者之间纠缠,让你云里雾里。 理想主义架构 可以认为是比较唯心的,偏离了实际情况,追求完美,追求内心的舒适。这种架构思路在非常优秀的程序员身上都能找到,是难以避免的人性问题。常见的一些情况 可靠性:谈及可靠性容忍不了单点错误,从各种可能性上全面考虑,假设大量出错场景并解决。过度设计通常会导致系统复杂,可维护性低,因可提高靠性本身的功能产生了不可靠的问题。 可扩展性:过度追求设计上分离,分层,假设变化无处不在,通常会导致服务切分太细,维护工作量大,资源利用率低,性能下降。 性能:追求性能的极致,会产生会系统和环境的依赖,导致可移植性低,模块耦合严重。 理论深度:喜欢套用理论升华方法,本身是本末倒置的行为,但用在商业包装上却是合适的。是对外不对内的架构。 回过头来看,可以看到架构设计实际上很多时候是取舍,所以“什么都要的”的成年人想法是不实际的,根据具体场景,产品差异做好小孩子的选择。 商业包装的架构 理想主义常存在于追求完美的人性弱点里,而商业包装就是针对这种人性弱点所设计的有商业目的的架构,把程序员作为客户,包装出的架构或技术。它们有时不是为了解决问题,而是谋取更高的利益,鼓吹双赢,所以更加隐蔽。我们也思考一些例子 商业驱动的热门架构:比如云原生架构,微服务,上云,大力传播这种架构理念的是AWS,阿里云及其关联企业或组织,哪怕是开源组织,赞助商也是他们。不是说微服务不好,而是要审视自身的需求,平衡好预算和组织能力。因为对于商业来说数字化转型花了钱就一定要是“成功”的,“来都来了,做也做了”也只能说它好,上车容易下车难,所以一定要提前想明白。这种问题在大公司比较突出。 设备厂商的完美可靠性:通常提完美可靠性方案的话,都是设备厂商,因为可靠性最简单的就是“冗余”,说白了就是利用技术人员追求完美可靠性的心理,多卖一些设备,多赚一份钱,所以在技术架构上都打着一些旗号,也为甲方设计好了说辞。我承认作为乙方这是商业上的成功,也确实应该这样做。但最为甲方客户时,很容易过度投资。 开源技术的成本:但天下没有免费的午餐,除了“商业驱动”,还有就是“请君如翁”式的沉没成本。利用开源解决你的所有问题,需要自己“搭积木”,比如Hadoop表面上给出了完美的开放性,生态,但如果想搭建一套完整的大数据平台,那么至少涉及5,6个开源组件,并且有很多复杂的技术细节和经验,一旦因为免费,你投入了时间和精力,像极了“爱情”,被沉没成本冲昏头脑。而往往这种大而全的架构都很中庸,对场景模糊,需求贪婪的甲方很容易中招。 技术的阴谋论:因为各种商业目的,一些并不好的架构模式或实践也会包装成优秀实践,毕竟角度不同。哪怕角度相同,体质也不同。有的大公司通过分享复杂技术,完美架构方案,来进行人力和智力资源的对抗,最终必定大鱼吃小鱼。小鱼还得向大鱼求救,为大鱼买单,所以这些商业因素所影响的技术目的是很复杂的。 感想 虽然说了这么多负面的东西,但技术的本源还是正向的,会长期推动生产力的进步。还是要鼓励拥抱变化,无畏学习。 同时不要局限在技术上看架构,要从产品,组织,商业上多角度选择,还包括资源,人力,团队能力,商业合作,产品差异。 刚工作时,一位架构师培训时说“架构是长出来”,现在来看颇有深意,“架构”长得好不好,除了人的辛勤栽培,还有土壤,阳光,温度… 技术上承认自己的不完美,接受妥协,擦亮双眼,辩证而全面的想,低成本而无畏的学和试。

大数据(2)-数据处理-格式

数据的输入的原始存储格式,和内存中的组织形式,是决定数据处理性能的关键。 格式的场景 所以大数据中很多技术是关于格式的,或新或老的一些技术,比如 存储(on-disk)的格式:Parquet,ORC,Avro,CSV,JSON… 通信(on-wire)的格式:Protobuf,Avro,JSON… 计算(In-memory)的格式:Arrow 共性来说,就是数据的组织形式,行式或列式,数据的编码/压缩格式,不同场景的话,各有所长。 如最熟悉的CSV,JSON都是无压缩的字符串,JSON的结构化更适合阅读。 Parquet,ORC都是列式,面向机器,因为计算过程往往是按列的,所以存储上按列可以减少随机访问,提高IO。 Avro是行式的,因为有时列持久化需要等所有或一大波数据才能持久化一次,而按行更符合通信流,适合通信持久化。 无论批处理还是流处理了,需要处理合适的输入的格式。流处理情况下大部分还是需要处理行式的,批处理则更适合列式。 计算上还需要用列格式,所以流式处理上需要有一个行到列的反序列化,这会降低一定的吞吐。 性能 or 扩展性 计算类型格式理论上是一个很私密的东西,和之前讨论的计算状态一样。如何很好的将计算(Stateless)与 格式分开是不容易的。俗称“存算分离”,分离清晰,可以快速横向扩展,有更好的可扩展性,但可能会使性能下降。这中间有个度需要结合自己的需求场景把握。 提到性能,参考一下当前流行的计算组件的速度 https://h2oai.github.io/db-benchmark/ 除了Spark,Pandas这些耳熟能详的,我们看看前几名: Clickhouse是OLAP数据库,主场景是存算合一的数据库,比如交互式查询 R语言的 data.table 主场景是科学计算 Julia的Dataframe.jl 主场景是科学计算 https://dataframes.juliadata.org/stable/ 都在自己的计算场景下,也没有开放格式,使得内部处理和格式更紧密,更容易优化性能。 Polars是基于Apache Arrow是目前一个面向计算的内存格式的项目,是一个Libary。Arrow是一个计算格式的Libary,目前很火。 计算与格式 Hadoop MapReduce时代计算格式可以认为和持久化格式相同,中间结果都存储在HDFS中,所以内存的开销很小,也符合最早Hadoop的定位,整合“弱鸡”的计算能力。100%纯净的“存算分离”,但也足以可见,计算格式和持久化格式最初是一致的,这样的IO节省了格式之间的转换。 但速度需求永远是大数据的刚性需求,用内存空间换时间的Spark,很快取代了MapReduce,其区别就是Spark在内存中定义计算,并可以对内存中的计算分布式交换(Shuffle),大大提升了计算性能。 但Spark的Dataframe本身是封闭的与计算过程耦合紧密,不光Spark,各个组件都有优先自己场景的格式。大家很快意识到,格式和计算确实紧密,也就是格式一定程度决定了计算的速度,而数据应用的Python,Java程序员并不想自己再来一套这个。 于是一个C++ Arrow项目诞生了,其定位是一个计算格式的通用库,统一计算格式,因为是C++写的,性能自然又要高Java一个量级,本身又是库,所以提供了各种语言的接口,让大家专注于计算部分,然后对外提供FFI到各种组件。 总结 格式上的选择也很多,存储容量,成本,IO,转换的开销,延迟都在不同的数据场景下有不同的偏爱。方案或者架构的本身就是不断做选择题,MAX(客户预算-产品成本)就是不断求解的过程。还是那句话,适合的才是最好的。尤其是大数据领域,大坑太多,请平衡好成本。

大数据(1)-流式处理-状态

转行搞了三年大数据,计划写些的东西,对这个方向总结一下,包括架构,工具,格式,库等等。 最近准备造轮子,就先从一些目前最常见的流式数据处理手段开始。 Spark & Flink Spark,Flink是最知名的通用数据处理工具,不限定场景,不限定数据量。支持分布式,支持自定义状态,灵活定义数据处理逻辑(执行计划)。 当然缺点就是:人工参与程度大,速度慢,系统臃肿。 缺点与优点是相互取舍的,因为本身就是通用平台,不能与业务场景过分绑定,所以很多功能在实际使用时是不需要的,比如只用20%功能,但也有80%的功能拖慢了速度。 另外磁盘和网络IO,也是持久化,分布式必须的。 调用方式:因为两者定位都是数据平台,都是异步的网络API,即使有SDK,也相当于客户端封装再异步调用。 状态 Flink (https://flink.apache.org/) 举例,他官方描述就是 Stateful Computations over Data Streams 顾名思义,有两个东西,一个是Data Stream,一个是Computation State,这个是任何流处理系统的共识抽象。 最简单理解就是上图,流入一些数据A,B经过处理系统,数据会通过当前定义的函数或执行计划,改变内部存储的State(比如内置RocksDB),数据与State相互作用后,输出了C,D。 基于这个抽象,思考几个简单的场景和问题: State与Function的关系:State是Computation State,所以顾名思义和计算函数Function是共生的。举个最简单的例子,我要做一个累加的状态,那么A,B,C进来,Function就是 ++,State就是存储 ++ 结果的持久化内容。这样很容易理解吧。 分离计算与计算对应的状态,其好处就是可以将计算并发(快),读写共享状态(慢),在处理海量数据时,更容易进行扩展,比如A,B在一个线程上相加,C,D在另外一个线程相加,然后State再加到一起,或者说每个线程都可以有个State,相加后,在处理合并State的的步骤。 而具体用那种策略更好呢?其实就是一种执行计划,它是根据你定义的计算过程而制定的。甚至可以在计算过程中根据流入数据的情况进行动态调整。 流式处理里什么事后不需要状态(Stateless),简单的格式转换,丢弃,没有信息的增加,对上线文无关,都可以不需要状态。通常不需要状态的,我理解是计算无关的,不是流式计算引擎的重点。 Spark和Flink都内置了大量的计算函数和对应的State,一般来说只用内置计算函数时,对其状态是不太感知的。但作为通用计算引擎,提供自定义计算是必需功能,那此时也必定涉及到State的定义。 通常我们使用的UDFs(User Defined Functions)就是无状态的(Stateless),只定义函数,不定义状态。 而UDAFs(User Defined Aggregate Functions)就是要定义,在给定聚合和Key情况下,状态的变化。 而更灵活的自定义聚合函数和State则还需要定义状态迁移介入的过程,即什么时候开始,什么时候结束。 感想 如果你有幸在通用平台上钻研过自定义状态处理,你发现它是构建在一个通用框架上的扩展,你需要了解这个框架,而框架则为了考虑所有场景,所以将其抽象到一个爹妈都不认的高度。你需要将你的业务问题套进去,这个学习和试错成本并不低,有时甚至是一个本末倒置的过程。 所以当你的业务是“杀鸡”问题时,切勿寻求“宰牛”方案,也不要轻信网上那些技术营销或大厂经验而投入Spark或Flink大坑。 合适的永远是最好的。 参考: Flink基本原理 https://flink.apache.org/flink-applications.html UDAFs https://spark.apache.org/docs/latest/sql-ref-functions-udf-aggregate.html Spark State https://spark.apache.org/docs/1.6.1/api/java/org/apache/spark/streaming/State.html Flink State https://ci.apache.org/projects/flink/flink-docs-release-1.13/docs/dev/datastream/fault-tolerance/state/

2021网络系统流行架构

2021年了,看看网络系统的流行架构。 系统的质量属性要满足客户需求,所以架构的第一出发点也是需求。 有偏好的需求构成场景,架构的取舍就是基于应用场景的偏好。 网络系统在管道的位置,大致分为两类: 傻快型:内容无感知,以交换和路由为主。如各种交换机,路由器等设备,主要靠硬件。 纯软件实现上的需求主要是牺牲一些硬件的高性能,换取管理和维护的方便和统一,如SDN,NFV。 目前为了融合硬件与软件,一般都采用x86的架构配合高速可编程的NIC和转发芯片(如支持P4)。 以获得性能与管理的双重优势。 但本质还是矛盾,硬件的特殊化就会带来管理的特殊化,具体问题需要具体讨论解决,不展开。 智慧型:内容感知,以业务驱动的负载均衡和网关系统为主。如负载均衡,API网关等,主要靠软件。 今天重点说一下2021年软件上的流行架构。 因为两种类型没有明显分界,但内容感知程度是有的,业务驱动的网络系统在互联网行业需求很大。 所以网络基础架构软件化不仅仅是管理统一的问题,还有具体业务的问题很难在通用设备上完美解决。 软件实现虽然性能不行,但其灵活性和对硬件的解偶带来的收益是大于性能收益的,其横向扩展能力也弥补了全局性能。收益主要体现在迭代迅速(需求满足的速度),硬件统一,部署灵活,运维简单。所以暂时将引入硬件解决单点性能问题作为第二考虑的因素。 我们一层一层来说。 eBPF - Passthrough 2021年eBPF打底应该没有争议吧,对比以eBPF实现的XDP与DPDK,结合我们刚说过的问题。DPDK还是有Intel,DPDK网卡的硬件约束。而eBPF系统约束更小,Kernel > 4.8即可。虽然性能稍微弱一些,但可以在纯Linux运行,可以灵活在用户态和内核态对接,需求迭代速度也远高与DPDK。所以软件上做傻快型可以选DPDK,但智慧型XDP更适合。 以此为基础的项目有k8s网络组件Cilium,Facebook的业务负载均衡Katran。 Cilium - Network 迭代和硬件说完了,我们看下部署,部署上:盒子,私有系统,各种云。对应也就是Metal,VM,容器等。因为有了eBPF的约束,没有操作系统的Rare Metal就不在讨论范围内,它更适合傻快的方案。 各种部署下都能运行的网络就是用户态网络。XDP只要是内核满足的Linux,Cilium已经证明了和容器结合,DPDK更费劲。所以还是eBPF更有优势。以此为基础的软件系统,可以安装在任意Linux,VM,Docker上,实现各种环境的架构统一。 未来网络层应该还会有其他XDP的用户协议栈方案,如果不需要路由交换的网络功能,可直接与应用结合,如Katran。 Envoy - Gateway Cilium解决网络的问题,路由交换,简单策略。但业务感知还需要灵活的网关,关于网关的选择我之前也研究过。 https://donge.org/posts/envoy-vs-traefik/ 这里网络如果选择了Cilium(主要是容器场景),那么结合最好的还是Envoy,Evony在四层进行业务感知,进行业务层面的路由和网关,有强大的策略配置驱动和插件机制,也是快速迭代的优选。 这里虽然拿了一个K8S中CNI的图,但Cilium也可以仅作为有网络路由功能的用户态协议栈使用,也可以省略。 Golang - Plugins 采用通用网关驱动特定业务,插件或二次开发是绕不过的,平衡性能与迭代速度,Golang比C++,Lua,JavaScript,Rust都稍微占一些优势。因为开发效率和不俗的性能。Envoy是C++,有开发门槛,但插件系统较为完善,Cilium是Golang。 WASM插件也是强有力的方案,只是今年来看还优点早,得不偿失。而且和Golang也不冲突,Envoy同时也支持WASM和LUA。 但只要不是天天变化的逻辑,Golang中庸的综合实例还是略胜一点。 未来Rust with WASM很有想象力。 全家福 为什么叫2021流行架构,因为过几年也许还有更好的选择,就如同XDP对比DPDK的优势,顺应了一些DPDK出生时没有的潮流,比如容器化。 最后祭出这张原创全家福,欢迎抄袭。 以此为基础,可以快速满足大部分的网络系统,包括业务路由(负载均衡),WAF,API网关,单点认证,日志,QoS,跟踪系统等。并可部署与单机,私有化,混合云环境等无硬件依赖环境。 性能虽然在第二梯队,但XDP,Golang这样的选择也是第二梯队的王者。而网络性能的热点更可能会在IO,并发(锁),加解密/压缩反压缩(计算),而他们的解决方案从来不是哪种语言,有机会再探讨。 P.S. K3S是轻量级K8S,适用于小系统部署。 参考文档: http://arthurchiao.art/blog/transparent-chaos-testing-with-envoy-cilium-ebpf-zh/ https://gitlab.com/gitlab-org/gitlab/-/issues/205129 https://github.com/zoidbergwill/awesome-ebpf

爬虫的钳形攻势

爬虫的起源 先科普一下,这里说的“爬虫”是指网络爬虫,起源于互联网早期的搜索引擎。为了自动完成网页信息收集的工作被创造出来。 爬虫诞生后,虽然看起来非主流,却实质上是互联网应用最重要技术之一。除了我们熟知的谷歌,百度爬虫这些老牌,新起之秀今日头条,点评美团,去哪儿,58等等互联网巨头都是以爬虫为基础搭建的信息聚合平台,同时也拥有经验丰富的爬虫团队。 除了狭义以网页内容为线索爬虫外,其他以自动化形式获得信息的程序或脚本都可以称为“爬虫”。 爬虫的规模 爬虫在互联网上有多少流量呢,保守估计平均过半的流量都来自爬虫,有些行业甚至可以达到90%。 因为与人类相比,人类数量增长是缓慢的,反应时间也是有限的,人产生的流量有限。 而爬虫的规模则是随着IT基础设施,算力,带宽,吞吐的增加而正比增加的,其本质就是随着互联网中的信息增加而增加,这个是指数级的。 而且还在不断得高速增长,爬虫不会被消灭,只能被管理。 爬虫的黑白 “爬虫”是“人”为了简化工作而创造出的工具。它是中性的,创造和使用它的人们可以用来简化工作也可以用来做恶。 有时甚至无法定义黑白,不同的人商业目的,在互联网的战场上相互厮杀,爬虫技术自然成了这场战争中的武器。 爬虫的攻防就是规模大小,自动化,智能程度的高低的较量。其本质也是背后人与人的对抗。 最近有幸和头部互联网公司有过交手,略胜一筹,有感分享。 爬虫的钳形攻势 爬虫的技术细节很多,不想聊。回到主题,今天说一说最近这次对抗的爬虫,也许是你未闻的。 一般我们知道爬虫是自动化,想要对抗爬虫,就要找到自动化的规律,破解它。 没错,但这个规律是什么呢?五花八门,是不是可以用机器学习或者深度学习解决呢?有可能。 我们总说“攻防对抗”,对抗是不断升级的,指挥双方都是人,高手对决谁也不比谁差,你能想到的别人也可以,是对等的。 所谓“钳形攻势”就是在对目标发起攻击时,同时派出两个不同的分队,从不同角度进行攻击,甚至更多。 其中一个是大特征爬虫,炮火猛烈,人数众多,看来起就像是主力部队,也会比较容易被你或系统发现,摸清规律后控制。 另外一个时分散特征爬虫,像游击队一样,不断变化特征,频率,让你不容易发现它,悄悄得抢夺重要信息。 这样攻势的目的是通过大特征爬虫可以混淆你的自动规则和机器学习系统,让你的反爬虫系统表面上看起来工作顺利,发现并遏制了大量的爬虫。 但实际上关键信息还在不断流失。这种爬虫攻势不但有武器技术层面的杀伤,还有战术上的经验和灵活的应变能力。 也是爬虫战争终极对抗的关键。高手对决,最终消耗的就是资源(成本)和团队的规模。 广告 互联网巨头们垄断了技术和人才,谁也不想和他们较量。一旦他们的爬虫盯上中小企业或非技术驱动企业时,几个回合这些企业就会被打得落花流水。 我及我们的团队恰好可以在这里可以帮助这样的企业,守护你的每一寸信息。对爬虫技术,反爬虫产品有兴趣的伙伴也欢迎咨询与交流。 dongdong@servicewall.ai

Envoy VS Traefik

云原生场景,产生了很多的Edge Router,Load balance,API Gate Way,Proxy等组件。 最近研究了一下,分享几个喜欢的项目,它们大致分为两类: Gateway为主:Kong,Krakend Proxy为主:Envoy,Traefik 但两类没有实际功能的边界,Proxy为主,一般要支持在L4,Gateway为主,支持在L7即可。 Proxy主要位置是中间,可以做sidecar,Gateway在服务endpoint前面。 再比如传统的HAProxy就是Proxy,Nginx就偏Gateway。 这个概念和数据通信网络的Core Router和Edge/Service Router是差不多的,Edge Router是感知服务的,理论上功能更多,Data Plane基本一样,Control Plane功能更丰富而已。 所以Gateway一般是一个Control Plane + Data Plane,比如Kong的Data Plane就是OpenResty。 使用Envoy作为Data Plane的Control Plane有Solo.io(Istio族下)。 从需求角度,我有几个偏好: 高性能:C++,Rust,Golang还可以,其他语言就别Data Plane了 高扩展:必须支持插件,动态(如LuaJIT)或者静态(链接库)。 独立:Serverless,无依赖,无状态,单daemon,最好自带UI。 小而美:其实和上面几个也是一个意思,最好带简单Control Plane,但要节制。 功能性能上,需要看场景。我关注在差异上,也就是高扩展与独立。 Envoy:C++原生性能没得说,线程模型比Nginx还先进,水平扩展,所有配置均支持动态接口。最吸引我的是WASM的插件机制,逻辑上WASM可以编译到原生水平,还有很好的容器属性。只要push/pull就能增加插件进行使用。 Traefik在今年上半年选型时,我很看好,独立,2.0开始支持L4,与Swarm,K8S结合都很好,性能也与Nginx不相上下,但配置动态还自带UI,可惜当时不支持插件,惜败。没想到从2.3开始支持golang的动态链接库和golang代码解析执行两种(Dev Mode),实验阶段。 Kong/OpenResty:Nginx性能没的说,Lua动态没得说,Kong增加了控制平面的动态能力,差就差在Kong是几个东西组合的,大而全,但不小也不美,配置部署都麻烦。 Krakend:这个是个欧洲公司,小众,golang,插件支持Lua与Golang,性能说是比Kong高,有很技术后发优势,小而美,自带UI。但生态上还是和几个大哥差太多了,怕半路夭折了,长期观望。 Envoy VS Traefik C++ VS Golang WASM插件 VS Golang插件 小而聚(无控制) VS 小而全(自带UI) Envoy WASM插件: https://github.com/envoyproxy/envoy/tree/master/examples/wasm-cc BodyRewrite的流程,弄了一遍,总体不算太痛苦,哭在写C++上比较烦,当前还支持Rust,所以不算缺点。 本身插件是WASM文件,如果支持容器,还需要一些繁琐的步骤。据说性能目前还不行。可以先用Lua。 这里是Hub的生态,还比较冷清 https://docs.solo.io/web-assembly-hub/latest Traefik插件: https://github.com/traefik/plugindemo Golang的开发成本更低,写起来比较快,动态性上差点。 Plugins的生态更冷清。

软件的生死

软件是有生命的,最终走向EOL。 那如何定义软件的“衰老”呢? 是功能不够用,满足不了需求?还是功能太多,架构太复杂,无法维护呢? 显然是“后者”,如果一个软件因为功能不够用,满足不了需求,那么它连“成长”的机会都没有。 所以我这里指的软件都是在市场成功后,快速下滑的。 这种经过“年富力强”,最后走向“衰老”,而且几乎是必然的。 软件产品经理的诞生是业界挽救“衰老”的已经验证的成功经验。 并不是产品经理有能耐,不然也不会说“人人都是产品经理”。 产品经理的角色设定,真正改变了软件需求的供需关系。 产品经理折射的玄学 没有产品经理的时候,程序员会根据自己的喜好开发软件系统,产生了大量“假设需求”,“万一需求”和“将来需求“,这些会使软件系统“衰老”加速。 为什么有独立产品经理时不同呢,因为产品经理要间接麻烦程序员开发需求,所以产品经理的大量“假设需求”,“万一需求”,“将来需求“没法都给到软件开发人员,只能低三下四次给几个,就在筛选这几个需求的过程中,“需求控制”的意义达到了。 没有哪个程序员愿意在高强度工作下,还能把产品经理的“假设需求”照单全收,都是推三阻四,提三个留一个,并不会都收下还连夜加班多送两个。 当然要达到这种控制的平衡,产品经理和程序员地位一定是一致的,虽然有“经理”二字,但一定是平级,否则悲剧还是会重演。 如果没有产品就没办法了么,有! 那就是程序员的“克制”,自己克制对技术完美,架构完美的追求,克制对假设需求,万一需求,将来需求的恐惧。敏捷理论的“拥抱变化“并不是鼓励“需求变更”,而是说“将来”真的到来时再考虑这个需求。 程序员的克制 除了产品经理,玄学,还有几个方法: 让程序员自己实现自己提出的需求 让程序员自己测试自己开发的系统 让程序员自己维护自己开发的系统 DevPM,DevOps,DevTest 这不容易实现,其实就是独立开发者。 所以也不难理解独立开发者的软件水平要高与团队系统一个等级,独立开发者的时间开销和收入也必然要求他做最有价值的需求。 比如张小龙当年的Foxmail,最后变成了PM头子还能把微信需求把持得这么好。 现实情况下一个大系统一般不可能一个人开发,除非克服人性,极度“克制”。 当然一个没有产品经理的团队也要学会“克制”,“克制”软件系统在当下的需求。 预言 最后预言一下Hadoop全家桶快走向“死亡”了。 不是因为它不支持什么功能,而是支持的功能太多,引入组件太多,架构复杂,依赖复杂,维护困难,性价比低。 一个刚过“年富力强”的软件系统,过于贪婪,膨胀太快,“死亡”只会来得更快,拭目以待。

下下下一代防火墙关键技术漫谈

防火墙到底几代了? Siri:“抱歉,很难回答你的问题”。 防火墙虽然是个网络设备,但其功能不需要与其他防火墙之间互联互通,所以没有“互联”标准化的诞生。 防火墙是在一个L2/L3网络设备基础上叠加不同的功能的软件系统,“功能”的标准化最后只停留在了“营销话术”,“第三方认证评级”,“市场调查机构”,“等保国标”的手上。 但有一点不可否认,相对上一代,下一代防火墙其实是“下一层”防火墙,将对网络流量的认知深入一层。 如果说ACL,五元祖的防火墙规则是第一代,那么相当于3层,网络层。 其下一代,状态防火墙可以认知TCP三次握手,位于4-5层,传输和会话层。 再下一代,UTM防病毒等认知到了应用数据,位于6-7层,应用层。 那下下下一代呢,已经超出网络的层次了,那么合理的推论就是在,在以上几代都检查不出来的情况下,认知对用户业务的威胁。 所以下下下一代算是目前看到防火墙的终极形态了。 如何理解针对业务的威胁? 这个看起来是个玄学,因为这个层面上已经没有了协议的约束,所以是道“主观题”,还是文科的。 “主观题”在市场营销上可谓随意发挥,各种危机案例,骇人场景,人工智能,深度学习都上了。 但真正的工程角度,还是要把文科“主观题”转化给理科的“证明题”。 如何证明这道题目呢?既然我们知道主观因素很多,那么人的因素增加大,理解业务的深度和广度增大了。我们需要 更加深入灵活的规则 更深更广的数据支撑 更全面及时的情报 更智能的分析逻辑 所以最终这题关键考点“数据分析”。翻译成“人话”就是“找规律,找不同”。 比如:张三总是半夜访问,和正常人不同。李四像个机器人,每天都是固定模式读图。 工程与技术如何选择? 大数据分析,机器学习,深度学习技术在过去10年有了一次越迁,技术层出不穷,但落地到安全场景是否合适? 抛开市场营销不说,只谈干货。安全领域需求是主要分类“正常”与“不正常”的问题。 深度学习:基于神经网络技术,用于自然语言理解,图形图像视频识别,语音识别场景,其都是人的感官模拟。 看过一些论文将网络流特征弄成图片,然后做图像学习,感觉明显画蛇添足。虽然用了深度学习,其效果比传统机器学习还差。 目前我才疏学浅,还没认知到基于流量的安全领域使用深度学习的必要场景,而且人因素最大,算力资源要求也最大。 (补充: NPL可用于URL参数注入分析场景) 机器学习/大数据分析:相比统计规则,机器学习相当于在一定公式下进行最优解查找,找到最合适的参数。方法也很多。 但也都需要“训练”过程,这个过程在防火墙设备中进行目前还不是很适合,因为需要人指导,但训练后的模型进行“预测”完全可以在防火墙中进行。 目前我觉得决策树及其衍生模型,包括随机森林,GBDT均适用于实时预测,可以使用的工程框架如 XGBoost 的 C++ 版本。 其可行性论文网上已经有很多。 关键技术指标在哪里? 首先防火墙都是以性能指标为参照,实现相同功能下以硬件代价小(成本)性能高为竞争力。 除了算法的领先,需要在架构上领先。无论使用机器学习,还是统计规则,都要在比过去大几个数量级的数据下提取特征为基础的。 也就是“数据量”与“计算速度”还有“灵活性”的能力要超过上一代。而这三者关系却是互斥的,需要做减法。 既然是“数据分析”是关键,我们看看现在有的技术Hadoop生态,显然可以处理大数据量,但是速度慢,成本高。 后起之秀 Spark / Flink 解决速度问题,但还是基于Hadoop生态,是一个通用框架,灵活性上更好,性能还是太慢。 而下下下一代防火墙被限定在一个固定输入的“数据分析”系统下,显然灵活性可以牺牲一些,数据量也可以牺牲一些,但速度绝对不能妥协,因为防火墙是嵌入在关键路径上的。 首先需要一个通用的深度解析引擎,能灵活将业务字段从流量中提取,显然当代防火墙都已经具备。 然后需要一个通用的计算分析引擎,能够缓存大量的关键数据,然后根据规则进行计算。 基于状态管理的流计算分析 首先这个不是新东西,做过状态防火墙的都知道,流表(Flow Session Table)就是基于流或会话关系的状态管理。 从会话产生,状态变迁到结束的过程,需要符合一定规律,这个规律是网络协议定义的,所有的检查都是基于这个状态进行叠加的。 对应到业务风险就是对业务状态的管理,一般来说正常人在线完成一个业务的平均值为30分钟以内。所以通常这个数据量只需要1个小时即可解决90%的场景,数据量的问题被减掉了。

Servicewall是“疫苗”公司?NO

Servicewall是家什么公司? 公司成立于2018年5月,并获得了由北极光等著名VC联合投资,公司创始团队由来自美国 Netscreen、American Express 等知名企业的专家组成。Servicewall结合设备指纹,数据加密,大数据,人工智能等技术致力于为中国客户提供专业化的在线反欺诈服务。 解决什么问题? 从需求角度就是解决这个决策树上的问题,把业务风险识别出来,并提供有效的消除方案。 如何解决? 方法,工程,和我个人对系统的理解。 方法: 通过有效的设备探针检测用户终端环境,收集非敏感信息,如硬件属性。 利用数据分析,机器学习等技术将人与机器的特征区分开。并在特定业务领域下,分析用户的行为,识别潜在风险。 提供串联,旁路等软硬件方案,实时解决业务过程中的风险 灵活的组合和接入方案,满足业务场景的变化和客户的私有化定制需求。 工程: 想解决好这些问题,在工程上其实有很多的挑战 设备探针如何加密不被破解? 大数据平台Hadoop / Spark实时性低,如何实时获得结果? SaaS服务与私有化服务器架构如何保持一致? 无网络环境如何快速无依赖部署? 私有化环境数据平台如何无人值守运维? 如何平衡分析结果的准确率与召回率? … 等等,虽然是新领域,但所有的问题都不是独特的,我们拥抱新技术,勇于探索,大胆尝试,创造黑科技。 至少有以下特色: 云原生,微服务:真Docker全容器化,包括基础设施组件,甚至数据平台。 Java / Golang技术栈:兼顾开发效率,稳定,性能的新老搭配。 节制的数据平台:追求数据的性价比,不浪费。Spark / Clickhouse。 基于事实的分析理念:不假设,简单有效。“如无必要,勿增实体”(Occam’s Razor)。 我的理解 系统中有一个“防火墙” 和“分析平台”,或者说是一个“数据平面”和一个“控制平面”。 数据平面可以串行部署在用户业务线上,所以要稳定可靠,性能高,功能不能太复杂,是系统的“肌肉”。 控制平面有智能,配置灵活,是系统的“大脑”,与数据平面不强耦合,可以独立升级规则,版本。 两个平面形成一个完整的反馈系统,通过强大的“神经”(控制通道/RPC)和“血管”(数据通道/MQ)链接。 而数据则是打通系统的“养料”,数据分析系统都是长出来的,没有真正遇到过“病毒”怎么可能产生健康的“免疫机能”呢? 仅用假设是做不好安全,问题总是出现在未知的地方。这里我们在这个方向上积累了2年多,用很多事实问题的抽象了不少模型,算是“疫苗”研制初见成果吧。 有了有效的“疫苗”可以迅速解决客户问题,当然在业务安全方向,“病毒”也随着技术的进步,进步很快,对抗“病毒”升级是业务安全的常态。 所以我们不仅仅是“疫苗”的搬运工,而是给用户提供一套完整的注入已知有效“疫苗”的智能“免疫”系统。 广告时间 目前Servicewall已经在“疫苗”量产的路上,客户数量也在稳步提升,为了更好的支撑客户和改良系统,我们需要更多的伙伴加入。 后端开发工程师 负责产品功能、后端服务接口的设计与实现。 具备 3 年以上服务端开发经验,具备扎实的计算机专业基本功; 精通 Java / Golang,擅长分布式系统设计与开发,熟悉函数式编程,对 JVM 原理有一定的了解; 掌握常见的缓存、消息等机制,熟悉 IO/NIO、多线程、集合等基础框架; 熟悉 Spring Boot、Kafka、Redis、MySQL 等开源服务框架或组件;

关于规则引擎的思考(3)

做一个安全风控的引擎,用规则配置,需要能够自反馈。所以也不是一个简单的规则引擎。 也就是实时引擎 + 离线引擎两个部分。或者说是 数据平面 + 控制平面也行。 实时引擎在业务流量上处理,离线引擎给实时引擎提供弹药。 实时引擎: 逻辑匹配70%:if else 有状态的计算30%:虽然比重小,但实现麻烦。 state管理的流式数据计算。原理参考Spark,Flink,但又不是通用系统。不能用Spark,Flink是需要同步做决策,Spark,Flink显然不合适。 https://spark.apache.org/docs/1.6.2/api/java/org/apache/spark/streaming/State.html 有需求边界夹持,可以做的更快,更小。 举个例子:状态防火墙中的session table,以IP五元祖为key,其中一种状态是tcp状态。 我们使用数据流式处理如何实现呢 key: ip 5-tuple state: 就是tcp状态顺序,在一定生命周期下统计,有明确开始(create),和退出时机(remove)。 def sequnceFunction(ip, tcp_action, state) := { if (state.exists) { if (tcp_ack == FIN_ACK) { state.remove() } else { state.update(transState(tcp_action)); } } else { state.update(initStatinitState(tcp_action)); } 这个例子的状态比较具体,如果抽象一些,这个状态大概分为这些 https://ci.apache.org/projects/flink/flink-docs-stable/dev/stream/state/state.html 状态 场景 需求 ValueState 单值统计 需要 ListState 序列统计 需要 ReducingState 单值 不是简单累加,比如求唯一数量,可以用近似算法HyperHyperLog,这样就变成单值 AggregatingState 复杂统计 Reducing 和 ListState更复杂的表达,目前不需要 MapState 二维矩阵 目前不需要,场景上可以用预测接口PMML替代 实时引擎要有嵌入机器学习模型的能力,使用PMML。