C# 在C语言中向Cassandra插入大数据集合的最快方法#
我对向cassandra数据库插入大型集合的最快方法有点困惑。我读到我不应该使用批插入,因为它是为原子性而创建的。甚至Cassandra也为我提供了一个信息,可以使用异步写入来实现性能。 我使用的代码是最快的插入,没有“批处理”关键字:C# 在C语言中向Cassandra插入大数据集合的最快方法#,c#,performance,cassandra,batch-insert,C#,Performance,Cassandra,Batch Insert,我对向cassandra数据库插入大型集合的最快方法有点困惑。我读到我不应该使用批插入,因为它是为原子性而创建的。甚至Cassandra也为我提供了一个信息,可以使用异步写入来实现性能。 我使用的代码是最快的插入,没有“批处理”关键字: var cluster = Cluster.Builder() .AddContactPoint(“127.0.0.1") .Build(); var session = cluster.Connect(); //Save off the prepar
var cluster = Cluster.Builder()
.AddContactPoint(“127.0.0.1")
.Build();
var session = cluster.Connect();
//Save off the prepared statement you’re going to use
var statement = session.Prepare (“INSERT INTO tester.users (userID, firstName, lastName) VALUES (?,?,?)”);
var tasks = new List<Task>();
for (int i = 0; i < 1000; i++)
{
//please bind with whatever actually useful data you’re importing
var bind = statement.Bind (i, “John”, “Tester”);
var resultSetFuture = session.ExecuteAsync (bind);
tasks.Add (resultSetFuture);
}
Task.WaitAll(tasks.ToArray());
cluster.Shutdown();
var cluster=cluster.Builder()
.AddContactPoint(“127.0.0.1”)
.Build();
var session=cluster.Connect();
//保存准备好的要使用的语句
var语句=session.Prepare(“插入tester.users(userID,firstName,lastName)值(?,,?)”;
var tasks=新列表();
对于(int i=0;i<1000;i++)
{
//请使用您正在导入的任何实际有用的数据进行绑定
var bind=statement.bind(i,“John”,“Tester”);
var resultSetFuture=session.ExecuteAsync(绑定);
任务。添加(结果未来);
}
Task.WaitAll(tasks.ToArray());
cluster.Shutdown();
发件人:但它仍然比我使用的批处理选项慢得多。我当前的代码如下所示:
IList<Movie> moviesList = Movie.CreateMoviesCollectionForCassandra(collectionEntriesNumber);
var preparedStatements = new List<PreparedStatement>();
foreach (var statement in preparedStatements)
{
statement.SetConsistencyLevel(ConsistencyLevel.One);
}
var statementBinding = new BatchStatement();
statementBinding.SetBatchType(BatchType.Unlogged);
for (int i = 0; i < collectionEntriesNumber; i++)
{
preparedStatements.Add(Session.Prepare("INSERT INTO Movies (id, title, description, year, genres, rating, originallanguage, productioncountry, votingsnumber, director) VALUES (?,?,?,?,?,?,?,?,?,?)"));
}
for (int i = 0; i < collectionEntriesNumber; i++)
{
statementBinding.Add(preparedStatements[i].Bind(moviesList[i].Id, moviesList[i].Title,
moviesList[i].Description, moviesList[i].Year, moviesList[i].Genres, moviesList[i].Rating,
moviesList[i].OriginalLanguage, moviesList[i].ProductionCountry, moviesList[i].VotingsNumber,
new Director(moviesList[0].Director.Id, moviesList[i].Director.Firstname,
moviesList[i].Director.Lastname, moviesList[i].Director.Age)));
}
watch.Start();
Session.ExecuteAsync(statementBinding);
watch.Stop();
IList moviesList=Movie.CreateMoviesCollectionForCassandra(collectionEntriesNumber);
var preparedStatements=新列表();
foreach(准备报表中的var报表)
{
语句.SetConsistenceLevel(ConsistenceLevel.One);
}
var statementBinding=new BatchStatement();
statementBinding.SetBatchType(BatchType.Unlocked);
对于(int i=0;i
它的运行速度确实快得多,但我只能插入大约2500条准备好的语句,不能再插入了,我想测量大约100000个对象的插入时间。我的代码正确吗?也许我应该增加insert treshold?
请解释一下我的正确方法。记住,您应该准备一次,然后重新使用相同的
PreparedStatement
绑定到不同的参数
如果目标是同一分区,则可以使用小批量,如果不是,则应使用单个请求
当使用单个请求时,您可以并行调度执行,并使用信号量限制未完成请求的数量
比如:
public async Task<long> Execute(
IStatement[] statements, int parallelism, int maxOutstandingRequests)
{
var semaphore = new SemaphoreSlim(maxOutstandingRequests);
var tasks = new Task<RowSet>[statements.Length];
var chunkSize = statements.Length / parallelism;
if (chunkSize == 0)
{
chunkSize = 1;
}
var statementLength = statements.Length;
var launchTasks = new Task[parallelism + 1];
var watch = new Stopwatch();
watch.Start();
for (var i = 0; i < parallelism + 1; i++)
{
var startIndex = i * chunkSize;
//start to launch in parallel
launchTasks[i] = Task.Run(async () =>
{
for (var j = 0; j < chunkSize; j++)
{
var index = startIndex + j;
if (index >= statementLength)
{
break;
}
await semaphore.WaitAsync();
var t = _session.ExecuteAsync(statements[index]);
tasks[index] = t;
var rs = await t;
semaphore.Release();
}
});
}
await Task.WhenAll(launchTasks);
await Task.WhenAll(tasks);
watch.Stop();
return watch.ElapsedMilliseconds;
}
公共异步任务执行(
IStatement[]语句、int并行性、int maxOutstandingRequests)
{
var信号量=新信号量lim(maxOutstandingRequests);
var tasks=新任务[statements.Length];
var chunkSize=statements.Length/parallelism;
if(chunkSize==0)
{
chunkSize=1;
}
var statementLength=statements.Length;
var launchTasks=新任务[parallelism+1];
var watch=新秒表();
watch.Start();
对于(变量i=0;i
{
对于(var j=0;j=语句长度)
{
打破
}
wait semaphore.WaitAsync();
var t=_session.ExecuteAsync(语句[索引]);
任务[指数]=t;
var-rs=等待t;
semaphore.Release();
}
});
}
等待任务。WhenAll(启动任务);
等待任务。何时(任务);
看,停;
返回watch.elapsedmillistes;
}
增加默认批量大小如何?我有一个带有主键(ID)的表