Apache Cassandra和低延迟应用程序
介紹
多年來, Grid Dynamics擁有許多與NoSQL相關的項目,尤其是Apache Cassandra。 在這篇文章中,我們要討論一個給我們帶來挑戰的項目,而我們在該項目中試圖回答的問題今天也仍然適用。
數字營銷和在線廣告在2012年很受歡迎,并且對它們的需求僅在增加。 實時出價(RTB)是領域的組成部分。 實時出價工具假設通過數字廣告的實時拍賣來放置(購買和出售)廣告。 如果中標,則買方的廣告會立即顯示在發布商的網站上。 實時出價需要服務器端的低延遲響應(<100ms),否則出價將丟失。 我們的客戶之一,一家美國媒體公司,對實時出價和用戶跟蹤(即對網站訪問者的行為及其偏好的分析)感興趣。
最初,客戶用于處理RTB請求的基礎結構包括安裝Kyoto Cabinet 。 在下圖(圖片1)上,您可以看到RTB和第三方請求的來源。 所有請求都發送到實時應用程序,該應用程序在數據庫中執行查找和更新請求。 Kyoto Cabinet會將整個數據集保存在內存中,而自定義附件提供了保留管理和持久性功能。
圖1.以前的體系結構。
從延遲的角度來看,上述架構足夠好,但是它有幾個缺點:
我們的任務是為系統創建一個新的體系結構,該體系結構不具有上述缺點,同時使我們能夠在響應延遲方面獲得良好的結果。 換句話說,我們需要一個數據存儲區,該數據存儲區將允許我們保留用戶個人資料以及對其進行查找和更新,并且所有操作都將在特定時間間隔內執行。 該體系結構應該圍繞這樣的數據存儲構建。
要求
新的體系結構旨在解決所有這些問題。 對新體系結構的要求如下:
- 持久性(一個或兩個數據中心停電時,任何數據都不應丟失)
- 高可用性(應該沒有單點故障)
- 可伸縮性(通過添加更多節點,數據庫量應該相對容易增加)
- 跨數據中心復制(兩個數據中心之間的數據應同步)
- 數據的TTL(過期的用戶配置文件應自動清除)
- 數據量(約10億個具有多個屬性的同類記錄,其中一個記錄約為400字節)
- 吞吐量(每個數據中心每秒5000次隨機讀取+每秒5000次隨機寫入)
- 響應延遲(平均3毫秒,對于99%的請求,處理時間不應超過10毫秒)
另外,我們還有一些與基礎架構有關的限制。 限制之一是每個數據中心最多只能為每個數據庫安裝八臺服務器。 同時,我們可以選擇某些服務器硬件,例如內存量,存儲類型和大小。 客戶的其他要求之一是使用復制因子TWO,由于數據的統計性質,該因子是可以接受的。 這樣可以降低硬件成本。
我們研究了幾種可能滿足我們要求的解決方案,最后選擇了Cassandra。 Cassandra的新體系結構成為一種更為優雅的解決方案。 它只是兩個數據中心之間同步的Cassandra集群。 但是,有關其硬件規格的問題仍然沒有答案。 最初,我們有兩種選擇:
- SDD,但內存較少(少于整個數據集)
- HDD和更多內存(足以保留整個數據集)
實際上,還有一個選項暗示使用硬盤驅動器和更少的內存,但是這種配置不能提供我們要求的可接受的讀取延遲,因為從HDD隨機讀取甚至需要10ms RPM的硬盤也需要8毫秒。 結果,它從一開始就被拒絕了。
因此,我們有兩種配置。 經過一些調整(調整本身將在下一節中討論),它們都滿足了我們的需求。 他們每個人都有自己的優點和缺點。 SSD配置的主要缺點之一是成本。 當時,企業級SDD相當昂貴。 此外,一些數據中心提供商對使用SSD維護服務器收取額外費用。
使用HDD的方法意味著從磁盤緩存中讀取數據。 該配置的大多數缺點與高速緩存有關,例如,冷啟動問題。 這是由于在系統重新引導后清除了緩存而造成的。 結果,從HDD讀取未緩存的數據會導致額外的超時。 實際上,超時是在10毫秒內沒有響應的請求。 此外,由于在啟動時從Cassandra服務器復制了大量數據,可能會意外清理磁盤緩存。 最后一個問題與內存大小有關,而不是與緩存有關。 增加單個節點的數據量非常困難。 可以添加一個額外的HDD或幾個HDD,但是單臺計算機的內存大小是有限的,并且不是很大。
最后,我們設法解決了大多數上述HDD配置問題。 通過使用cat實用程序讀取數據并將其輸出重定向到啟動時的/ dev / null,解決了冷啟動問題。 修補了用于創建備份的rsync之后,與磁盤緩存清理相關的問題就消失了。 但是內存限制問題仍然存在,并在以后引起了一些麻煩。
最后,客戶端選擇了HDD + RAM配置。 每個節點在RAID 5 + 0中配備了96GB內存和8個HDD。
調整卡桑德拉
我們開始使用的Cassandra版本是1.1.4。 進一步,在開發過程中我們嘗試了不同的版本。 最后,我們決定批準使用1.2.2版,因為它包含我們已承諾對Cassandra存儲庫進行的更改。 例如,我們添加了一項改進 ,使我們可以為每個列族分別指定populate_io_cache_on_flush選項(它將在內存表刷新和壓縮時填充磁盤緩存)。
我們必須測試其余兩種配置,以選擇一種更好的配置。 在我們的測試中,我們使用了一個Cassandra群集,該群集包含3個節點,每個節點具有64GB內存和8個內核。 我們從寫操作開始測試。 在測試期間,我們以每秒7000次寫入的速度將數據寫入Cassandra。 選擇的速度與群集大小和所需的吞吐量成正比(將寫入速度加倍,以考慮跨數據中心復制的開銷)。 該方法已應用于所有測試。 值得一提的是,我們使用了以下首選項:
- 復制因子= 2
- write_consistency_level =兩個
- 分層壓縮策略
之所以使用LeveledCompactionStrategy(LCS),是因為客戶端的工作流應該具有大量的更新操作。 使用LCS的另一個原因是整體數據集大小和讀取延遲減小。 兩種配置的測試結果均相同:
- 平均延遲時間:?1ms
- 超時:0.01%
- CPU使用率:<5%
兩種配置都滿足了我們的需求,盡管在此階段我們沒有花時間調查超時的性質。 超時將在后面討論。 據推測,大多數響應時間是由網絡傳輸占用的。 另外,我們嘗試增加每秒的寫查詢次數,并產生了良好的結果。 沒有明顯的性能下降。
之后,我們進入下一步,即測試讀取操作。 我們使用了相同的集群。 所有讀取請求均以read_consistency_level = ONE發送。 寫入速度設置為每秒3500個查詢。 每個服務器上大約有40GB的數據,單個記錄大小約為400字節。 因此,整個數據集適合內存大小。 測試結果如下:
表1.讀取操作的初始測試結果
查看兩種配置的測試結果,我們發現超時值的百分比不令人滿意,它們是所需值的2-3倍(2-3%對1%)。 此外,我們還擔心CPU負載過高(約20%)。 至此,我們得出的結論是我們的配置有問題。
找到與超時相關的問題的根源并不是一件容易的事。 最終,我們修改了Cassandra的源代碼,并為所有讀取請求返回一個固定值(跳過從SSTables,memtables等中進行的任何查找)。 之后,再次對讀取操作執行相同的測試。 結果是完美的:GC活動和CPU使用率顯著降低,并且幾乎沒有檢測到超時。 我們還原了更改,并嘗試為GC找到最佳配置。 在嘗試了其選項之后,我們確定了以下配置:
- -XX:+ UseParallelGC
- -XX:+ UseParallelOldGC
- -XX:MaxTenuringThreshold = 3
- -Xmn1500M
- -Xmx3500M
- -Xms3500M
我們設法減少了GC對Cassandra性能的影響。 值得注意的是,讀取操作的超時次數超過了寫入操作的超時次數,因為Cassandra在讀取過程中在堆中創建了許多對象,這又導致大量的CPU使用率。 至于等待時間,它足夠低,可以很大程度上歸因于數據傳輸時間。 與更密集的讀取一起執行相同的測試表明,與寫入操作相比,增加讀取操作的數量會顯著影響超時的數量。 據推測,這一事實與GC的生長活性有關。
眾所周知的事實是,應針對每種情況分別配置GC。 在這種情況下,并發標記掃描(CMS)效果不如Parallel Old GC。 將堆大小減小到相對較小的值也很有幫助。 盡管上面的配置可能不是最好的配置,但它是滿足我們需求的一種。 另外,我們嘗試了不同版本的Java。 Java 1.7使我們相對于Java 1.6有了一些性能改進。 相對超時數減少了。 我們嘗試的另一件事是在Cassandra中啟用/禁用行/鍵緩存。 禁用緩存會稍微降低GC活動。
下一個產生令人驚訝結果的選項是池中處理Cassandra中的讀/寫請求的線程數。 由于我們的基準測試模擬了多個客戶端(最多500個線程),因此將該值從32增加到128會對性能產生重大影響。 另外,我們嘗試了不同版本的CentOS和SELinux的各種配置。 切換到更高的6.3版本后,我們發現Java期貨在較短的時間內通過超時返回了控制權。 SELinux的配置更改對性能沒有影響。
解決讀取性能問題后,我們便以混合模式(讀取+寫入)進行了測試。 在這里,我們觀察到一種情況,如下圖所示(圖2)。 在每次刷新到SSTable之后,Cassandra開始從磁盤讀取數據,這又導致客戶端超時增加。 此問題與HDD + RAM配置有關,因為從SSD讀取不會導致其他超時。
圖2.改進之前混合模式(讀+寫)中的磁盤使用情況。
我們嘗試修改Cassandra配置選項,即populate_io_cache_on_flush(如上所述)。 默認情況下,此選項是關閉的,這意味著文件系統緩存未填充新的SSTables。 因此,當訪問來自新SSTable的數據時,將從HDD中讀取數據。 將其值設置為true可解決此問題。 下圖(圖3)顯示了改進后的磁盤讀取數。
圖3.改進后,混合模式下磁盤的使用情況(讀+寫)。
換句話說,在整個數據集緩存在內存中后,即使在混合模式下,Cassandra也停止了從磁盤讀取數據。 值得注意的是,雖然從配置文件中排除了該選項,但從2.1版開始,默認情況下在Cassandra中populate_io_cache_on_flush選項處于打開狀態。 下面的摘要(表2)描述了我們嘗試的更改及其影響。
表2.對Cassandra和系統本身的更改及其對延遲的影響。
最后,應用了本文中描述的更改之后,我們在SSD和HDD + RAM配置上均取得了可接受的結果。 在調整Cassandra客戶端(我們使用Astyanax)以使其在復制因子為2的情況下正常運行并在超時的情況下可靠地按時返回控制方面也付出了很多努力。 我們還希望分享一些有關操作自動化,監控以及確保跨數據中心復制正常工作的細節,但是很難在一個帖子中涵蓋所有方面。 如上所述,我們已經開始使用HDD + RAM配置進行生產,并且可以毫無意外地可靠地工作,包括在不停機的情況下在活動集群上進行Cassandra升級。
結論
卡桑德拉(Cassandra)在引入該項目時對我們來說是新手。 我們不得不花費大量時間來探索其功能和配置選項。 它使我們能夠實現所需的體系結構并按時交付系統。 同時,我們獲得了豐富的經驗。 我們進行了大量工作,將Cassandra集成到我們的工作流程中。 我們對Cassandra源代碼的所有更改都已反饋給社區。 我們的數字營銷客戶受益于擁有更穩定,可擴展的基礎架構以及自動同步功能,從而減少了他們維護系統所需的時間。
關于網格動力學
Grid Dynamics是為Tier 1零售提供開放,可擴展的下一代商務技術解決方案的領先提供商。 Grid Dynamics在商務技術方面擁有深厚的專業知識,并廣泛參與開源社區。 偉大的公司與Grid Dynamics合作,通過在全渠道平臺,產品搜索和個性化以及持續交付方面實施和管理解決方案,獲得了可持續的業務優勢。 要了解更多關于網格動態,找到我們在www.griddynamics.com或者按照我們的Twitter @GridDynamics。
翻譯自: https://www.javacodegeeks.com/2015/02/apache-cassandra-low-latency-applications.html
總結
以上是生活随笔為你收集整理的Apache Cassandra和低延迟应用程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OSGi服务测试助手:ServiceCo
- 下一篇: 网站被ddos攻击了(网站被ddos攻击