本文目錄一覽:
- 1、java查詢的分頁思路!!
- 2、ES 深度分頁scroll使用方式
- 3、怎麼用spring獲取es數據
- 4、ES深度分頁與批量操作
- 5、ElasticSearch第5天 es實現分頁查詢的幾種方式
java查詢的分頁思路!!
分頁顯示一般有兩種實現方式:業務層分頁、數據庫層分頁(以下會用到兩個參數,提前說明下 page:請求第幾頁,size:每頁顯示多少條)
業務層分頁:從數據庫取出所有數據,然後通過傳過來的page和size對所有數據截取,比如一共查了100條數據,保存在list裏面,要求查詢第2頁,每頁顯示10條,則可以通過list屬性,取100條數據 中的第11條到第20條,可通過遍歷實現。
數據庫層分頁:數據庫都會有分頁函數(mysql 是limit函數,sqlServer是row_number()函數,可自行百度下)該方法是通過傳過來的page和size在查詢數據庫時就開始分頁,以mysql為例,查詢第2頁,每頁顯示10條,則sql語句是 」select * from XX limit 10,10「(第一個10表示從下標為10開始查,第二個10是共讀取10條)
性能肯定是第二種分頁方式好,只要搞懂分頁原理,想實現分頁其實很簡單,只要搞清楚分頁是將多條數據中的某幾條挑出來
ES 深度分頁scroll使用方式
我們知道ES對於from+size的個數是有限制的,二者之和不能超過1w。當所請求的數據總量大於1w時,可用scroll來代替from+size。
首次查詢使用方式如下:
接下來的查詢方式如下:
如果你對scroll取出的數據順序沒有要求的話,則可以對「_doc」進行排序,es對這種排序做了優化。使用方式如下:
如果你想通過slice並行分片查詢的話,可以這樣設置:
兩個請求可以同時運行。但是這樣做會有個缺陷,內存佔用較大,且第一次查詢很慢。因為查詢是O(N)的複雜度且每個slice佔用N個bits,N是shard的總文檔數。之後緩存的數據將加快查詢。
為了避免上述情況,可以選擇一個doc_values做slice,但是必須要確保這個field有以下特性:
在第一次查詢時,記錄上一次查詢的位置,在接下來的查詢中獲取到上次查詢的位置,接着查詢。
比如說將查詢order by time offset 0 limit 100,改寫成order by time where time0 limit 100,記錄最後一個$time_max,接下來的查詢order by time offset 100 limit 100,改寫成order by time where time$time_max limit 100。如此往複,可以看出scroll是一個常量查詢延遲和開銷,並無什麼副作用。
關於scroll 和search after的詳細信息,請看 .
對應到java api中,可用addSort(“_doc”, SortOrder.ASC)代替。
怎麼用spring獲取es數據
1. ES和solr都是作為全文搜索引擎出現的。都是基於Lucene的搜索服務器。
2. ES不是可靠的存儲系統,不是數據庫,它有丟數據的風險。
3. ES不是實時系統,數據寫入成功只是trans log成功(類似於MySQL的bin log),寫入成功後立刻查詢查不到是正常的。因為數據此刻可能還在內存里而不是進入存儲引擎里。同理,刪除一條數據後也不是馬上消失。寫入何時可查詢?ES內部有一個後台線程,定時將內存中的一批數據寫入到存儲引擎,此後數據可見。默認後台線程一秒運行一次。該線程運行的越頻繁,寫入性能越低。運行的頻率越低,寫入的性能越高(不會無限高)。
4. 目前已知的單ES集群可以存儲PB級別的數據,不過這個就非常費勁了。TB級別數據沒壓力。
5. 如果使用ES官方提供的jar包訪問,需要JDK1.7及以上。
6. 使用對應的版本訪問ES server。如果ES server端的版本是1.7,那麼請使用ES 1.7的client。如果ES server是2.1,請使用2.1的client。
7. ES索引存在Linux服務器的文件系統之上(背後是文件系統,不是類似於HDFS的分佈式文件系統)
8. ES Java client是線程安全的,全局構建一個即可滿足讀寫需求,不要每次都創建ES client。每次訪問ES都構建新的es client即會拋出次異常。
9. 非常不建議使用ES的動態識別和創建的機制,因為很多情況下這並非你所需要。推薦的做法是在寫數據之前仔細的創建mapping。
10. 強烈不建議在ES中使用深分頁。可能會導致集群不可用。
11. ES是靜態分片,一旦分片數在創建索引時確定那麼後繼不能修改。
12. ES里提供了type,很多人以為type是物理表,一個type的數據是獨立存儲的;但是在ES內部並不是這樣,type在ES內部僅僅是一個字段。所以在很多數據能分為獨立index的情況下,不要放到一個index里用type去分。只有嵌套類和父子類的情況下使用type才是合理的。
13. ES並不提供原生的中文分詞的能力。有第三方的中文分詞的插件,比如ik等。Ik是個toy分詞器,有嚴肅的分詞需求的話,請在使用ES之前使用獨立的分詞器分好詞後向ES寫入。
14. ES中的index,首先會進行分片,每一個分片數據一般都會有自己的副本數據,ES分配分片的策略會保證同一個分片數據和自己的副本不會分配到同一個節點上。當集群中的某一節點宕機後,ES的master在ping該節點時通過一定的策略會發現該節點不存活;會開啟ES的恢復過程
15. ES沒有update的能力。所有的update都是標記刪除老文檔,然後重新insert一條新文檔。
ES深度分頁與批量操作
一、分頁查詢
1.普通分頁查詢
2.深度分頁
其實就是搜索的深淺度,比如第一頁、第二頁、第二十頁等等,是淺分頁。第一萬頁,第兩萬頁等就是很深了
我們在獲取第9999條到10009條數據的時候,其實每個分片都會拿到10009條數據,然後集合在一起,總共是30027條數據,針對這些數據再做排序處理,最後獲得十條數據。
如此一來,搜索的太深,就會造成性能問題,會耗費內存和佔用cpu。而且es為了性能,也不支持超過一萬條數據以上的分頁查詢。解決深度分頁問題,就是應該避免深度分頁的操作(限制分頁頁數)。比如最多提供100頁的展示等。
3.scroll滾動搜索
滾動搜索可以先查詢出一些數據,然後再緊接着以此往下查詢。在第一次查詢的時候會有一個滾動id,相當於一個錨標記,隨後再次滾動搜索需要上次的標記。每次搜索都是基於一個歷史的數據快照,在查詢期間,如果有數據變更,所有的內容不會變化
4.批量查詢mget
未命中的結果也會返回json顯示是否有值。
POST /_doc/_mget
{
“ids”:[
“1008”,
“1007”,
“555”
]
}
ElasticSearch第5天 es實現分頁查詢的幾種方式
es實現分頁查詢,在ES中有三種方式可以實現分頁:from+size、scroll、search_after
這種分頁方式雖然查詢變快了,但滾動上下文代價很高,每一個 scroll_id 不僅會佔用大量的資源(特別是排序的請求),而且是生成的歷史快照,對於數據的變更不會反映到快照上,那麼在實時情況下如果處理深度分頁的問題呢?es 給出了 search_after 的方式,這是在 = 5.0 版本才提供的功能。
searchAfter的方式通過維護一個實時游標來避免scroll的缺點,它可以用於實時請求和高並發場景。
search_after的理念是,=在不同分片上(假設有5個分片),先按照指定順序排好,根據我們傳的search_after值 ,然後僅取這個值之後的size個文檔。這 5*size 個文檔拿到Es內存中排序後,返回前size個文檔即可。避免了淺分頁導致的內存爆炸情況,經實際使用性能良好,ES空閑狀態下查詢耗時穩定在50ms以內,平均10~20ms。
ElasticSearch之Search_After的注意事項
1.搜索時,需要指定sort,並且保證值是唯一的(可以通過加入_id或者文檔body中的業務唯一值來保證);
2.再次查詢時,使用上一次最後一個文檔的sort值作為search_after的值來進行查詢;
3.不能使用隨機跳頁,只能是下一頁或者小範圍的跳頁(一次查詢出小範圍內各個頁數,利用緩存等技術,來實現小範圍分頁,比較麻煩,比如從第一頁調到第五頁,則依次查詢出2,3,4頁的數據,利用每一次最後一個文檔的sort值進行下一輪查詢,客戶端或服務端都可以進行,如果跳的比較多,則可能該方法並不適用)
它與滾動API非常相似,但與它不同,search_after參數是無狀態的,它始終針對最新版本的搜索器進行解析。因此,排序順序可能會在步行期間發生變化,具體取決於索引的更新和刪除
from+ size 分頁,如果數據量不大或者from、size不大的情況下,效率還是蠻高的。但是在深度分頁的情況下,這種使用方式效率是非常低的,並發一旦過大,還有可能直接拖垮整個ElasticSearch的集群。
scroll 分頁通常不會用在客戶端,因為每一個 scroll_id 都會佔用大量的資源,一般是後台用於全量讀取數據使用
search_after通過維護一個實時游標來避免scroll的缺點,它可以用於實時請求和高並發場景,一般用於客戶端的分頁查詢
大體而言就是在這三種分頁方式中,from + size不適合數據量很大的場景,scroll不適合實時場景,而search after在es5.x版本之後應運而生,較好的解決了這個問題。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/242008.html