编程魔术师-01: 函数式重塑编程世界(大数据,devops,云计算, 区块链...)

我是一个深资的函数式爱好者,研究得不深,但做过许多有趣的东西,应用在很多地方。。。
这些有趣的东西,就像成为魔术一样,让我变得自信快乐。。。
分享快乐会更加快乐,所以我很开心能够分享给大家。。。

很多人觉得函数式只是一个奇技淫巧,大多是用不上的,这里我想从心底告诉大家,函数式将无处不在!
下面开始我的表演:

  1. 极效开发环境REPL开发,尽情享受函数式
    a. 简单开始REPL在线编程
    b. 远程也能REPL在线编程
    c. hadoop集群上REPL编程
  2. 大数据引擎,因函数式而生,因函数式而伟大
    a. 定长之痛,第一代DataSet数据引擎COBOL/SAS的缺陷及思考
    b. Report之痛,第二代OLTP数据引擎Mysql的缺陷及思考
    c. 3NF之痛,第三代OLAP数据引擎Oracle/Postgres的缺陷及思考
    d: Transform之痛,第四代半结构数据引擎Hive/SparkSQL的缺陷及思考
    e: State之痛,第五代实时数据引擎storm的缺陷及思考
    f: 传统函数式之痛, 第六代函数式引擎SQL与传统函数式融合之SparkSQL On lamdba的缺陷与思考
    g: 非明细累计之痛,第七代半结构实时SQL引擎KSQL的缺陷及思考
    h: 终级挑战: 函数式引擎SQL on transducer
  3. SQL好兄弟transducer助力,一招打遍无敌手,函数式未来不再是梦
    a. javascript上跑起来
    b. java上跑起来
    c. kafka上跑起来
    d. spark上跑起来
    e. ksql上跑起来
  4. 一切数据结构尽在KV,datalog/specs保驾护航
    a. 索引查询即map, map结构及数据库rocksdb
    b. 菜单层级即tree,tree结构及数据库zookeeper
    c. 依赖关系即graph,graph 结构及数据库datomic/neo4j
    d: tree与graph积极拥抱函数式
    e: 终极挑战: tree与graph之争与转换,调度系统未来的思考
  5. 函数式终级无锁编程,这个世界突然清净了
    a. STM
    b. agent
    c. core.async
    d. zookeeper
    e. avout
    f. kafka
  6. 函数式运维,将革命野火越烧越烈
    a. 函数式编程语言nix
    b. 函数式操作系统nixos
    c. 函数式软件包nixpkg
    e. 函数式构建nix-env
    f. 函数式部署nix-store
    g. 函数式隔离nixops
  7. 函数即服务Faas,云上争霸天下
  8. 函数式区块链Cardano

一. 极效开发环境REPL开发,尽情享受函数式

相信大家对repl不陌生吧?
repl就是Read-eval-print-loop, 简单说就是边写边调,立即检查结果。。。
用过python/r/js/scala的朋友自然能感受到它的高效,现在java也抵抗不了诱惑加入了阵营。

1 单纯的repl的编辑功能比较弱,所以我们要高级一点,选择代码就运行!

image.png

2. 前面的功能确实不太过瘾。那我们在远程服务器上开个后门,悄悄连过去为所欲为如何?

a. 首先, 在服务器上拷贝安装后门REPL程序。

image.png

b. 紧接着,启动后门程序

image.png

c. 最后,我们可以对远程服务器为所欲为,为所欲为。。。
直接cider-connect连接到远程服务器:(如遇到ssh连接,请删除.ssh/know_host入口)

image.png

接着运行shell命令随意操纵远程服务器

image.png

3. 远程的操作权限于java跟clojure标准库,因为我们没有添加依赖的MAVEN库。。。没关系, maven库可以运行时添加! 事情开始变得有趣 了。。。

a. 首先在远程添加牛逼的动态maven解析库: [com.cemerick/pomegranate "1.0.0"]后启动repl后门

image.png

b. 连接到远程repl服务器,想要哪个MAVEN库就用哪个MAVENY库。。。

image.png

至此,基本告一段落了,现在已经可以随意运行各种SHELL命令,使用运行时加载各种MAVEN库为所欲为了。

4. 通过SSH开后门太简单了,我们应该把后门开到HADOOP集群上去!这么多机器其实可以拿来挖矿喽。。。

这里我们介绍一下hadoop, hadoop分为两部分: hdfs分布式文件存储 & yarn资源管理.
hdfs可以通过9000端口进行rpc接口调用。。。而yarn可以通过8032端口访问。。。
如果是HA的话,则可以通过ZOOKEEPER读取,这里不过多细诉。
正常 的HADOOP运行过程是:

  1. 本地上传JAR包及至HDFS
  2. 客户端通过向Yarn申请ApplicationMaster容器运行AM程序
  3. AM启动后向Yarn进行注册
  4. AM接着向Yarn申请executor, 得到driver的task后分配运行并监控
  5. AM根据所有executor运行的结果,返回给Yarn后退出。

那么我们怎么开后门呢?

  1. 编写我们的ApplicationMaster逻辑运行后门repl服务,打成jar包上传hdfs
  2. 通过repl启动注册服务,方便后门服务回连回来
  3. 通过repl连接至yarn,提交AM Repl后门程序,并传入监听注册中心服务地址
  4. AM repl后门程序被 yarn随机分配到集群上启动后,通过参数回连到repl进行服务注册。
  5. 我们本地的repl服务连接到回连注册的repl服务器上,发送代码对hadoop为所欲为...

代码示例如下:
a. 编写repl后台服务并打包上传至hdfs(参数包含了回连的注册服务器地址):

image.png

b. 通过repl启动注册服务供远程后门回连

image.png

c. 通过repl连接至yarn,提交并运行AM REPL后门程序


image.png

d. AM REPL后门回连至注册服务(属于a过程中代码)


image.png

e. 对回连注册的AM REPL后门,发送任意代码至远程服务器执行


image.png

由于时间关系,后续将会进一步对其进行代码整理,思路大致如此.

二. 大数据引擎,因函数式而生,因函数式而伟大

自从Hadoop的MR框架出现以后,大数据便以燎原之势迅速占领了数据处理的主战场。
随后storm流式框架以及spark批量引擎的出现,将函数式编程推向了至高点。

也许你要问,Hadoop跟函数式编程有啥关系?
如果你稍弱了解一下,将会知道map以及reduce是函数式最基本的功能。
map是单行处理数据,如果进行过滤,则产生了一对零操作filter,如果进行explode分解,则进行了一对多mapcat/flatmap操作。
如果需要跨行操作,则是需要进行reduce处理。
所以map + reduce,就是先逐行处理,然后进行跨行处理,单行处理不关心状态,多行处理往往伴随着状态。
跨行过程中,如果在分布式集群中,又涉及数据 的洗牌shffle或者 重分区repartition操作。

是不是感觉很熟悉?因为spark的基本API就是map, filter, flatmap, reduce操作...
如果熟悉storm trident机制,接口也是完全对等的。
除了数据处理操作之外,还有任务依赖的处理,那就属于图的概念了,后续将会详细介绍。

最近随着一股SQL On lambda之气,presto以及spark选手纷纷上场。
clojure更是推出通用复合性引擎transducer,一统所有模式。
实在不得不感叹到:

大数据处理,非函数式不破也!


本人从工作后一直从事数据搬运工工作,
玩过SAS/COBOL, MYSQL, Oracle/Teradata/SQL server/PostgreSQL, Hive/SparkSql, Storm, KSQL, Presto各种工具,
所以很清淅地看到了数据引擎发展的轨迹。也看懂了数据处理各阶段的难题。
当然每一代都在一起发展,所以这里的区分也不一定严格。

1. 最早的一代属于COBOL跟SAS。

也许你没听过COBOL,那你听过BUG这个词吧?那你听过JAVA吧?那你听过ATM取款机吧?
没错,BUG就是COBOL之母发明的,当时的COBOL就如当前的JAVA如此火爆,那怕是现在的银行核心系统以及ATM上的代码很多都是从COBOL诞用,延用直今。并且COBOL是完全面向人类习惯设计的语言,所有保贬不一,争议极大。
紧接着统计分析工作越来越显得重要,面向统计分析的SAS软件也面世,它的数据处理功能也是非常强大的。
那时候的数据格式都是长度固定的,所以处理性能极高。但是模式是不可改变的!
那时候的操作都是原生数据处理操作,所以开发效率极高,并且很灵活。
当然SAS通过内置一些基本的RPOC操作,加大了复用性,但是每一个功能都得自己做一步步来,一遍遍处理。
所以很多人写SAS不耐烦了,直接调用它的PROC SQL引擎以SQL方式处理也不为过了。

这一代的问题,是最基础的问题。

  1. 擅长处理定长文件,所以对模式扩展不友好,变长或者稀疏不太好搞。
  2. 开发效率过低,由于采用的原生的代码方式,对于多种操作的组合性不强,代码理解力极差。
    比如要同时计算前十跟后十的计算,同比与环比的计算,移动平均值的计算。。。
    要想一次处理所有逻辑,各种变量转移逻辑异常混乱

最终的结局:
数据模式及编程模式较为固定,故最终在特定领域发挥较大作用。
COBOL面向业务逻辑,SAS面向统计分析。

行业发展:
随着SQL时代的到来,通用性的引擎开始发光发热。

2. 第二代,关系型数据库Mysql开始登场

这时关系型数据库开始诞生,大部分用在OLTP事务处理上。
有了SQL引擎,不管怎么样,对于第一代有了明显的进步。
开始有了函数与聚合函数的概念,是不是跟map/reduce有点像?
函数及表达式 <=> map, where <=> filter, 多次insert<=>mapcat, group by <=> reduce。

所以简单看来基本的数据操作功能也算是有了,那么它到底还弱在那里呢?

  1. 分析功能太弱。比如我想算每个组排名前十的逻辑 ,需要自join才能处理好。自join随着数据量的增大带来了极大的性能开销。
  2. 数据量过大性能下降厉害,这个后期发展自然有分片机制发展,但是OLTP对于大数据处理,还是存在较大的问题。
  3. 灵活度差,相比于第一代系统一次遍历混乱搞定多个功能 来说,代码是清晰不少了,但是性能也下降了。这里组合功能不弱,而是只能对于标准模式进行组合,组合自由度下降了。比如同时比多个维度处理,分别计算每一级维度的汇总值。

最终的结局:
常用的事务支持非常优势,对于历史性数据分析,性能极差,甚至影响OLTP系统。
对于OLTP查看历史数据报表,甚至可以引起生产环境DOWN机的情况 发生。
这样,所有早期的系统会进行历史数据于当前数据区的划分,就是为减缓历史区对当前区所带来的负担。

发展:
ERP系统开始出现,DW+BI系统开始出现。新的OLAP引擎开始主载数据战场。OLTP+OLAP完成分离。

3. 第三代, 主要以Oracle/Teradata//PostgreSQL为代表。

应该是人们眼中传统的BI解析方案。SQL Server由于其经济性,在数据量不是很大的情况下,也是占领了一部分市场,影响力稍少。

这一代引擎的特点是,为分析而生。所以常用的分析强能80%以上都能轻松解决,哪剩下的呢,后面再说。

前面讲了多维度聚合的问题,它们有了grouping sets, cube, rollup去支持。
还有窗口状态自定义,它们有了leading, lag, row_number+partition by去支持
递归功能有了connect by, with recursive支持。

看起来接近完美 了。 真的是这样吗?
让我们一起来看一看它的弱点吧。

  1. 分析性能较差
    传统的SQL出生于存储资源比较宝贵的年代。
    所有的数据都是分离了,之间的关联则是通过主外键动态连接的,最终不断地加工直至产生所谓的"宽表"
  2. 状态管理仍然不够灵活
    虽然引入了窗口管理机制,可以引入不同层级的窗口进行跨行方面更细粒度的管理,但从本质上来说,并不能灵活定制。
    仅仅只是实现了常用的环比,占比,排名之类的功能 。对于递归功能也是挺无奈,只是简单地进行关系关联。
    但是分析功能的出现,在很大意义上提升了OLAP的实用性。
  3. UDF开发极其困难。
    由于分析功能以及内部SQL引擎的复杂性,大部分并没有开放期UDAF接口,仅支持简单的非状态化的MAP逻辑。
  4. 反人类的三范式。
    三范式一方面有了第一步所提到的数据分离问题,另一方面由于其原子性上的静态特征破坏了数据的结构性。
    a. UV算法难题。
    比如,一个用户,进行了多次的记录访问,从分析的本质上来说,其实都 是用户的访问分析,应该在同一条记录上。而在关系型数据库中,必须存成多份,这就产生了臭名昭著的”UV算法难题“。如果要计算一年的UV,那么要把所有的明细计算提取出来去重计算才行! 而不采用关系型存储形式,所有的用户记录通过函数提取访问记录结构体简单计算即可得出。
    b. 历史拉链算法难题。
    比如,一个用户,进行了多次状态的变更,从分析的本质上来说,其实都是用户的状态结构,应该在同一条记录上。而在关系型数据库中,甚至还需要闭链操作去处理跨行的状态管理 ,加上拉链修复难题,简单是惨不忍暏啊!这个本质上来写个函数提取一下状态数据结构就能解决的事情,但是它们做不到啊。

发展:
由于三范式引起的结构破坏,以及UDF开发困难,状态管理之难题等。新一代的半结构化数据开始逐渐登入舞台。
而真正的函数式技术由于其状态管理的高度自由,函数功能组合的高度自由 ,数据结构组合的高度自由 ,开始发光发热,呼风唤雨,天下大势,仅函数式是也!

第四代, 半结构化引擎HIVE为函数式之道义攻破关系型数据库的城门!

从传统OLAP发展得漫长岁月里,人们慢慢感觉到了它的局限性。
整个IT世界的,数据格式亦从最基本的CSV格式慢慢过渡到了JSON。

这说明了一个道理:数据之间的关系越来越紧密了。

所谓的数据关系,用专业角度来说,就是denormalize,反正则化。
一旦反正则化,好戏就要开始了,作为组合数据中,最基本的二种数据结构,MAP跟ARAAY登场了。
当然有人说还有STRUCT结构,STRUCT结构本质上等同于已知键模式的MAP,殊途同归。。。
这里已经能清楚看到了,MAP跟ARRAY是函数式的基本结构,可以不停地组合并多层级转换。

而函数式天生从骨子里就擅长干这个。

即然denormalize之后,数据组合在一起之后,多个表结构密集在一起了。
这个时候的数据模式,必定是多级的。HIVE在此种背景下应运而生。

为了支持模式的多样性,HIVE采用了SerDe来自定义数据的读取转换,对于数据的collect及explode操作
因此打开了半结构化世界的大门。
另一方面,由于模式的多样性,必然引入了复杂度。
所以当前主流的关结构化引擎都采取了自建门户的模式,比如HIVE采用ORC, SPARK采用parquet。

诸子百家,好不热闹,数据行业由于半结构化的到来,重新显示出了一片繁荣。

当然所有的核心结构依然是MAP跟ARRAY,互联网连接依然以浅模式JSON和深模式AVRO格式互连。

在新的半结构化世界里,表模式就是STRUCT结构,关系则以MAP结构组织,一对多则用ARRAY结构打包。

有了可自由组合以及自由扩展的数据结构,处理这些数据结构的逻辑也是非常急需的。

所以,慢慢的HIVE开始显示出不适应,而spark则以函数式为核心慢慢占领了主战场。

所以这一阶段处于先行军,所急需解决的问题也是不少。

  1. 最重要的一点,当然是对于数据结构的处理引擎。
    hive这个引擎提供了UDAF(自定义聚合函数)的接口,可以说是打开了一个新世界。但是由于HIVE本身的类型系统不完善,最终致使HIVE这个功能非常难用。最终HIVE只能妥协,提供了collect的方法将跨行的状态累积起来编写UDF处理。这本身会消耗大量内存,但也是一种可以使用的临时解决方案。既然可以用UDAF COLLECT函数之后用UDF来处理,但是对于JAVA编程来说,处理半结构数据也是比较吃力的。
    spark引擎在HIVE的基础上稍有增强,有RDD方法跟SQL方法 。Spark SQL方法本质上是传统OLAP的继承,采用窗口状态模型,所以对于半结构化数据也是非常无力的,直至最近的2.3 版本开始支持SQL on lambda,当然这是后面的话题了。当然, spark还是有退路的,spark提供了RDD提供底层接口供自由编程。Spark RDD是将函数式编程的方法分布式化,提供了核心的map, filter,mapcat/flatmap.reduce功能, 但是Spark RDD这种思路也是有问题,它的函数式组合能力太弱,因为reduce功能涉及状态管理,所有同时做sum与count处理就没有SQL那么强大,而sql on lambda就是将这些功能集成在sql上,一定程度上解决了这种问题。
  2. 数据引擎的统一性。
    对于大数据处理,依然会有人使用HADOOP MR + HIVE UDF处理,新一点的则是Spark RDD + Spark SQL。这说明了两种模式的互补性。底层的函数式引擎能灵活处理各种问题,但是编码开发困难,复用性差。而上层的窗口状态模型依然存在传统OLAP所面监的问题,状态管理模式具有一定的局限性。随着hive把半结构化数据推上了OLAP上,传统OLAP引擎已显得苍白无力了。所以需要编写大量的UDAF来处理。UDAF状态管理模型与传统OLAP的冲突,最终导致了新的两代引擎诞生: 实时引擎 + SQL-on-lambda.

发展:
前面介绍了半结构数据的发展诞生了两个分支: 实时引擎以及SQL-on-lambda。也许有人不明白了,这两者有什么联系?
对于实时引擎来说,既然状态不好处理,那我们专心去处理状态。
而对于大量的OLAP来说,放弃窗口模型状态是不可能的!我们把函数式放在SQL上来用!
两者都是函数式原型的代表,第一种代表了函数式引擎 transducer的发展方向,第二种代表 了传统函数式的高阶函数操作。
从未来发展上来看,实时引擎的路更好走一些。
因为随着半结构化数据的成熟,所有的数据只需要遍历一次,管理 好状态就能得到结果。
现在的数据处理模式也在往这方面发展,达到”MapReduce边转换边聚合,Explode多维状态分解提取结果“。
接着,我们一一介绍。

第五代,实时引擎重新定义OLAP。

我们把实时引擎放在第五代,还不是SQL-on-lambda是有原因的。
在半结构化数据没有到来之前,就有实时引擎开始活跃。但是随着半结构化数据的到来,更加加剧了它的发展。

从技术上来说,主要有两个原因:

  1. 半结构化减 少了数据之间的分离,而实时处理对于表的join是很有局限性的,后期的KSQL很大程序上解决了这个问题
  2. 半结构化增加了状态复杂性,由于半结构化到来,传统的OLAP的状态管理不是特别适应,需要更灵活地解决方案。

从业务上来说,实时引擎有着极强的业务需要性。

对于传统的ETL流程,一天跑批对于急剧变化的商业世界也不再适应用。
所以大量的OLAP需求从1天转为1小时,接着10分钟,接着1分钟,最终形成了微批量!
微批量就是传统的OLAP模式,这种模式在很大程度上解决了很多问题,也在一定程度上限定了技术的发展。
微批量有很大的局限性,批量调度更复杂,作业间并行影响更复杂,编程模型更复杂。

商业上实时处理引擎最早出现的就是STORM引擎,它是由函数式编程语言clojure开发的。
如果读者读 到这里,应该不难承认,函数式已经占领了数据引擎战场。

实时处理引擎面临的问题也很多。

backpress回压技术,严格一次处理,tupl DAG依赖消息重发,状态管理。
上面提到的核心点,状态管理 。
对于严格一次来说,STORM处理得比较复杂,采用了微批量方式,按批次发送后补充发送完整,达到至少一次,接着将数据按照事务ID进行Persistent到外部存储,达到严格一次。在persistent过程中,引入了窗口状态管理机制。
所以,storm分为两派:
一派是单tuple执行自由状态管理,所有编程需要自己完成,可以通过数据间的依赖树进行消息重发
另一派相似于spark,通过外部管理状态实现窗口状态管理 ,失去了底层的灵活性。

所以,初期的storm模型的基础问题就在于以下几点:

  1. 状态管理要么太低级,要么太封闭。
    如果采用最原生的tuple模型,需要大量的编码。而如果采用trident微批量形式,则状态管理其实是OLAP的这种微批量窗口模式。
  2. 状态管理需要外部系统侵入,低层接口与微批量接口的不一致严重损害系统的扩展能力。
    前者状态比较自由,所以需要配合redis或者hbase进行状态持久化。后者状态比较封闭,则需要使用专用的接口去调用函数式接口编程。这两者的分离,加上外部状态管理 的耦合性,使流式计算扩展性大大削弱
  3. 流式系统的join操作
    由于大部分平台的数据还处于3NF模式,所以不可避免存在JOIN的操作。即使denormalize之后,对于关联性不强的实体,依然是会有这种需求。所以呢,流式系统必然要实现join的操作
  4. 模式系统支持
    由于早期的实时引擎需要管理状态,并且依赖于外部系统,所有的数据处理过程均采用编程模型完成,最终代码 没有模式支持,均靠API接口实现。

发展:
实时引擎发展越来越壮大,对于状态化管理 ,越来越多的方案出来了,并且实时引擎上面SQL平台也开始成熟起来。
随着函数式技术的进一步发展,可自由组合状态的transducer技术也开始横空出世,独领风骚,未来不可预期。。。

第六代,SQL与传统函数式融合之SQL On lamdba,持续发力中。。。

对于半结构化的到来,一方面函数式热不可挡,另一方面传统的函数式对于状态管理复合性过弱。比如,同时进行sum跟count操作。SQL引擎本身类似于流式引擎,是单条处理的,所以在固有的窗口状态模式下,是可以得合的,所以是可以同时进行SUM跟COUNTR的,这就是流式处理模式带来的好处,而传统的函数式采用的是映射式模式,对于状态复合还是理解不到味,以致于后面的transducer出世成功解决了这一点。
现在有了SQL,可以做基础的窗口状态管理 ,有了lamdba/reduce高阶函数,去处理半结构化数据进一步细化定制管理状态 。

一切看起来非常得完美 了。

然而呢,我们还需要往前走,往前看。

对于半结构化数据处理, map/reducel的lamdba转换只是函数式的基本功能!

前面已经论述过,lambda在一定程度上复合性太弱。哪种复合性?
首先你在SQL上能同时计算sum跟count了 ?可是如果lambda上面有这种需求呢?
当然你可以用SQL分别计算 之后通过lambda组合起来进行引擎的互补。
但是呢,函数式很多高级的操作,SQL是没有的。
比如我要计算半结构中上下级关系,lamdba复用性就跟不上了。
这么多年SparkSQL跟hive在半结构化进程中发展缓慢,很大一部分就是因为半结构化转换逻辑具复合实现难度太大!
当然有了SQL on lambda,我们的状态管理自由了,总体来说算是进步很大了。。。

所以,我们总结一下SQL on lambda的缺 陷.

  1. 数据处理逻辑 的复合性。
    数据处理逻辑的复合很大程度上取决于状态的复合,在SQL一定的状态复合机制下,SQL on lambda会有较大成功的概率,因为一方面它吸收了OLAP模型,另一方面引入了半结构化与函数式处理机制,在一定程度上能很高效的解决问题
  2. SQL与映射函数式模型的不一致性
    它的函数式功能还处于基础阶段,传统的函数式采用了sequence的映射机制,没有完善的状态复合功能。对于没有复合状态的传统函数式,想在半结构转换中组合状态,难度真不是一般的大啊!
  3. SQL与函数式的融入性
    对于函数式处理深层级结构的自由灵活编码方式,在SQL也不一定能成功地融入进去。当然非常值得人期待。

发展:
由于函数式在商业模式中仍处于起步阶段,这种风险小,效果显示的方式会被 大多数数据引擎所接受。
像很早之前presto查询引擎就率先加入了此阵列,不难想像,传统OLAP也会慢慢转移。

第七代,半结构实时SQL引擎KSQL,数据仓库革命者,实时数仓之领军者!

第七代引擎简单是厉害得不行,前面有Kafka流式队列的长久考验,再之后有Kafka Streams流式状态的技术突破,再加上samza流式引擎在商业应用上的广泛成熟。KSQL集一人之力,成功吸收之,并开创了第七代半结构实时SQL引擎。

它的伟大之处在于哪里呢?

  1. 模式化。传统的流式平台模式性很差,很大一部分状态由外部系统管理 。而KSQL在流式引擎存储底层就集成了模式。模式分为两种,一种是表Table,一种是流Stream,两者相辅相成,直接接成到了Kafka存储中去了!采用avro格式来实现半结构化数据结构的统一性,在整个引擎上达到了高度的简化与灵活性。
  2. 状态化。KSQL的状态处理模式非常帅气逼人。对于严格一次,KAFKA本身就有topic+offset来进行区分。对于状态的更新, kafka底层存储rocksdb直接 支持,就是那无敌的Table模式!状态还可以复合,表上再建表,开创了强大的undo机制!
  3. UDF/UDAF支持。KSQL的UDF/UDAF状态模型非常简单,成功吸收了HIVE的经验,但是又抛弃了很多复杂的机制。利用UDF/UDAF进行扩展,没难度!
  4. SQL支持。KSQL采用了熟悉的SQL模型,非常轻易地实现了窗口管理状态。
  5. 流式join处理。KSQL由于底层的Table与Stream模型,Stream-Streamg, Table-Table, Stream-Table都支持!

这样一来,KSQL要开创实时半结构数据的先行,太了不起了!
你可能要问,KSQL与SQL on lambda最大的优势在于哪里?

  1. KSQL采用了流式模型,能够很方便与函数式最新技术transducer结束,达到数据处理模式的高度一致性! transducer模型可以复合状态!当然SQL on transducer的批量引擎也是一个发展方向。
  2. KSQL对于非累计明细数据处理有着极大的优势。比如算UV,KSQL得计算所有明细数据,而KSQL的实时模型可以达到响应式效果。随着数据处理复杂度的提升,越来越多地非累计型计算会越来越多,以前OLAP解决不了的问题KSQL现在也可以处理了!

当然,实时引擎的发展不可避免有着它需要处理的问题。

  1. 流式状态处理的复杂度
    前面所学的简单的流式状态已不再话下,自然也证明了KSQL的强大性。
    但是新的变态需求还是不断显现的, 特别是对于非累计明细计算来说,UV是比较简单的概念 ,以此为例。
    本人自创了一套明细-统计分离法,对于如何标准化得融入引擎,仍在大量尝试阶段
    a. 非累计明细之任意时间段难题。(比如要计算任意时间段的UV访问数量)
    对于每一条数据,都要更新所有的历史范围的数据。
    比如从2018-01-01开始 ,接着2018-01-02,
    在2018-01-03的时候,对于所有的日期{2018-01-01, 2018-01-02, 2018-01-03}的任意日期明细计算都要进行更新。
    b. 非累计明细之维度组合难题。(比如要计算各种平台组合下的UV访问数据 )
    比如有三个平台 [A,B,C], 我们对于不同的组合就要分别计算, [A, B], [A, C], [B, C], [A, B, C], A, B, C...
    c. 非累计明细之度量值漂移。(比如对用户访问时长进行分组统计,用户的时长一直累计,有可能从一个组漂移到另一个组,当出现这种情况的时候则需要撤消先前维度的值,新增新维度的值)
    例 子还有很多,后面会写文章专门讨论明细-统计分离法。在此不再多诉。
  2. 流式SQL引擎的灵活性
    由于SQL在目录来看已经不属于关系型数据库,本质上来说是一种数据处理的语法表达,与XML有着相似的功能。
    由于此种背景,SQL中的各种子循环,以及explode操作的结合性,以及未来模式的演化性,都具有极大的不确定性。
    SQL作为一种数据表达语言,是否能真正适应未来的数据引擎需求,还是说更底层的transducer,或者 datalog之类的引擎日益发展壮大,成为新一代标准。这个自然是未来来经验了。当前,SQL还是无敌的。

发展:
按前面所描述的来说,流式引擎在实时数据仓库中会慢慢发挥具大的作用。
其中三点特别值得注意 ,一是半结构化SQL模式与复合性多层级函数式技术(lens, transducer)的深度结合,另一种是对于非累计明细的状态标准化,第三种是新型流式引擎的出现。。。

终级挑战: 新一代函数式引擎SQL on transducer

transducer是我非常喜欢的一个技术,也是应用非常广。当前也积极在研究SQL解析器,试图集成transducer功能。
如果能将SQL引擎在解析器上面集成transducer,那么它的威力是相互可怕的。
最近比较忙,这里对具体技术不做过多讲解,后续将会更新。

不经意间多次提到了transducer功能。那么我们下一步讲解的主题就是:

三:transducer重演SQL老大哥之路, 热血青春,让数据世界布满函数式的脚步,无处不在!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容