为了实现在线库的复杂查询,你还在双写吗?
一、在線庫不支持在線復雜查詢
做在線業務的開發者經常會碰到這樣的難題:在線數據庫上面運行稍微復雜點的查詢,在線業務就掛了!不管是單機數據庫如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界面三個途徑才能把流程走通。
首先,用戶要自己定義從HBase column到Solr field的映射;其次,用戶要自己保證實際寫入到HBase中的類型正確。比如HBase中一個列對應Solr中一個long類型,因為HBase API并不檢查用戶實際寫入的數值是否合法,導致寫入HBase成功,但是同步到Solr是通不過的。這就要求用戶要自己基于HBase API寫一套類型檢查系統,費時費力。
用戶需要自己決定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服務可以后續單獨開通,單獨升級管理。歡迎感興趣的開發者共同交流。
原文鏈接
本文為云棲社區原創內容,未經允許不得轉載。
總結
以上是生活随笔為你收集整理的为了实现在线库的复杂查询,你还在双写吗?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【从入门到放弃-ZooKeeper】Zo
- 下一篇: 一键托管,阿里云全链路追踪服务正式商用: