導航:首頁 > APP軟體 > esjavaapimapping

esjavaapimapping

發布時間:2023-01-11 11:18:01

㈠ ES 常見面試問題

1 增大內存: es性能優化的殺手鐧: filesystem cache(OS cache): 也就是說 盡量讓內存可以容納所有的索引數據文件,那麼搜索的時候就基本都是走內存的,性能會非常高。磁碟和OS cache掃描速度相差近一個數量級,可能一個是1到幾百毫秒,另一個是秒。最佳的情況下,就是單機機器的內存,至少可以容納單機數據量的一半。另一個方面就是寫數據的時候,僅僅寫入要用來檢索的少數幾個欄位就可以了,其餘的數據放到hbase或者mysql上
2 數據預熱
假設機器內存達到上面的要求,比如 內存是100G,數據是200G。那麼有一半的數據存放在磁碟上,那麼這個時候可以設計一個 數據預熱子系統 就是對熱數據每隔一段時間,就提前訪問一下,讓熱數據進入 filesystem cache 裡面去。這樣下次別人訪問的時候,性能一定會好很多。
3 document 模型設計
document 模型設計是非常重要的,很多操作,不要在搜索的時候才想去執行各種復雜的亂七八糟的操作,盡量存放單純的數據放到ES上去,不要考慮用 es 做一些它不好操作的事情,比如 join/nested/parent-child 搜索都要盡量避免,性能都很差的。
4 分頁性能優化
分頁性能差的原因: https://www.jianshu.com/p/e4da06b55e63
解決方案1:跟產品經理說,你系統不允許翻那麼深的頁,默認翻的越深,性能就越差。
解決方案2:類似於 app 里的推薦商品不斷下拉出來一頁一頁的
就像淘寶商品一樣,一頁一頁往下刷,不能從第一頁跳到100頁,從100頁跳到50頁,不能這樣操作。
可以使用 scroll api 來實現,scroll 會一次性給你生成所有數據的一個快照,然後每次滑動向後翻頁就是通過游標 scroll_id 移動,獲取下一頁下一頁這樣子,性能會比上面說的那種分頁性能要高很多很多,基本上都是毫秒級的。
初始化時必須指定 scroll 參數,告訴 es 要保存此次搜索的上下文多長時間。你需要確保用戶不會持續不斷翻頁翻幾個小時,否則可能因為超時而失敗。
除了用 scroll api,你也可以用 search_after 來做,search_after 的思想是使用前一頁的結果來幫助檢索下一頁的數據,顯然,這種方式也不允許你隨意翻頁,你只能一頁頁往後翻。初始化時,需要使用一個唯一值的欄位作為 sort 欄位。參考: https://www.cnblogs.com/hello-shf/p/11543453.html#4527510

見 https://www.jianshu.com/p/a5c1ec91c92e

先寫入內存 buffer,在 buffer 里的時候數據是搜索不到的;同時將數據寫入 translog 日誌文件。

如果 buffer 快滿了,或者到一定時間,就會將內存 buffer 數據 refresh 到一個新的 segment file 中,但是此時數據不是直接進入 segment file 磁碟文件,而是先進入 os cache 。這個過程就是 refresh。只要數據進入了OS cache那麼就可以被訪問到了。

每隔 1 秒鍾,es 將 buffer 中的數據寫入一個新的 segment file (如果 buffer 裡面此時沒有數據,那當然不會執行 refresh 操作) ,每秒鍾會產生一個新的磁碟文件 segment file,這個 segment file 中就存儲最近 1 秒內 buffer 中寫入的數據。

這里就解釋了為什麼叫 es 是 准實時 的? NRT,全稱 near real-time。默認是每隔 1 秒 refresh 一次的,所以 es 是准實時的,因為寫入的數據 1 秒之後才能被看到。可以通過 es 的 restful api 或者 java api,手動執行一次 refresh 操作,就是手動將 buffer 中的數據刷入 os cache中(但是這樣會影響ES批量插入數據的效率),讓數據立馬就可以被搜索到。只要數據被輸入 os cache 中,buffer 就會被清空了,因為不需要保留 buffer 了,數據在 translog 裡面已經持久化到磁碟去一份了。

重復上面的步驟,新的數據不斷進入 buffer 和 translog,不斷將 buffer 數據寫入一個又一個新的 segment file 中去,每次 refresh 完 buffer 清空,translog 保留。隨著這個過程推進,translog 會變得越來越大。當 translog 達到一定長度的時候,就會觸發 commit 操作。

commit 操作發生第一步,就是將 buffer 中現有數據 refresh 到 os cache 中去,清空 buffer。然後,將一個 commit point 寫入磁碟文件,裡面標識著這個 commit point 對應的所有 segment file,同時強行將 os cache 中目前所有的數據都 fsync 到磁碟文件中去。最後清空 現有 translog 日誌文件,重啟一個 translog,此時 commit 操作完成。

這個 commit 操作叫做 flush。默認 30 分鍾自動執行一次 flush,但如果 translog 過大,也會觸發 flush。flush 操作就對應著 commit 的全過程,我們可以通過 es api,手動執行 flush 操作,手動將 os cache 中的數據 fsync 強刷到磁碟上去。

translog 日誌文件的作用是什麼?你執行 commit 操作之前,數據要麼是停留在 buffer 中,要麼是停留在 os cache 中,無論是 buffer 還是 os cache 都是內存,一旦這台機器死了,內存中的數據就全丟了。所以需要將數據對應的操作寫入一個專門的日誌文件 translog 中,一旦此時機器宕機,再次重啟的時候,es 會自動讀取 translog 日誌文件中的數據,恢復到內存 buffer 和 os cache 中去 這里和Redis持久化機制是類似的

translog 其實也是先寫入 os cache 的,默認每隔 5 秒刷一次到磁碟中去,所以默認情況下,可能有 5 秒的數據會僅僅停留在 buffer 或者 translog 文件的 os cache 中,如果此時機器掛了,會丟失 5 秒鍾的數據。但是這樣性能比較好,最多丟 5 秒的數據。也可以將 translog 設置成每次寫操作必須是直接 fsync 到磁碟,但是性能會差很多。

總結一下,數據先寫入內存 buffer,然後每隔 1s,將數據 refresh 到 os cache,到了 os cache 數據就能被搜索到(所以我們才說 es 從寫入到能被搜索到,中間有 1s 的延遲)。每隔 5s,將數據寫入 translog 文件(磁碟裡面)(這樣如果機器宕機,內存數據全沒,最多會有 5s 的數據丟失),translog 大到一定程度,或者默認每隔 30mins,會觸發 commit 操作,將緩沖區的數據都 flush 到 segment file 磁碟文件中。

可以通過 doc id 來查詢,會根據 doc id 進行 hash,判斷出來當時把 doc id 分配到了哪個 shard 上面去,從那個 shard 去查詢。

客戶端發送請求到任意一個 node,成為 coordinate node。
coordinate node 對 doc id 進行哈希路由,將請求轉發到對應的 node,此時會使用 round-robin 隨機輪詢演算法,在 primary shard 以及其所有 replica 中隨機選擇一個,讓讀請求負載均衡。
接收請求的 node 返回 document 給 coordinate node。
coordinate node 返回 document 給客戶端。
搜索
es 最強大的是做全文檢索,就是比如你有三條數據:
java真好玩兒啊
java好難學啊
j2ee特別牛
你根據 java 關鍵詞來搜索,將包含 java的 document 給搜索出來。es 就會給你返回:java真好玩兒啊,java好難學啊。
1 客戶端發送請求到一個 coordinate node。
2 協調節點將搜索請求轉發到所有的 shard 對應的 primary shard 或 replica shard,都可以。
3 query phase:每個 shard 將自己的搜索結果(其實就是一些 doc id)返回給協調節點,由協調節點進行數據的合並、排序、分頁等操作,產出最終結果。
4 fetch phase:接著由協調節點根據 doc id 去各個節點上拉取實際的 document 數據,最終返回給客戶端。

如果是更新操作,就是將原來的 doc 標識為 deleted 狀態,然後新寫入一條數據。
buffer 每 refresh 一次,就會產生一個 segment file,所以默認情況下是 1 秒鍾一個 segment file,這樣下來 segment file 會越來越多,此時會定期執行 merge。每次 merge 的時候,會將多個 segment file 合並成一個 (這里類似於Redis的RDB文件重寫) ,同時這里會將標識為 deleted 的 doc 給 物理刪除掉 ,然後將新的 segment file 寫入磁碟,這里會寫一個 commit point,標識所有新的 segment file,然後打開 segment file 供搜索使用,同時刪除舊的 segment file。

㈡ ES的java API在更新數據時,有沒有方法根據指定欄位更新

兩表根據兩個欄位關聯即可
如 select distinct b.type_name from news a,news_type b where a.news_type_id= b.type_id and a.news_type_id = '1'

㈢ ES實現模糊搜索

最近使用ES時,有一個簡單的需求,要求實現按照某個欄位實現類似mysql中的like查詢。
這里記錄下實現方式。
這里java的api使用的是RestHighLevelClient,RestHighLevelClient從字面意思理解就是restful風格的高級別的客戶端,底層封裝的是一個http連接池,當需要執行 update、index、delete操作時,直接從連接池中取出一個連接,然後發送http請求到ElasticSearch服務端,服務端基於Netty接收請求。新版本的elasticsearch java client 都推薦用RestHighLevelClient去連接ES集群。
以下為實現方式:
這里要實現模糊匹配的欄位為:plateNo(業務上表示車牌號)
以下是一開始的實現方法。plateNo欄位type為text,現在保存了一條值為京A00000的數據

剛開始時候一直無法實現,可以搜索 京 查詢出數據;或者搜索 A00000 查詢到數據,但是使用全部 京A00000 查詢數據為空。
後來確定原因,因為為text,所以這個欄位在保存時會分詞,所以索引中不會有 京A00000,因此解決思路就是該欄位type指定為keyword,同時使用查詢時指定查詢時使用keyword,如下。
boolQueryBuilder.must(QueryBuilders.wildcardQuery("plateNo.keyword", (" 京A00000 ")));
解決問題。

㈣ es索引開啟壓縮參數

Elasticsearch 索引的配置項主要分為靜態配置屬性和動態配置屬性,靜態配置屬性是索引創建後不能修改,而動態配置屬性則可以隨時修改。

索引設置

es 索引設置的 api 為 _settings,完整的示例如下:

PUT /my_index

{

"settings": {

"index": {

"number_of_shards": "1",

"number_of_replicas": "1",

"refresh_interval": "60s",

"analysis": {

JAVA代碼ES設置setting
打開APP

weixin_39533307
關注
JAVA代碼ES設置setting_Elasticsearch(es)索引設置(settings)參數詳解 原創
2021-02-24 03:00:19

weixin_39533307

碼齡5年

關注
Elasticsearch 索引的配置項主要分為靜態配置屬性和動態配置屬性,靜態配置屬性是索引創建後不能修改,而動態配置屬性則可以隨時修改。

索引設置

es 索引設置的 api 為 _settings,完整的示例如下:

PUT /my_index

{

"settings": {

"index": {

"number_of_shards": "1",

"number_of_replicas": "1",

"refresh_interval": "60s",

"analysis": {

"filter": {

"tsconvert": {

"type": "stconvert",

"convert_type": "t2s",

"delimiter": ","

},

"synonym": {

"type": "synonym",

"synonyms_path": "analysis/synonyms.txt"

}

},

"analyzer": {

"ik_max_word_synonym": {

"filter": [

"synonym",

"tsconvert",

"standard",

"lowercase",

"stop"

],

"tokenizer": "ik_max_word"

},

"ik_smart_synonym": {

es 修改setting
打開APP

weixin_39533307
關注
JAVA代碼ES設置setting_Elasticsearch(es)索引設置(settings)參數詳解 原創
2021-02-24 03:00:19

weixin_39533307

碼齡5年

關注
Elasticsearch 索引的配置項主要分為靜態配置屬性和動態配置屬性,靜態配置屬性是索引創建後不能修改,而動態配置屬性則可以隨時修改。

索引設置

es 索引設置的 api 為 _settings,完整的示例如下:

PUT /my_index

{

"settings": {

"index": {

"number_of_shards": "1",

"number_of_replicas": "1",

"refresh_interval": "60s",

"analysis": {

"filter": {

"tsconvert": {

"type": "stconvert",

"convert_type": "t2s",

"delimiter": ","

},

"synonym": {

"type": "synonym",

"synonyms_path": "analysis/synonyms.txt"

}

},

"analyzer": {

"ik_max_word_synonym": {

"filter": [

"synonym",

"tsconvert",

"standard",

"lowercase",

"stop"

],

"tokenizer": "ik_max_word"

},

"ik_smart_synonym": {

"filter": [

"synonym",

"standard",

"lowercase",

"stop"

],

"tokenizer": "ik_smart"

}

},

"mapping": {

"coerce": "false",

"ignore_malformed": "false"

},

"indexing": {

"slowlog": {

"threshold": {

"index": {

"warn": "2s",

"info": "1s"
固定屬性

index.creation_date:顧名思義索引的創建時間戳。

index.uuid:索引的 uuid 信息。

index.version.created:索引的版本號。

索引靜態配置

index.number_of_shards:索引的主分片數,默認值是 5。這個配置在索引創建後不能修改;在 es 層面,可以通過 es.index.max_number_of_shards 屬性設置索引最大的分片數,默認為 1024。

index.codec:數據存儲的壓縮演算法,默認值為 LZ4,可選擇值還有 best_compression,它比 LZ4 可以獲得更好的壓縮比(即占據較小的磁碟空間,但存儲性能比 LZ4 低)。

index.routing_partition_size:路由分區數,如果設置了該參數,其路由演算法為:( hash(_routing) + hash(_id) % index.routing_parttion_size ) % number_of_shards。如果該值不設置,則路由演算法為 hash(_routing) % number_of_shardings,_routing 默認值為 _id。靜態配置里,有重要的部分是配置分析器(config analyzers)。

index.analysis:分析器最外層的配置項,內部主要分為 char_filter、tokenizer、filter 和analyzer。

char_filter:定義新的字元過濾器件。

tokenizer:定義新的分詞器。

filter:定義新的 token filter,如同義詞 filter。

analyzer:配置新的分析器,一般是char_filter、tokenizer 和一些 token filter 的組合。

索引動態配置

index.number_of_replicas:索引主分片的副本數,默認值是 1,該值必須大於等於 0,這個配置可以隨時修改。

index.refresh_interval:執行新索引數據的刷新操作頻率,該操作使對索引的最新更改對搜索可見,默認為 1s。也可以設置為 -1 以禁用刷新。更詳細信息參考 Elasticsearch 動態修改 refresh_interval 刷新間隔設置。

㈤ es使用與原理2 -- scoll技術,bouncing results,零停機重建索引等等

默認情況下,是按照_score降序排序的,我們也可以定製排序規則

Elasticsearch使用的是 term frequency/inverse document frequency演算法,簡稱為TF/IDF演算法
Term frequency(TF): 搜索文本中的各個詞條在field文本中出現了多少次,出現次數越多,就越相關
如:搜索請求:hello world
doc1:hello you, and world is very good
doc2:hello, how are you
doc1 肯定比doc2的評分高,因為hello world都在doc1中出現了。
Inverse document frequency(IDF): 搜索文本中的各個詞條在整個索引的所有文檔中出現了多少次,出現的次數越多,就越不相關
搜索請求:hello world
doc1:hello, today is very good
doc2:hi world, how are you
比如說,在index中有1萬條document,hello這個單詞在所有的document中,一共出現了1000次;world這個單詞在所有的document中,一共出現了100次
那最終的結果肯定是 word的得分所佔比更高

關於_score,ES還有一條規則。
Field-length norm:field長度,field越長,相關度越弱
搜索請求:hello world
doc1:{ "title": "hello article", "content": "babaaba 1萬個單詞" }
doc2:{ "title": "my article", "content": "blablabala 1萬個單詞,hi world" }
hello world在整個index中出現的次數是一樣多的。最終 doc1得分更高

搜索的時候,要依靠倒排索引;排序的時候,需要依靠正排索引,看到每個document的每個field,然後進行排序,所謂的正排索引,其實就是doc values,doc values 也可以供排序,聚合,過濾等操作使用。doc values是被保存在磁碟上的,此時如果內存足夠,os會自動將其緩存在內存中,性能還是會很高;如果內存不足夠,os會將其寫入磁碟上
正排索引如下:

倒排索引不可變的好處

想像一下有兩個文檔有同樣值的時間戳欄位,搜索結果用 timestamp 欄位來排序。 由於搜索請求是在所有有效的分片副本間輪詢的,那就有可能發生主分片處理請求時,這兩個文檔是一種順序, 而副本分片處理請求時又是另一種順序。
這就是所謂的 bouncing results 問題: 每次用戶刷新頁面,搜索結果表現是不同的順序。 讓同一個用戶始終使用同一個分片,這樣可以避免這種問題, 可以設置 preference 參數為一個特定的任意值比如用戶會話ID來解決。

如果一次性要查出來比如10萬條數據,那麼性能會很差,此時一般會採取用scoll滾動查詢,一批一批的查,直到所有數據都查詢完處理完。

scoll,看起來挺像分頁的,但是其實使用場景不一樣。分頁主要是用來一頁一頁搜索,給用戶看的;scoll主要是用來一批一批檢索數據,讓系統進行處理的

使用scoll滾動搜索,可以先搜索一批數據,然後下次再搜索一批數據,以此類推,直到搜索出全部的數據來
scoll搜索會在第一次搜索的時候,保存一個當時的視圖快照,之後只會基於該舊的視圖快照提供數據搜索,如果這個期間數據變更,是不會讓用戶看到的
採用基於_doc進行排序的方式,性能較高
每次發送scroll請求,我們還需要指定一個scoll參數,指定一個時間窗口,每次搜索請求只要在這個時間窗口內能完成就可以了

獲得的結果會有一個scoll_id,下一次再發送scoll請求的時候,必須帶上這個scoll_id

1 創建索引

2 修改索引

3 刪除索引

lucene是沒有type的概念的,在document中,實際上將type作為一個document的field來存儲,即_type,es通過_type來進行type的過濾和篩選
一個index中的多個type,實際上是放在一起存儲的,因此一個index下,不能有多個type重名,而類型或者其他設置不同的,因為那樣是無法處理的
比如

底層存儲是這樣的

將類似結構的type放在一個index下,這些type應該有多個field是相同的
假如說,你將兩個type的field完全不同,放在一個index下,那麼就每條數據都d會有大量field在底層的lucene中是空值,會有嚴重的性能問題

1、定製dynamic策略
true:遇到陌生欄位,就進行dynamic mapping
false:遇到陌生欄位,就忽略
strict:遇到陌生欄位,就報錯

2、定製自己的dynamic mapping template(type level)

上面的設置是/my_index/my_type 的欄位,如果是以_en結尾的,那麼就自動映射為string類型

一個field的設置是不能被修改的,如果要修改一個Field,那麼應該重新按照新的mapping,建立一個index,然後將數據批量查詢出來,重新用bulk api寫入index中。
批量查詢的時候,建議採用scroll api,並且採用多線程並發的方式來reindex數據,每次scoll就查詢指定日期的一段數據,交給一個線程即可。

(1)一開始,依靠dynamic mapping,插入數據,但是不小心有些數據是2017-01-01這種日期格式的,所以title這種field被自動映射為了date類型,實際上業務認為它應該是string類型的

(2)當後期向索引中加入string類型的title值的時候,就會報錯

(3)如果此時想修改title的類型,是不可能的

(4)此時,唯一的辦法,就是進行reindex,也就是說,重新建立一個索引,將舊索引的數據查詢出來,再導入新索引
(5)如果說舊索引的名字,是old_index,新索引的名字是new_index,終端java應用,已經在使用old_index在操作了,難道還要去停止java應用,修改使用的index為new_index,才重新啟動java應用嗎?這個過程中,就會導致java應用停機,可用性降低
(6)所以說,給java應用一個別名,這個別名是指向舊索引的,java應用先用著,java應用先用goods_index alias來操作,此時實際指向的是舊的my_index

(7)新建一個index,調整其title的類型為string

(8)使用scroll api將數據批量查詢出來

(9)採用bulk api將scoll查出來的一批數據,批量寫入新索引

(10)反復循環8~9,查詢一批又一批的數據出來,採取bulk api將每一批數據批量寫入新索引

(11)將goods_index alias切換到my_index_new上去,java應用會直接通過index別名使用新的索引中的數據,java應用程序不需要停機,零提交,高可用

(12)直接通過goods_index別名來查詢,是否ok

現有流程的問題,每次都必須等待fsync將segment刷入磁碟,才能將segment打開供search使用,這樣的話,從一個document寫入,到它可以被搜索,可能會超過1分鍾!!!這就不是近實時的搜索了!!!主要瓶頸在於fsync實際發生磁碟IO寫數據進磁碟,是很耗時的。

㈥ Elastic Search 讀寫底層執行過程

1、es寫數據大概過程

1)客戶端選擇一個node發送請求過去,這個node就是coordinating node(協調節點)
2)coordinating node,對document進行路由,將請求轉發給對應的node(有primary shard)
3)實際的node上的primary shard處理請求,然後將數據同步到replica node
4)coordinating node,如果發現primary node和所有replica node都搞定之後,就返回響應結果給客戶端

2、寫數據的底層執行過程

1)先寫入buffer,在buffer里的時候數據是搜索不到的;同時將數據寫入translog日誌文件

2)如果buffer快滿了,或者到一定時間,就會將buffer數據refresh到一個新的segment file中,但是此時數據不是直接進入segment file的磁碟文件的,而是先進入os cache的。這個過程就是refresh。

每隔1秒鍾,es將buffer中的數據寫入一個新的segment file,每秒鍾會產生一個新的磁碟文件,segment file,這個segment file中就存儲最近1秒內buffer中寫入的數據

但是如果buffer裡面此時沒有數據,那當然不會執行refresh操作咯,每秒創建換一個空的segment file,如果buffer裡面有數據,默認1秒鍾執行一次refresh操作,刷入一個新的segment file中

操作系統裡面,磁碟文件其實都有一個東西,叫做os cache,操作系統緩存,就是說數據寫入磁碟文件之前,會先進入os cache,先進入操作系統級別的一個內存緩存中去

只要buffer中的數據被refresh操作,刷入os cache中,就代表這個數據就可以被搜索到了

為什麼叫es是准實時的?NRT,near real-time,准實時。默認是每隔1秒refresh一次的,所以es是准實時的,因為寫入的數據1秒之後才能被看到。

可以通過es的restful api或者java api,手動執行一次refresh操作,就是手動將buffer中的數據刷入os cache中,讓數據立馬就可以被搜索到。

只要數據被輸入os cache中,buffer就會被清空了,因為不需要保留buffer了,數據在translog裡面已經持久化到磁碟去一份了

3)只要數據進入os cache,此時就可以讓這個segment file的數據對外提供搜索了

4)重復1~3步驟,新的數據不斷進入buffer和translog,不斷將buffer數據寫入一個又一個新的segment file中去,每次refresh完buffer清空,translog保留。隨著這個過程推進,translog會變得越來越大。當translog達到一定長度的時候,就會觸發commit操作。

buffer中的數據,倒是好,每隔1秒就被刷到os cache中去,然後這個buffer就被清空了。所以說這個buffer的數據始終是可以保持住不會填滿es進程的內存的。

每次一條數據寫入buffer,同時會寫入一條日誌到translog日誌文件中去,所以這個translog日誌文件是不斷變大的,當translog日誌文件大到一定程度的時候,就會執行commit操作。

5)commit操作發生第一步,就是將buffer中現有數據refresh到os cache中去,清空buffer

6)將一個commit point寫入磁碟文件,裡面標識著這個commit point對應的所有segment file

7)強行將os cache中目前所有的數據都fsync到磁碟文件中去

translog日誌文件的作用是什麼?就是在你執行commit操作之前,數據要麼是停留在buffer中,要麼是停留在os cache中,無論是buffer還是os cache都是內存,一旦這台機器死了,內存中的數據就全丟了。

所以需要將數據對應的操作寫入一個專門的日誌文件,translog日誌文件中,一旦此時機器宕機,再次重啟的時候,es會自動讀取translog日誌文件中的數據,恢復到內存buffer和os cache中去。

commit操作:1、寫commit point;2、將os cache數據fsync強刷到磁碟上去;3、清空translog日誌文件

8)將現有的translog清空,然後再次重啟啟用一個translog,此時commit操作完成。默認每隔30分鍾會自動執行一次commit,但是如果translog過大,也會觸發commit。整個commit的過程,叫做flush操作。我們可以手動執行flush操作,就是將所有os cache數據刷到磁碟文件中去。

不叫做commit操作,flush操作。es中的flush操作,就對應著commit的全過程。我們也可以通過es api,手動執行flush操作,手動將os cache中的數據fsync強刷到磁碟上去,記錄一個commit point,清空translog日誌文件。

9)translog其實也是先寫入os cache的,默認每隔5秒刷一次到磁碟中去,所以默認情況下,可能有5秒的數據會僅僅停留在buffer或者translog文件的os cache中,如果此時機器掛了,會丟失5秒鍾的數據。但是這樣性能比較好,最多丟5秒的數據。也可以將translog設置成每次寫操作必須是直接fsync到磁碟,但是性能會差很多。

實際上你在這里,如果面試官沒有問你es丟數據的問題,你可以在這里給面試官炫一把,你說,其實es第一是准實時的,數據寫入1秒後可以搜索到;可能會丟失數據的,你的數據有5秒的數據,停留在buffer、translog os cache、segment file os cache中,有5秒的數據不在磁碟上,此時如果宕機,會導致5秒的數據丟失。

如果你希望一定不能丟失數據的話,你可以設置個參數,官方文檔,網路一下。每次寫入一條數據,都是寫入buffer,同時寫入磁碟上的translog,但是這會導致寫性能、寫入吞吐量會下降一個數量級。本來一秒鍾可以寫2000條,現在你一秒鍾只能寫200條,都有可能。

10)如果是刪除操作,commit的時候會生成一個.del文件,裡面將某個doc標識為deleted狀態,那麼搜索的時候根據.del文件就知道這個doc被刪除了

11)如果是更新操作,就是將原來的doc標識為deleted狀態,然後新寫入一條數據

12)buffer每次refresh一次,就會產生一個segment file,所以默認情況下是1秒鍾一個segment file,segment file會越來越多,此時會定期執行merge

13)每次merge的時候,會將多個segment file合並成一個,同時這里會將標識為deleted的doc給物理刪除掉,然後將新的segment file寫入磁碟,這里會寫一個commit point,標識所有新的segment file,然後打開segment file供搜索使用,同時刪除舊的segment file。

es里的寫流程,有4個底層的核心概念,refresh、flush、translog、merge

當segment file多到一定程度的時候,es就會自動觸發merge操作,將多個segment file給merge成一個segment file。

查詢,GET某一條數據,寫入了某個document,這個document會自動給你分配一個全局唯一的id,doc id,同時也是根據doc id進行hash路由到對應的primary shard上面去。也可以手動指定doc id。

你可以通過doc id來查詢,會根據doc id進行hash,判斷出來當時把doc id分配到了哪個shard上面去,從那個shard去查詢

1)客戶端發送請求到任意一個node,成為coordinate node
2)coordinate node對document進行路由,將請求轉發到對應的node,此時會使用round-robin隨機輪詢演算法,在primary shard以及其所有replica中隨機選擇一個,讓讀請求負載均衡
3)接收請求的node返回document給coordinate node
4)coordinate node返回document給客戶端

es最強大的是做全文檢索

1)客戶端發送請求到一個coordinate node
2)協調節點將搜索請求轉發到所有的shard對應的primary shard或replica shard也可以
3)query phase:每個shard將自己的搜索結果(其實就是一些doc id),返回給協調節點,由協調節點進行數據的合並、排序、分頁等操作,產出最終結果
4)fetch phase:接著由協調節點,根據doc id去各個節點上拉取實際的document數據,最終返回給客戶端

㈦ 用java怎麼造es的mappings元數據

用java怎麼造es的mappings元數據
Mapping,就是對索引庫中索引的欄位名及其數據類型進行定義,類似於關系資料庫中表建立時要定義欄位名及其數據類型那樣,不過es的mapping比資料庫靈活很多,它可以動態添加欄位。一般不需要要指定mapping都可以,因為es會自動根據數據格式定義它的類型,如果你需要對某些欄位添加特殊屬性

㈧ 怎麼用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一條新文檔。

㈨ ElasticSearch java 如何更改索引最大查詢窗口(max_result_window)

java查詢elasticsearch 有哪些索引

次查詢可分為下面四個步驟:

  1. 創建連接ElasticSearch服務的client.

  2. 索引在ElasticSearch伺服器上,進行索引的查詢首先要和伺服器創建連接,這是第一步。

  3. <code>Client client = TransportClient.builder().build()

  4. .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

  5. </code>

2.創建QueryBuilder.

QueryBuilder可以設置單個欄位的查詢,也可以設置多個欄位的查詢.

e.g.1: 查詢title欄位中包含hibernate關鍵字的文檔:

<code>QueryBuilder qb1 = termQuery("title", "hibernate");

</code>


e.g.2: 查詢title欄位或content欄位中包含git關鍵字的文檔:

<code>QueryBuilder qb2= QueryBuilders.multiMatchQuery("git", "title","content");

</code>


3.執行查詢

通過client設置查詢的index、type、query.返回一個SearchResponse對象:

<code>SearchResponse response = client.prepareSearch("blog").setTypes("article").setQuery(qb2).execute()

.actionGet();

</code>


4.處理查詢結果

SearchResponse對象的getHits()方法獲取查詢結果,返回一個SearchHits的集合,遍歷集合獲取查詢的文檔信息:

?


1

2

<code>SearchHits hits = response.getHits();

</code>

㈩ [ElasticSearch] Aggregation :簡單聚合查詢

ES提供的聚合介面相當靈活和豐富,值得系統的學習一下。學習方式想了下,應該跟SQL結合起來,SQL相對來說比較直觀,ES官網對Aggregation描述的展開也是從SQL開始的,所以通過設計不同的SQL 聚合查詢場景,分別看下ES中用Aggregation API和Java API是怎麼實現的。

測試數據源於 官網

測試數據是汽車的銷售信息,這次實現的SQL是按顏色groupby,查詢每種顏色的銷售數目。

Aggregation API:

java API:

閱讀全文

與esjavaapimapping相關的資料

熱點內容
maya粒子表達式教程 瀏覽:84
抖音小視頻如何掛app 瀏覽:283
cad怎麼設置替補文件 瀏覽:790
win10啟動文件是空的 瀏覽:397
jk網站有哪些 瀏覽:134
學編程和3d哪個更好 瀏覽:932
win10移動硬碟文件無法打開 瀏覽:385
文件名是亂碼還刪不掉 瀏覽:643
蘋果鍵盤怎麼打開任務管理器 瀏覽:437
手機桌面文件名字大全 瀏覽:334
tplink默認無線密碼是多少 瀏覽:33
ipaddgm文件 瀏覽:99
lua語言編程用哪個平台 瀏覽:272
政采雲如何導出pdf投標文件 瀏覽:529
php獲取postjson數據 瀏覽:551
javatimetask 瀏覽:16
編程的話要什麼證件 瀏覽:94
錢脈通微信多開 瀏覽:878
中學生學編程哪個培訓機構好 瀏覽:852
榮耀路由TV設置文件共享錯誤 瀏覽:525

友情鏈接