2015-09-15 36 views
2

我有一個CQL表,看起來像(CQL 3,卡桑德拉2.0。*):同步SELECT + INSERT與INSERT ...之間的性能差異...如果CQL中不存在?

CREATE TABLE IF NOT EXISTS user_things (
    user_id bigint, 
    thing_id bigint, 
    created_at timeuuid, 
    PRIMARY KEY (user_id, thing_id) 
); 

我想要做的插入像

INSERT INTO user_things (user_id, thing_id, created_at) VALUES (?, ?, now()) 

,但只有當行不存在。

我可以在兩個同步語句做到這一點(第一個SELECT,後跟一個INSERT如果SELECT沒有返回行)或我可以使用INSERT ... IF NOT EXISTS。

CQL docs狀態「但請注意,使用IF NOT EXISTS將產生不可忽略的性能成本(內部使用Paxos),因此應謹慎使用。」

我想知道是否有人已經做基準測試,看看有什麼更好的性能,如果我們有很多這些操作發生的? (說數百第二)

回答

0

雖然我沒有做過標杆自己,我會想象這兩個同步語句會更快運行,因爲簡單地說,它沒有做那麼多。它執行兩個精心設計的CQL查詢,而另一種方法涉及至少4個節點之間的通信「階段」。

但是,如果您確實使用這種方法,您是否能夠保證這些查詢是以原子方式執行的,並且在運行SELECT和運行INSERT之間的時間內不會存在具有相同user_id和thing_id的INSERT?避免這種情況的需要是推動在Cassandra和Paxos中使用輕量級事務的一般原因。

4

這很大程度上取決於您使用的拓撲結構。如果將其限制在本地數據中心(使用LOCAL_SERIAL)並使用小的複製因子,則IF NOT EXISTS速度非常快。如果您嘗試跨多個數據中心使用它,或者使用更高的複製因子,則它會顯着減慢。有一個開放ticket以提高其性能,所以希望這將很快完成,因爲它目前是一個過多的往返行程過於昂貴的操作。

,這將減緩IF NOT EXISTS下來的另一件事情是,當你使用它的集羣行。當你的表只有一個複合分區鍵和沒有聚簇列時,它似乎工作得最快。

如果你去寫路由之前讀取,那麼你已經有了其他的問題需要解決。首先你會遇到競爭狀況,因爲如果兩個客戶在同一時間進行閱讀,然後雙方都決定寫一個,你會得到一個覆蓋另一個,這會使讀取變得毫無意義(請參閱另一種方法:collision detection。如果您不介意競爭條件,並且使用像ONE這樣的低一致性進行讀寫,那麼它可能會超過IF NOT EXISTS。

幾乎你不得不將它作爲基準您的系統和架構,看看哪一個是您的情況要快。

+0

由 「複合分區鍵」 你的意思是像'PRIMARY KEY((USER_ID,thing_id))'VS'PRIMARY KEY(USER_ID,thing_id)'(聚類列)? –

+0

是的,這就是我的意思。 –