Elasticsearch叢集搭建及Python互動
本文記錄Elasticsearch物理叢集的安裝步驟,在3臺機器上部署一個叢集。行文順序為整個安裝過程從頭到尾,期間發現不少問題。因此,本文不適合一步步跟著做,建議您看完整篇文章,然後再開始搭建叢集。
1 . 環境
- 機器: 3臺物理機器,分別為130,132,134
- 作業系統:CentOS 6.6
- Elasticsearch: 2.3.3 版本
確保安裝相應版本JDK,使用java -version
確認安裝。
2. 下載安裝
從官網下載穩定版本:
wget https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution /tar/elasticsearch/2.3.3/elasticsearch-2.3.3.tar.gz
拷貝到待安裝的目錄:
cp /home/soft/es/elasticsearch-2.3.3.tar.gz /opt/es
解壓:
cd /opt/es
tar -zxvf elasticsearch-2.3.3.tar.gz
3.配置叢集
elasticsearch的配置檔案採用YAML標記語言,在config目錄下:
vim elasticsearch-2.3.3/config/elasticsearch.yml
需要的基本配置主要包括:
- cluster.name: 叢集名稱,叢集名稱用於跟其他相同名字的節點構成整個叢集.
- node.name: 節點名稱, 是該elasticsearch例項的唯一標識
- path.data: 資料路徑,指定文件,索引存放的位置。
- path.logs:日誌路徑,指定執行日誌的存放目錄
- network.host: 主機名稱
一個示例配置如下:
cluster.name: brandon-elasticsearch
#
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
#
node.name: node-130
#
# Add custom attributes to the node:
#
# node.rack: r1
#
# ----------------------------------- Paths ------------------------------------
#
# Path to directory where to store the data (separate multiple locations by comma):
#
path.data: /home/data/es
#
# Path to log files:
#
path.logs: /var/log/es
network.host: 192.168.1.132
配置完成後,將整個檔案copy到132和134.
scp -r elasticsearch-2.3.3 root@192.168.1.132:/opt/es
scp -r elasticsearch-2.3.3 root@192.168.1.134:/opt/es
4. 啟動及問題解決
完成叢集配置之後,啟動:
./elasticsearch-2.3.3/bin/elasticsearch
出現如下異常:
java.lang.RuntimeException: don't run elasticsearch as root.
at org.elasticsearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:93)
at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:144)
at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:270)
at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:35)
Elasticsearch不允許使用root賬號啟動,因此需要建一個專用的賬號。
adduser es
passwd es
chown -R es ./elasticsearch-2.3.3
再次啟動,還是異常:
從日誌可以看出是資料路徑和日誌路徑的許可權問題,修改對應檔案的許可權:
chown -R es /home/data/es/
chown -R es /var/log/es/
其他2臺機器也要一樣的操作,很麻煩,尤其是在多臺機器的時候,因此建議一開始就先建立賬號,再安裝ElasticSearch。
再啟動,成功:
其他機器使用一樣的方式啟動。
檢視叢集資訊,啟動瀏覽器訪問如下頁面:http://192.168.1.132:9200/。發現叢集只有一個節點,說明3臺機器並沒有構成一個叢集,查詢文件發現需要配置其他機器的ip,如下:
discovery.zen.ping.unicast.hosts: ["192.168.1.130", "192.168.1.134"]
其他節點配置類似。重新啟動,從日誌中可以看出32這個節點作為salve加入到master中:
如果此時停掉master,elasticsearch將重新選舉出新的master,日誌可以證明這一點:
大功告成。但是用這種方式啟動,一旦退出命令列,elasticsearch就會停止,有以下2中解決方案;
此時如果退出控制檯,es會被關掉,解決方式:
1) 使用rpm安裝,然後service elasticsearch start
2) nohup後臺執行
5. 使用Python與Elasticsearch互動
Elasticsearch對外提供REST API,同時也可以使用二進位制協議與其互動。各種語言的客戶端都提供了相應的封裝,這裡以python為例說明。
我們使用elasticsearch-py,可以在這裡查到相關資訊。
使用pip安裝:
pip install elasticsearch
簡單的搜尋例子:
from elasticsearch import Elasticsearch
from elasticsearch import helpers
es = Elasticsearch()
res = es.get(index="megacorp", doc_type="employee", id=1)
print res
下面這個例子使用批量api,批量匯入網上抓取的微博資料:
from elasticsearch import Elasticsearch
from elasticsearch import helpers
import sys
# 設定編碼,避免中文亂碼
reload(sys)
sys.setdefaultencoding('utf8')
# 連線到叢集,提供節點,不一定要全部節點
es = Elasticsearch(["192.168.1.130", "192.168.1.132","192.168.1.134"])
# 開啟檔案準備讀取資料
file_name = 'E:\weibo_freshdata.2016-05-31'
wbfile = open(file_name, 'r')
actions = []
# 迴圈每一行
for line in wbfile:
fields = line.split('\t')
action = {
"_index": "wb",
"_type": "may",
"_id": fields[0],
"_source": {"id": fields[0], 'crawler_time': fields[1], 'crawler_time_stamp': fields[2],
'is_retweet': fields[3],
'user_id': fields[4],
'nick_name': fields[5], 'touxiang': fields[6], 'user_type': fields[7], 'weibo_id': fields[8],
'weibo_content': fields[9],
'zhuan': fields[10], 'ping': fields[11], 'zhan': fields[12], 'url': fields[13],
'device': fields[14],
'locate': fields[15],
'time': fields[16],
'time_stamp': fields[17],
'r_user_id': fields[18],
'r_nick_name': fields[19],
'r_user_type': fields[20],
'r_weibo_id': fields[21],
'r_weibo_content': fields[22],
'r_zhuan': fields[23],
'r_ping': fields[24],
'r_zhan': fields[25],
'r_url': fields[26],
'r_device': fields[27],
'r_location': fields[28],
'r_time': fields[29],
'r_time_stamp': fields[30],
'pic_content': 'http://ww3.sinaimg.cn/large/' + fields[31] + '.jpg'}
}
actions.append(action)
# 每1完條批量匯入一次
if len(actions) == 10000:
# helper批量匯入
helpers.bulk(es, actions)
actions = []
print "insert 10000"
if len(actions) > 0:
# 匯入最後剩餘的資料
helpers.bulk(es, actions)
print "finish"
(完)