2

對於Cassandra(2.1.11)和Spark(1.4.1)我都很新,並且有興趣知道是否有人看到/開發了用於原子寫入兩個不同Cassandra表的解決方案使用Spark Streaming。Atomic通過Spark Streaming提交給Cassandra

我目前有兩個表保存相同的數據集,但具有不同的分區鍵。爲了簡單起見,我將使用熟悉的用戶表的例子來解釋:

CREATE TABLE schema1.user_by_user_id 
(
    user_id uuid 
    ,email_address text 
    ,num int //a value that is frequently updated 
    ,PRIMARY KEY (user_id) 
); 

CREATE TABLE schema1.user_by_email_address 
(
    email_address text 
    ,user_id uuid 
    ,num int //a value that is frequently updated 
    ,PRIMARY KEY (email_address) 
); 

email_address柱將具有高基數(實際上這將是50%和user_id值的數量的100%之間) 。高基數使得二級索引表現不佳,因此需要第二個表。

我正在使用Spark Streaming來處理num列中的更改並更新這兩個表。據我所知,saveToCassandra()方法執行寫入在一個UNLOGGED BATCH RDD中的每個項目,從而執行原子寫入(如「保存對象的集合」部分here部分所述)。但是,saveToCassandra()只能用於保存到單個表中。爲了保持兩個schema1.user_by_user_idschema1.user_by_email_address表同步的,我必須發出兩個獨立的saveToCassandra()電話:

rdd.saveToCassandra("schema1","user_by_user_id",SomeColumns("user_id","email"address","num")) 
rdd.saveToCassandra("schema1","user_by_email_address",SomeColumns("user_id","email"address","num")) 

的寫入每次通話以原子的方式完成內ocurring,但在這兩個電話一起不是原子。第二次調用中的一些錯誤會使兩個表不同步。

顯然我的數據集和實際的表結構比這更復雜,但我試圖以儘可能簡單的方式傳達我的問題的要點。雖然我的問題是能夠保存到兩個表格,但我希望對數據模型更改提出任何其他建議,以完全消除此需求。

回答

1

首先要明白的是:UNLOGGED批次是而不是原子。請參閱documentationUNLOGGED批處理給你的是能夠使用相同的時間戳進行多次寫入。

所以,如果你想多次調用saveToCassandra並讓它們表現得像是一次通話,只需要specify the WRITETIME就可以同時通話。一切完成後,所有修改後的數據將具有相同的時間戳。

至於你的問題如何更新多個表原子......你不能。卡桑德拉不支持它。

我能想到的最好的建議是創建你自己的批處理日誌,你可以在崩潰後進行諮詢以找出需要重新同步的東西。

想象這樣的事情:

CREATE TABLE batch_log 
(
    id uuid, 
    updated_users set<uuid>, 
    PRIMARY KEY(id) 
) 

當開始你的工作,產生一個新的UUID,這將是這項工作的ID。然後,你會發出3節省:

rdd.saveToCassandra("schema1", "batch_log", SomeColumns("batch_id", "user_id" append) 
rdd.saveToCassandra("schema1","user_by_user_id",SomeColumns("user_id","email"address","num")) 
rdd.saveToCassandra("schema1","user_by_email_address",SomeColumns("user_id","email"address","num")) 

如果批處理沒有任何崩潰完成後,您可以刪除已創建的batch_log行。 但是,如果系統中途崩潰,那麼一旦事情恢復在線,您可以查閱batch_log以獲取已更新的用戶列表。去查詢這些用戶的電子郵件地址,然後更新user_by_email_address表。一旦你完成這個修復,你可以刪除你的batch_log

實際上,您正在實施「手工」卡桑德拉LOGGED BATCH。

+0

謝謝你的迴應!我錯過了刪除寫入批處理日誌以避免性能衝突消除原子性的事實。至於解決方法,我認爲這是我需要的一個很好的解決方案。 – JakeElliott44