我使用cassandra-c ++ - 驱动程序在100列表中写入100000行,如下所示:
#include <cstdlib>
#include <stdio.h>
#include <cassandra.h>
#include <string>
#include <iostream>
#include <random>
#include <chrono>
#include <unistd.h>
#include <thread>
CassFuture *connect_future = NULL;
CassCluster *cluster = NULL;
CassSession *session = NULL;
std::random_device rd;
std::mt19937_64 gen(rd());
std::uniform_int_distribution<unsigned long long> dis;
int COLUMNS_COUNT = 100;
using namespace std;
void insertQ() {
auto t1 = std::chrono::high_resolution_clock::now();
for (int row = 0; row < 10000; ++row) {
string columns;
for (int i = 0; i < COLUMNS_COUNT; ++i) {
columns += "name" + to_string(i) + " , ";
}
string result = "INSERT INTO mykeyspace.users2 (user_id,";
result += columns;
result += "lname) VALUES (";
string values = to_string(dis(gen) % 50000000) + ",";
for (int i = 0; i < COLUMNS_COUNT; ++i) {
values += "'name" + to_string(dis(gen)) + "' , ";
}
values += " 'lname" + to_string(dis(gen) % 20) + "'";
result += values;
result += ");";
CassStatement *statement = cass_statement_new(result.c_str(), 0);
CassFuture *result_future = cass_session_execute(session, statement);
cass_future_wait(result_future);
if (cass_future_error_code(result_future) == CASS_OK) {
// cout << "insert ok" << endl;
}
else {
const char *message;
size_t message_length;
cass_future_error_message(result_future, &message, &message_length);
fprintf(stderr, "Unable to run query: '%.*s'\n", (int) message_length,
message);
cerr << "index : " << row << endl;
}
cass_statement_free(statement);
cass_future_free(result_future);
if (row % 1000 == 0)
{
// usleep(1000000);
// std::this_thread::sleep_for(std::chrono::seconds(1));
// cass_se
}
}
auto t2 = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1);
cout << "duration: " << duration.count() << endl;
}
int main() {
/* Setup and connect to cluster */
connect_future = NULL;
cluster = cass_cluster_new();
session = cass_session_new();
/* Add contact points */
// cass_cluster_set_contact_points(cluster, "127.0.0.1,127.0.0.2,127.0.0.3");
cass_cluster_set_contact_points(cluster, "127.0.0.1");
/* Provide the cluster object as configuration to connect the session */
connect_future = cass_session_connect(session, cluster);
if (cass_future_error_code(connect_future) == CASS_OK) {
CassFuture *close_future = NULL;
insertQ();
/* Close the session */
close_future = cass_session_close(session);
cass_future_wait(close_future);
cass_future_free(close_future);
} else {
/* Handle error */
const char *message;
size_t message_length;
cass_future_error_message(connect_future, &message, &message_length);
fprintf(stderr, "Unable to connect: '%.*s'\n", (int) message_length,
message);
}
cass_future_free(connect_future);
cass_cluster_free(cluster);
cass_session_free(session);
return 0;
}
它的工作和写入大约90000行然后落在这个错误:
index : 91627
Unable to run query: 'Operation timed out - received only 0 responses.'
..
并继续,我可以执行'SELECT'查询但在此之后'INSERT'失败。 unitl我重启cassandra servcice。
问题是什么?
我的系统:Ubuntu 14.04 x64,8 gig ram,cassandra 2.1.4(来自cassandra debian存储库,默认配置)
感谢。
答案 0 :(得分:2)
这个错误是从Cassandra回来的。它表示在cassandra中配置的时间段内,少于所需的副本数量响应您的读/写请求。由于您没有指定一致性级别,因此所需的只是一个节点响应且不在写入超时内。要在cassandra.yaml中查看的最相关配置是:
write_request_timeout_in_ms (default 2000ms)
read_request_timeout_in_ms (default: 5000ms)
range_request_timeout_in_ms (default: 10000ms)
由于您正在进行插入,因此write_request_timeout_in_ms可能是最相关的配置。
可能发生的事情是你压倒了你的cassandra集群。您是否在运行测试时查看了服务器上的CPU利用率/磁盘io /内存利用率?
有趣的是,你的代码一次只执行1次INSERT,这是正确的吗?我希望这应该没问题,但也许正在发生的事情是,这会对cassandra中的内存堆造成巨大的压力,并且它无法足够快地刷新数据,因此在写入磁盘时会备份。你应该看看你的cassandra system.log(通常在/ var / log / cassandra中,如果在linux上),看看是否有任何关于长垃圾收集(寻找GCInspector)或可记忆压力的可疑消息。