2014-04-17 17 views
0

我剛剛從Oracle切換到使用帶Datastax驅動程序的Cassandra 2.0,並且我很難爲此大數據方法構建模型。我有一個帶有UUID和序列化人員的Persons表。這些人有地址,姓名,標識和DOB列表。對於這些列表中的每一個,我都有一個附加表格,其中包含相應列表中每個值的複合關鍵字以及其他person_UUID列。這個模型對我來說太關係了,但我不知道如何構建它,以便我可以在地址,名稱,標識和DOB上有索引(可以搜索)。如果Cassandra支持列表中的索引,我只需要一個Persons表,其中包含每個列表的索引列表。如何優化Cassandra模型,同時仍支持列表內容查詢

在我的應用程序中,我們收到的交易中可以包含0個或更多的地址,名稱,標識和DOB。根據哪個人匹配哪個標準來對這些人進行評分。具有最高分數的單個人與交易相匹配。然後將所匹配的交易中的任何附加地址,名稱,標識和DOB數據添加到該人員。

我遇到的問題是,這種匹配時間過長,處理速度遠遠落後。這是由於我不能在Cassandra中執行復雜的查詢而必須循環執行其他查詢的結果集所致,而且我沒有足夠的內存來執行全部和全部篩選。例如,我想選擇所有與交易至少有兩個名字的人(名字可以有他們的訂單亂碼,所以沒有第一個,中間,最後一個;這只是三個名字),但這需要一個Cassandra不支持的'group by',如果我只是選擇了所有具有相同名稱的所有名稱,以便在java中過濾,則結果集太大而且內存不足。

我目前僅通過標識和地址進行搜索,這會產生一個較小的結果集(儘管它仍可能是數百個),並且對於此結果集中的每個結果集,我查詢它是否也與名稱和/或DOB。除了速度還很慢,這不符合項目的要求,因爲如果沒有找到更高的分數,單獨的名稱和DOB就足以將交易與人聯繫起來。

我知道卡桑德拉你應該通過查詢來建模你的表,而不是通過實體之間的關係來建模,但我不知道如何應用這個,同時保持按地址,名稱,標識單獨查詢的能力,和DOB。

任何幫助或建議將不勝感激。卡桑德拉給我留下了非常深刻的印象,但我還沒有弄清楚如何讓它適合我。

表:

  • 人 [UUID | serialized_Person]
  • 地址 [地址| person_UUID]
  • 名稱 [名稱| person_UUID]
  • 標識 [identification | person_UUID]
  • DOBs [DOB | person_UUID]

我做了很多更多的閱讀,現在我想我應該圍繞這些表更改爲以下內容:

  • 人 [UUID | serialized_Person]
  • 地址 [地址|一套person_UUID]
  • 名稱 [名稱|一套person_UUID]
  • 標識 [identification |一套人_UUID]
  • DOBs [DOB |一套person_UUID]

但是我害怕超過一些名稱和DOB的集合(65,536 UUID)的最大存儲空間。相反,我想我必須創建一個列名稱爲Person_UUID的動態列族,或者是一個超過65k列的行非常有問題?思考?


它看起來就像你不能在卡桑德拉新版本的這些動態列族,你必須改變表與特定名稱插入新列。然後,我不知道如何爲一行存儲超過64k的值。如果分配完善,我將用盡2300萬人的DOB空間,我預計有超過2億人。也許我必須有多個設置列?

  • DOBs [DOB |一套person_UUID_A |一套person_UUID_B |一套person_UUID_C]

我只是檢查大小和更改表,如果大小= 64k?我能做的更好嗎?


我想這只是CQL3,強制執行,如果我真的想我仍然可以做動態列與Cassandra 2.0?


哎,從Datastax DOC本頁面似乎在說我說得對第一種方式...: When to use a collection

回答

0

這個答案是不是很具體,但我會回來,並加入到當我有機會的時候。

第一件事 - 不要將您的人序列化爲一個列。這使搜索和更新任何人員信息變得複雜。 OTOH,有些人知道他們的意見不同意這個觀點。 ;)

接下來,請不要規範化您的數據。磁盤空間很便宜。所以,不要害怕將相同的數據寫入兩個地方。你的代碼將需要確保正確的事情完成。

這些項目反映了這一點:如果您希望查詢速度更快,請考慮您需要快速進行查詢。即,爲該查詢創建一個表。這可能意味着將數據寫入多個表以進行多個查詢。選擇一個查詢,然後構建一個表,該表正確地包含了該查詢所需的內容,並將其索引到任何可用於查找的索引,例如一個id。

所以,如果你需要通過地址查詢,建立一個表(真的是一個列族)索引的地址。如果你需要支持另一個基於身份識別的查詢,那就索引。每個表可能包含重複的數據。這意味着當您添加新用戶時,您可能會將相同的數據寫入多個表中。儘管如果關係數據庫是您曾經使用過的唯一類型,但這樣做看起來並不自然,但您會得到回報 - 即由CAP定理引起的橫向可伸縮性。

編輯:在最後一個例子

兩個欄式家庭可以牽住標識符到另一個表。所以,voilà你已經做了一個索引。 OTOH,這意味着每個查詢需要兩次讀取。但是,在許多情況下,仍然會有性能提升。

編輯:

試圖解釋先前編輯:

假設你有一個users表/列族:

CREATE TABLE users (
    id uuid PRIMARY KEY, 
    display_name text, 
    avatar text 
); 

你想找到一個用戶的化身給出的顯示名稱(一個人爲的例子)。搜索users會很慢。所以,你可以創建一個表/ CF充當一個索引,我們稱之爲users_by_name

CREATE TABLE users_by_name (
    display_name text PRIMARY KEY, 
    user_id uuid 
} 

上DISPLAY_NAME搜索是現在完成了對users_by_name,併爲您提供了user_id,您可以使用它發出第二個查詢針對users。在這種情況下,user_idusers_by_name中的主鍵id的值爲users。這兩個查詢都很快。

或者,您可以將avatar放入users_by_name,並通過使用更多磁盤空間來完成同一個查詢。

CREATE TABLE users_by_name (
    display_name text PRIMARY KEY, 
    avatar text 
} 
+0

感謝您的快速回復。除了擁有Person表格之外,我可以在每個表格中只有一個UUID,但是這會導致在選擇匹配時不得不再次查詢所有表格,並且迄今爲止似乎不是性能問題。 我不確定我是否跟着其餘部分,爲每個查詢創建一個單獨的表格是我以爲我所做的。我根本沒有遵循你的編輯。 – jwalk

+0

如果你所說的是,如果我想找到所有具有相同名稱和DOB的人員,我應該爲該特定目標建立一個專欄家庭,我不知道該怎麼做。假設我的人有4個名字和3個DOB,然後插入name1-dob1,name1-dob2,name1-dob3,name2-dob1 ...等。每次我添加一個額外的名字或DOB時,我必須查詢所有當前的信息並插入更多的信息。對不起,如果我誤解了。 – jwalk

+0

我編輯了一些簡單案例的細節。我需要花一些時間來閱讀你的具體案例並擴展這個答案。 –