How is data updated?
Cassandra將每個新行都當做一個upsert:如果一個新行和一個已有的行有相同的primary key,Cassandra就會對這已有的行進行更新操作聊浅。
寫數(shù)據(jù)時城看,Cassandra將每個新行都添加到數(shù)據(jù)庫中恰梢,而不去檢查是否有重復的記錄存在。這個方法將有可能導致相同行在數(shù)據(jù)庫中有多個版本存在。
存儲在內存中的row會周期性地被flush到磁盤中的叫做SSTables的結構文件中臀晃。Cassandra周期性地將小的SSTables compacts成大的SSTables窗轩。如果在這個過程中夯秃,Cassandra遇到同一行數(shù)據(jù)的2個或多個版本,Cassandra只會將最新版本的數(shù)據(jù)寫到新的SSTable痢艺。compaction結束后仓洼,Cassandra會刪除掉原來的SSTables,以刪除過時的row堤舒。
Cassandra的大部分生產環(huán)境下色建,會將每一行的副本存在兩個或多個節(jié)點上。每個節(jié)點都獨立的執(zhí)行compaction舌缤。這意味著即使一個過時版本的行數(shù)據(jù)在某個節(jié)點上被刪除了箕戳,可能仍然存在于其他節(jié)點上。
這就是為什么Cassandra會在讀操作過程中會執(zhí)行另外一輪比較友驮。當一個客戶端根據(jù)一個特定的主鍵請求數(shù)據(jù)時漂羊,Cassandra會從一個或多個副本中拿到多個版本的行數(shù)據(jù)。帶有最新的時間戳的數(shù)據(jù)是唯一會被返回到客戶端的數(shù)據(jù)(“l(fā)ast-write-wins”)卸留。
注:數(shù)據(jù)庫操作可能只會更新一行數(shù)據(jù)的部分列走越,因此有些版本的行數(shù)據(jù)只包括部分列,而不是全部耻瑟。在compaction或write階段旨指,Cassandra收集各個更新操作來組成一個完整的行數(shù)據(jù),每一列都使用最新的版本喳整。
How is data deleted?
為了提高性能谆构,并考慮到數(shù)據(jù)分布,和故障容忍等內置特性框都,Cassandra這樣實現(xiàn)刪除數(shù)據(jù):
Cassandra將一個刪除視為一個insert或者upsert搬素。使用DELETE命令刪除的數(shù)據(jù)會被加上一個刪除標記,叫做墓碑。墓碑標記走的也是寫過程熬尺,會被寫到一個或多個節(jié)點的SSTables摸屠。墓碑最主要的不同點在于:它有一個內置的過期時間(grace period),compaction過程會將過期的墓碑(所對應的數(shù)據(jù)真正)刪除掉粱哼。
Deletion in a distributed system
在一個多節(jié)點的集群中季二,Cassandra可以在2個或者更多的節(jié)點上存儲一份數(shù)據(jù)的多個副本。這樣可以防止數(shù)據(jù)丟失揭措,但是會使得刪除過程變得復雜胯舷。如果一個節(jié)點接收到一個record的刪除操作,節(jié)點將這個記錄標記為墓碑绊含,然后嘗試將墓碑傳遞給其他包含這個記錄的節(jié)點桑嘶。但是如果某個存有該數(shù)據(jù)的節(jié)點在這個時間點沒有應答,不能夠馬上收到墓碑艺挪,因此它仍會有這些記錄被刪除前的版本不翩。如果在這個節(jié)點recover之前,集群中其他被標記的墓碑數(shù)據(jù)都已經被真正刪除了麻裳,Cassandra會將recovered這個節(jié)點上的這個記錄作為新的數(shù)據(jù)口蝠,并且將它傳送到集群的其他節(jié)點。這種已經被刪除津坑,但是仍殘留的記錄叫做zombie妙蔗。
為了防止出現(xiàn)zombies,Cassandra給每個墓碑一個寬限期(grace period)疆瑰。grace period的目的就是給沒有應答的節(jié)點時間去recover和正常處理墓碑眉反。When multiple replica answers are part of a read request, and those responses differ, then whichever values are most recent take precedence. For example:如果一個節(jié)點有一個墓碑數(shù)據(jù),但另一個節(jié)點有關于這一行更新的操作穆役,那么最終的結果是返回更新的操作寸五;如果一個節(jié)點有一個墓碑數(shù)據(jù),但另一個節(jié)點有關于這一行更舊的value耿币,那么最終的結果是返回墓碑數(shù)據(jù)(也就是該數(shù)據(jù)被刪除了梳杏,數(shù)據(jù)不存在)。如果一個客戶端在墓碑數(shù)據(jù)的grace period寫入了一個新的更新淹接。Cassandra會覆蓋掉此墓碑十性。
When an unresponsive node recovers, Cassandra uses?hinted handoff?to replay the database?mutations?the node missed while it was down. Cassandra does not replay a mutation for a tombstoned record during its grace period. But if the node does not recover until after the grace period ends, Cassandra may miss the deletion.
當一個無應答的節(jié)點恢復過來,Cassandra使用hinted handoff來replay 恢復節(jié)點down期間錯過的mutations塑悼。Cassandra不會去replay處于grace period的墓碑的數(shù)據(jù)(也就是說劲适,如果這個墓碑還在寬限期,那么這個recover的節(jié)點就不要這個墓碑數(shù)據(jù)了厢蒜,因為它被刪除了霞势,不是指不要這個墓碑標記烹植,是不要這個數(shù)據(jù)!V尽)刊橘。但是如果在grace period結束后,節(jié)點還沒有恢復颂鸿,則Cassandra可能會丟失這個數(shù)據(jù)的墓碑標記,因此錯過這個數(shù)據(jù)的刪除操作(就會導致刪除的數(shù)據(jù)重現(xiàn))攒庵。
也就是說 正常的節(jié)點嘴纺,一開始寫入了一個數(shù)據(jù)A,然后刪除數(shù)據(jù)A浓冒,也就是在commmit log和memtable中都寫入了一個insert A 和deleteA的record栽渴,但是另一個節(jié)點宕機了,只接收到insert A的record稳懒,然后正常的節(jié)點 把memtable dump成sstable闲擦,然后sstable compaction后 就將A數(shù)據(jù)刪除了,但是replay的時候不是replay commitlog嗎场梆? 那么deleteA這個record應該還在的吧墅冷?commitlog 難道也要GC?
當墓碑的grace period結束后或油,Cassandra會在compaction階段刪除墓碑寞忿。
一個墓碑的grace period是通過設置gc_grace_seconds屬性來設置的。默認值是86400秒(10天)顶岸。每個表這個屬性可以單獨設置腔彰。
More about Cassandra deletes
l 墓碑數(shù)據(jù)過期的日期/時間是它創(chuàng)建的日期/時間加上表的gc_grace_seconds參數(shù)。
l Cassandra也支持批量插入和更新辖佣。這個過程(和普通的插入和更新相似)也可能會產生zombie霹抛。Cassandra不會在墓碑數(shù)據(jù)的grace period期間 replay batched mutations。
l 在一個單節(jié)點的集群中卷谈,你可以設置gc_grace_seconds的值為0
l 為了完全防止zombie數(shù)據(jù)的再現(xiàn)杯拐,可以在節(jié)點恢復后,在節(jié)點上運行nodetool?repair命令雏搂,必須是在每個表的gc_grace_seconds期間內執(zhí)行藕施,不能超期。
l 如果表中的所有數(shù)據(jù)在創(chuàng)建時都被賦予TTL凸郑,并且所有數(shù)據(jù)都允許過期自動刪除裳食,而不是手動刪除,則不需要定期為該表運行nodetool?repair命令芙沥。
l 如果使用SizeTieredCompactionStrategy或DateTieredCompactionStrategy诲祸,則可以通過手動觸發(fā)compaction來立即刪除墓碑浊吏。
警告:如果使用force compaction,Cassandra可能會從所有數(shù)據(jù)中創(chuàng)建一個非常大的SSTable救氯。 因此在很長一段時間內找田,都不會觸發(fā)下一次compaction,因此在下次compaction發(fā)生前着憨,這次force?compaction過程中產生的SSTable中的數(shù)據(jù)會變得非常陳舊墩衙。
l 可以為整張表設置default_time_to_live屬性。標有常規(guī)TTL的列和行如上所述進行處理;但是當記錄超過表級TTL時甲抖,Cassandra會立即刪除它漆改,而不會標記為墓碑然后再compaction。
l?可以通過DROP KEYSPACE和DROP TABLE語句立即刪除數(shù)據(jù)准谚。