【问题标题】:C#: Slow inserting with Cassandra DatabaseC#:使用 Cassandra 数据库缓慢插入
【发布时间】:2018-02-26 06:57:25
【问题描述】:

我正在尝试将数百万条记录插入 Cassandra 数据库,甚至可能有数十亿条记录。有没有更快的方法来做到这一点?每个文件需要 30 分钟,我有 100 多个文件。我需要遍历某个目录中的每个文件并遍历所有行,并将每个文件的每一行插入到 Cassandra 数据库中。这些文件的大小从 1KB 到最大 300,000 KB 不等。

我指的是9734KB,已经处理了30分钟没有完成。当然必须有一种更快的方法来插入记录?其处理的文件有 942,345 行。

按照这个速度,插入所有这些记录需要几天时间。

在有批次和没有批次的情况下都试过,速度都一样(大致)

Console.CursorVisible = false;

var cluster = Cluster.Builder().AddContactPoints("127.0.0.1").Build();
var session = cluster.Connect("cracking");

Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine();
Console.WriteLine("  [" + DateTime.Now.ToShortTimeString() + "]" + " Connected to the Cassandra Database");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.White;

string filepath = @"C:\Users\admin\Desktop\wecrack lists\test";
DirectoryInfo directory = new DirectoryInfo(filepath);

int fileCount = 0;

foreach (var file in directory.GetFiles("*"))
{
    fileCount++;

    Console.WriteLine("  [" + DateTime.Now.ToShortTimeString() + "]" + " Working through file: {" + file + "} {" + fileCount + "/" + directory.GetFiles("*").Count() + "}");

    var lines = File.ReadLines(filepath + @"\" + file.ToString()).ToList();

    var batch = new BatchStatement();

    int lineCount = 0;

    while (lines.Count > 0)
    {
        foreach (string line in lines.ToList())
        {
            if (lineCount >= 2000)
            {
                lineCount = 0;

                Console.WriteLine("  [" + DateTime.Now.ToShortTimeString() + "]" + " Changing batch for file: {" + file + "} {" + fileCount + "/" + directory.GetFiles("*").Count() + "}");
                session.Execute(batch);
                batch = new BatchStatement();
                break;
            }

            lineCount++;
            lines.Remove(line);

            var userTrackStmt = session.Prepare("INSERT INTO passwords (id, password) VALUES (?, ?)");
            batch.Add(userTrackStmt.Bind(Guid.NewGuid(), line));
        }
    }
}

Console.WriteLine();
Console.WriteLine("  [" + DateTime.Now.ToShortTimeString() + "]" + " Finished inserting records, press any key to get the count.");
Console.ReadKey(true);

Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("  " + string.Format("{0:n0}", session.Execute("SELECT * FROM passwords").Count()) + " records.");

while (true)
{
    Console.ReadKey(true);
}

【问题讨论】:

  • 你能在你的代码中做一些关注点分离并在这里发布结果吗?即,将 i/o 操作与 DB 分开
  • 您使用哪个库来连接和写入 cassandra?
  • 您不需要批处理,因为批处理将为您提供您不需要的事务保证。只需使用准备好的语句单独发送所有插入。

标签: c# .net cassandra cql


【解决方案1】:

您无需在每次使用时都准备该语句。您应该准备一次并为每个插入操作绑定。

此外,您应该按照user23477763 的建议分离关注点。您将能够隔离创建许多列表并从这些列表的开头删除的成本。

您不需要批处理,因为批处理将为您提供您不需要的事务保证。如果不知道您的架构是什么样子,就很难知道确切的影响是什么。看看https://docs.datastax.com/en/cql/3.3/cql/cql_using/useBatchBadExample.html

另外请记住,您可以将多个插入操作并行发送到 cassandra。

【讨论】:

    猜你喜欢
    • 2019-03-13
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    相关资源
    最近更新 更多