源於公司須要把原來存儲在redis的數據遷移到cassandra,這部分數據很大(每次插入千萬級),但屬於能夠過時的數據(通常1~2天過時)。
redis
好了,咱們採用DateTieredCompactionStrategy來作壓縮存儲策略。而後往cassandra裏面插入數據5千萬,而後設置的TTL爲1小時。插入數據完成之後,使用select ttl(field) from table limit 10;查看一下數據以及觀察數據還有多久過時。這時候數據很快返回。測試
直到全部數據都過了TTL時間,這時候再執行select ttl(field) from table limit 10; 會發現超時。spa
一開始以爲奇怪,爲何這時候會超時,因而重複執行此cql,結果固然是繼續超時啦。而後還發現cassandra此時變得不穩定,節點間同步都出現問題。
內存
此處省略了一萬字......(各類懷疑、調參、從新測試)
ci
最後回頭想,TTL過時後,根據cassandra特性,數據依然保存在磁盤,採用墓碑標記數據已經失效。可是若是執行select ttl(field) from table limit 10; 語句,因爲全部分區都沒有數據,這至關於須要掃描已經失效的所有磁盤數據。若是屢次執行此語句,可能會引起爆內存的問題,而後連鎖反應致使節點不一樣步等問題。同步
歸根結底,是本身用法不對。解決辦法其實也沒有很好的辦法,能夠往這個表插入一部分沒有TTL的記錄,保證這個表一直有數據,這樣select ttl(field) from table limit 10; 語句就會很快命中並返回結果。固然,實際上咱們業務上是不該該執行select * from table limit 10; 這種語句的,而是應該帶上partitionKey的,如select * from table where partitionKey = ? limit 10; 。上面的語句select * from table limit 10;只是管理員纔會用到的(實際上應該謹慎使用)it
補充:目前能規避此問題的方法是,控制TTL過時時間點發生在凌晨,而且gc_grace_seconds設置在1小時內,等到compaction操做回收了舊的過時數據後,再執行select * from table limit 10;的話就不會有問題了。這樣在正常上班時間,就不會遇到問題。io