Literate Computing for Reproducible Infrastructure: Elasticsearch運用をJupyter + Ansibleでおこなう際のお手本Notebookです。
このリポジトリでは、Elasticsearch( https://www.elastic.co/jp/products/elasticsearch )の環境を構築し、運用するためのNotebook例を紹介しています。
なお、これらのNotebookはNIIクラウドチーム内で行っている作業の考え方を示すためのもので、環境によってはそのままでは動作しないものもあります。
Literate-computing-Elasticsearch (c) by National Institute of Informatics
Literate-computing-Elasticsearch is licensed under a Creative Commons Attribution 4.0 International License.
You should have received a copy of the license along with this work. If not, see http://creativecommons.org/licenses/by/4.0/.
Elasticsearchは、リアルタイムにデータを検索/分析するための分散型の全文検索エンジンであり、次のような特徴を持っています。
-
リアルタイム分析
収集したデータをリアルタイムに検索/分析することができます。
また、高速に検索できるため、他のBIツールのように事前に分析項目を決めなくても、すでに蓄積されたデータに対してインタラクティブな分析をすることが可能です。 -
クラスタリングが容易
クラスタリングを想定した設計が行われており、他のミドルウェアを利用せずにクラスタを組むことができます。
ノードを追加することによりスケールアウトできるため、必要な処理性能や可用性などに応じたコントロールが容易です。 -
ドキュメント指向、スキーマフリー
データベースであれば、データをレコードの単位で管理しますが、 Elasticsearchではドキュメントと呼ばれる構造化されたJSONデータの形式で管理します。
すべてのフィールドはデフォルトでインデックスされるため、簡単かつ高速に検索できます。
また、このドキュメントはスキーマを決めずに投入することもできるため、すぐに使い始めることができます。
なお、ログデータのような構造化されていないデータを投入する際には、Logstashなどを用いてJSON形式に加工して保持することになります。 -
REST API
Elasticsearchはシンプルで使いやすいREST APIを提供しています。
検索処理や登録処理(indexing)だけでなく、インデックスやマッピングの定義、クラスタ管理やメンテナンスなど、Elasticsearchのクラスタ・ノードに対する操作は、ほぼすべてAPIを通じて実施できます。 -
オープンソース
Elasticsearchはオープンソース製品として開発されています。
ライセンスはApache License Version 2.0です。
ただし、一部のプラグインを利用するためにはサブスクリプション契約(兼サポート契約)を結ぶ必要があります。
このNotebookで前提にしているOS/ミドルウェアのバージョンは次の通りです。
OS/ミドルウェア | バージョン |
---|---|
Elasticserach | elasticsearch-6.1.3-1.noarch |
Logstash | logstash-6.1.3-1.noarch |
Ansible | 2.4.2.0 |
OS | CentOS Linux release 7.2.1511 |
JDK | jdk1.8.0_112-1.8.0_112-fcs.x86_64 |
お手本NotebookはこのNotebookと同じディレクトリにあります。
Notebook名は XX_(XX_)Notebook名
の形で表現され、Jupyter Notebookのファイル一覧の上でも整理された形で表示できるようにしてあります。
お手本Notebookとそれぞれの利用局面の関係については、以下のフローを参考にしてください。
from IPython.display import SVG
SVG(filename='images/notebooks-filled.svg')
※SVGファイルには各Notebookへのリンクを埋め込んでおります。notebooks-filled.svgから参照可能です。
構築フェーズは、構築・運用対象とするElasticsearchのためのマシンを準備し、ソフトウェアのインストール、設定を行います。
確認・診断フェーズは、構築したElasticsearchの日々の運用や、問題発生時の健康診断を行います。
改善フェーズは、健康診断の結果、Nodeの追加により容量を増やしたり、データをクリーンアップしたりといった操作を行います。
各Notebookの詳細な目次を参照するには、以下のセルを実行(Run cell
)してください。Notebookファイルへのリンクが表示されます。
%run scripts/get-display-contents.py
display_notebook_contents()
/usr/local/lib/python2.7/dist-packages/cffi/model.py:525: UserWarning: 'point_conversion_form_t' has no values explicitly defined; guessing that it is equivalent to 'unsigned int'
% self._get_c_name())
About: Prerequisites for Literate Computing via Notebook - 文芸的機械化の準備 - Notebookでね
Ansibleの設定 - Notebook環境は、以下の条件を満たしている必要がある。
・AnsibleでDefault Moduleが利用可能であること - A - DefaultのModuleが使えればよい。特にカスタマイズすべき項目はなし。
資材の準備 - - Oracle JDK ライセンス認証・RPMパッケージの配置
・JVMの資材が準備されていること - A - Elasticsearchを動作させるのに必要なJVMのファイルを用意します。
・Elasticsearchのダウンロードサイトにアクセスできること - A - Elasticsearchの媒体を公式サイトからダウンロード可能か確認します。
Elastic Stackの構築:概要 - Elastic Stackの概念やNodeの種類、 サイジングの観点について説明します。
・基本概念 - 実際の構築の前に、クラスタやそれを構成するNodeに関する基本概念を説明します。
・サイジングの考え方 - 構築にあたり、1サーバのスペック、設定するshardの数、各役割のノード数を決める必要があります。
・典型的な構成 - Elasticsearchを動作させるための典型的な設定を示します。
・設定の出力 - 前の章の構成例を元に、この後の「収容」「インストール」のNotebookで用いるパラメータを生成します。
Elastic Stackの構築手順:収容(AWS) - Elasticsearchのインストール先となる Amazon EC2インスタンスを確保します。
・設定 - インスタンスの生成に必要な情報を設定します。
・EC2インスタンスの設定と生成 - サーバ構成に応じたEC2インスタンスの設定を定義し、インスタンスを生成します。
・Inventory作成用のインスタンスリストを作成 - ホストのパブリックDNS一覧をリスト化します
Elastic Stackの構築手順:収容(GCE) - Elasticsearchのインストール先となるGoogle Compute Engineインスタンスを確保します。
動作環境の確認 - このNotebookは、 [Google Python Client Library](https://github.com/google/google-api-python-client) を使ってマシンの確保を行います。そのため、Libraryがインポート可能であることの確認と、Credentialsが設定されている
・Libraryの確認 - このNotebook環境にGoogle Python Client Libraryがインストールされている必要があります。インストールされていない場合は、以下のセル実行に失敗し、 ImportError となります。
・Credentialの指定 - Google Compute EngineにアクセスするためのCredentialを指定してください。
GCEインスタンスの設定と生成 - サーバ構成に応じたGCEインスタンスの設定を定義し、インスタンスを生成します。
・ゾーンの設定 - どのZoneにインスタンスを確保するかを定義しておく。
・インスタンスの設定
・Inventory作成用のインスタンスリストを作成
Elastic Stackの構築手順:インベントリの設定 - Ansibleで利用するインベントリ情報を ファイルに出力します。
・設定 - アカウントや通信先などを設定します。
・既存のインベントリのバックアップ - 出力前に、既存の内容をバックアップ用ディレクトリに退避します。
・ファイルの生成 - インベントリファイルを生成します。
・内容の確認・修正 - 生成したインベントリファイルの内容を確認、修正したり、前回のバージョンと比較したい場合は以下から実施できます。
・インベントリのテスト - 作成したインベントリにある各ホストに、Ansibleから各種の操作が可能か確認します。
Elastic Stackの構築手順:インストール - Elasticsearchをインストールし、 各種パラメータを設定してクラスタを構築します。
・設定 - アカウントや通信先などを設定します。
・インストール - Elasticsearchのインストールし、設定、起動します。
・クラスタのステータスの確認方法と監視方法 - クラスタのステータスを確認するためにCluster APIを発行します。
・Logstashへのサンプルデータ投入(オプション) - インストール済みのLogstashに、この後のNotebookで利用するサンプルデータを投入します。
Elastic Stackの構築:状態の診断 - 稼働しているElasticsearchに異常がないか調べ、 異常がある場合の対処手順について説明します。
・準備 - 本章のコマンドを実行するための設定を行います。
・診断 - 現在の状態を把握するために、各種の状態を診断します。
・症状と対処 - 診断の章で異常があった場合、本章の内容に従い対処します。
Data Node追加操作 - 新しいData Nodeを クラスタに追加します。
・準備 - 本章のコマンドを実行するための設定を行います。
・サーバの追加生成 - Data Nodeを生成する先のサーバを生成します。
・インベントリへホストを追加 - 追加したホスト情報を既存のインベントリに追記します。
・追加したホストへのインストール - 追加したホストに、Elasticsearchをインストールし、設定します。
・クラスタの状態確認 - クラスタに追加したData Nodeが参加できているか確認します。
・Data Node追加・障害復旧時の注意点 - Data Nodeを追加したり、一度障害が発生してクラスタから抜けたData Nodeを復旧させる際の注意点について説明します。
Force Merge操作 - ディスクの使用量を削減するために、強制的な Merge操作によってセグメント数を減らします。
・準備 - 本章のコマンドを実行するための設定を行います。
・削除可能なデータ件数の確認 - 削除フラグがonの状態のデータが何件あるか、Indices Statsで確認します。
・Force Merge APIの発行 - 実際にAPIを発行します。
バックアップ&リストア - Data Node上にあるデータのバックアップと リストアについて説明します。
・準備
・バックアップ - バックアップ方法について説明します。
・リストア - リストア方法について説明します。
サーチエンジンとしての利用手順(検索) - 様々な条件で投入したドキュメントを検索する 方法について説明します。
・サーチエンジンとしてのElasticsearch
・リクエストの基本構文
・ドキュメントの検索
・ドキュメントの追加
・ドキュメントの更新
・ドキュメントの削除
・大量データ取得時の検索
・実行クエリ解析
サーチエンジンとしての利用手順(集計) - 検索したドキュメントをさらに集計する 方法について説明します。
・準備
・Aggregationとは
・リクエストの基本構文
・レスポンスの基本構文
・Metrics Aggregations
・Bucket Aggregations
・Pipeline Aggregations
・Matrix Aggregations
・実行クエリ解析
サーチエンジンとしての利用手順(データ蓄積) - LogstashからElasticsearchへ、様々な形式の データを蓄積する方法について説明します。
・準備
・Logstashとは
・Logstashの設定
・データフォーマット
・データ加工
・Ingest Nodeの利用方法
・トラブルシューティング
サーチエンジンとしての利用手順(インデックス設計) - インデックスに与えるマッピング定義の内容や、 reindexの方法について説明します。
・準備
・マッピング設定
・マッピングの設定方法と注意点
・reindex APIを使った投入後データの加工方法
・パラメータ設定
About: Notebookの利用フローまとめ - Notebookの利用フローを図としてまとめる例です。
必要なツール - このNotebookの実行には[blockdiag](http://blockdiag.com/ja/blockdiag/)が必要です。
ブロック図による一覧生成 - 以下のセルを実行(`Run All Below`)することで、Notebookがそれぞれどのような局面での利用を想定しているのか、ブロック図で確認することができます。
・雛形の生成 - まず、Notebookの利用フローを表したブロック図の雛形を作成します。
・詳細情報の埋め込み - 生成した雛形に対して、見出しの情報など詳細な情報を埋め込みます。
後始末 - 一時ファイルを削除します。
お手本Notebookを使う場合は、お手本をコピーし、そのコピーを開きます。このように、お手本と作業証跡は明確に分けながら作業をおこないます。
また、お手本をコピーする際は、 YYYYMMDD_NN_
といった実施日を示すプレフィックスを付加することで、後で整理しやすくしています。
以下のJavaScriptを実行することで、簡単にお手本から作業用Notebookを作成することもできます。
以下のセルを実行すると、Notebook名のドロップダウンリストと[作業開始]ボタンが現れます。 [作業開始]ボタンを押すと、お手本Notebookのコピーを作成した後、自動的にブラウザでコピーが開きます。 Notebookの説明を確認しながら実行、適宜修正しながら実行していってください。
from datetime import datetime
import shutil
def copy_ref_notebook(src):
prefix = datetime.now().strftime('%Y%m%d') + '_'
index = len(filter(lambda name: name.startswith(prefix), os.listdir('.'))) + 1
new_notebook = '{0}{1:0>2}_{2}'.format(prefix, index, src)
shutil.copyfile(src, new_notebook)
print(new_notebook)
ref_notebooks = filter(lambda m: m, map(lambda n: re.match(r'([0-9][0-9a-z]+_.*)\.ipynb', n), os.listdir('.')))
ref_notebooks = sorted(ref_notebooks, key=lambda m: m.group(1))
frags = map(lambda m: '<option value="{name}">{title}</option>'.format(name=m.group(0), title=m.group(1)),
ref_notebooks)
HTML('''
<script type="text/Javascript">
function copy_otehon() {
var sel = document.getElementById('selector');
IPython.notebook.kernel.execute('copy_ref_notebook("' + sel.options[sel.selectedIndex].value + '")',
{'iopub': {'output': function(msg) {
window.open(msg.content.text, '_blank')
}}});
}
</script>
<select id="selector">''' + ''.join(frags) + '</select><button onclick="copy_otehon()">作業開始</button>')
00_Prerequisites for Literate Computing via Notebooks01_01_Outline01_02_Accommodation_AWS01_02g_Accommodation_GCE01_03_Set_Inventory01_04_Install01_05_Diagnostics01_50_Add_Data_Node01_51_Force_Merge01_52_Backup_Restore02_Search03_Aggregation04_Store_Data05_Indexing99_Summarizing notebooks作業開始
以下のセルで、お手本NotebookのZIPアーカイブを作成できます
ref_notebooks = filter(lambda m: m, map(lambda n: re.match(r'([A-Z][0-9][0-9a-z]+_.*)\.ipynb', n), os.listdir('.')))
ref_notebooks = sorted(ref_notebooks, key=lambda m: m.group(1))
!zip ref_notebooks-{datetime.now().strftime('%Y%m%d')}.zip *.ipynb {' '.join(map(lambda n: '"' + n.group(0) + '"', ref_notebooks))} logstash_conf/* playbooks/*.yml sample_data/* images/* scripts/*
updating: 00_Prerequisites for Literate Computing via Notebooks.ipynb (deflated 76%)
updating: 01_01_Outline.ipynb (deflated 81%)
updating: 01_02_Accommodation_AWS.ipynb (deflated 85%)
updating: 01_02g_Accommodation_GCE.ipynb (deflated 86%)
updating: 01_03_Set_Inventory.ipynb (deflated 86%)
updating: 01_04_Install.ipynb (deflated 87%)
updating: 01_05_Diagnostics.ipynb (deflated 89%)
updating: 01_50_Add_Data_Node.ipynb (deflated 80%)
updating: 01_51_Force_Merge.ipynb (deflated 95%)
updating: 01_52_Backup_Restore.ipynb (deflated 86%)
updating: 02_Search.ipynb (deflated 92%)
updating: 03_Aggregation.ipynb (deflated 94%)
updating: 04_Store_Data.ipynb (deflated 88%)
updating: 05_Indexing.ipynb (deflated 90%)
updating: 99_Summarizing notebooks.ipynb (deflated 89%)
updating: Delete_01_06_Manual-Operation.ipynb (deflated 94%)
updating: Delete_01_07_Troubleshooting.ipynb (deflated 88%)
updating: Readme.ipynb (deflated 84%)
updating: logstash_conf/csv.conf (deflated 53%)
updating: logstash_conf/document_id.conf (deflated 54%)
updating: logstash_conf/geoip.conf (deflated 45%)
updating: logstash_conf/json.conf (deflated 30%)
updating: logstash_conf/json_multiline.conf (deflated 41%)
updating: logstash_conf/ltsv.conf (deflated 81%)
updating: logstash_conf/main.conf (deflated 53%)
updating: logstash_conf/multi_line.conf (deflated 77%)
updating: logstash_conf/single_line.conf (deflated 78%)
updating: logstash_conf/tsv.conf (deflated 53%)
updating: logstash_conf/useragent.conf (deflated 36%)
updating: playbooks/copy_logstash_conf.yml (deflated 35%)
updating: playbooks/copy_sample_data.yml (deflated 28%)
updating: playbooks/install_elasticsearch.yml (deflated 36%)
updating: playbooks/install_jdk.yml (deflated 52%)
updating: playbooks/install_logstash.yml (deflated 34%)
updating: playbooks/set_api_parameter.yml (deflated 37%)
updating: playbooks/set_elasticsearch.yml (deflated 74%)
updating: playbooks/set_heap-size.yml (deflated 54%)
updating: playbooks/set_iptables-rule.yml (deflated 57%)
updating: playbooks/set_kernelparameter.yml (deflated 39%)
updating: playbooks/set_test.yml (deflated 35%)
updating: playbooks/start_cluster.yml (deflated 33%)
updating: sample_data/geoip.csv (deflated 79%)
updating: sample_data/geoip.json (deflated 79%)
updating: sample_data/mapping.txt (deflated 76%)
updating: sample_data/multi_line.txt (deflated 61%)
updating: sample_data/single_line.txt (deflated 43%)
updating: sample_data/tokyo2015.csv (deflated 74%)
updating: sample_data/useragent.txt (deflated 38%)
updating: sample_data/weather.csv (deflated 62%)
updating: sample_data/weather.json (deflated 89%)
updating: sample_data/weather.ltsv (deflated 50%)
updating: sample_data/weather.tsv (deflated 62%)
updating: sample_data/weather_multiline.json (deflated 89%)
updating: images/01_1server.png (deflated 10%)
updating: images/01_5server.png (deflated 23%)
updating: images/01_basic_concept.png (deflated 17%)
updating: images/01_node_type.png (deflated 7%)
updating: images/01_server_construction.png (deflated 10%)
updating: images/03_pipeline.png (deflated 16%)
updating: images/images.pptx (deflated 19%)
updating: images/notebooks-filled.svg (deflated 90%)
adding: scripts/generate-diagram.py (deflated 73%)
adding: scripts/get-display-contents.py (deflated 49%)
adding: scripts/get-json-repr.py (deflated 46%)
adding: scripts/get-replace-file.py (deflated 52%)
adding: scripts/get-struct-selector.py (deflated 61%)