Cassandra 文件

版本

您正在檢視預發行版本的說明文件。

常見問題

為何我無法將 listen_address 設定為監聽 0.0.0.0(我所有的位址)?

Cassandra 是基於八卦的分布式系統,而 listen_address 是節點告知其他節點用來連線的位址。告知其他節點「透過我的任何位址與我連線」並非好主意;如果叢集中的不同節點為您選擇不同的位址,就會發生不好的事情。

如果您不想手動為叢集中每個節點的 listen_address 指定 IP(可以理解!),請將其留空,Cassandra 會使用 InetAddress.getLocalHost() 選擇位址。然後,您或您的運作團隊必須讓事情正確解析(/etc/hosts/、dns 等)。

這個程序的一個例外是 JMX,它預設會繫結至 0.0.0.0(Java 錯誤 6425769)。

請參閱 25643 以取得更詳細的資訊。

Cassandra 使用哪些埠?

預設情況下,Cassandra 使用 7000 進行叢集通訊(如果啟用 SSL,則為 7001),使用 9042 進行原生通訊協定用戶端,以及使用 7199 進行 JMX。節點間通訊和原生通訊協定埠可以在 cassandra-yaml 中設定。JMX 埠可以在 cassandra-env.sh(透過 JVM 選項)中設定。所有埠都是 TCP。

當我新增節點時,叢集中現有資料會發生什麼事?

當新節點加入叢集時,它會自動連絡叢集中的其他節點,並將正確的資料複製給自己。請參閱 topology-changes

我從 Cassandra 刪除資料,但磁碟使用量保持不變。這是怎麼回事?

您寫入 Cassandra 的資料會持續到 SSTable。由於 SSTable 是不可變的,因此當您執行刪除時,資料實際上無法移除,而是會寫入一個標記(也稱為「墓碑」)來表示該值的最新狀態。不過不用擔心,在資料和墓碑之間發生的第一次壓縮中,資料將會被完全清除,並回收對應的磁碟空間。請參閱 compaction 以取得更多詳細資訊。

即使我的節點已記錄到它們看到彼此加入環,為什麼 nodetool ring 只顯示一個條目?

當您將相同的代幣分配給每個節點時,就會發生這種情況。不要這樣做。

最常發生這種情況的人是透過在 VM 上安裝 Cassandra 來部署的人(特別是在使用 Debian 套件時,該套件會在安裝後自動啟動 Cassandra,從而產生並儲存代幣),然後將該 VM 克隆到其他節點。

最簡單的修復方法是清除資料和提交日誌目錄,從而確保每個節點在下一次重新啟動時產生隨機代幣。

我可以在執行中的叢集上變更複製因子(a a 鍵空間)嗎?

可以,但需要執行完整修復(或清除)才能變更現有資料的複製品數量

  • Alter <alter-keyspace-statement> 複製因子以取得所需的鍵空間(例如使用 cqlsh)。

  • 如果您要減少複製因子,請在叢集上執行 nodetool cleanup 以移除多餘的複製品資料。清除會逐節點執行。

  • 如果您要增加複製因子,請執行 nodetool repair -full 以確保資料根據新設定進行複制。修復會逐複製品組執行。這是一個密集的程序,可能會導致叢集效能不佳。強烈建議進行滾動修復,因為嘗試一次修復整個叢集很可能會淹沒它。請注意,您需要執行完整修復(-full)以確保不會跳過已修復的 SSTable。您應使用 ConsistencyLevel.QUORUMALL(取決於您現有的複製因子)以確保會諮詢實際擁有資料的複製品。否則,一些客戶端可能會被告知在修復完成之前沒有資料。

我可以在 Cassandra 中儲存(大型)BLOB 嗎?

Cassandra 沒有針對大型檔案或 BLOB 儲存進行最佳化,而且單一 blob 值總是會讀取並完整傳送給客戶端。因此,儲存小型 BLOB(小於個位數 MB)不應構成問題,但建議手動將大型 BLOB 分割成較小的區塊。

請特別注意,預設情況下,任何大於 16MiB 的值都會被 Cassandra 拒絕,因為 cassandra-yaml 檔案的 max_mutation_size 組態(預設為 commitlog_segment_size 的一半,而 commitlog_segment_size 本身預設為 32MiB)。

Nodetool 對任何遠端主機都顯示「Connection refused to host: 127.0.1.1」。這是怎麼回事?

Nodetool 依賴於 JMX,而 JMX 又依賴於 RMI,而 RMI 又會在交換的每一端根據需要設定自己的監聽器和連接器。通常,所有這些都會在幕後透明地發生,但是連接主機或被連接主機的名稱解析不正確,可能會導致連線錯誤和令人困惑的例外狀況。

如果您沒有使用 DNS,請確保兩端的 /etc/hosts 檔案都正確無誤。如果這樣做失敗,請嘗試在 cassandra-env.sh 的底部附近設定 -Djava.rmi.server.hostname=<public name> JVM 選項,以設定一個可以從遠端機器存取的介面。

批次處理我的作業會加速我的大量載入嗎?

不會。使用批次處理載入資料通常只會增加延遲的「尖峰」。請改用非同步 INSERT,或使用真正的 bulk-loading

例外情況是批次處理對單一分區的更新,這可能是件好事(只要單一批次的大小保持合理)。但千萬不要盲目地批次處理所有內容!

在 RHEL 節點上無法加入環狀網路

檢查 SELinux 是否已開啟;如果已開啟,請關閉它。

我如何取消訂閱電子郵件清單?

請寄送電子郵件至 user-unsubscribe@cassandra.apache.org

為什麼 top 報告 Cassandra 使用的記憶體遠多於 Java 堆積最大值?

Cassandra 在內部使用 記憶體對應檔案 (mmap)。也就是說,我們使用作業系統的虛擬記憶體系統將許多磁碟檔案對應到 Cassandra 程序的位址空間。這將「使用」虛擬記憶體;換句話說,位址空間,並且會由 top 等工具相應地報告,但在 64 位元系統上,虛擬位址空間實際上是無限的,所以您不必擔心這一點。

從「記憶體使用」的角度來看,重要的是在 brk() 或 mmap’d /dev/zero 上配置的資料量,它們代表實際使用的記憶體。關鍵問題是,對於 mmap’d 檔案,從不需要將資料保留在實體記憶體中。因此,無論您將什麼資料保留在實體記憶體中,基本上都只是作為快取存在,就像正常的 I/O 會導致核心頁面快取保留您讀取/寫入的資料一樣。

mmap() 與一般 I/O 的差異在於,mmap() 的情況下,記憶體實際上會對應到程序,因此會影響 top 所回報的虛擬大小。使用 mmap() 而非標準 I/O 的主要論點在於,讀取僅需觸及記憶體,如果記憶體為駐留狀態,您只需讀取它,甚至不會發生分頁錯誤(因此不會有進入核心和執行半上下文切換的負擔)。此處有更詳細的說明。

種子是什麼?

種子用於啟動期間發現叢集。

如果您將節點設定為將某個節點視為種子,則環中的節點會比非種子更常將 Gossip 訊息傳送給種子(另請參閱有關八卦 <gossip>的章節)。換句話說,種子用作 Gossip 網路的樞紐。有了種子,每個節點都可以快速偵測其他節點的狀態變更。

新節點在開機時也會參考種子以了解環中的其他節點。當您將新節點加入環時,您需要指定至少一個要連繫的有效種子。一旦節點加入環,它就會了解其他節點,因此在後續開機時不需要種子。

您可以在任何時候將節點設為種子。種子節點沒有什麼特別之處。如果您在種子清單中列出節點,它就是種子

種子不會自動開機(也就是說,如果節點在自己的種子清單中,它不會自動將資料傳輸給自己)如果您希望節點執行此動作,請先開機,然後再將它加入種子。如果您沒有資料(新安裝),您完全不必擔心開機。

種子的建議用法

  • 每個資料中心選取兩個(或更多)節點作為種子節點。

  • 將種子清單同步到您所有的節點

單一種子是否表示單點故障?

戒指可以在沒有種子的情況下操作或啟動;但是,您將無法將新節點新增到叢集。建議在生產系統中設定多個種子。

為什麼我無法在 jconsole 上呼叫 jmx 方法 X?

某些 JMX 作業使用陣列引數,而 jconsole 不支援陣列引數,因此這些作業無法使用 jconsole 呼叫(按鈕對它們而言是處於非活性狀態)。您需要撰寫一個 JMX 程式來呼叫此類作業,或需要支援陣列的 JMX 監控工具。

為什麼我在記錄中看到「…​ 已捨棄訊息 …​」?

這是負載捨棄的症狀,Cassandra 會自我防禦超過其所能處理的請求。

節點接收到的節點間訊息,但在適當的逾時時間內未得到處理(請參閱 cassandra-yaml 中的 read_request_timeout、write_request_timeout、…​),會被捨棄而不是處理(因為協調節點將不再等待回應)。

對於寫入,這表示變更並未套用至傳送給它的所有複本。不一致性將透過讀取修復、提示或手動修復來修復。寫入作業也可能因此逾時。

對於讀取,這表示讀取請求可能尚未完成。

負載捨棄是 Cassandra 架構的一部分,如果這是一個持續性的問題,通常表示節點或叢集過載。

Cassandra 會因「java.lang.OutOfMemoryError: Map failed」而死掉

如果 Cassandra 特別是因為「Map failed」訊息而死掉,表示作業系統拒絕 java 鎖定更多記憶體。在 linux 中,這通常表示 memlock 受到限制。檢查 /proc/<pid of cassandra>/limits 以驗證這一點並提高它(例如,透過 bash 中的 ulimit)。您可能還需要增加 vm.max_map_count。請注意,debian 套件會自動為您處理這件事。

如果使用相同時間戳記進行兩次更新,會發生什麼事?

更新必須是可交換的,因為它們可能以不同的順序到達不同的複本。只要 Cassandra 有確定性的方式來選擇獲勝者(在時間戳記平手時),所選的獲勝者與任何其他獲勝者一樣有效,而具體細節應視為實作細節。話雖如此,在時間戳記平手的情況下,Cassandra 會遵循兩個規則:首先,刪除優先於插入/更新。其次,如果有兩個更新,則會選取字元較大的更新。

為什麼以「串流失敗」錯誤啟動新節點會失敗?

兩個主要可能性

  1. GC 可能會造成長時間暫停,中斷串流處理

  2. 背景中發生的壓縮會讓串流保持足夠長的時間,導致 TCP 連線失敗

在第一種情況下,套用一般 GC 調整建議。在第二種情況下,您需要將 TCP 保持連線設定為較低的值(Linux 上的預設值很高)。請嘗試執行以下操作

$ sudo /sbin/sysctl -w net.ipv4.tcp_keepalive_time=60 net.ipv4.tcp_keepalive_intvl=60 net.ipv4.tcp_keepalive_probes=5

若要讓這些設定永久生效,請將它們新增到您的 /etc/sysctl.conf 檔案。

注意:GCE 的防火牆會在 TCP 連線閒置超過 10 分鐘時中斷連線。強烈建議在該環境中執行上述指令。