2017-08-02 82 views
1

我們在我們的項目中使用NoSQL(Cassandra)。我們有一個表A(5000條記錄),它是一個主表。我們還有另一個表B(2000年的記錄)。表B有4列,表A有25列。我們公開了一個REST服務來獲取B中的所有記錄;像/ service/getB。這項服務將在響應,返回6列 -提高Cassandra和java集合的性能

{ 
    "result": [ 
     { 
      "col1FromB": "1B", 
      "col2FromB": "2B", 
      "col3FromB": "3B", 
      "col4FromB": "4B", 
      "col1FromA": "1A", 
      "col2FromA": "2A" 
     }, 
     { 
      "col1FromB": "11B", 
      "col2FromB": "12B", 
      "col3FromB": "13B", 
      "col4FromB": "14B", 
      "col1FromA": "11A", 
      "col2FromA": "12A" 
     } 
    ] 
} 

所以,有一個查找查詢表A表B.每個項目這是我正在做它 -

//Get all from Table B (took 90 ms in Local and 30 ms in Test) 
    Select select = QueryBuilder.select().from("B"); 
    List<B> bList = cassandraOperations.select(select, B.class); 

    //Loop through bList and do a lookup using id in Table A (took 46000 ms (46 sec) in Local (horrible) and 6000 ms (6 sec) in Test) 
    For(B b: bList) { 
    Select select = QueryBuilder.select(「col1FromA」, 「col2FromA」).from("A"); 
    select.where(QueryBuilder.eq(「id」, b.getId())); 
    A a = cassandraOperations.selectOne(select, A.class); 

    ---- 
    ---- 
    //Prepare final Pojo with a and b objects and add into a List<finalPjo> and return 
} 

因此,本地環境中的查找時間非常高,在測試環境中也不太好。我所使用的只是Java集合。

有沒有什麼辦法讓它更好,讓我們在較短的時間內獲得記錄。

+0

是否有這些記錄不能共位的原因? – dilsingi

回答

2
For(B b: bList) { 
Select select = QueryBuilder.select(「col1FromA」, 「col2FromA」).from("A"); 
select.where(QueryBuilder.eq(「id」, b.getId())); 
A a = cassandraOperations.selectOne(select, A.class); 

該代碼執行在每個迭代阻塞請求cassandraOperations.selectOne,它意味着每個下一迭代必須等待前一個。所有2000個請求將被逐個執行並且很長一段時間。

爲了避免這種情況,使用異步方式獲取循環中的記錄(就像我看到的,您使用的是Spring並且selectOne可以被返回ResultSetFuture的selectOneAsynchronously取代,將這些期貨保存在某個列表中並使用它來檢索記錄當所有請求被髮送時)。

+0

太好了。謝謝。我在FutureCallback中使用了session.executeAsync(),現在結果僅在583 ms內出現。 – Saurabh

2

Cassandra根據分區鍵在其節點上分配數據。它可以確保分區內的所有行(具有相同分區鍵的一組行)位於同一節點上,爲全分區或部分分區快速創建SELECT語句。

如果您有一個查詢拉下多個分區,則每個分區可能位於不同的節點上,導致選擇過程中的網絡流量會導致性能下降。通過添加第二個表格,您正在解決問題。

在卡桑德拉你應該看看你的查詢,然後如果可能的話,每個查詢創建一個表。當您擁抱數據重複並避免連接時,Cassandra數據模型可提升性能。

因此,我將創建一個新表,將查詢數據預加入到名爲C的表中。當您在A中編寫數據時,您會將它寫入A和C,並且當您向B寫入數據時會將其寫入B和C.如果可能,您希望將要在同一分區中一起查詢的數據。如果每次調用端點時都要下拉整個數據集,則可能需要考慮對錶中的所有數據使用單個分區鍵(因爲您的數據量相對較少),這將保證在何時您讀取表格時,整個讀取將從單個節點開始。

我想你在你的本地機器上看到很好的性能,因爲你的查詢沒有打到網絡上。