倒排索引存儲-分段存儲(lucene的功能)
在lucene中:lucene index包含了若干個segment
在elasticsearch中:index包含了若干主從shard,shard包乾了若干segment
segment是elasticsearch中存儲的最小文件單元,也就是分段存儲,segment被設計爲不可變的
新增:新創建索引時,新建一個segment存儲新的數據
刪除:由於segment是隻讀的,所以在索引文件中新增了.del文件,專門存儲被刪除的數據id,當查詢時被刪除的數據仍能被查詢,進行查詢結果合併時纔會過濾掉,merge segment時會真正刪除
更新:新增和刪除的組合
segment的不可變性的優點
- 不需要鎖(沒有直接修改已經存在段的情況)
- 可以利用內存,由於segment不可變,所以segment被加載到內存後無需改變,只要內存足夠,segment就可以長期駐村,大大提升查詢性能
- 更新、新增的增量的方式很輕,性能好
segment的不可變性的缺點
- 刪除操作不會馬上刪除有一定的空間浪費
- 頻繁更新涉及到大量的刪除動作,會有大量的空間浪費
- segment的數量可能非常多,對服務器的文件句柄消耗很大,查詢性能會隨着segment的數量增加而增加
新增數據的過程
這個流程的目的是:提升寫入性能(異步落盤)
1、保存到index buffer中,同時寫入Transaction log(防止內存的數據丟失,有點想redo log)
2、當index buffer空間滿了(默認佔用jvm10%)或每1秒(通過index.refresh_interval 配置)執行Refresh操作,寫入segment並清空index buffer(這裏的1秒內是查不到剛保存的數據的,所以es也被成爲近實時的搜索引擎)
3、於此同時將segment刷入內存,開放查詢
4、flush操作將segment寫入磁盤(默認30分鐘執行一次)
flash操作包含:
- 調用一次refresh
- fsync:將segment寫入磁盤
- 清空對應的trans log