2013-08-29 15 views
6

我想在Cassandra 1.2.8中插入一列有50,000列的行。之前插入,我都爲整個行的數據準備好(在內存中):使用Cassandra和CQL3,如何在單個請求中插入整個寬行?

+---------+------+------+------+------+-------+ 
|   | 0 | 1 | 2 | ... | 49999 | 
| row_id +------+------+------+------+-------+ 
|   | text | text | text | ... | text | 
+---------+------+------+------|------+-------+ 

列名是整數,允許分頁切片。 列值是該特定索引處的值。

CQL3表定義:

create table results (
    row_id text, 
    index int, 
    value text, 
    primary key (row_id, index) 
) 
with compact storage; 

正如我已經有ROW_ID和內存50,000名名稱/值對,我只是想插入一個一行到卡桑德拉在單個請求/操作,它是儘可能快。

我似乎可以找到的唯一的事情就是做執行以下50000次:

INSERT INTO results (row_id, index, value) values (my_row_id, ?, ?); 

第一?是一個索引計數器(i)和第二?是存儲在文本值位置i

這需要很多時間。即使我們將上面的INSERT放入批處理中,也需要很長時間。

我們有完整的數據需求(完整的一行),我認爲這很簡單,只需說出「Cassandra,在一個請求中將這些數據作爲單行存儲」,例如:

//EXAMPLE-BUT-INVALID CQL3 SYNTAX: 
insert into results (row_id, (index,value)) values 
    ((0,text0), (1,text1), (2,text2), ..., (N,textN)); 

該實施例通過電流CQL3語法是不可能的,但希望它示出了所期望的效果:一切都將被插入作爲一個單一的查詢。

是否可以在CQL3和DataStax Java驅動程序中執行此操作?如果沒有,我想我會被迫使用Hector或Astyanax司機和Thrift batch_insert操作?

+0

您是否嘗試過使用列表/套/地圖它會更容易和更快,因爲他們會在批量啓用準備好的聲明。對於這種情況,它應該這樣做,但是,正如Alex所說,它會對CQL3做一個有趣的補充。 – jorgebg

+0

是的,我們已經嘗試過了,而且速度相當快,但它完全打破了所需的數據模型:您無法對CQL3集合執行切片查詢。 –

回答

3

編輯:我發佈了關於Cassandra 1.2.9的這個問題後4天,Cassandra 2.0 final才被釋放。 2.0支持批處理準備語句,其中應爲比需要用於C * < 2.0的非批處理CQL3快得多。我們還沒有測試過這一點。

當這個問題在4天前發佈在2013年8月30日的時候,CQL3中C *版本低於2.0是不可能的。它只能通過Thrift客戶端,例如Astyanax的MutationBatch

按照Alex的建議,我創建了CASSANDRA-5959作爲功能請求,但它被標記爲CASSANDRA-4693,它被認爲解決了C * 2.0的問題。

+3

感謝Les。雖然我確實同意這可以被認爲是java驅動程序的限制,但我實際上認爲這更多的是CQL限制。希望Cassandra傢伙會同意並添加它。 –

+0

作爲補充 - 我在#cassandra頻道與thobbs進行了對話。他說,發送到一個分區的未記錄的批次是作爲單個操作執行的,因此可以以這種方式獲得相當高效的查詢。建議批量大小爲〜1k以避免在節點上施加太多的堆壓力。 –

2
  1. CQL3 INSERT語句不支持多值元組。但我認爲這可能會使CQL變得有趣,因此請submit a feature request

  2. DataStax Java驅動程序基於CQL,因此如果語句不受支持,它可以執行任何操作。

  3. 因爲如果你需要這個你最好的辦法是使用基於節儉庫(NB暫且:我不是很熟悉的基於節儉API,以確認此插入將是可能的,但我認爲它應該)

+0

只是一個更新 - 這與Thrift絕對是可能的。我們在本地開發機上使用Datastax Java Driver和CQL3批處理(使用實際的Batch API)進行測試需要1.5分鐘。與Astyanax(通過[MutationBatch](http://netflix.github.io/astyanax/javadoc/com/netflix/astyanax/MutationBatch.html)又名'batch_mutate')相同的操作耗時235 _milliseconds_。這對我們的項目中的Datastax Java Driver而言並不是一個好兆頭。話雖如此,我是一位讚賞的開源公民,所以我會打開一個功能請求。 –

+0

@Les Hazlewood perf與實際的Bath API很差,可能是因爲它是純文本查詢(因此解析文本很昂貴)。如果您有機會使用準備好的語句測試批處理API,那麼我會感興趣的是獲得結果。關於CQL3 perf與節儉有很大爭論 – doanduyhai

+0

如果我記得在測試後發佈結果,我當然會! –

3

多個插入/更新可以使用Thrift API中的batch_mutate方法,通過使用變異多圖來完成。

Map<byte[], Map<String, List<Mutation>>> mutationMap = new HashMap<byte[], Map<String, List<Mutation>>>(); 

List<Mutation> mutationList = new ArrayList<Mutation>(); 

mutationList.add(mutation); 
Map<String, List<Mutation>> m = new HashMap<String, List<Mutation>>(); 

m.put(columnFamily, mutationList); 

mutationMap.put(key, m); 
client.batch_mutate(mutationMap, ConsistencyLevel.ALL); 
+0

問題在於如何用CQL 3來實現而不是節儉 – Adrian

0

如果要執行多重插入,請在CQL3中使用批處理語句。

隨着C * 2.0,

+0

根據我原來的文章,CQL3中針對寬行

+0

完全同意你Les Hazlewood。幸運的是C * 2.0剛剛發佈,所以你可以用它:) – doanduyhai

+0

我試着用Cassandra 2.0編寫批處理語句,但它仍然很慢。 http://stackoverflow.com/questions/21778671/how-to-insert-a-wide-row-with-good-performance-using-cql –

相關問題