Я использую Cassandra 0.8.7, Aquiles в качестве клиента C # и Thrift 0.7, и я пытаюсь получить довольно большой объем данных из SuperColumnFamily со следующим определением:
create column family SCF with column_type=Super and comparator=TimeUUIDType and subcomparator=AsciiType;
IЯ хочу вставить данные, извлеченные из Cassandra, в DataTable, чтобы я мог отфильтровать строки и сгенерировать некоторые отчеты, основанные на этом, но я всегда получаю исключение OutOfMemoryException.Оптимизировав мой код, моя окончательная версия состояла в том, чтобы разделить период времени (и количество ключей, если они превышают префиксное число), которые я использую, чтобы разделить SuperColumn на меньшие диапазоны, но ничего, в итоге я всегда получаю одно и то же исключение.*
Может ли это быть ошибкой библиотеки Thrift?Когда я получаю исключение, оно всегда указывает на следующую часть кода внутри Thrift.Transport.TFramedTransport:
private void ReadFrame()
{
byte[] i32rd = new byte[header_size];
transport.ReadAll(i32rd, 0, header_size);
int size =
((i32rd[0] & 0xff) << 24) |
((i32rd[1] & 0xff) << 16) |
((i32rd[2] & 0xff) << 8) |
((i32rd[3] & 0xff));
byte[] buff = new byte[size]; //Here the exception is thrown
transport.ReadAll(buff, 0, size);
readBuffer = new MemoryStream(buff);
}
Ниже приводится код, который я пытаюсь запустить:
string columnFamily = "SCF";
ICluster cluster = AquilesHelper.RetrieveCluster(ConfigurationManager.AppSettings["CLUSTERNAME"].ToString());
ColumnParent columnParent = new ColumnParent()
{
Column_family = columnFamily
};
List<byte[]> keys = //Function that return the list of the key i want to query
SlicePredicate predicate = new SlicePredicate();
foreach (DateTime[] dates in dateList)
{
from = GuidGenerator.GenerateTimeBasedGuid(dates[0]);
to = GuidGenerator.GenerateTimeBasedGuid(dates[1]);
predicate = new SlicePredicate()
{
Slice_range = new SliceRange()
{
Count = int.MaxValue,
Reversed = false,
Start = Aquiles.Helpers.Encoders.ByteEncoderHelper.UUIDEnconder.ToByteArray(from),
Finish = Aquiles.Helpers.Encoders.ByteEncoderHelper.UUIDEnconder.ToByteArray(to)
},
};
cluster.Execute(new ExecutionBlock(delegate(CassandraClient client)
{
int maxKeys = Convert.ToInt32(ConfigurationManager.AppSettings["maxKeys"]);
CassandraMethods.TableCreator(ref dt, columnParent, predicate, keys, client, maxKeys);
return null;
}), ConfigurationManager.AppSettings["KEYSPACE"].ToString());
}
И это функция, которая должна вставлять данные из Кассандры в DataTable:
public static DataTable TableCreator(ref DataTable dt, ColumnParent columnParent, SlicePredicate predicate, List<byte[]> keys, CassandraClient client, int maxKeys)
{
int keyCount = keys.Count;
if (keyCount < maxKeys)
CassandraMethods.CassandraToDataTable(ref dt, client.multiget_slice(keys, columnParent, predicate, ConsistencyLevel.ONE));
else
{
int counter = 0;
while (counter < keyCount)
{
if (counter + maxKeys <= keyCount)
CassandraMethods.CassandraToDataTable(ref dt, client.multiget_slice(keys.GetRange(counter, maxKeys), columnParent, predicate, ConsistencyLevel.ONE));
else
CassandraMethods.CassandraToDataTable(ref dt, client.multiget_slice(keys.GetRange(counter, keyCount - counter), columnParent, predicate, ConsistencyLevel.ONE));
counter += maxKeys;
}
}
return dt;
}
Я что-то упустил?Что я делаю не так?
Обновление 1: Я пробовал также с Cassandra 1.0, Aquiles 1.0, обеими версиями Thrift 0.6 и 0.7, но ничего, все равно то же исключение.
Обновление 2: Проблема решена, прочитайте мой ответ ниже