有什么 Spark 的替代技术

HANA是常见的内存数据库,理论上足以替代Spark,但不开源这一点劝退了很多人。Sqlite是开源的内存数据库,但只支持嵌入式调用,数据量和计算性能都受到极大限制。Redis既开源又支持高性能大数据量,但计算能力严重不足,必须大量硬编码才能完成内存计算。

要替代Spark,集算器SPL是个更好的选择。

SPL是开源的大数据内存计算库,比Spark内存占用更少,性能更高,计算能力更强,还可以方便稳定地实现内外存混合计算。

 

SPL提供了透明直观的语法进行大数据内存计算。启动集群的各个节点后,先用下面的SPL脚本将数据从数据库加载到内存中:

A
1 =["192.168.1.11:8281","192.168.1.12:8281"]
2 fork [[0,2000000],[2000000,   4000000]];A1 =connect("orcl").query@x("select   OrderID,Amount,Client,OrderDate from Orders

where OrderID>=? And OrderID<?"

,A2(1),A2(2)).keys(OrderID)

3 =env(Order,B2)
4 return

再用简单直观的语法进行计算内存:

A
1 =["192.168.1.11:8281","192.168.1.12:8281"]
2 =Orders=memory(A1,Order)
3 =Orders.select(Amount>=arg1   && Amount<arg2)
4 =A3.groups(year(OrderDate):y,month(OrderDate):m;   sum(Amount):s,count(1):c)

除了集群计算,SPL也支持单机服务和嵌入式调用。

SPL提供了JDBC接口,可以被JAVA方便地集成。加载的数据量一般比较大,通常在应用的初始阶段运行一次;内存计算并发大,通常要反复运行。比如,在JAVA中调用内存计算的脚本文件名:

…
Class.forName("com.esproc.jdbc.InternalDriver");
Connection conn =DriverManager.getConnection("jdbc:esproc:local://onlyServer=true");
CallableStatement statement = conn.prepareCall("{call MemoryQuery(?, ?)}");
statement.setObject(1, 1000);
statement.setObject(2, 2000);
statement.execute();
...

SPL提供了丰富的库函数,可以方便地进行内存计算,更多例子:

A B
1 =Orders.find(arg_OrderIDList) //多键值查找
=Orders.select(Amount>1000   && like(Client,\"*S*\")) //模糊查询
2 =Orders.sort(Client,-Amount)" //排序
3 =Orders.id(Client) //去重
4 =join(Orders:O,SellerId;   Employees:E,EId)
.new(O.OrderID, O.Client,O.Amount,E.Name,E.Gender,E.Dept)
//关联

SPL计算能力强大,可简化分步计算、有序计算、分组后计算等逻辑较复杂的计算,SQL和存储过程难以实现的计算,用SPL解决起来就很轻松。比如,先按客户汇总销售额,再找出销售额累计占到一半的前n个大客户,并按销售额从大到小排序:

A B
=Orders.groups(Client;sum(Amount):subtotal) /按客户汇总
2 =A1.sort(subtotal:-1) /销售额逆序排序
3 =A2.cumulate(subtotal) /计算累计序列
4 =A3.m(-1)/2 /最后的累计即总额
5 =A3.pselect(~>=A4) /超过一半的位置
6 =A2(to(A5)) /按位置取值

 

除了常规的主键和索引外,SPL还提供了很多高性能的数据结构和算法支持,比使用SQL的内存数据库性能好得多,且占用内存更少。需要HANA/Spark集群才能完成的运算,在SPL中常常用单机就解决了。

SPL支持指针式复用,可以显著节省内存。SPL的数据以指针的形式参与计算,多步骤算法、不同的算法、并发算法只是复用同一个表,而不像SQL那样每次都要复制记录。

SPL支持预关联技术,可以提升计算性能。SQL只能用复制记录的方式实现预关联,会占用大量内存,SPL支持指针式复用,加载阶段的预关联几乎不占内存。内存计算时,用"."引用关联字段,不必再进行耗时的关联计算:

=callRecord.sum(OUTID.BRANCHID.OUTCOST+INID.BRANCHID.INCOST+OUTID.AGENTID.OUTCOST+INID.AGENTID.INCOST)

除了普通的维表预关联,SPL还可以利用有序数据的特性,实现性能更高的主子表预关联。内存计算时,直接用"."号引用关联字段:

=relation.groups(year(main.orderdate):fieldyear, month(main.orderdate):fieldmonth; sum(sub.price*sub.amunt):subtotal,count(1):quantity)

 

SPL提供了名为组表的高性能存储格式,支持压缩和列存,天然有序,自带主键和索引,信息密度和计算性能远高于普通格式,可极大提升加载速度。比如,启动单机的SPL服务,将组表加载到内存:

A
1 =file("order.ctx").open().cursor@m(OrderID,Amount,Client,OrderDate)
2 =A1.memory(OrderID)
3 >env(Orders,A2)

SPL支持内存压缩,允许将更多的数据加载到内存,计算时会自动解压。加载代码几乎相同:

A
1 =file("order.ctx").open().cursor@m(OrderID,Amount,Client,OrderDate)
2 =A1.memory@z(OrderID)
3 >env(Orders,A2)

SPL支持并行计算,可充分利用多核CPU提升内存计算的性能,在计算代码加选项即可:

A
1 =Orders.select@m(Amount>=arg1 && Amount<arg2)
2 =A1.groups(year(OrderDate):y,month(OrderDate):m;   sum(Amount):s,count(1):c)

 

SPL支持多种外部数据源,可避免入库或格式转换的麻烦。除了关系型数据库,还支持txt\csv\xls等文件,MongoDB、Hadoop、redis、ElasticSearch、Kafka、Cassandra等NoSQL,以及WebService XML、Restful Json等多层数据。比如,将HDSF里的文件加载到内存:

A
1 =hdfs_open(;"hdfs://192.168.0.8:9000")
2 =hdfs_file(A1,"/user/Orders.csv":"GBK")
3 =A2.cursor@t()
4 =hdfs_close(A1)
5 =A3.memory(OrderID).index()
6 >env(orders,A5)

SPL还可以方便地实现内外存混合计算,使总体数据量远超内存。由于采用了统一的数据类型,SPL的混合计算更加稳定,代码也更简单。比如,主表orders已加载到内存,大明细表orderdetail是组表(也可以是其他数据源),下面进行主表和明细表的关联计算:

A
1 =file("orderdetail.ctx").cursor(orderid,product,amount)
2 =orders.cursor()
3 =join(A1:detail,orderid   ; A2:main,orderid)
4 =A3.groups(year(main.orderdate):y;   sum(detail.amount))

SPL可以方便地实现冷热路由或温度分层,只须付出计算性能偶尔降低的代价,就可以充分利用现有硬件实现高性能大数据计算。SPL可用统一的数据类型代表内存和外存数据,以及任意数据源,利用这一点,先将近期的热数据预加载在内存中,远期的冷数据放在文件或数据库中,之后就可以根据时间区间自动计算热数据、冷数据、或混合数据:

A
1 =connect@l("orcl").query@x("select   * from orders where orderdate>=? And orderdate<? Order by   orderdate",min(pBeginDate,hotcoldLine),min(pEndDate,hotcoldLine))
2 =hotData.select@b(orderdate>=max(pBeginDate,hotcoldLine)   && orderdate<max(pEndDate,hotcoldLine))
3 =A1|A2
4 =A3.groups@o(year(orderdate):y   ;sum(amount):s)

在高性能大数据计算方面,SPL还具有倍增分段、双向索引、预汇总、自动负载均衡、备胎式容错等技术,不展开说了。