ES能為你解決什么問題,又會帶來什么問題?
本文轉載自微信公眾號「 寫PHP的老王」,轉載本文請聯系 寫PHP的老王公眾號。
業務需求痛點
- 業務增長,查詢條件越來越多,索引越來越多
業務發展初期,數據量不多。查詢,寫入都很快。隨著業務的發展,數據量增大,出現慢查詢,開始往表里不斷的加索引,保證數據查詢效率。但是當數據量繼續增大,業務查詢越來越復雜。程序員天天想著這個表怎么加索引。索引的增加,寫入數據的時間成本越來越高。
- 表數據增加,數據拆分越來越復雜
數據量增大,開始進行分表處理。慢慢的發現,尼瑪,分的表越來越多。再這么下去,這臺數據庫服務器上都容不下他了,這是要做數據分片的操作啊。分表已經夠費勁了,還要分片?
- 全文檢索功能
嗨,哥們,給我加個全文搜索的功能。簡單的一句話,你心里十萬個草泥馬。這么多的數據量你讓我搞全文搜索。
上面業務通點總結起來就是要查的快,要分布式,要全文搜。
ES 能解決什么問題
S主要運用于全文搜索、數據分析, 底層使用開源庫Lucene,擁有豐富的REST API。內部分布式的數據存儲、倒排索引等設計,使其可以快速存儲、搜索、分析海量數據。典型的使用方和應用場景,如github,StackOverflow,elasticsearch+logstash+kibana 一體化的日志分析。
ES 搜索為什么快的原因
對于mysql中如上的數據表,ES會對每個字段的值建立索引,通過索引的值去找數據,而且這些索引都是在內存里面的。
name段索引:
age字段索引
address 字段索引
這樣,當我們要找上海市,年齡為21歲的數據就能夠通過address,age索引快遞定位到數據id=2的是我們需要查找的。
然后在從磁盤中把數據id=2的數據讀取出來。
上面的其實就是ES中倒排索引的一個簡化版本。
實際上的ES的倒排序使用的是前綴作為索引,同時會使用*FST*對索引數據進行壓縮,以保證在內存的數據量不會因為索引多而帶來比較大的內存消耗。
對于上面的數據表,如果采用HashMap的方式對name字段索引的話,索引所占用內存20個字節。
但是如果轉換成FST結構的話,可以用四個字節表示name,總共占用內存為4+4*3=16。(假設數據范圍只有M,i,e,c) 四個字符。
ES 分布式數據結構設計
- 數據分片均衡
分片是 Elasticsearch 在集群中分發數據的關鍵。文檔存儲在分片中,然后分片分配到集群中的節點上。當集群擴容或縮小,Elasticsearch 將會自動在節點間遷移分片,以使集群保持平衡。
- 數據可靠
分片有主分片,復制分片。復制分片只是主分片的一個副本,它可以防止硬件故障導致的數據丟失,同時可以提供讀請求,比如搜索或者從別的 shard 取回文檔。
每個主分片都有一個或多個副本分片,當主分片異常時,副本可以提供數據的查詢等操作。主分片和對應的副本分片是不會在同一個節點上的 。
- 分布式搜索
分片本身就是一個完整的搜索引擎,它可以使用單一節點的所有資源。主分片或者復制分片都可以處理讀請求——搜索或文檔檢索,所以數據的冗余越多,能處理的搜索吞吐量就越大
ES 集群中每個節點通過路由都知道集群中的文檔的存放位置,所以每個節點都有處理讀寫請求的能力。
在一個寫請求被發送到某個節點后,該節點即為協調節點,協調節點會根據路由公式計算出需要寫到哪個分片上,再將請求轉發到該分片的主分片節點上。如果是查詢操作,則協調節點會將請求分發到其他分片上,其他分片查詢結果之后再由協調節點將數據組裝返回。
所以,引入ES,能夠實現幫你解決數據量多,分布式查詢問題。同時ES會自動的替你對所有字段建立索引,以實現高性能的復雜聚合查詢,因此只要是存入ES的數據,無論再復雜的聚合查詢也可以得到不錯的性能,而且你再也不用為如何建立各種復雜索引而頭痛了。另外,ES支持多種分詞器,對全文搜索支持更加高效。
ES引入會有什么樣的問題
- 字段類型無法修改、寫入性能較低和高硬件資源消耗
ES需要在創建字段前要預先建立Mapping,Mapping中包含每個字段的類型信息,ES需要根據Mapping為字段建立合適的索引。由于這個Mapping的存在,ES中的字段一但建立就不能再修改類型了。ES在數據結構靈活度上高于MySQL但遠不如MongoDB
- 不支持事務,JOIN
- 吃硬件
ES的排序和聚合(Aggregation)操作會把幾乎所有相關不相關的文檔都加載到內存中,一個Query就可以很神奇地吃光所有內存,現在新的Lucene版本優化了基于硬盤的排序,但也僅當你使用SSD的情況下,才不會犧牲過多的搜索性能。其他的問題還包括,大量的增量寫操作會導致大量的后臺Merge,CPU和硬盤讀寫都會很容易達到瓶頸。ES確實在橫向Scale方面做的很出色,但前提是有足夠的預算買硬件。
- 數據實時性
每當有新增的數據時,就將其先寫入到內存中,在內存和磁盤之間是文件系統緩存,當達到默認的時間(1秒鐘)或者內存的數據達到一定量時,會觸發一次刷新(Refresh),將內存中的數據生成到一個新的段上并緩存到文件緩存系統 上,稍后再被刷新到磁盤中并生成提交點。因此,從Index請求到對外可見能夠被搜到,最少要1秒鐘的數據延時。
- 不支持數據的權限管理
總結
ES香不香看你怎么用。有人用的很爽,有人用的很痛苦。用好了就少加班調索引,調sql。用不好就常加班調ES。
優點:
- 1.高并發
- 2.容錯能力比mg強。比如1主多從,主片掛了從片會自動頂上
- 3.滿足大數據下實時讀寫需求,無需分庫(不存在庫的概念)。
- 4.易擴展。分片數據自動均衡
- 5.支持較復雜的條件查詢,group by、排序都不是問題
缺點:
- 1.不支持事務
- 2.讀寫有一定延時
- 3.無權限管理
- 4.吃硬件