Apache Arrow,消除序列化与反序列化的损耗,GC友好的框架

大家有没有想过一个问题,RPC的实现分两部分,序列化与反序列化协议和传输协议,其中传输协议可以用TCP/UDP/HTTP等,序列化与反序列化协议可以用JSON/XML/ProtoBuf/hessian等等,那么能不能消除序列化与反序列化的损耗呢?有没有一个大一统的协议,跨语言跨平台,一个数据结构,大家拿来就处理,不用转成对象,这样能省不少资源,这就是apache arrow的目标之一,还有没有其他的好处?当然有了,如果数据都在一起,那么cpu的缓存利用率就很高了,性能提升不是一点半点。

  • 添加依赖
<!-- https://mvnrepository.com/artifact/org.apache.arrow/arrow-vector -->
        <dependency>
            <groupId>org.apache.arrow</groupId>
            <artifactId>arrow-vector</artifactId>
            <version>1.0.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.arrow/arrow-memory-unsafe -->
        <dependency>
            <groupId>org.apache.arrow</groupId>
            <artifactId>arrow-memory-unsafe</artifactId>
            <version>1.0.1</version>
        </dependency>
  • 简单测试
@Test
    public void testIntVector() {
        RootAllocator allocator = new RootAllocator(Long.MAX_VALUE);
        IntVector vector = new IntVector("int vector", allocator);
        vector.allocateNew(10);
        vector.set(/*index*/5, /*value*/25);
        vector.set(/*index*/0, /*value*/125);
        vector.setValueCount(10);
        System.out.println(vector.get(5));
        System.out.println(vector.get(0));
        vector.close();
    }
  • 复杂场景,网络传输,可以看到写入流并转为byte数组,同样从byte数组又转回vector
    需要注意的是,这个不同于序列化反序列化,这个底层是byte数组,类似于列式存储,可以很大程度利用cpu缓存特性,如果是java对象,那么可能是散落在堆内存当中,处理数据就会慢下来。
    @Test
    public void testVectorSchemaRoot() throws IOException {
        RootAllocator allocator = new RootAllocator(Long.MAX_VALUE);
        BitVector bitVector = new BitVector("boolean", allocator);
        VarCharVector varCharVector = new VarCharVector("varchar", allocator);
        bitVector.allocateNew();
        varCharVector.allocateNew();
        for (int i = 0; i < 10; i++) {
            bitVector.setSafe(i, i % 2 == 0 ? 0 : 1);
            varCharVector.setSafe(i, ("test" + i).getBytes(StandardCharsets.UTF_8));
        }
        bitVector.setValueCount(10);
        varCharVector.setValueCount(10);
        List<Field> fields = Arrays.asList(bitVector.getField(), varCharVector.getField());
        List<FieldVector> vectors = Arrays.asList(bitVector, varCharVector);
        VectorSchemaRoot root = new VectorSchemaRoot(fields, vectors);

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ArrowStreamWriter writer = new ArrowStreamWriter(root, /*DictionaryProvider=*/null, Channels.newChannel(out));

        writer.start();
        writer.writeBatch();

        /*for (int i = 0; i < 4; i++) {
            // populate VectorSchemaRoot data and write the second batch
            BitVector childVector1 = (BitVector)root.getVector(0);
            VarCharVector childVector2 = (VarCharVector)root.getVector(1);
            //为什么要reset why
            //childVector1.reset();
            //childVector2.reset();
            writer.writeBatch();
        }*/
        writer.end();

        try (ArrowStreamReader reader = new ArrowStreamReader(new ByteArrayInputStream(out.toByteArray()), allocator)) {
            Schema schema = reader.getVectorSchemaRoot().getSchema();
            System.out.println(schema);
            while(reader.loadNextBatch()){
                System.out.println("-------------------------batch-------------");
                VectorSchemaRoot readBatch = reader.getVectorSchemaRoot();
                //拿到VectorSchemaRoot以后,就能得到值
                BitVector childVector1 = (BitVector) readBatch.getVector("boolean");
                VarCharVector childVector2 = (VarCharVector) readBatch.getVector("varchar");
                //处理
            }
        }

    }
  • 特性解析

    1. 省去大部分序列化与反序列化的损耗
    2. cpu缓存友好
    3. 压缩,列式数据存储可以实现很高的压缩
    4. 对程序员不友好,不过我们可以写工具来实现转换过程
  • 可应用场景

  1. 数据分析领域
  2. 某些rpc热点代码,场景单一切并发很高,可以用此方式优化,用来改善GC和处理速度。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值