Cassandra hector loader应用程序耗尽内存

时间:2011-08-26 13:23:03

标签: java cassandra hector

这个简单的应用程序采用带有标题的逗号分隔文件并放入Cassandra。 它适用于小文件,但内存只是在内存不足之前就会消失。

我错过了什么?

package com.company;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import me.prettyprint.cassandra.serializers.StringSerializer;
import me.prettyprint.hector.api.Cluster;
import me.prettyprint.hector.api.Keyspace;
import me.prettyprint.hector.api.beans.HColumn;
import me.prettyprint.hector.api.factory.HFactory;
import me.prettyprint.hector.api.mutation.Mutator;

public class QuickLoad {
    public static Keyspace keyspace = null;
    public static void main(String[] args) {
        File file = new File(args[0]);
        String keyspaceName = args[1];
        String columnFamilyName = args[2];
        BufferedReader reader = null;
        try {
            keyspace = GetKeyspace(keyspaceName);
            reader = new BufferedReader(new FileReader(file));
            String fileLine = null;
            String[] headers = null;
            String[] fields = null;
            boolean headerLine = true;

            while ((fileLine = reader.readLine()) != null) {
                if (headerLine){
                    headerLine = false;
                    headers = fileLine.substring(1, fileLine.length()-1).split("\",\"");
                } else {
                    fields = fileLine.substring(1, fileLine.length()-1).split("\",\"");
                    CassandraSave(keyspace, columnFamilyName, headers, fields);
                }
            }
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.exit(0);
    }

    public static void CassandraSave(Keyspace keyspace, String columnFamily, String[] headers, String[] columns) 
    {
        try 
        {
            Mutator mutator = HFactory.createMutator(keyspace, StringSerializer.get());
            for (int i = 1; i < headers.length-1; i++)
            {
                if ((columns[i] != null) || (!columns[i].equals("null"))) {
                    if (columns[i].length() > 0) {
                        HColumn<String, String> col = HFactory.createStringColumn(headers[i], columns[i]);
                        mutator.insert(columns[1], columnFamily, col);
                    }
                }
            }
            mutator.execute();
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    public static Keyspace GetKeyspace(String keyspaceName)
    {
        String serverAddress = "localhost:9160";
        Cluster cluster = HFactory.getOrCreateCluster("My Cluster", serverAddress);
        Keyspace keyspace = HFactory.createKeyspace(keyspaceName, cluster);
        return keyspace;
    }

}

3 个答案:

答案 0 :(得分:1)

如果输入文件中的某个“列”大于分配的堆,我可以将此视为一个问题。您可以通过在突变的大小上设置上限来解决这个问题。你的CassandraSave函数只能在一次操作中完成100次左右的突变。

答案 1 :(得分:1)

  

加载的“com.ecyrd.speed4j.log.PeriodicalLog”的一个实例   “sun.misc.Launcher $ AppClassLoader @ 0x899902f8”占据127,293,432   (99.62%)个字节。关键词com.ecyrd.speed4j.log.PeriodicalLog   sun.misc.Launcher $ AppClassLoader @ 0x899902f8

看起来您正在使用较旧版本的hector并遇到bug with speed4j leaking memory。如果你升级到hector 0.8.0-2,它应该是固定的。

需要注意的一点是,默认情况下,speed4j在0.8.0-2中被禁用,如果要启用它,请参阅this thread

答案 2 :(得分:1)

我看到的两件事 - 它是单线程的,批量大小非常小。

添加一个外部循环以使用批处理收集mutator中的插入 大小约500行开始,看看如何。 以下是我用于压力测试的高性能mutator插入的示例: https://github.com/zznate/cassandra-stress/blob/master/src/main/java/com/riptano/cassandra/stress/InsertCommand.java

此外,它有点旧,但这是一个方法的要点 并行加载程序与您描述的类似: https://gist.github.com/397574