5

使用 cassandra .net 驱动程序,我们面临以下问题:当使用参数化 INSERT 插入大量行时,应用程序内存使用量不断增长:

class Program
{
    static Cluster cluster = Cluster.Builder()
        .AddContactPoints(ConfigurationManager.AppSettings["address"])
        .Build();
    static Session session = cluster
        .Connect(ConfigurationManager.AppSettings["keyspace"]);
    static int counter = 0;

    static void Main(string[] args)
    {
        for (int i = 0; i < 50; i++)
        {
            new Thread(() =>
            {
                while (true)
                {
                    new Person()
                    {
                        Name = Interlocked.Increment(ref counter).ToString(),
                        ID = Guid.NewGuid(),
                        Data = new byte[4096],
                    }.Save(session);
                }
            }).Start();
        }

        Console.ReadLine();
    }
}

class Person
{
    public Guid ID
    {
        get;
        set;
    }

    public string Name
    {
        get;
        set;
    }

    public byte[] Data
    {
        get;
        set;
    }

    public void Save(Session session)
    {
        Stopwatch w = Stopwatch.StartNew();

        session.Execute(session.Prepare(
            "INSERT INTO Person(id, name, data) VALUES(?, ?, ?);")
            .Bind(this.ID, this.Name, this.Data));

        Console.WriteLine("{1} saved in {0} ms",
            w.Elapsed.TotalMilliseconds, this.Name);
    }
}

根据创建的内存转储,托管堆包含大量小字节数组(其中大多数是第 2 代),这可以追溯到内部 TypeInterpreter 类中 cassandra 驱动程序的字节转换方法 (InvConvert*)。

您对我们如何摆脱这个问题有任何建议或想法吗?

4

3 回答 3

5

对于遇到此问题的其他任何人。Cassandra.ISession即使我通过using语句正确处理它,我在创建大量 s 时也会遇到内存问题。更改我的代码以重用单个ISession似乎已经修复它。我不知道这是否是最好的解决方案。

于 2015-02-26T18:09:09.493 回答
1

您正在为您尝试插入的每条记录创建preparedstatement。在创建会话时尝试创建一次preparedstatement。

于 2015-05-27T15:06:52.247 回答
0

如果可能,尝试使用 dispose 。也许您的垃圾收集器无法清除它们。您还应该编写 Cassandra 的开发人员。对我来说似乎是一个错误。

这对你有帮助吗?

于 2013-09-03T16:27:30.617 回答