1. 程式人生 > >Elasticsearch叢集搭建及Python互動

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"

(完)