2011-03-21 38 views
1

我有一個應用程序將幾十億條記錄寫入Cassandra並通過鍵刪除重複項。然後在連續階段將其按照其他字段(如標題)進行分組,以便可以對相似記錄組進行進一步處理。應用程序分佈在一組機器上,因爲我需要它在合理的時間內完成(幾個小時而不是幾個星期)。Cassandra 0.7.2是否對get_range_slices有性能問題?

應用程序的一個階段通過使用hector客戶端將記錄寫入Cassandra並將記錄的主鍵存儲在列族中作爲Cassandra鍵來工作。時間戳被設置爲記錄的最後更新日期,以便我只獲取每個密鑰的最新記錄。

後來的階段需要讀取Cassandra的所有內容,對記錄執行一些處理,然後使用各種其他鍵將記錄添加回不同的列族,以便可以對記錄進行分組。

我通過使用Cassandra.Client.describe_ring()來計算出環中哪臺機器是哪個TokenRange的主機,從而完成了這批讀取。然後,我將每個TokenRange的master與本地主機進行比較,以找出本地機器擁有哪些令牌範圍(對於此類批處理,遠程讀取速度太慢)。一旦我知道本地每臺機器上有哪些TokenRanges,我就可以使用Cassandra.Client.describe_splits()獲得大小均勻的分割。

一旦我有一堆可以從本地Cassandra實例中讀取的大小均勻的分割塊,我就可以像使用ConsistencyLevel.ONE一樣使用Cassandra.Client.get_range_slices(),儘快讀取它們,從而它不會需要做任何遠程讀取。我一次獲取100行,順序通過整個TokenRange(我已經嘗試了各種批量大小,100似乎最適合這個應用程序)。

在Cassandra 0.7.0中,這一切都很好,並對內存大小和列族配置進行了一些調整。通過這種方式,我可以每秒鐘讀取4000到5000條記錄,並保持本地磁盤儘可能地工作。

這裏是分裂的一個例子,我會卡桑德拉0.7.0下可見的速度:

10/12/20 20:13:08 INFO m4.BulkCassandraReader: split - 20253030905057371310864605462970389448 : 21603066481002044331198075418409137847 
10/12/20 20:13:08 INFO m4.BulkCassandraReader: split - 21603066481002044331198075418409137847 : 22954928635254859789637508509439425340 
10/12/20 20:13:08 INFO m4.BulkCassandraReader: split - 22954928635254859789637508509439425340 : 24305566132297427526085826378091426496 
10/12/20 20:13:08 INFO m4.BulkCassandraReader: split - 24305566132297427526085826378091426496 : 25656389102612459596423578948163378922 
10/12/20 20:13:08 INFO m4.BulkCassandraReader: split - 25656389102612459596423578948163378922 : 27005014429213692076328107702662045855 
10/12/20 20:13:08 INFO m4.BulkCassandraReader: split - 27005014429213692076328107702662045855 : 28356863910078000000000000000000000000 
10/12/20 20:13:18 INFO m4.TagGenerator: 42530 records read so far at a rate of 04250.87/s 
10/12/20 20:13:28 INFO m4.TagGenerator: 90000 records read so far at a rate of 04498.43/s 
10/12/20 20:13:38 INFO m4.TagGenerator: 135470 records read so far at a rate of 04514.01/s 
10/12/20 20:13:48 INFO m4.TagGenerator: 183946 records read so far at a rate of 04597.16/s 
10/12/20 20:13:58 INFO m4.TagGenerator:5 records read so far at a rate of 04640.62/s 

當我升級到0.7.2卡桑德拉我,因爲有幾個新的重建CONFIGS選項等,但我小心地嘗試從0.7.0配置工作中獲得所有相關的調整設置。不過,我幾乎無法用新版本的Cassandra讀取每秒50條記錄。

這裏是分裂的例子和速度我現在看到卡桑德拉0.7.2下:

21:02:29.289 [main] INFO c.p.m.a.batch.BulkCassandraReader - split - 50626015574749929715914856324464978537 : 51655803550438151478740341433770971587 
21:02:29.290 [main] INFO c.p.m.a.batch.BulkCassandraReader - split - 51655803550438151478740341433770971587 : 52653823936598659324985752464905867108 
21:02:29.290 [main] INFO c.p.m.a.batch.BulkCassandraReader - split - 52653823936598659324985752464905867108 : 53666243390660291830842663894184766908 
21:02:29.290 [main] INFO c.p.m.a.batch.BulkCassandraReader - split - 53666243390660291830842663894184766908 : 54679285704932468135374743350323835866 
21:02:29.290 [main] INFO c.p.m.a.batch.BulkCassandraReader - split - 54679285704932468135374743350323835866 : 55681782994511360383246832524957504246 
21:02:29.291 [main] INFO c.p.m.a.batch.BulkCassandraReader - split - 55681782994511360383246832524957504246 : 567137278201564105772291
21:09:06.910 [Thread-0] INFO c.p.m.assembly.batch.TagGenerator - 100 records read so far at a rate of 00000.25/s 
21:13:00.953 [Thread-0] INFO c.p.m.assembly.batch.TagGenerator - 10100 records read so far at a rate of 00015.96/s 
21:14:53.893 [Thread-0] INFO c.p.m.assembly.batch.TagGenerator - 20100 records read so far at a rate of 00026.96/s 
21:16:37.451 [Thread-0] INFO c.p.m.assembly.batch.TagGenerator - 30100 records read so far at a rate of 00035.44/s 
21:18:35.895 [Thread-0] INFO c.p.m.assembly.batch.TagGenerator - 40100 records read so far at a rate of 00041.44/s 

你大概可以從代碼移動到不同的包日誌中看到,但比其他代碼沒有改變。它運行在相同的硬件上,並且所有內存設置都相同。

我可以看到Cassandra版本之間的一些性能差異,但是像這樣(100倍性能下降)破碎的東西看起來像我必須缺少一些基本的東西。即使在0.7.0上調整列系列和內存設置之前,它也不會很慢。

有誰知道有什麼可以解釋這個?是否有一些調整設置可能會導致此錯誤? Cassandra函數做了些什麼改變來支持那些沒有記錄的hadoop?通過發行說明閱讀我找不到任何可以解釋這一點的內容。任何幫助解決這個問題,或者甚至只是解釋爲什麼它可能停止工作,將不勝感激。

回答

2

我想我應該關閉這個循環,因爲我們已經到了問題的底部,問題不是Cassandra問題,而是配置問題。

當我們升級到0.7.2時,一個配置發生變化,而我錯過了,這是令牌環。在我們的0.7.0配置中,我們有第一個標記爲2^127/12,在我們的0.7.2配置中,第一個標記爲0.這導致一個節點獲得分裂0:0。 0:0似乎是一個向卡桑德拉詢問一切的神奇範圍。所以我們在集羣中有一個節點通過網絡提取所有數據。到該節點的網絡流量最終導致我們發現問題的根源。

該修復程序是爲了糾正代碼以檢查0:0的情況並處理它,所以現在代碼將以任何方式處理分區的Cassandra集羣(第一個節點爲0或其他)。

所以總之不是卡桑德拉的問題。我的配置問題。

1

這裏不響鈴。我的猜測是你擊中了一個誠實向善的迴歸。

您可以嘗試將磁盤訪問模式切換爲標準模式。您也可以嘗試禁用JNA。 (這些應該分別繞過1713和1470,這是最有可能的罪魁禍首,但是,「最有可能」這裏只是一個問題,我可能會給出20%的賠率。)

如果你可以煮沸使用contrib/stress可以看到緩慢的東西,然後我們可以從中找出原因。但是,如果只能用自己的設置進行復制,則必須對分(二進制搜索整個提交,部署構建和檢查性能),以找出造成這種迴歸的原因。

對於將來的參考,Cassandra用戶列表是一個比StackOverflow更好的論壇,用於「我認爲我發現了一個bug」的討論。那裏有更多的專業知識。

+0

感謝您的建議。這指出我要嘗試一些事情,並讓我記住一些事情。我記得我在0.7.0版本中設置了disk_access_mode:mmap_index_only,而我嘗試故障排除OutOfMemoryError,並將此配置更改爲0.7.2配置。我從來沒有在0.7.0上安裝JNA,因爲我沒有需要它的性能問題,而且我也將它帶入了0.7.2。我在cassandra日誌中看到一條消息:INFO [main] 2011-03-20 20:21:37,412 CLibrary.java(第61行)未找到JNA。本機方法將被禁用。 – 2011-03-21 18:13:13

+0

那麼我試着用安裝了JNA和mmap和標準磁盤訪問。沒有成功。不幸的是時間壓力並不能讓我找到這個根本原因。我將不得不恢復到0.7.0,並接受我將無法獲得錯誤修復和改進。我討厭這樣做,但後來通過徵用時間來解決可能需要Cassandra升級的未來問題總比通過「未預見到的問題」延遲已承諾工作的交付更容易。 – 2011-03-21 20:46:58