為了實現線上庫的複雜查詢,你還在雙寫嗎?
一、線上庫不支援線上複雜查詢
做線上業務的開發者經常會碰到這樣的難題:線上資料庫上面執行稍微複雜點的查詢,線上業務就掛了!不管是單機資料庫如MySQL、PG,還是分散式資料庫,HBase、MongoDB、Cassandra都有這個問題。下面,本文就以HBase為例對該問題進行說明,其他庫原理類似。
HBase作為海量線上儲存引擎,被廣泛應用於推薦、風控、物聯網、畫像、表單等大資料場景。Phoenix作為HBase的SQL層,極大降低了使用者使用門檻,並且實現了二級索引、加鹽表、動態列等大量實用功能。HBase底層儲存基於LSM,LSM能將業務的隨機寫轉為順序寫,能有效提升寫吞吐,但是其查詢只適合於Rowkey的字首匹配,查詢模式單一;Phoenix二級索引,底層是跟原表關聯的索引表,同樣也是字首匹配,一個表可以有多個索引,這樣可以增加查詢模式,但是索引數目不能太多,否則寫放大的問題會比較嚴重。
對於更加複雜的查詢場景,比如表單、日誌查詢裡面的模糊查詢,使用者畫像裡面的隨機條件組合等等,HBase + Phoenix的組合就不能支援。該問題是基於LSM的NoSQL線上資料庫的通用問題,除了HBase,Cassandra、LevelDB、RocksDB、MongoDB引擎等都有相同的問題。
有開發者選擇在備庫上做複雜查詢,不過前面提到線上庫本身的查詢能力往往有限,要麼很慢,要麼就查不出來,滿足不了線上複雜查詢的實時性要求。
二、雙寫遇到的問題
為了解決問題1,使用者自然會想到藉助檢索引擎,比如ES、Solr、Lucene等來解決該問題。不少使用者選擇的是雙寫的方式,也就是每一條記錄同時寫線上庫和檢索引擎,該方式看起來簡單,但實際使用過程中問題很多。我們瞭解到的case,把這套方案解決較好的客戶往往都是要投入月級別的時間和大量人力。下面以雙寫HBase和Solr為例,舉幾個使用者遇到比較多的問題。
- 一致性難以保證
雙寫很難保證線上庫跟檢索引擎的一致性。比如,兩個連結併發雙寫,並且有修改的操作,那麼很難保證HBase中同一欄位的寫入順序跟Solr中同一個doc的修改順序一致,那HBase和Solr中資料就出現了不一致,而且出現問題很難排查;另外,線上庫往往只需要儲存最近一段時間的資料,超過TTL的資料會被自動清理掉,而Solr中同樣會有這個需求。但是HBase是按照KV做TTL的,Solr是按照doc,那兩者在做資料清理的時候同樣會出現不一致。不一致的場景有很多,這裡就不一一介紹了。
- 寫入效能下降
相同配置下,HBase的吞吐要比Solr高很多,這源於軟體設計的出發點不同,最佳化的方向不同等諸多因素。如果雙寫,那勢必會導致Solr的寫吞吐限制了HBase的寫吞吐。
- 歷史資料的同步
雙寫只是解決了新資料的問題,對於歷史資料則不適用,使用者需要自己解決歷史資料批次同步問題。特別是,對於不能停機的場景,在歷史資料rebuild過程中,如何解決跟新資料跟歷史資料相互覆蓋的問題,也是十分棘手的問題。
- 冗餘儲存空間
檢索引擎專門解決索引問題,其資料儲存格式要比線上庫要更復雜,一份線上庫的資料在檢索引擎中可能需要儲存多份,比如原始資料儲存,倒排索引儲存,為提升聚合和排序的列存DocValue的儲存。那麼,勢必有儲存冗餘的問題,如何降成本也是一大挑戰。
- 穩定性
雙寫要求HBase和Solr同時保證穩定性,如果Solr出現故障,寫流程會被block住,對線上業務造成影響。
三、HBase + Solr易用性不足
阿里雲HBase Solr全文檢索引擎,採用在系統層做資料轉換和同步的方式一站式解決了使用者使用雙引擎遇到的大部分問題。但是,試用過的使用者會有一個體會,就是使用太靈活了,步驟也比較繁瑣,容易出問題,如果不是資深玩家難以駕馭。下面舉幾個使用者痛點:
- 使用門檻高
使用者需要同時理解HBase、Solr、Indexer(資料同步服務),同時操作HBase Shell,Indexer命令列,Solr介面三個途徑才能把流程走通。
- Schemaless的HBase跟強Schema的Solr資料型別
難以保證對齊
首先,使用者要自己定義從HBase column到Solr field的對映;其次,使用者要自己保證實際寫入到HBase中的型別正確。比如HBase中一個列對應Solr中一個long型別,因為HBase API並不檢查使用者實際寫入的數值是否合法,導致寫入HBase成功,但是同步到Solr是通不過的。這就要求使用者要自己基於HBase API寫一套型別檢查系統,費時費力。
- HBase + Solr對於資料冗餘儲存的問題解決不友好
使用者需要自己決定Solr中是否開啟stored,docValued選項,對於只開啟indexed選項的Field,使用者可以透過回讀HBase的方式來拿到最終結果資料,而對於開啟了stored或者docValued的Field,直接從Solr中返回結果效能會更好。這套最佳化的邏輯需要使用者自己管理和實現。
四、SearchIndex靈活易用一體化線上庫引擎
SearchIndex是阿里雲HBase SQL(Phoenix)基於HBase + Solr雙引擎的新的索引實現,其架構如上圖所示。Phoenix層將SQL(DDL、DML)語句轉化為對HBase和Solr的具體操作,SearchService負責索引同步,一致性,後設資料管理等。
SearchService內部會統一管理HBase中TimeStamp和Solr中DocVersion的對應關係,來實現最終一致性。簡單來說,Solr一行資料的DocVersion等於當前已被同步的HBase對應行各個column的TimeStamp最大值,在解決亂序時,如果前面新的cell已經被同步了,老的cell則被直接丟掉即可。而對於TTL問題,我們實現了基於行的HBase Compaction機制,來保證一致性。
SearchIndex解決了前面提到的所有問題,使用者只需要幾分鐘,幾條SQL語句就可以跑通整個流程,可參考 快速開始文件;Phoenix強型別直接對映Solr型別,並支援分詞、Array等複雜型別;自適應回查的最佳化策略更好解決了資料冗餘儲存問題。相比於HBase Solr全文檢索引擎,大大提高了易用性,並且覆蓋絕大部分的場景和需求。但目前SearchIndex還不能完全取代HBase + Solr,對於資深玩家,比較喜歡直接寫HBase API和Solr API帶來的靈活性,仍然可以選擇使用HBase Solr全文檢索引擎的方式。
SearchIndex是針對阿里雲公共雲客戶定製開發的一體化雲原生線上NoSQL資料庫引擎,具有低成本、靈活、易用、穩定等特點,已經被用於物流巴槍、線下支付表單、電商表單、醫藥實驗日誌等行業和場景,使用者資料量已達數百億規模,經歷過雙十一的考驗。使用者第一步可以只購買HBase例項,全文服務和SQL服務可以後續單獨開通,單獨升級管理。歡迎感興趣的開發者共同交流。
本文為雲棲社群原創內容,未經允許不得轉載。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69949601/viewspace-2665571/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 複雜查詢還是直接寫sql吧SQL
- 基於 MongoTemplate 實現MongoDB的複雜查詢MongoDB
- Laravel Query Builder 複雜查詢案例:子查詢實現分割槽查詢 partition byLaravelUI
- 複雜查詢—子查詢
- SQL 複雜查詢SQL
- 分散式資料庫下子查詢和 Join 等複雜 SQL 如何實現?分散式資料庫SQL
- es的複雜查詢測試,使用jest的dsl工具寫查詢語句
- JPA的多表複雜查詢
- Spring Data JPA + QueryDSL實現CRUD和複雜查詢案例Spring
- oracle表複雜查詢Oracle
- Solr複雜查詢一:函式查詢Solr函式
- Laravel使用MongoDB複雜的查詢LaravelMongoDB
- 寫一個“特殊”的查詢構造器 – (四、條件查詢:複雜條件)
- 為什麼我建議在複雜但是效能關鍵的表上所有查詢都加上 force indexIndex
- 你的 SQL 還在回表查詢嗎?快給它安排覆蓋索引SQL索引
- LinQ查詢基礎(三)LINQ to ADO.net(1)LINQ to DataSet實現複雜資料查詢
- SQL學習(三) 複雜查詢SQL
- 離線查詢與線上查詢
- linux中查詢find命令的複雜用法Linux
- 你還在為元件文件煩惱嗎?元件
- 你還在用Adapter和ViewHolder寫RecyclerView嗎?Out了!APTView
- Spring JPA聯表情況下的複雜查詢Spring
- 探討一個比較複雜的查詢
- 如何完成複雜查詢的動態構建?
- MYSQL資料庫複雜查詢練習題(難度適中)MySql資料庫
- 微服務複雜查詢之快取策略微服務快取
- 你還在這樣寫SQL嗎?趕緊改改吧SQL
- 現在的AI工具還能寫劇本殺了?AI
- 今天,你遇到redis線上連線超時了嗎?Redis
- 老闆說了,線上再出現慢查詢,開發就滾蛋!
- WPF使用Shape實現複雜線條動畫動畫
- 在MongoDB資料庫中查詢資料(上)MongoDB資料庫
- 寫文章都能靠AI了,你還在手動組網嗎?AI
- 直面不確定性與非線性的複雜現實:邁向複雜性經濟 - Cilliers
- 模糊查詢區分大小寫嗎?
- 害怕軟體的複雜嗎?其實複雜性是必須存在的 - ferd
- mybatis plus 使用LambdaQueryWrapper設定複雜的條件查詢MyBatisAPP
- 年底了!你還在為年度總結掉頭髮嗎?那還不趕緊學起來~