У меня есть проект, и я должен улучшить его производительность. У меня есть большая база данных Mysql, созданная из огромного файла CSV (100 миллионов строк). Время вставки не является проблемой, но время ответа на запрос очень важно, и иногда запрос с 2 соединениями занимает около 20 часов...
Чтобы сократить это время отклика, я попытался перенести свою базу данных на Cassandra, но безуспешно: моя модель данных не соответствует концепциям Cassandra. Тогда я хотел бы попробовать другой способ повысить производительность: Parallel Virutal File System. Вместо того, чтобы вставлять данные в базу данных Mysql и отправлять, а затем отправлять запрос, я попытался прочитать весь CSV-файл с многопоточностью и выполнил свои вычисления. Но результат был не очень хорошим: 2 м 20 с только для 1 000 000 строк.
На данный момент мои вычисления очень просты: в C++ с API-интерфейсом MPI-IO я просто подсчитываю количество значений пары различий из 2 столбцов. Для выполнения этих вычислений я использую хэш-карту, где каждый ключ представляет собой парное значение из CSV-файла. В конце я возвращаю размер хэш-карты. Вот небольшой код:
MPI::Init(argc,argv);
cout << " INFO init done" << endl;
int myrank = MPI::COMM_WORLD.Get_rank();
int numprocs = MPI::COMM_WORLD.Get_size();
get_filename(path_name, myrank);
cout << " INFO open file : " << path_name << endl;
MPI::File thefile = MPI::File::Open(MPI::COMM_WORLD, path_name.c_str(),
MPI::MODE_RDONLY,
MPI::INFO_NULL);
MPI::Offset offset = 101;
MPI::Offset limit = thefile.Get_size();
cout << " INFO go computing" << endl;
do {
thefile.Read_at(offset, buf, bufsize, MPI_CHAR, status);
temp.assign(buf);
Tokenize(temp,tokens,"\n");
line.assign(tokens.at(0));
tokens.clear();
Tokenize(line,tokens,"\t");
nidt_count(tokens);
tokens.clear();
offset += (line.size() + 1);
}while(offset < limit);
count = status.Get_count(MPI_INT);
cout << "process " << myrank << " reads " << nidt_hash.size() << " nidt" << endl;
Я работаю на сервере с 4 ядрами, 8 ГБ оперативной памяти. Мои данные находятся на NAS, смонтированном в NFS или Samba на моем сервере. Я мог бы добавить 2 или 3 сервера для обработки, но на данный момент я просто попробовал небольшой файл (1 миллион строк) на одном сервере, чтобы измерить производительность.
Наконец, мои вопросы:
- Это хороший способ подумать о переходе на PVFS для моей проблемы? Я хотел бы сказать, что буду обрабатывать более сложный запрос, например: выбрать все строки с определенной датой (диапазон часов) и конкретным значением пары из определенных столбцов.
- Знаете ли вы другие вещи, которые могли бы помочь мне улучшить обработку CSV-файла? Я думаю использовать Hadoop, Pytables или FasterCSV.
Вот образец моих данных, состоящий из 2 файлов csv:
Самый большой из них (100 миллионов строк) состоит из следующих элементов:
ID DATE NUM_1 NUM_2 NB_UNITE TYPUNIT CODE_1 CODE_2
0 2007-05-13 15:37:48 33671624244 33698802900 547 s 0 17
0 2007-05-13 15:52:22 33671624244 33672211799 5 s 0 17
....
Второй более простой и небольшой (90 000), он похож на словарь, где из code_1
и code_2
я получаю значение с именем CODEVAL:
CODE_1 CODE_2 CODEVAL
0 17 VS
0 34 SS
Как вы и ожидали, обычно я создаю 2 таблицы по одной для каждого файла, и типичный запрос:
Select CODEVAL, hour(date) AS HEURE, COUNT(*) AS NBSMSSOR
From Tables_1 Join CODEVAL using(CODE_1,CODE_2)
Where CODEVAL='SS'
Извините за изложение, я не знаю, как сделать массив.
Вот образец моих данных, состоящий из 2 файлов csv:
самый большой из них (100 миллионов строк) состоит из следующих элементов:
ID ДАТА NUM_1 NUM_2 NB_UNITE TYPUNIT CODE_1 CODE_2
0 2007-05-13 15:37:48 33671624244 33698802900 547 s 0 17
0 2007-05-13 15:52:22 33671624244 33672211799 5 s 0 17 ....второй более простой и маленький (90 000), это как словарь, где из code_1 и code_2 я получаю значение с именем CODEVAL:
CODE_1 CODE_2 CODEVAL
0 17 VS
0 34 SS
Как вы и ожидали, обычно я создаю 2 таблицы по одной для каждого файла, и типичный запрос:
- Выберите CODEVAL, час(дата) AS HEURE, COUNT(*) AS NBSMSSOR Из Tables_1 Присоединитесь к CODEVAL, используя (CODE_1,CODE_2), где CODEVAL='SS'
Извините за изложение, я не знаю, как сделать массив.