- elasticsearch 是什麼?
elasticsearch 簡稱 es,是一個開源的分散式搜尋引擎,可以用來實現搜尋、日誌統計、分析、系統監控等功能。
- 安裝
1、下載
官網下載地址
2、 解壓
tar zxvf elasticsearch-8.13.0-linux-x86_64.tar.gz -C /usr/local/
3、解決JDK依賴問題
新版本的 es 壓縮包中包含自帶的jdk
,如果當前 Linux 環境中已經安裝了 jdk,啟動 es 時預設找的是已經裝好的jdk,此時可能會由於 jdk 版本不一致而報錯!
進入 bin 目錄下修改 elasticsearch 配置
# 將jdk修改為es中自帶jdk的配置目錄
export JAVA_HOME=/usr/local/elasticsearch-7.13.2/jdk
export PATH=$JAVA_HOME/bin:$PATH
if [ -x "$JAVA_HOME/bin/java" ]; then
JAVA="/usr/local/elasticsearch-8.13.0/jdk/bin/java"
else
JAVA=`which java`
fi
4、建立 es 使用者
注意root使用者不能啟動!
#建立使用者
useradd user-es
#遞迴設定 es 目錄使用者及使用者組
chown user-es:user-es -R /usr/local/elasticsearch-8.13.0
#切換使用者
su user-es
#進入bin目錄
cd /usr/local/elasticsearch-8.13.0/bin
#啟動elasticsearch
./elasticsearch
本地訪問http://ip:9200
進行測試,預設會需要輸入密碼
如需取消登入密碼,將 /usr/local/elasticsearch-8.13.0/config/elasticsearch.yml
檔案中 xpack.security.enabled
引數修改為 false
。
修改日誌路徑、埠號等資訊檔案:
/usr/local/elasticsearch-7.13.2/config/elasticsearch.yml
補充:以下問題可能會遇到
- es 記憶體不足問題
vim /usr/local/elasticsearch-8.13.0/config/jvm.options
## -Xms4g
## -Xmx4g
修改為(注意頂格,不要留空格):
-Xms1g
-Xmx1g
- 使用 Python 操作 es
目的:將某一目錄下的大量檔案全部匯入到 es,之後對某個檔案進行查詢操作
- 版本一
import os
from datetime import datetime
from elasticsearch import Elasticsearch
#連線到 es
es = Elasticsearch(['http://ip:port'])
file_index = "test1"
directory = "/mnt/dir1"
for root, dirs, files in os.walk(directory):
for filename in files:
file_path = os.path.join(root, filename)
if not es.exists(index=file_index, id=file_path):
file_info = {
"file_path": file_path,
"file_size": os.path.getsize(file_path),
"created_at": datetime.fromtimestamp(os.path.getctime(file_path)),
}
#插入檔案資訊
es.index(index=file_index, id=file_path, body=file_info)
else:
#print(f"Document with id '{file_path}' already exists in the index.")
pass
#查詢
file_name = "file2"
query = {
"query": {
"match": {
"file_path": file_name
}
}
}
result = es.search(index="test1", body=query)
for hit in result['hits']['hits']:
print(hit['_source'])
#es.indices.delete(index=file_index)
實現了基本功能,但效率極低
- 版本二
一條一條將檔案資訊插入到 es 效率太低,可以將資料打包好再發給 es,使用 es 的 bluk 庫一併提交
bulk指令用於批次新增、更新或刪除文件。這個指令允許使用者在一個請求中提交多個操作
import os
from datetime import datetime
from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulk
#連線到 es
es = Elasticsearch(['http://ip:port'])
file_index = "test1"
directory = "/mnt/dir1"
data = []
for root, dirs, files in os.walk(directory):
for filename in files:
file_path = os.path.join(root, filename)
if not es.exists(index=file_index, id=file_path):
file_info = {
"file_path": file_path,
"file_size": os.path.getsize(file_path),
"created_at": datetime.fromtimestamp(os.path.getctime(file_path)),
}
#打包資料
data.append(file_info)
else:
#print(f"Document with id '{file_path}' already exists in the index.")
pass
#批次提交
success, failed = bulk(es, data)
print(f"成功寫入文件數: {success}, 失敗文件數: {failed}")
#查詢
file_name = "file2"
query = {
"query": {
"match": {
"file_path": file_name
}
}
}
result = es.search(index="test1", body=query)
for hit in result['hits']['hits']:
print(hit['_source'])
#es.indices.delete(index=file_index)
- 版本四
分片 + 執行緒池 + bulk
import os
import concurrent.futures
from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulk
# Elasticsearch連線配置
es = Elasticsearch(['http://ip:port'])
files_index = "test4"
directory = "/mnt/dir1"
# 準備一個函式用於將檔案資訊匯入到Elasticsearch中
def index_files_bulk(file_paths):
actions = []
for file_path in file_paths:
file_info = {
'file_name': os.path.basename(file_path),
'file_path': file_path,
# 這裡可以根據需要新增更多的檔案資訊
}
# 準備批次操作
doc_id = hash(file_path) # 以檔案路徑的雜湊值作為文件ID
action = {
'_op_type': 'update',
'_index': files_index,
'_id': doc_id,
'doc': file_info,
'doc_as_upsert': True # 如果文件不存在則插入
}
actions.append(action)
# 使用批次操作
bulk(es, actions)
def index_files_parallel(directory):
file_paths = []
for root, dirs, files in os.walk(directory):
for file in files:
file_paths.append(os.path.join(root, file))
# 使用多執行緒處理檔案資訊匯入
with concurrent.futures.ThreadPoolExecutor() as executor:
# 將檔案路徑切分成小塊,每個執行緒處理一部分
chunk_size = 1000 # 每個執行緒處理的檔案數量
for i in range(0, len(file_paths), chunk_size):
chunk = file_paths[i:i + chunk_size]
executor.submit(index_files_bulk, chunk)
# 呼叫函式並行匯入檔案資訊到Elasticsearch中
#index_files_parallel(directory)
#查詢
file_name = "file4"
query = {
"query": {
"match": {
"file_path": file_name
}
}
}
result = es.search(index="test1", body=query)
for hit in result['hits']['hits']:
print(hit['_source'])
#es.indices.delete(index=file_index)
未完。。。。