本篇主要介紹一下Elasticsearch Document的數據格式,在Java應用程序、關係型數據庫建模的對比,介紹在Kibana平臺編寫Restful API完成基本的集羣狀態查詢,Document最基本CRUD操做示例以及bulk批處理示例。java
Java應用系統的數據模型都是面向對象的,有些對象比較複雜,傳統的業務系統,數據須要落地到關係型數據庫,在數據庫領域模型設計時,會把複雜的POJO對象設計成一對一或一對多的關係,進行扁平化處理,查詢的時候,須要多表查詢並還原回POJO對象的格式。
Elasticsearch是文檔數據庫,Document存儲的數據結構,能夠和POJO保持一致,而且使用JSON格式,這樣查詢數據時比較方便。node
Document文檔數據示例:web
{ "fullname" : "Three Zhang", "text" : "hello elasticsearch", "org": { "name": "development", "desc": "all member are lovely" } }
前面文章有說起Elasticsearch與Kibana搭配使用,Kibana界面的Dev Tools菜單,能夠發送Elasticsearch的Restful請求。後續的Restful API請求,如無例外,均是在Kibana平臺上執行的。數據庫
咱們先拿幾個查詢集羣信息的請求來試試json
GET /_cat/health?v
api
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent 1573626290 14:24:50 hy-application yellow 1 1 1 1 0 0 1 0 - 50.3%
從上面能看出node、shard的數量等,還有一個是集羣的狀態,上面顯示的是yellow,爲何是yellow?
集羣的狀態有green、yellow、red三種,定義以下:性能優化
咱們的示例只啓動了一個elasticsearch實例,只有一個node,因爲索引默認會使用5個primary shard和5個replica shard,而且同一個node下面的primary shard和replica shard不能分配在一臺機器上(容錯機制),全部只有1個primary shard被分配和啓動了,replica shard沒有第二臺node去啓動,於是是yellow狀態。若是想變成green判斷,另外啓一臺node便可。restful
GET /_cat/indices?v
數據結構
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size yellow open location 48G_CgE7TiWomlYsyQW1NQ 5 1 3 0 11kb 11kb yellow open company_mem s9DKUeyWTdCj2J8BaFYXRQ 5 1 3 0 15kb 15kb yellow open %{[appname]} ysT9_OibR5eSRu19olrq_w 5 1 32 0 386.5kb 386.5kb yellow open .kibana 4yS67TTOQGOD7l-uMtICOg 1 0 2 0 12kb 12kb yellow open tvs EM-SvQdfSaGAXUADmDFHVg 5 1 8 0 16.3kb 16.3kb yellow open company_org wIOqfx5hScavO13vvyucMg 5 1 3 0 14.6kb 14.6kb yellow open blog n5xmcGSbSamYphzI_LVSYQ 5 1 1 0 4.9kb 4.9kb yellow open website 5zZZB3cbRkywC-iTLCYUNg 5 1 12 0 18.2kb 18.2kb yellow open files _6E1d7BLQmy9-7gJptVp7A 5 1 2 0 7.3kb 7.3kb yellow open files-lock XD7LFToWSKe_6f1EvLNoFw 5 1 1 0 8kb 8kb yellow open music i1RxpIdjRneNA7NfLjB32g 5 1 3 0 15.1kb 15.1kb yellow open book_shop 1CrHN1WmSnuvzkfbVCuOZQ 5 1 4 0 18.1kb 18.1kb yellow open avs BCS2qgfFT_GqO33gajcg_Q 5 1 0 0 1.2kb 1.2kb
GET /_cat/nodes?v
架構
響應:
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name 192.168.17.137 38 68 0 0.08 0.03 0.05 mdi * node-1
咱們能夠看到node的名稱。
建立名稱爲"location"的索引
PUT /location?pretty
響應:
{ "acknowledged": true, "shards_acknowledged": true }
查看索引,能看到剛剛建立的索引location
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size yellow open location 48G_CgE7TiWomlYsyQW1NQ 5 1 3 0 11kb 11kb yellow open .kibana 4yS67TTOQGOD7l-uMtICOg 1 0 2 0 12kb 12kb
刪除名稱爲"location"的索引
DELETE /location?pretty
再查看索引,剛剛建立的索引location已經刪除掉了
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size yellow open .kibana 4yS67TTOQGOD7l-uMtICOg 1 0 2 0 12kb 12kb
是否是很簡單,交互界面挺友好吧?
介紹document最基本的CRUD操做,以兒童英文歌曲爲背景
咱們設計的兒歌結構包含四個字段:歌名name,歌詞content,語言種類language,歌曲時間長length,單位是秒,放在JSON字符串裏。
PUT語法:
<REST Verb> /<Index>/<Type>/<ID>
REST Verbs能夠是PUT、POST、DELETE,後斜槓後的內容分別是索引名、類型名、ID。
請求以下:
PUT /music/children/1 { "name": "gymbo", "content": "I hava a friend who loves smile, gymbo is his name", "language": "english", "length": "75" }
響應內容包含索引名、類型名、ID值,version版本號(樂觀鎖控制),結果類型(created/updated/deleted三種),shard信息等,若是新增時該索引不存在,會自動建立索引,索引名即請求時指定的那個,document裏面的field類型,就根據elasticsearch定義的自動映射類型,而且每一個field都會創建倒排索引,讓其能夠被搜索到。
total和successful爲何數據不相等?
新增document時,會往primary shard和replica shard分別寫入document,但因爲只有一個node,replica未啓動,因此總共寫入2次,primary shard成功,數量是1。failed只記錄primary shard寫入失敗的狀況。
響應以下:
{ "_index": "music", "_type": "children", "_id": "1", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 0, "_primary_term": 1 }
POST /music/children/1/_update { "doc": { "length": "76" } }
響應:
{ "_index": "music", "_type": "children", "_id": "1", "_version": 2, "result": "updated", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 1, "_primary_term": 1 }
PUT /music/children/1 { "name": "gymbo", "content": "I hava a friend who loves smile, gymbo is his name", "language": "english", "length": "77" }
響應:
{ "_index": "music", "_type": "children", "_id": "1", "_version": 3, "result": "updated", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 2, "_primary_term": 1 }
細心的童鞋能夠,全量替換文檔的語法和建立索引是同樣的,對!就是同一個語法 ,是建立仍是更新取決於上面的ID存不存在,不存在作建立,存在作更新,更新成功version+1,但這種全量替換有個很差的地方,必須帶上完整的屬性,不然未聲明屬性就沒有了。
想一想要使用這個語法的場景:先GET全部的屬性,而後把要更新的屬性更新上,再調用全量替換的更新語法。實際上這種作法很少,緣由不外乎兩個:操做複雜,要先查詢後更新;報文過大(相對於增量更新)。因此企業研發通常使用增量方式作document更新。
查詢語句:GET /music/children/1
_source即爲JSON的內容,查詢結果:
{ "_index": "music", "_type": "children", "_id": "1", "_version": 1, "found": true, "_source": { "name": "gymbo", "content": "I hava a friend who loves smile, gymbo is his name", "language": "english", "length": "75" } }
刪除語句:DELETE /music/children/1
響應結果:
{ "_index": "music", "_type": "children", "_id": "1", "_version": 4, "result": "deleted", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 3, "_primary_term": 1 }
上一節說起的增刪改操做,是針對單個document的,Elasticsearch還有一個批處理命令,能夠批量執行這些操做。
POST /music/children/_bulk {"index":{"_id":"1"}} {"name": "gymbo", "content": "I hava a friend who loves smile, gymbo is his name", "language": "english", "length": "75"} {"create":{"_id":"2"}} {"name": "wake me, shark me", "content": "don't let me sleep too late", "language": "english", "length": "55"} { "update": {"_id": "2", "retry_on_conflict" : 3} } { "doc" : {"content" : "don't let me sleep too late, gonna get up brightly early in the morning"} } { "delete": {"_id": "3" }}
能夠把多條命令放在一塊兒執行,若是一個bulk請求內有不一樣的index和type,能夠把index和type也能夠寫在body json裏,每個操做要兩個json串:
{"action": {"metadata"}} {"data"}
delete例外,它只須要1個json串就能夠了
action的類型有如下幾種:
bulk注意事項
bulk api有嚴格的語法要求,每一個json串內不能換行,同時每一個json串之間必需要有一個換行,不然會報語法錯誤。
bulk既然是多條命令批量執行,遇到錯誤怎麼辦?會中斷嗎?
若是bulk請求內有命令執行錯誤,會直接跳過,繼續執行下一條,同時在響應報文裏會對每條命令的結果分別展現,正確的就展現正確的結果,錯誤的會相應提示錯誤日誌。
bulk的性能問題
bulk既然是批處理,那bulk size與最佳性能確定存在必定的聯繫,bulk請求的內存會先加載到內存裏,bulk的請求取決於命令的條數和每一個命令內容的多少,與性能的關係示例圖(表達概念,數據不具有參考性)以下:
bulk性能優化的目標就是找到這個拐點,須要反覆嘗試一個最佳的size,跟具體的業務數據特性,併發量有關,常見的設置範圍通常是1000-5000之間,bulk請求的大小控制在5-15MB之間(僅供參考)。
本篇簡單介紹了一下document的數據格式,並順帶講解了一下Elasticsearch集羣紅黃綠三種狀態的斷定標準,重點是在kibana平臺演示的CRUD小案例和bulk批處理示例,最爲基礎,能夠多花一些時間熟悉熟悉。
專一Java高併發、分佈式架構,更多技術乾貨分享與心得,請關注公衆號:Java架構社區