有什么 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 |
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) |
//关联 |
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 |
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 |
2 |
=hotData.select@b(orderdate>=max(pBeginDate,hotcoldLine) && orderdate |
3 |
=A1|A2 |
4 |
=A3.groups@o(year(orderdate):y ;sum(amount):s) |
在高性能大数据计算方面,SPL还具有倍增分段、双向索引、预汇总、自动负载均衡、备胎式容错等技术,不展开说了。
英文版