ES 的 4 種分頁方式,如何選擇?
在 Elasticsearch 中,有 4 種常見的分頁方法,這篇文章,我們將分析每種方法的優缺點以及我們該如何選擇。
1. 使用 from
和 size
使用 from
和 size
是最常用的分頁方式,通過設置 from
參數指定從結果集的哪個位置開始,size
參數指定返回多少條記錄。使用語法如下:
GET /index/_search
{
"from": 10,
"size": 10,
"query": {
"match": {
"field": "value"
}
}
}
優點
-
簡單易用:實現起來非常直觀,適用於大多數基本的分頁需求。
-
廣泛支持:Elasticsearch 搜索 API 默認支持這種分頁方式。
缺點
-
性能問題:對於深頁(高
from
值),性能會顯著下降,因爲 Elasticsearch 需要跳過前面的from
條記錄。這會導致查詢時間增加,尤其是當from
值較大時。 -
資源消耗:高
from
值會消耗更多的內存和 CPU 資源,可能影響集羣性能。
適用場景
-
淺分頁:適用於前幾頁的查詢(例如,第 1 頁到第 10 頁)。
-
小數據集:當數據量較小且分頁需求不復雜時。
2. 使用 search_after
search_after
基於排序值實現深度分頁,通過提供上一個頁面的排序值來繼續檢索下一頁的數據。使用語法如下:
GET /index/_search
{
"size": 10,
"query": {
"match": {
"field": "value"
}
},
"sort": [
{ "timestamp": "asc" },
{ "_id": "asc" }
],
"search_after": [ "2023-01-01T00:00:00", "some_id" ]
}
優點
-
高效深度分頁:相比
from/size
,search_after
在處理深層分頁時性能更好,不會隨着頁數增加而顯著下降。 -
去重性強:結合唯一排序字段(如
_id
),可以避免重複數據。
缺點
-
狀態管理:需要在客戶端保存上一次查詢返回的排序值,增加了實現複雜度。
-
不可跳頁:無法像傳統分頁那樣直接跳轉到任意頁,只能順序翻頁。
適用場景
-
深度分頁:適用於需要訪問大量數據且需要高效性能的場景。
-
數據連續流:適合數據流式訪問,如日誌檢索、實時數據分析等。
3. 使用 Scroll API
Scroll API
適用於處理大量數據的批量檢索,通過保持一個在查詢時刻的快照,允許用戶遍歷整個結果集。使用語法如下:
POST /index/_search?scroll=1m
{
"size": 100,
"query": {
"match_all": {}
}
}
# 獲取後續數據
POST /_search/scroll
{
"scroll": "1m",
"scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAA..."
}
優點
-
處理大量數據:適合導出或批量處理大量數據,性能穩定。
-
避免跳頁問題:通過持續的快照避免數據在檢索過程中變化影響結果。
缺點
-
資源消耗:保持 scroll 上下文會佔用集羣資源,尤其是在併發請求較高時。
-
不適合實時搜索:Scroll API 主要用於一次性檢索,不適合用戶交互的分頁需求。
適用場景
-
批量數據導出:如數據遷移、備份等。
-
大規模分析:需要一次性處理大量文檔的場景。
4. 使用 Point in Time
使用 Point in Time (PIT) 提供了一種基於時間點的查詢方式,允許在多個分頁請求中維持一致的視圖。使用語法如下:
POST /index/_search?pit=true&size=10
{
"sort": [...],
"query": { ... }
}
# 後續請求使用 pit_id
POST /index/_search
{
"pit": {
"id": "some_pit_id",
"keep_alive": "1m"
},
"sort": [...],
"query": { ... },
"search_after": [ ... ]
}
優點
-
一致性視圖:在多個分頁請求中保持數據的一致性,即使索引發生變化。
-
結合 search_after 使用:提高深度分頁的效率和一致性。
缺點
-
複雜度增加:需要管理 PIT 會話,包括生命週期和資源釋放。
-
資源消耗:維持 PIT 會話會佔用集羣資源。
適用場景
-
需要一致性分頁:如多用戶同時分頁瀏覽數據,確保每個用戶看到的數據一致。
-
結合 search_after:需要高效的深度分頁且保持一致視圖的場景。
5. 如何選擇?
5.1 根據分頁深度選擇
-
淺分頁(前幾頁):使用
from
和size
,實現簡單且性能可接受。 -
深度分頁:使用
search_after
或結合Point in Time
,提高性能並避免資源浪費。
5.2 根據數據一致性要求
-
無需嚴格一致性:
from
和size
已足夠,適用於數據不頻繁變動的場景。 -
需要一致性視圖:使用
Point in Time
,確保分頁過程中數據的一致性。
5.3 根據使用場景
-
用戶交互分頁:通常使用
from
和size
,適合大多數 Web 應用分頁需求。 -
批量處理或導出:使用 Scroll API,適合一次性處理大量數據的任務。
5.4 根據資源和性能考慮
-
資源有限:避免使用 Scroll API,尤其是在高併發環境下。
-
性能優化:對於頻繁的深度分頁,
search_after
和Point in Time
是更優的選擇。
6. 總結
本文,我們介紹了 ES的4種分頁方式:
-
from
和size
:適用於淺分頁,簡單易用,但不適合深度分頁。 -
search_after
:適合深度分頁,性能更優,但實現複雜度略高,且不支持隨機跳頁。 -
Scroll API:適用於批量處理和導出,不適合實時用戶交互的分頁需求。
-
Point in Time (PIT):提供一致的分頁視圖,適合需要數據一致性的深度分頁場景。
在實際開發中,我們需要根據具體的業務需求、數據量、分頁深度和系統資源,選擇最合適的分頁方法,以達到最佳的性能和用戶體驗。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/cZSPYWwKkpl_cqWIqNpAtw